1a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang/* libunwind - a platform-independent unwind library 2a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang Copyright (C) 2003-2004 Hewlett-Packard Co 3a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 5a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangThis file is part of libunwind. 6a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 7a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangPermission is hereby granted, free of charge, to any person obtaining 8a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tanga copy of this software and associated documentation files (the 9a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang"Software"), to deal in the Software without restriction, including 10a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tangwithout limitation the rights to use, copy, modify, merge, publish, 11a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tangdistribute, sublicense, and/or sell copies of the Software, and to 12a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tangpermit persons to whom the Software is furnished to do so, subject to 13a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tangthe following conditions: 14a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 15a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangThe above copyright notice and this permission notice shall be 16a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tangincluded in all copies or substantial portions of the Software. 17a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 18a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-TangWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 26a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#define UNW_LOCAL_ONLY 27a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 28c4133e879b8cfa7e7295f7d35bde22dfc800ebc8Arun Sharma#undef _FORTIFY_SOURCE 29a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#include <assert.h> 30a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#include <libunwind.h> 31a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#include <setjmp.h> 32a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#include <signal.h> 33a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#include <stdlib.h> 34a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 35a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#include "jmpbuf.h" 36a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#include "setjmp_i.h" 37a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 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 longjmp here. */ 502b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#define _longjmp __nonworking__longjmp 512b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#define longjmp __nonworking_longjmp 522b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousovstatic void _longjmp (jmp_buf env, int val); 532b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousovstatic void longjmp (jmp_buf env, int val); 542b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#endif 552b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#endif /* __GLIBC__ */ 56297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov 57a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tangvoid 58a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang_longjmp (jmp_buf env, int val) 59a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang{ 60a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang extern int _UI_longjmp_cont; 61a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang unw_context_t uc; 62a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang unw_cursor_t c; 63a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang unw_word_t sp; 64a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang unw_word_t *wp = (unw_word_t *) env; 65a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 66a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) 67a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang abort (); 68a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 69a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang do 70a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang { 71a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) 72a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang abort (); 735715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov#ifdef __FreeBSD__ 745715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov if (sp != wp[JB_SP] + sizeof(unw_word_t)) 755715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov#else 76a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang if (sp != wp[JB_SP]) 775715d912f4f43041735031170d7f8ead6f70924dKonstantin Belousov#endif 78a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang continue; 79a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 80a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang if (!bsp_match (&c, wp)) 81a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang continue; 82a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 83a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang /* found the right frame: */ 84a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 85a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang assert (UNW_NUM_EH_REGS >= 2); 86a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 87a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0 88a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0 89a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang || unw_set_reg (&c, UNW_REG_IP, 903842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz (unw_word_t) (uintptr_t) &_UI_longjmp_cont)) 91a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang abort (); 92a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 93a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang unw_resume (&c); 94a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 95a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang abort (); 96a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang } 97297d9cd07d7ea9b541fb13bffe418c8b2a8c3aa6Paul Pluzhnikov while (unw_step (&c) > 0); 98a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 99a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang abort (); 100a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang} 101a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 102a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#ifdef __GNUC__ 1032b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#define STRINGIFY1(x) #x 1042b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#define STRINGIFY(x) STRINGIFY1(x) 1052b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousovvoid longjmp (jmp_buf env, int val) 1062b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov __attribute__ ((alias (STRINGIFY(_longjmp)))); 107a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang#else 108a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 109a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tangvoid 110a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tanglongjmp (jmp_buf env, int val) 111a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang{ 112a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang _longjmp (env, val); 113a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang} 114a369768c279654ae247643f81e0d2f6f7ddd4d15David Mosberger-Tang 1152b606faa21024932f6819ba31e846d866db9d2f9Konstantin Belousov#endif /* __GNUC__ */ 116