1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-26 17:17:39 +01:00

(depth): New global variable.

(raise_exception): Make non-static, unwind "depth - 1" steps to get to
	top-most a() frame.
(__builtin_ia64_bsp): Also define for Intel-compiler.
(a): Restructure so it works in the face of global optimization and also
	remove GCC dependencies.
(main): Initialize depth based on argv[1].

(Logical change 1.232)
This commit is contained in:
hp.com!davidm 2004-05-06 21:11:29 +00:00
parent 4280d5c860
commit 9fb355e096

View file

@ -35,15 +35,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
int nerrors = 0; int nerrors = 0;
int verbose = 0; int verbose = 0;
int depth = 13;
static void b (void *); extern void b (int);
static void void
raise_exception (void *addr) raise_exception (void)
{ {
unw_cursor_t cursor; unw_cursor_t cursor;
unw_word_t ip;
unw_context_t uc; unw_context_t uc;
int i;
unw_getcontext (&uc); unw_getcontext (&uc);
if (unw_init_local (&cursor, &uc) < 0) if (unw_init_local (&cursor, &uc) < 0)
@ -59,27 +60,17 @@ raise_exception (void *addr)
return; return;
} }
/* unwind to frame a(): */ /* unwind to top-most frame a(): */
for (i = 0; i < depth - 1; ++i)
if (unw_step (&cursor) < 0) if (unw_step (&cursor) < 0)
{ {
panic ("unw_step() failed!\n"); panic ("unw_step() failed!\n");
return; return;
} }
unw_get_reg (&cursor, UNW_REG_IP, &ip);
if (verbose)
printf ("old ip = %lx, new ip = %p\n", (long) ip, addr);
if (unw_set_reg (&cursor, UNW_REG_IP, (unw_word_t) addr) < 0)
{
panic ("unw_set_reg() failed!\n");
return;
}
unw_resume (&cursor); /* transfer control to exception handler */ unw_resume (&cursor); /* transfer control to exception handler */
} }
#if !UNW_TARGET_IA64 #if !UNW_TARGET_IA64 || defined(__INTEL_COMPILER)
void * void *
__builtin_ia64_bsp (void) __builtin_ia64_bsp (void)
@ -89,29 +80,22 @@ __builtin_ia64_bsp (void)
#endif #endif
static int int
a (void) a (int n)
{ {
long stack; long stack;
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) if (verbose)
void *label; printf ("a(n=%d)\n", n);
if (n > 0)
return a (n - 1);
if (verbose) if (verbose)
printf ("a: sp=%p bsp=%p\n", &stack, __builtin_ia64_bsp ()); printf ("a: sp=%p bsp=%p\n", &stack, __builtin_ia64_bsp ());
#ifdef UNW_TARGET_IA64
asm ("movl %0=Label" : "=r"(label));
#else
label = &&handler;
#endif
b (label);
panic ("FAILURE: unexpected return from func()!\n");
#if UNW_TARGET_IA64 b (16);
asm volatile ("Label:"); /* force a new bundle */
#else
handler:
#endif
if (verbose) if (verbose)
{ {
printf ("exception handler: here we go (sp=%p, bsp=%p)...\n", printf ("exception handler: here we go (sp=%p, bsp=%p)...\n",
@ -121,19 +105,18 @@ a (void)
__builtin_ia64_bsp() gets predicated. */ __builtin_ia64_bsp() gets predicated. */
getpid (); getpid ();
} }
#else
if (verbose)
printf ("a: this test only works with GNU C compiler.\n");
#endif
return 0; return 0;
} }
static void void
b (void *addr) b (int n)
{ {
if ((n & 1) == 0)
{
if (verbose) if (verbose)
printf ("b() calling raise_exception()\n"); printf ("b(n=%d) calling raise_exception()\n", n);
raise_exception (addr); raise_exception ();
}
panic ("FAILURE: b() returned from raise_exception()!!\n"); panic ("FAILURE: b() returned from raise_exception()!!\n");
} }
@ -141,9 +124,12 @@ int
main (int argc, char **argv) main (int argc, char **argv)
{ {
if (argc > 1) if (argc > 1)
{
++verbose; ++verbose;
depth = atol (argv[1]);
}
if (a () != 0 || nerrors > 0) if (a (depth) != 0 || nerrors > 0)
{ {
fprintf (stderr, "FAILURE: test failed; try again?\n"); fprintf (stderr, "FAILURE: test failed; try again?\n");
exit (-1); exit (-1);