mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-03-10 18:30:08 +01:00
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)
This commit is contained in:
parent
d8023cf208
commit
fb1997ff0a
1 changed files with 91 additions and 24 deletions
|
@ -4,24 +4,29 @@
|
||||||
#define UNW_LOCAL_ONLY
|
#define UNW_LOCAL_ONLY
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
|
|
||||||
#define panic(args...) \
|
#include "ia64-test-rbs.h"
|
||||||
do { fprintf (stderr, args); ++nerrors; return; } while (0)
|
|
||||||
|
#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
|
/* The loadrs field in ar.rsc is 14 bits wide, which limits all ia64
|
||||||
implementations to at most 2048 physical stacked registers
|
implementations to at most 2048 physical stacked registers
|
||||||
(actually, slightly less than that, because loadrs also counts RNaT
|
(actually, slightly less than that, because loadrs also counts RNaT
|
||||||
slots). Since we can dirty 95 stacked registers per recursion, we
|
slots). Since we can dirty 93 stacked registers per recursion, we
|
||||||
need to recurse RECURSION_DEPTH times to ensure all physical
|
need to recurse RECURSION_DEPTH times to ensure all physical
|
||||||
stacked registers are in use. */
|
stacked registers are in use. */
|
||||||
#define MAX_PHYS_STACKED 2048
|
#define MAX_PHYS_STACKED 2048
|
||||||
#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 94) / 95)
|
#define RECURSION_DEPTH ((MAX_PHYS_STACKED + 92) / 93)
|
||||||
|
|
||||||
typedef void spill_func_t (long iteration, void (*next_func[])());
|
typedef int spill_func_t (long iteration, int (*next_func[])());
|
||||||
|
|
||||||
extern void loadup (long iteration, int *values, void (*next_func[])());
|
extern int loadup (long iteration, int *values, int (*next_func[])());
|
||||||
|
extern char resumption_point_label;
|
||||||
|
|
||||||
#define DCL(n) \
|
#define DCL(n) \
|
||||||
extern void rbs_spill_##n (long iteration, void (*next_func[])())
|
extern int rbs_spill_##n (long iteration, int (*next_func[])())
|
||||||
DCL(2); DCL(3); DCL(4); DCL(5); DCL(6); DCL(7);
|
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(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(16); DCL(17); DCL(18); DCL(19); DCL(20); DCL(21); DCL(22); DCL(23);
|
||||||
|
@ -52,18 +57,21 @@ spill_func_t *spill_funcs[] =
|
||||||
SPL(88), SPL(89), SPL(90), SPL(91), SPL(92), SPL(93), SPL(94)
|
SPL(88), SPL(89), SPL(90), SPL(91), SPL(92), SPL(93), SPL(94)
|
||||||
};
|
};
|
||||||
|
|
||||||
static long nerrors;
|
static int verbose;
|
||||||
static long unwind_count;
|
static int nerrors;
|
||||||
|
static int unwind_count;
|
||||||
|
|
||||||
static void
|
static int
|
||||||
unwind_and_resume (long iteration, void (*next_func[])())
|
unwind_and_resume (long iteration, int (*next_func[])())
|
||||||
{
|
{
|
||||||
unw_context_t uc;
|
unw_context_t uc;
|
||||||
unw_cursor_t c;
|
unw_cursor_t c;
|
||||||
|
unw_word_t ip;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
printf ("%s: iteration=%ld, next_func=%p\n",
|
if (verbose)
|
||||||
__FUNCTION__, iteration, next_func);
|
printf (" %s: test%ld, next_func=%p\n",
|
||||||
|
__FUNCTION__, iteration, next_func);
|
||||||
|
|
||||||
unw_getcontext (&uc);
|
unw_getcontext (&uc);
|
||||||
if ((ret = unw_init_local (&c, &uc)) < 0)
|
if ((ret = unw_init_local (&c, &uc)) < 0)
|
||||||
|
@ -73,26 +81,85 @@ unwind_and_resume (long iteration, void (*next_func[])())
|
||||||
if ((ret = unw_step (&c)) < 0)
|
if ((ret = unw_step (&c)) < 0)
|
||||||
panic ("unw_step (ret=%d)", ret);
|
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);
|
ret = unw_resume (&c);
|
||||||
panic ("unw_resume() returned (ret=%d)!!\n", ret);
|
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
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
spill_func_t *test1[16];
|
int i;
|
||||||
int i, reg_values[88];
|
|
||||||
|
|
||||||
for (i = 0; i < (int) (sizeof (reg_values) / sizeof (reg_values[0])); ++i)
|
if (argc > 1)
|
||||||
reg_values[i] = random ();
|
verbose = 1;
|
||||||
|
|
||||||
test1[0] = SPL (3);
|
for (i = 0; i < 100000; ++i)
|
||||||
test1[1] = SPL (10);
|
run_check (i + 1);
|
||||||
test1[2] = SPL (5);
|
|
||||||
test1[3] = SPL (17);
|
|
||||||
test1[4] = unwind_and_resume;
|
|
||||||
unwind_count = 6;
|
|
||||||
loadup (RECURSION_DEPTH, reg_values, test1);
|
|
||||||
|
|
||||||
|
if (nerrors > 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
if (verbose)
|
||||||
|
printf ("SUCCESS.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue