Gos-freebsd.c revision 8a75ba971a295ce7e6b7b73b90272fb9c04e5b2f
1e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm/* libunwind - a platform-independent unwind library 2e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm Copyright (C) 2002-2003 Hewlett-Packard Co 3e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 5e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmThis file is part of libunwind. 6e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 7e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmPermission is hereby granted, free of charge, to any person obtaining 8e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidma copy of this software and associated documentation files (the 9e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm"Software"), to deal in the Software without restriction, including 10e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmwithout limitation the rights to use, copy, modify, merge, publish, 11e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmdistribute, sublicense, and/or sell copies of the Software, and to 12e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmpermit persons to whom the Software is furnished to do so, subject to 13e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmthe following conditions: 14e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 15e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmThe above copyright notice and this permission notice shall be 16e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmincluded in all copies or substantial portions of the Software. 17e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 18e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 26e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm#include "unwind_i.h" 27e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 28e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmPROTECTED int 29e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidmunw_is_signal_frame (unw_cursor_t *cursor) 30e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm{ 31a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov#if defined __linux__ 32e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm struct cursor *c = (struct cursor *) cursor; 33e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm unw_word_t w0, w1, ip; 34e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm unw_addr_space_t as; 35e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm unw_accessors_t *a; 36e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm void *arg; 37e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm int ret; 38e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 39e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm as = c->dwarf.as; 40e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm a = unw_get_accessors (as); 41e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm arg = c->dwarf.as_arg; 42e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 43e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm /* Check if EIP points at sigreturn() sequence. On Linux, this is: 44e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 45e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm __restore: 46e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 0x58 pop %eax 47e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 0xb8 0x77 0x00 0x00 0x00 movl 0x77,%eax 48e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 0xcd 0x80 int 0x80 49e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 50e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm without SA_SIGINFO, and 51e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 52e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm __restore_rt: 53e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 0xb8 0xad 0x00 0x00 0x00 movl 0x80,%eax 54e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 0xcd 0x80 int 0x80 55e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 0x90 nop 56e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm 57e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm if SA_SIGINFO is specified. 58e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm */ 59e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm ip = c->dwarf.ip; 60e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 61e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0) 62e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov return ret; 63e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov ret = X86_SCF_NONE; 64e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov if (w0 == 0x0077b858 && w1 == 0x80cd0000) 65e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov ret = X86_SCF_LINUX_SIGFRAME; 66e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov else if (w0 == 0x0000adb8 && w1 == 0x9080cd00) 67e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov ret = X86_SCF_LINUX_RT_SIGFRAME; 68e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm Debug (16, "returning %d\n", ret); 69e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm return ret; 70a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov#elif defined __FreeBSD__ 71a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov struct cursor *c = (struct cursor *) cursor; 72a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov unw_word_t w0, w1, w2, w3, w4, w5, ip; 73a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov unw_addr_space_t as; 74a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov unw_accessors_t *a; 75a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov void *arg; 76a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov int ret; 77a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov 78a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov as = c->dwarf.as; 79a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov a = unw_get_accessors (as); 80a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov arg = c->dwarf.as_arg; 81a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov 82a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov /* Check if EIP points at sigreturn() sequence. It can be: 838a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousovsigcode+4: from amd64 freebsd32 environment 848a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov8d 44 24 20 lea 0x20(%esp),%eax 858a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov50 push %eax 868a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousovb8 a1 01 00 00 mov $0x1a1,%ea 878a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov50 push %eax 888a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousovcd 80 int $0x80 898a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov 908a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousovsigcode+4: from real i386 91a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov8d 44 24 20 lea 0x20(%esp),%eax 92a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov50 push %eax 93a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousovf7 40 54 00 02 00 testl $0x20000,0x54(%eax) 94a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov75 03 jne sigcode+21 95a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov8e 68 14 mov 0x14(%eax),%gs 96a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousovb8 a1 01 00 00 mov $0x1a1,%eax 97a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov50 push %eax 98a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousovcd 80 int $0x80 99a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov 100a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousovfreebsd4_sigcode+4: 101a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin BelousovXXX 102a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousovosigcode: 103a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin BelousovXXX 104a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov */ 105a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov ip = c->dwarf.ip; 106e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov ret = X86_SCF_NONE; 1078a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov if ((*a->access_mem) (as, ip, &w0, 0, arg) < 0 || 1088a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov (*a->access_mem) (as, ip + 4, &w1, 0, arg) < 0 || 1098a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov (*a->access_mem) (as, ip + 8, &w2, 0, arg) < 0 || 1108a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov (*a->access_mem) (as, ip + 12, &w3, 0, arg) < 0) 1118a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov return ret; 1128a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov if (w0 == 0x2024448d && w1 == 0x01a1b850 && w2 == 0xcd500000 && 1138a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov (w3 & 0xff) == 0x80) 114e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov ret = X86_SCF_FREEBSD_SIGFRAME; 1158a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov else { 1168a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov if ((*a->access_mem) (as, ip + 16, &w4, 0, arg) < 0 || 1178a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov (*a->access_mem) (as, ip + 20, &w5, 0, arg) < 0) 1188a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov return ret; 1198a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov if (w0 == 0x2024448d && w1 == 0x5440f750 && w2 == 0x75000200 && 1208a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov w3 == 0x14688e03 && w4 == 0x0001a1b8 && w5 == 0x80cd5000) 1218a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov ret = X86_SCF_FREEBSD_SIGFRAME; 1228a75ba971a295ce7e6b7b73b90272fb9c04e5b2fKonstantin Belousov } 123a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov Debug (16, "returning %d\n", ret); 124e9cd30040e2794ee586ff853b360b47881824fdaKonstantin Belousov return (ret); 125e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm#else 126a6b23dcb0c42198ad01764a27a084fd49116a544Konstantin Belousov#error Port me 127e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm#endif 128e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm return -UNW_ENOINFO; 129e1eb2d465605ac4eae98dd4f8264de4c6d56aab4homeip.net!davidm} 130