1e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm/* libunwind - a platform-independent unwind library 2f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm Copyright (C) 2001-2004 Hewlett-Packard Co 3e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 5e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmPermission is hereby granted, free of charge, to any person obtaining 6e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidma copy of this software and associated documentation files (the 7e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm"Software"), to deal in the Software without restriction, including 8e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 9e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 10e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmpermit persons to whom the Software is furnished to do so, subject to 11e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmthe following conditions: 12e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 13e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmThe above copyright notice and this permission notice shall be 14e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmincluded in all copies or substantial portions of the Software. 15e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 16e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 24f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm/* This test uses the unwind interface to modify the IP in an ancestor 25e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm frame while still returning to the parent frame. */ 26e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 27e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm#include <signal.h> 28e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm#include <stdio.h> 29e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm#include <stdlib.h> 30e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 31e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm#include <libunwind-ia64.h> 32e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 33e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm#define panic(args...) \ 34e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm { fprintf (stderr, args); exit (-1); } 35e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 36f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidmint verbose; 37f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm 38e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmstatic void 39e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmsighandler (int signal) 40e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm{ 41e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm unw_cursor_t cursor, cursor2; 42e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm unw_word_t ip; 43e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm unw_context_t uc; 44e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 45f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm if (verbose) 46f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm printf ("caught signal %d\n", signal); 47e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 48e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm unw_getcontext (&uc); 49e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm if (unw_init_local (&cursor, &uc) < 0) 50e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm panic ("unw_init() failed!\n"); 51e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 52e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm /* get cursor for caller of sighandler: */ 53e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm if (unw_step (&cursor) < 0) 54e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm panic ("unw_step() failed!\n"); 55e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 56e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm cursor2 = cursor; 57e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm while (!unw_is_signal_frame (&cursor2)) 58e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm if (unw_step (&cursor2) < 0) 59e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm panic ("failed to find signal frame!\n"); 60e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 61e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm if (unw_step (&cursor2) < 0) 62e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm panic ("unw_step() failed!\n"); 63e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 64e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm if (unw_get_reg (&cursor2, UNW_REG_IP, &ip) < 0) 65e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm panic ("failed to get IP!\n"); 66e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 67e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm /* skip faulting instruction (doesn't handle MLX template) */ 68e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm ++ip; 69e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm if ((ip & 0x3) == 0x3) 70e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm ip += 13; 71e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 72e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm if (unw_set_reg (&cursor2, UNW_REG_IP, ip) < 0) 73e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm panic ("failed to set IP!\n"); 74e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 75e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm unw_resume (&cursor); /* update context & return to caller of sighandler() */ 76e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 77e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm panic ("unexpected return from unw_resume()!\n"); 78e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm} 79e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 80e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmstatic void 81e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmdoit (volatile char *p) 82e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm{ 83e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm int ch; 84e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 85e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm ch = *p; /* trigger SIGSEGV */ 86e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 87f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm if (verbose) 88f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm printf ("doit: finishing execution!\n"); 89e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm} 90e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm 91e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmint 92e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidmmain (int argc, char **argv) 93e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm{ 94f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm if (argc > 1) 95f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm verbose = 1; 96f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm 97e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm signal (SIGSEGV, sighandler); 98e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm doit (0); 99f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm if (verbose) 100f789a1e1d19c9e1bee57269bde8436cea59e12bbhp.com!davidm printf ("SUCCESS\n"); 101e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm return 0; 102e5b4f8a40dc15be7943b3a1996c33e1887e5735emostang.com!davidm} 103