1d9e100753f5694ebb14769048373e8171f336127hp.com!davidm/* libunwind - a platform-independent unwind library 2d9e100753f5694ebb14769048373e8171f336127hp.com!davidm Copyright (C) 2003-2005 Hewlett-Packard Co 3d9e100753f5694ebb14769048373e8171f336127hp.com!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 5d9e100753f5694ebb14769048373e8171f336127hp.com!davidmThis file is part of libunwind. 6d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 7d9e100753f5694ebb14769048373e8171f336127hp.com!davidmPermission is hereby granted, free of charge, to any person obtaining 8d9e100753f5694ebb14769048373e8171f336127hp.com!davidma copy of this software and associated documentation files (the 9d9e100753f5694ebb14769048373e8171f336127hp.com!davidm"Software"), to deal in the Software without restriction, including 10d9e100753f5694ebb14769048373e8171f336127hp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 11d9e100753f5694ebb14769048373e8171f336127hp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 12d9e100753f5694ebb14769048373e8171f336127hp.com!davidmpermit persons to whom the Software is furnished to do so, subject to 13d9e100753f5694ebb14769048373e8171f336127hp.com!davidmthe following conditions: 14d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 15d9e100753f5694ebb14769048373e8171f336127hp.com!davidmThe above copyright notice and this permission notice shall be 16d9e100753f5694ebb14769048373e8171f336127hp.com!davidmincluded in all copies or substantial portions of the Software. 17d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 18d9e100753f5694ebb14769048373e8171f336127hp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19d9e100753f5694ebb14769048373e8171f336127hp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20d9e100753f5694ebb14769048373e8171f336127hp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21d9e100753f5694ebb14769048373e8171f336127hp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22d9e100753f5694ebb14769048373e8171f336127hp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23d9e100753f5694ebb14769048373e8171f336127hp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24d9e100753f5694ebb14769048373e8171f336127hp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 26d9e100753f5694ebb14769048373e8171f336127hp.com!davidm#define UNW_LOCAL_ONLY 27d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 28d9e100753f5694ebb14769048373e8171f336127hp.com!davidm#include <setjmp.h> 29d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 30d9e100753f5694ebb14769048373e8171f336127hp.com!davidm#include "libunwind_i.h" 31d9e100753f5694ebb14769048373e8171f336127hp.com!davidm#include "jmpbuf.h" 32d9e100753f5694ebb14769048373e8171f336127hp.com!davidm#include "setjmp_i.h" 33d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 3429c110265f50c14b8611a3f14be3941b23952125Konstantin Belousov#if !defined(_NSIG) && defined(_SIG_MAXSIG) 3529c110265f50c14b8611a3f14be3941b23952125Konstantin Belousov# define _NSIG (_SIG_MAXSIG - 1) 3629c110265f50c14b8611a3f14be3941b23952125Konstantin Belousov#endif 3729c110265f50c14b8611a3f14be3941b23952125Konstantin Belousov 382b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#if defined(__GLIBC__) 392b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#if __GLIBC_PREREQ(2, 4) 40297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov 41297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov/* Starting with glibc-2.4, {sig,}setjmp in GLIBC obfuscates the 42297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov register values in jmp_buf by XORing them with a "random" 43297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov canary value. 44297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov 45297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov This makes it impossible to implement longjmp, as we 46297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov can never match wp[JB_SP], unless we decode the canary first. 47297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov 48297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov Doing so is possible, but doesn't appear to be worth the trouble, 49297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov so we simply defer to glibc siglongjmp here. */ 50297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov 512b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#define siglongjmp __nonworking_siglongjmp 52814bd79fb1814eb5bbeb2fdb652d5ae08f1edd28Arun Sharmastatic void siglongjmp (sigjmp_buf env, int val) UNUSED; 532b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#endif 542b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#endif /* __GLIBC_PREREQ */ 55297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov 56d9e100753f5694ebb14769048373e8171f336127hp.com!davidmvoid 57d9e100753f5694ebb14769048373e8171f336127hp.com!davidmsiglongjmp (sigjmp_buf env, int val) 58d9e100753f5694ebb14769048373e8171f336127hp.com!davidm{ 59d9e100753f5694ebb14769048373e8171f336127hp.com!davidm unw_word_t *wp = (unw_word_t *) env; 60d9e100753f5694ebb14769048373e8171f336127hp.com!davidm extern int _UI_siglongjmp_cont; 61d9e100753f5694ebb14769048373e8171f336127hp.com!davidm extern int _UI_longjmp_cont; 62d9e100753f5694ebb14769048373e8171f336127hp.com!davidm unw_context_t uc; 63d9e100753f5694ebb14769048373e8171f336127hp.com!davidm unw_cursor_t c; 64d9e100753f5694ebb14769048373e8171f336127hp.com!davidm unw_word_t sp; 65d9e100753f5694ebb14769048373e8171f336127hp.com!davidm int *cont; 66d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 67d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) 68d9e100753f5694ebb14769048373e8171f336127hp.com!davidm abort (); 69d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 70d9e100753f5694ebb14769048373e8171f336127hp.com!davidm do 71d9e100753f5694ebb14769048373e8171f336127hp.com!davidm { 72d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) 73d9e100753f5694ebb14769048373e8171f336127hp.com!davidm abort (); 745715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov#ifdef __FreeBSD__ 755715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov if (sp != wp[JB_SP] + sizeof(unw_word_t)) 765715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov#else 77d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if (sp != wp[JB_SP]) 785715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov#endif 79d9e100753f5694ebb14769048373e8171f336127hp.com!davidm continue; 80d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 81d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if (!bsp_match (&c, wp)) 82d9e100753f5694ebb14769048373e8171f336127hp.com!davidm continue; 83d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 84d9e100753f5694ebb14769048373e8171f336127hp.com!davidm /* found the right frame: */ 85d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 86d9e100753f5694ebb14769048373e8171f336127hp.com!davidm /* default to resuming without restoring signal-mask */ 87d9e100753f5694ebb14769048373e8171f336127hp.com!davidm cont = &_UI_longjmp_cont; 88d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 89d9e100753f5694ebb14769048373e8171f336127hp.com!davidm /* Order of evaluation is important here: if unw_resume() 90d9e100753f5694ebb14769048373e8171f336127hp.com!davidm restores signal mask, we must set it up appropriately, even 91d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if wp[JB_MASK_SAVED] is FALSE. */ 92d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if (!resume_restores_sigmask (&c, wp) && wp[JB_MASK_SAVED]) 93d9e100753f5694ebb14769048373e8171f336127hp.com!davidm { 94d9e100753f5694ebb14769048373e8171f336127hp.com!davidm /* sigmask was saved */ 9559328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov#if defined(__linux__) 9659328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov if (UNW_NUM_EH_REGS < 4 || _NSIG > 16 * sizeof (unw_word_t)) 97d9e100753f5694ebb14769048373e8171f336127hp.com!davidm /* signal mask doesn't fit into EH arguments and we can't 98d9e100753f5694ebb14769048373e8171f336127hp.com!davidm put it on the stack without overwriting something 99d9e100753f5694ebb14769048373e8171f336127hp.com!davidm else... */ 100d9e100753f5694ebb14769048373e8171f336127hp.com!davidm abort (); 101d9e100753f5694ebb14769048373e8171f336127hp.com!davidm else 102d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if (unw_set_reg (&c, UNW_REG_EH + 2, wp[JB_MASK]) < 0 103d9e100753f5694ebb14769048373e8171f336127hp.com!davidm || (_NSIG > 8 * sizeof (unw_word_t) 104d9e100753f5694ebb14769048373e8171f336127hp.com!davidm && unw_set_reg (&c, UNW_REG_EH + 3, wp[JB_MASK + 1]) < 0)) 105d9e100753f5694ebb14769048373e8171f336127hp.com!davidm abort (); 10659328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov#elif defined(__FreeBSD__) 10759328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov if (unw_set_reg (&c, UNW_REG_EH + 2, &wp[JB_MASK]) < 0) 10859328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov abort(); 10959328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov#else 11059328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov#error Port me 11159328832f7ee48682fcd0fd1ca0cb9cfdb32ec4aKonstantin Belousov#endif 112d9e100753f5694ebb14769048373e8171f336127hp.com!davidm cont = &_UI_siglongjmp_cont; 113d9e100753f5694ebb14769048373e8171f336127hp.com!davidm } 114d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 115d9e100753f5694ebb14769048373e8171f336127hp.com!davidm if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 116d9e100753f5694ebb14769048373e8171f336127hp.com!davidm || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 1173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) (uintptr_t) cont)) 118d9e100753f5694ebb14769048373e8171f336127hp.com!davidm abort (); 119d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 120d9e100753f5694ebb14769048373e8171f336127hp.com!davidm unw_resume (&c); 121d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 122d9e100753f5694ebb14769048373e8171f336127hp.com!davidm abort (); 123d9e100753f5694ebb14769048373e8171f336127hp.com!davidm } 124297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov while (unw_step (&c) > 0); 125d9e100753f5694ebb14769048373e8171f336127hp.com!davidm 126d9e100753f5694ebb14769048373e8171f336127hp.com!davidm abort (); 127d9e100753f5694ebb14769048373e8171f336127hp.com!davidm} 128