107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm/* libunwind - a platform-independent unwind library 207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm Copyright (C) 2004 Hewlett-Packard Co 307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmPermission is hereby granted, free of charge, to any person obtaining 607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidma copy of this software and associated documentation files (the 707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm"Software"), to deal in the Software without restriction, including 807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 1007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmpermit persons to whom the Software is furnished to do so, subject to 1107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmthe following conditions: 1207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 1307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmThe above copyright notice and this permission notice shall be 1407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmincluded in all copies or substantial portions of the Software. 1507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 1607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 2007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 2107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 2307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 2407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm/* Test to verify that we can siglongjmp() into a frame whose register 2507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm window is not backed by valid memory. */ 2607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 2707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#ifdef HAVE_CONFIG_H 2807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm# include "config.h" 2907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#endif 3007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 3107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <errno.h> 3207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <stdio.h> 3307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <stdint.h> 3407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <setjmp.h> 3507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <signal.h> 3607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <stdlib.h> 3783b02fa05b0b228a86e1055466447de312ff44a0hp.com!davidm#include <string.h> 3807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <unistd.h> 3907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 4007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#include <sys/mman.h> 4107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 4207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#ifdef HAVE_IA64INTRIN_H 4307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm# include <ia64intrin.h> 4407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#endif 4507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 4607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmstatic sigjmp_buf env; 4707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmstatic int return_level; 4807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmstatic uintptr_t return_bsp; 4907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmstatic int verbose; 5007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 5107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmuintptr_t 5207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmget_bsp (void) 5307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm{ 5407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#ifdef __INTEL_COMPILER 5507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return __getReg (_IA64_REG_AR_BSP); 5607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#else 5707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return (uintptr_t) __builtin_ia64_bsp (); 5807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm#endif 5907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm} 6007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 6107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmstatic void 6207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmsighandler (int signal, void *siginfo, void *sigcontext) 6307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm{ 6407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm ucontext_t *uc = sigcontext; 6507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm int local = 0; 6607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 6707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (verbose) 6807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm printf ("got signal, stack at %p, saved bsp=0x%lx\n", 6907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm &local, uc->uc_mcontext.sc_ar_bsp); 7007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm siglongjmp (env, 1); 7107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm} 7207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 73565ffdb75c36b7ba190610b5033f4986fd87e3b9Jan Kratochvil/* Direct call of doit () at the end of doit () would get optimized by GCC to 74565ffdb75c36b7ba190610b5033f4986fd87e3b9Jan Kratochvil a branch. */ 75565ffdb75c36b7ba190610b5033f4986fd87e3b9Jan Kratochvilstatic void doit (int n); 7623fdda6a28d31abfcda42567cc455bd46a4fc0d0Tommi Rantalatypedef void (*doit_type) (int); 7723fdda6a28d31abfcda42567cc455bd46a4fc0d0Tommi Rantalastatic volatile doit_type doit_pointer = doit; 78565ffdb75c36b7ba190610b5033f4986fd87e3b9Jan Kratochvil 7907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmstatic void 8007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmdoit (int n) 8107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm{ 8207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm uintptr_t guard_page_addr, bsp = get_bsp (); 8325739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang void *ret; 8407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 8507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (n == 0) 8607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm { 8707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm size_t page_size = getpagesize (); 8807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 8907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm guard_page_addr = (bsp + page_size - 1) & -page_size; 9007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (verbose) 9107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm printf ("guard_page_addr = 0x%lx\n", (unsigned long) guard_page_addr); 9225739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang ret = mmap ((void *) guard_page_addr, page_size, PROT_NONE, 9325739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 9425739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang if (ret != (void *) guard_page_addr) 9507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm { 9625739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang if (ret == MAP_FAILED) 9725739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang perror ("mmap"); 9825739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang else 9925739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang fprintf (stderr, "mmap() returned %p, expected 0x%lx\n", 10025739eec8667ae3a78a62b44a912a7fbcda3d43dDavid Mosberger-Tang ret, guard_page_addr); 10107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm exit (EXIT_FAILURE); 10207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm } 10307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm } 10407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 10507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (sigsetjmp (env, 1)) 10607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm { 10707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return_level = n; 10807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return_bsp = bsp; 10907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm } 11007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm else 111565ffdb75c36b7ba190610b5033f4986fd87e3b9Jan Kratochvil (*doit_pointer) (n + 1); 11207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm} 11307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 11407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmint 11507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidmmain (int argc, char **argv) 11607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm{ 11707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm struct sigaction sa; 11807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm stack_t ss; 11907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 12007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (argc > 1) 12107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm verbose = 1; 12207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 12307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm ss.ss_sp = malloc (2 * SIGSTKSZ); 12407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (ss.ss_sp == NULL) 12507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm { 12607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm puts ("failed to allocate alternate stack"); 12707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return EXIT_FAILURE; 12807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm } 12907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm ss.ss_flags = 0; 13007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm ss.ss_size = 2 * SIGSTKSZ; 13107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (sigaltstack (&ss, NULL) < 0) 13207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm { 13307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm printf ("sigaltstack failed: %s\n", strerror (errno)); 13407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return EXIT_FAILURE; 13507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm } 13607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 13707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm sa.sa_handler = (void (*) (int)) sighandler; 13807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm sigemptyset (&sa.sa_mask); 13907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm sa.sa_flags = SA_SIGINFO | SA_ONSTACK; 14007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (sigaction (SIGSEGV, &sa, NULL) < 0) 14107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm { 14207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm printf ("sigaction failed: %s\n", strerror (errno)); 14307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm exit (1); 14407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm } 14507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 14607e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm doit (0); 14707e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm 14807e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm if (verbose) 14907e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm { 15007e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm printf ("sigsetjmp returned at level %d bsp=0x%lx\n", 15107e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return_level, return_bsp); 15207e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm puts ("Test succeeded!"); 15307e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm } 15407e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm return EXIT_SUCCESS; 15507e9f4df8922b98da6c62ada5619e1b27ce0fccbhp.com!davidm} 156