1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-20 06:37:39 +01:00
libunwind-eh_elf/tests/ia64-test-rbs.c
mostang.com!davidm fb1997ff0a Add include of "ia64-test-rbs.h".
(NELEMS): New macro.
(RECURSION_DEPTH): Fix definition: loadup() allocates 93 local regs, not 95.
(spill_func_t): Make it return an "int".
(DCL): Adjust accordingly.
(verbose): New variable.
(nerrors): Make it an "int".
(unwind_count): Ditto.
(unwind_and_resume): Make it return an int.  Print info-output only if verbose is
	set.  After unwinding to the desired point, redirect IP to
	resumption_point_label and store return value in EH_ARG0 and original
	IP in EH_ARG1.
(run_check): New function.
(main): Remove open test code and call run_check() instead.

(Logical change 1.49)
2003-02-15 08:49:55 +00:00

165 lines
5.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include "ia64-test-rbs.h"
#define panic(args...) \
do { fprintf (stderr, args); ++nerrors; return -9999; } while (0)
#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64
implementations to at most 2048 physical stacked registers
(actually, slightly less than that, because loadrs also counts RNaT
slots). Since we can dirty 93 stacked registers per recursion, we
need to recurse RECURSION_DEPTH times to ensure all physical
stacked registers are in use. */
#define MAX_PHYS_STACKED 2048
#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 92) / 93)
typedef int spill_func_t (long iteration, int (*next_func[])());
extern int loadup (long iteration, int *values, int (*next_func[])());
extern char resumption_point_label;
#define DCL(n) \
extern int rbs_spill_##n (long iteration, int (*next_func[])())
DCL(2); DCL(3); DCL(4); DCL(5); DCL(6); DCL(7);
DCL(8); DCL(9); DCL(10); DCL(11); DCL(12); DCL(13); DCL(14); DCL(15);
DCL(16); DCL(17); DCL(18); DCL(19); DCL(20); DCL(21); DCL(22); DCL(23);
DCL(24); DCL(25); DCL(26); DCL(27); DCL(28); DCL(29); DCL(30); DCL(31);
DCL(32); DCL(33); DCL(34); DCL(35); DCL(36); DCL(37); DCL(38); DCL(39);
DCL(40); DCL(41); DCL(42); DCL(43); DCL(44); DCL(45); DCL(46); DCL(47);
DCL(48); DCL(49); DCL(50); DCL(51); DCL(52); DCL(53); DCL(54); DCL(55);
DCL(56); DCL(57); DCL(58); DCL(59); DCL(60); DCL(61); DCL(62); DCL(63);
DCL(64); DCL(65); DCL(66); DCL(67); DCL(68); DCL(69); DCL(70); DCL(71);
DCL(72); DCL(73); DCL(74); DCL(75); DCL(76); DCL(77); DCL(78); DCL(79);
DCL(80); DCL(81); DCL(82); DCL(83); DCL(84); DCL(85); DCL(86); DCL(87);
DCL(88); DCL(89); DCL(90); DCL(91); DCL(92); DCL(93); DCL(94);
#define SPL(n) rbs_spill_##n
spill_func_t *spill_funcs[] =
{
SPL(2), SPL(3), SPL(4), SPL(5), SPL(6), SPL(7),
SPL(8), SPL(9), SPL(10), SPL(11), SPL(12), SPL(13), SPL(14), SPL(15),
SPL(16), SPL(17), SPL(18), SPL(19), SPL(20), SPL(21), SPL(22), SPL(23),
SPL(24), SPL(25), SPL(26), SPL(27), SPL(28), SPL(29), SPL(30), SPL(31),
SPL(32), SPL(33), SPL(34), SPL(35), SPL(36), SPL(37), SPL(38), SPL(39),
SPL(40), SPL(41), SPL(42), SPL(43), SPL(44), SPL(45), SPL(46), SPL(47),
SPL(48), SPL(49), SPL(50), SPL(51), SPL(52), SPL(53), SPL(54), SPL(55),
SPL(56), SPL(57), SPL(58), SPL(59), SPL(60), SPL(61), SPL(62), SPL(63),
SPL(64), SPL(65), SPL(66), SPL(67), SPL(68), SPL(69), SPL(70), SPL(71),
SPL(72), SPL(73), SPL(74), SPL(75), SPL(76), SPL(77), SPL(78), SPL(79),
SPL(80), SPL(81), SPL(82), SPL(83), SPL(84), SPL(85), SPL(86), SPL(87),
SPL(88), SPL(89), SPL(90), SPL(91), SPL(92), SPL(93), SPL(94)
};
static int verbose;
static int nerrors;
static int unwind_count;
static int
unwind_and_resume (long iteration, int (*next_func[])())
{
unw_context_t uc;
unw_cursor_t c;
unw_word_t ip;
int i, ret;
if (verbose)
printf (" %s: test%ld, next_func=%p\n",
__FUNCTION__, iteration, next_func);
unw_getcontext (&uc);
if ((ret = unw_init_local (&c, &uc)) < 0)
panic ("unw_init_local (ret=%d)", ret);
for (i = 0; i < unwind_count; ++i)
if ((ret = unw_step (&c)) < 0)
panic ("unw_step (ret=%d)", ret);
if (unw_get_reg (&c, UNW_REG_IP, &ip) < 0
|| unw_set_reg (&c, UNW_REG_IP, (unw_word_t) &resumption_point_label) < 0
|| unw_set_reg (&c, UNW_REG_EH_ARG0, 0) /* ret val */
|| unw_set_reg (&c, UNW_REG_EH_ARG1, ip))
panic ("failed to redirect to resumption_point\n");
if (verbose)
{
unw_word_t bsp;
if (unw_get_reg (&c, UNW_IA64_BSP, &bsp) < 0)
panic ("unw_get_reg() failed\n");
printf (" bsp=%lx, old ip=%lx, new ip=%p\n", bsp,
ip, &resumption_point_label);
}
ret = unw_resume (&c);
panic ("unw_resume() returned (ret=%d)!!\n", ret);
return 0;
}
static int
run_check (int test)
{
int nfuncs, nspills, n, ret, i, reg_values[88];
spill_func_t *func[NSTACKS + 1];
/* First, generate a set of 88 random values which loadup() will load
into loc2-loc89 (r37-r124). */
for (i = 0; i < NELEMS (reg_values); ++i)
{
reg_values[i] = random ();
/* Generate NaTs with a reasonably probability (1/16th): */
if (reg_values[i] < 0x10000000)
reg_values[i] = 0;
}
nspills = 0;
nfuncs = 0;
do
{
n = random () % NELEMS (spill_funcs);
func[nfuncs++] = spill_funcs[n];
nspills += 2 + n;
}
while (nspills < 128);
func[nfuncs++] = unwind_and_resume;
unwind_count = 1 + (random () % (nfuncs + RECURSION_DEPTH));
if (verbose)
printf ("test%d: nfuncs=%d, unwind_count=%d\n",
test, nfuncs, unwind_count);
ret = loadup (RECURSION_DEPTH, reg_values, func);
if (ret < 0)
panic ("test%d: load() returned %d\n", test, ret);
else if (ret != RECURSION_DEPTH + 1 + nfuncs - unwind_count)
panic ("test%d: resumed wrong frame: expected %d, got %d\n",
test, RECURSION_DEPTH + 1 + nfuncs - unwind_count, ret);
return 0;
}
int
main (int argc, char **argv)
{
int i;
if (argc > 1)
verbose = 1;
for (i = 0; i < 100000; ++i)
run_check (i + 1);
if (nerrors > 0)
{
fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
exit (-1);
}
if (verbose)
printf ("SUCCESS.\n");
return 0;
}