1eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm/* libunwind - a platform-independent unwind library 21f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P. 3eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 5eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmThis file is part of libunwind. 6eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 7eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmPermission is hereby granted, free of charge, to any person obtaining 8eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidma copy of this software and associated documentation files (the 9eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm"Software"), to deal in the Software without restriction, including 10eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 11eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 12eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmpermit persons to whom the Software is furnished to do so, subject to 13eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmthe following conditions: 14eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 15eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmThe above copyright notice and this permission notice shall be 16eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmincluded in all copies or substantial portions of the Software. 17eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 18eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 26eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm/* Locate an FDE via the ELF data-structures defined by LSB v1.3 27eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm (http://www.linuxbase.org/spec/). */ 28eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 29eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#include <stddef.h> 303842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include <stdio.h> 313842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include <limits.h> 32eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 33e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm#include "dwarf_i.h" 34eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#include "dwarf-eh.h" 3503ba50ccaadbf962e9865d60e2171dc8e52ee24ehp.com!davidm#include "libunwind_i.h" 36eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 378241bb15a8ae2484d05238176284c5bed56eed24mostang.com!davidmstruct table_entry 388241bb15a8ae2484d05238176284c5bed56eed24mostang.com!davidm { 39e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm int32_t start_ip_offset; 40e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm int32_t fde_offset; 418241bb15a8ae2484d05238176284c5bed56eed24mostang.com!davidm }; 428241bb15a8ae2484d05238176284c5bed56eed24mostang.com!davidm 43eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#ifndef UNW_REMOTE_ONLY 44eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifdef __linux 463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#include "os-linux.h" 473842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif 483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 491f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidmstatic int 501f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidmlinear_search (unw_addr_space_t as, unw_word_t ip, 511f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm unw_word_t eh_frame_start, unw_word_t eh_frame_end, 521f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm unw_word_t fde_count, 531f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm unw_proc_info_t *pi, int need_unwind_info, void *arg) 541f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm{ 551f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm unw_accessors_t *a = unw_get_accessors (unw_local_addr_space); 561f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm unw_word_t i = 0, fde_addr, addr = eh_frame_start; 571f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm int ret; 581f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 591f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm while (i++ < fde_count && addr < eh_frame_end) 601f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm { 611f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm fde_addr = addr; 623842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, 0, 0, arg)) 631f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm < 0) 641f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return ret; 651f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 661f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if (ip >= pi->start_ip && ip < pi->end_ip) 671f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm { 681f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if (!need_unwind_info) 691f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return 1; 701f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm addr = fde_addr; 711f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, 723842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz need_unwind_info, 0, 733842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz arg)) 741f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm < 0) 751f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return ret; 761f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return 1; 771f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm } 781f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm } 791f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return -UNW_ENOINFO; 801f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm} 810fed502a81dd6d9eff4da9ff26d895a16ab828cfKen Werner#endif /* !UNW_REMOTE_ONLY */ 821f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 83a2c27a4ab724cf129cf956df4c6fb779bd2f5366Arun Sharma#ifdef CONFIG_DEBUG_FRAME 843842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* Load .debug_frame section from FILE. Allocates and returns space 853842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz in *BUF, and sets *BUFSIZE to its size. IS_LOCAL is 1 if using the 863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz local process, in which case we can search the system debug file 873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz directory; 0 for other address spaces, in which case we do not; or 883842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz -1 for recursive calls following .gnu_debuglink. Returns 0 on 893842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz success, 1 on error. Succeeds even if the file contains no 903842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz .debug_frame. */ 913842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */ 923842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 933842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic int 943842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzload_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) 953842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{ 963842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz FILE *f; 973842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Elf_W (Ehdr) ehdr; 983842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Elf_W (Half) shstrndx; 99546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma Elf_W (Shdr) *sec_hdrs = NULL; 100546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma char *stringtab = NULL; 1013842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz unsigned int i; 1023842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz size_t linksize = 0; 1033842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz char *linkbuf = NULL; 1043842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1053842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz *buf = NULL; 1063842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz *bufsize = 0; 1073842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz f = fopen (file, "r"); 1093842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (!f) 1113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return 1; 1123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 113546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (fread (&ehdr, sizeof (Elf_W (Ehdr)), 1, f) != 1) 114546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma goto file_error; 1153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz shstrndx = ehdr.e_shstrndx; 1173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Debug (4, "opened file '%s'. Section header at offset %d\n", 1193842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz file, (int) ehdr.e_shoff); 1203842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fseek (f, ehdr.e_shoff, SEEK_SET); 1223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr))); 123546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f) != ehdr.e_shnum) 124546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma goto file_error; 1253842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 126a2c27a4ab724cf129cf956df4c6fb779bd2f5366Arun Sharma Debug (4, "loading string table of size %zd\n", 1273842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz sec_hdrs[shstrndx].sh_size); 1283842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz stringtab = malloc (sec_hdrs[shstrndx].sh_size); 1293842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET); 130546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (fread (stringtab, 1, sec_hdrs[shstrndx].sh_size, f) != sec_hdrs[shstrndx].sh_size) 131546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma goto file_error; 1323842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1333842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz for (i = 1; i < ehdr.e_shnum && *buf == NULL; i++) 1343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 1353842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz char *secname = &stringtab[sec_hdrs[i].sh_name]; 1363842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1373842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (strcmp (secname, ".debug_frame") == 0) 1383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 1393842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz *bufsize = sec_hdrs[i].sh_size; 1403842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz *buf = malloc (*bufsize); 1413842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1423842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fseek (f, sec_hdrs[i].sh_offset, SEEK_SET); 143546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (fread (*buf, 1, *bufsize, f) != *bufsize) 144546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma goto file_error; 1453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 146a2c27a4ab724cf129cf956df4c6fb779bd2f5366Arun Sharma Debug (4, "read %zd bytes of .debug_frame from offset %zd\n", 1473842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz *bufsize, sec_hdrs[i].sh_offset); 1483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 149b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma else if (strcmp (secname, ".gnu_debuglink") == 0) 1503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 1513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz linksize = sec_hdrs[i].sh_size; 1523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz linkbuf = malloc (linksize); 1533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1543842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fseek (f, sec_hdrs[i].sh_offset, SEEK_SET); 155546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (fread (linkbuf, 1, linksize, f) != linksize) 156546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma goto file_error; 1573842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 158a2c27a4ab724cf129cf956df4c6fb779bd2f5366Arun Sharma Debug (4, "read %zd bytes of .gnu_debuglink from offset %zd\n", 159b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma linksize, sec_hdrs[i].sh_offset); 1603842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 1613842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 1623842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1633842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz free (stringtab); 1643842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz free (sec_hdrs); 1653842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1663842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fclose (f); 1673842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 168b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma /* Ignore separate debug files which contain a .gnu_debuglink section. */ 169b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma if (linkbuf && is_local == -1) 170b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma { 171b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma free (linkbuf); 172b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma return 1; 173b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma } 174b115ab645a44071f0a51742f5804dbceebd3f1acArun Sharma 1753842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (*buf == NULL && linkbuf != NULL && memchr (linkbuf, 0, linksize) != NULL) 1763842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 1773842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz char *newname, *basedir, *p; 1783842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz static const char *debugdir = "/usr/lib/debug"; 1793842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz int ret; 1803842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1813842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* XXX: Don't bother with the checksum; just search for the file. */ 1823842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz basedir = malloc (strlen (file) + 1); 1833842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz newname = malloc (strlen (linkbuf) + strlen (debugdir) 1843842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz + strlen (file) + 9); 1853842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz p = strrchr (file, '/'); 1873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (p != NULL) 1883842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 1893842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz memcpy (basedir, file, p - file); 1903842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz basedir[p - file] = '\0'; 1913842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 1923842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 1933842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz basedir[0] = 0; 1943842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 1953842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcpy (newname, basedir); 1963842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcat (newname, "/"); 1973842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcat (newname, linkbuf); 1983842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz ret = load_debug_frame (newname, buf, bufsize, -1); 1993842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2003842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (ret == 1) 2013842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 2023842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcpy (newname, basedir); 2033842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcat (newname, "/.debug/"); 2043842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcat (newname, linkbuf); 2053842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz ret = load_debug_frame (newname, buf, bufsize, -1); 2063842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 2073842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (ret == 1 && is_local == 1) 2093842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 2103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcpy (newname, debugdir); 2113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcat (newname, basedir); 2123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcat (newname, "/"); 2133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz strcat (newname, linkbuf); 2143842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz ret = load_debug_frame (newname, buf, bufsize, -1); 2153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 2163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz free (basedir); 2183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz free (newname); 2193842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 2203842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz free (linkbuf); 2213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return 0; 223546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 224546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma/* An error reading image file. Release resources and return error code */ 225546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharmafile_error: 22690d7baea352631f93ec7a9688fc59f58f148c19dTommi Rantala free(stringtab); 22790d7baea352631f93ec7a9688fc59f58f148c19dTommi Rantala free(sec_hdrs); 22890d7baea352631f93ec7a9688fc59f58f148c19dTommi Rantala free(linkbuf); 229984761515e6aafe8f27d0fda1151e2f81e2832e0Christopher Ferris free(*buf); 230546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma fclose(f); 231546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 232546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma return 1; 2333842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 2343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2353842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* Locate the binary which originated the contents of address ADDR. Return 236a2c27a4ab724cf129cf956df4c6fb779bd2f5366Arun Sharma the name of the binary in *name (space is allocated by the caller) 237a2c27a4ab724cf129cf956df4c6fb779bd2f5366Arun Sharma Returns 0 if a binary is successfully found, or 1 if an error occurs. */ 2383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 239bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris/* ANDROID support update. */ 240bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris/* Removed the find_binary_for_address function. */ 241bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris/* End of ANDROID update. */ 2423842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2433842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz/* Locate and/or try to load a debug_frame section for address ADDR. Return 2443842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz pointer to debug frame descriptor, or zero if not found. */ 2453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic struct unw_debug_frame_list * 247059676cb00cfdd3be17dfdeb25547037737f1b68Ken Wernerlocate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, 248059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner unw_word_t start, unw_word_t end) 2493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{ 2503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz struct unw_debug_frame_list *w, *fdesc = 0; 2513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz int err; 2523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz char *buf; 2533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz size_t bufsize; 254bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* ANDROID support update. */ 255bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris char *name = NULL; 256bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* End of ANDROID update. */ 257cc6cc088ba4077f5b6cfa3931a1737b03fc0446eChristopher Ferris 2583842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* First, see if we loaded this frame already. */ 2593842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2603842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz for (w = as->debug_frames; w; w = w->next) 2613842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 262250382c56d2c84fc3976cf8a4c834433bb68990dLassi Tuura Debug (4, "checking %p: %lx-%lx\n", w, (long)w->start, (long)w->end); 2633842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (addr >= w->start && addr < w->end) 2643842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return w; 2653842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 2663842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 267bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* ANDROID support update. */ 2683842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* If the object name we receive is blank, there's still a chance of locating 269bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris the file by looking at the maps cache. */ 2703842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2713842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (strcmp (dlname, "") == 0) 2723842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 273bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris#ifdef UNW_LOCAL_ONLY 274bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris name = map_local_get_image_name (addr); 275bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris#else 276bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris struct map_info *map = map_find_from_addr (as->map_list, addr); 277bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris if (map) 278bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris name = strdup (map->path); 279984761515e6aafe8f27d0fda1151e2f81e2832e0Christopher Ferris#endif 280bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris if (!name) 281bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* End of ANDROID update. */ 2823842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 2833842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n", 2843842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz (uint64_t) addr); 2853842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return 0; 2863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 2873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 2883842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 2893842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz name = (char*) dlname; 2903842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2913842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space); 2923842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2933842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (!err) 2943842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 2953842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fdesc = malloc (sizeof (struct unw_debug_frame_list)); 2963842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 2973842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fdesc->start = start; 2983842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fdesc->end = end; 2993842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fdesc->debug_frame = buf; 3003842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fdesc->debug_frame_size = bufsize; 3013842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fdesc->index = NULL; 3023842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fdesc->next = as->debug_frames; 3033842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3043842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz as->debug_frames = fdesc; 3053842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 306984761515e6aafe8f27d0fda1151e2f81e2832e0Christopher Ferris 307bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* ANDROID support update. */ 308bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris if (name != dlname) 309bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris free(name); 310bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* End of ANDROID update. */ 311984761515e6aafe8f27d0fda1151e2f81e2832e0Christopher Ferris 3123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return fdesc; 3133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 3143842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstruct debug_frame_tab 3163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 3173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz struct table_entry *tab; 3183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz uint32_t length; 3193842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz uint32_t size; 3203842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz }; 3213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic void 3233842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdebug_frame_tab_append (struct debug_frame_tab *tab, 3243842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz unw_word_t fde_offset, unw_word_t start_ip) 3253842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{ 3263842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz unsigned int length = tab->length; 3273842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3283842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (length == tab->size) 3293842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 3303842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz tab->size *= 2; 3313842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size); 3323842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 3333842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz tab->tab[length].fde_offset = fde_offset; 3353842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz tab->tab[length].start_ip_offset = start_ip; 3363842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3373842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz tab->length = length + 1; 3383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 3393842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3403842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic void 3413842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdebug_frame_tab_shrink (struct debug_frame_tab *tab) 3423842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{ 3433842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (tab->size > tab->length) 3443842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 3453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->length); 3463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz tab->size = tab->length; 3473842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 3483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 3493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzstatic int 3513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzdebug_frame_tab_compare (const void *a, const void *b) 3523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz{ 3533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz const struct table_entry *fa = a, *fb = b; 3543842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 3553842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (fa->start_ip_offset > fb->start_ip_offset) 3563842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return 1; 3573842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else if (fa->start_ip_offset < fb->start_ip_offset) 3583842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return -1; 3593842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 3603842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return 0; 3613842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz} 3623842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 363546463d1e78d52197ff2c204f793c343abb97dc5Arun SharmaPROTECTED int 364059676cb00cfdd3be17dfdeb25547037737f1b68Ken Wernerdwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip, 365059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner unw_word_t segbase, const char* obj_name, 366059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner unw_word_t start, unw_word_t end) 367546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma{ 368546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma unw_dyn_info_t *di; 369546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma struct unw_debug_frame_list *fdesc = 0; 370546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma unw_accessors_t *a; 371546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma unw_word_t addr; 372546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 373059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner Debug (15, "Trying to find .debug_frame for %s\n", obj_name); 374546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma di = di_debug; 375546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 376059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end); 377546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 378546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (!fdesc) 379546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 380546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma Debug (15, "couldn't load .debug_frame\n"); 381546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma return found; 382546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 383546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma else 384546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 385546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma char *buf; 386546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma size_t bufsize; 387546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma unw_word_t item_start, item_end = 0; 388546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma uint32_t u32val = 0; 389546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma uint64_t cie_id = 0; 390fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala struct debug_frame_tab tab; 391546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 392546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma Debug (15, "loaded .debug_frame\n"); 393546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 394546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma buf = fdesc->debug_frame; 395546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma bufsize = fdesc->debug_frame_size; 396546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 397546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (bufsize == 0) 398546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 399546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma Debug (15, "zero-length .debug_frame\n"); 400546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma return found; 401546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 402546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 403546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma /* Now create a binary-search table, if it does not already exist. */ 404546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (!fdesc->index) 405546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 406546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma addr = (unw_word_t) (uintptr_t) buf; 407546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 408546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma a = unw_get_accessors (unw_local_addr_space); 409546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 410546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma /* Find all FDE entries in debug_frame, and make into a sorted 411546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma index. */ 412546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 413fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala tab.length = 0; 414fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala tab.size = 16; 415fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala tab.tab = calloc (tab.size, sizeof (struct table_entry)); 416546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 417546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma while (addr < (unw_word_t) (uintptr_t) (buf + bufsize)) 418546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 419546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma uint64_t id_for_cie; 420546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma item_start = addr; 421546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 422546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL); 423546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 424546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (u32val == 0) 425546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma break; 426546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma else if (u32val != 0xffffffff) 427546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 428546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma uint32_t cie_id32 = 0; 429546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma item_end = addr + u32val; 430546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32, 431546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma NULL); 432546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma cie_id = cie_id32; 433546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma id_for_cie = 0xffffffff; 434546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 435546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma else 436546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 437546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma uint64_t u64val = 0; 438546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma /* Extended length. */ 439546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL); 440546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma item_end = addr + u64val; 441546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 442546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL); 443546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma id_for_cie = 0xffffffffffffffffull; 444546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 445546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 446546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/ 447546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 448546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (cie_id == id_for_cie) 449546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma ; 450546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma /*Debug (1, "Found CIE at %.8x.\n", item_start);*/ 451546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma else 452546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 453546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma unw_word_t fde_addr = item_start; 454546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma unw_proc_info_t this_pi; 455546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma int err; 456546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 457546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma /*Debug (1, "Found FDE at %.8x\n", item_start);*/ 458546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 459546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma err = dwarf_extract_proc_info_from_fde (unw_local_addr_space, 460546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma a, &fde_addr, 461546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma &this_pi, 0, 462546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma (uintptr_t) buf, 463546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma NULL); 464546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma if (err == 0) 465546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 466546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma Debug (15, "start_ip = %lx, end_ip = %lx\n", 467546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma (long) this_pi.start_ip, (long) this_pi.end_ip); 468fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala debug_frame_tab_append (&tab, 469546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma item_start - (unw_word_t) (uintptr_t) buf, 470546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma this_pi.start_ip); 471546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 472546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma /*else 473546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma Debug (1, "FDE parse failed\n");*/ 474546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 475546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 476546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma addr = item_end; 477546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 478546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 479fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala debug_frame_tab_shrink (&tab); 480fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala qsort (tab.tab, tab.length, sizeof (struct table_entry), 481546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma debug_frame_tab_compare); 482fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala /* for (i = 0; i < tab.length; i++) 483546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma { 484546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma fprintf (stderr, "ip %x, fde offset %x\n", 485fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala (int) tab.tab[i].start_ip_offset, 486fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala (int) tab.tab[i].fde_offset); 487546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma }*/ 488fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala fdesc->index = tab.tab; 489fce25d74c93e897439e5183fea7d8dbaf55848feTommi Rantala fdesc->index_size = tab.length; 490546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 491546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 492546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma di->format = UNW_INFO_FORMAT_TABLE; 493546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma di->start_ip = fdesc->start; 494546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma di->end_ip = fdesc->end; 495059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name; 496546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma di->u.ti.table_data = (unw_word_t *) fdesc; 497546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t); 498059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner di->u.ti.segbase = segbase; 499546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 500546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma found = 1; 501546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, " 502546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma "gp=0x%lx, table_data=0x%lx\n", 503546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma (char *) (uintptr_t) di->u.ti.name_ptr, 504546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma (long) di->u.ti.segbase, (long) di->u.ti.table_len, 505546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma (long) di->gp, (long) di->u.ti.table_data); 506546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma } 507546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma return found; 508546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma} 509546463d1e78d52197ff2c204f793c343abb97dc5Arun Sharma 510b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov#endif /* CONFIG_DEBUG_FRAME */ 511b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov 5120fed502a81dd6d9eff4da9ff26d895a16ab828cfKen Werner#ifndef UNW_REMOTE_ONLY 5130fed502a81dd6d9eff4da9ff26d895a16ab828cfKen Werner 5140b9f591823474c9651acdffec68256e077e4d601Ken Werner/* ptr is a pointer to a dwarf_callback_data structure and, on entry, 5153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz member ip contains the instruction-pointer we're looking 516eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm for. */ 5170b9f591823474c9651acdffec68256e077e4d601Ken WernerHIDDEN int 5180b9f591823474c9651acdffec68256e077e4d601Ken Wernerdwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr) 519eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm{ 5200b9f591823474c9651acdffec68256e077e4d601Ken Werner struct dwarf_callback_data *cb_data = ptr; 5211f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm unw_dyn_info_t *di = &cb_data->di; 522eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm const Elf_W(Phdr) *phdr, *p_eh_hdr, *p_dynamic, *p_text; 5231e644990c9afe9054ba7693929139f298cb3e53aKen Werner unw_word_t addr, eh_frame_start, eh_frame_end, fde_count, ip; 524786882ff8c0d1317558a4a805b2be319e64cb6a9Arun Sharma Elf_W(Addr) load_base, max_load_addr = 0; 5251f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm int ret, need_unwind_info = cb_data->need_unwind_info; 5261f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm unw_proc_info_t *pi = cb_data->pi; 527eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm struct dwarf_eh_frame_hdr *hdr; 528eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unw_accessors_t *a; 529eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm long n; 5303842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz int found = 0; 5311e644990c9afe9054ba7693929139f298cb3e53aKen Werner#ifdef CONFIG_DEBUG_FRAME 5321e644990c9afe9054ba7693929139f298cb3e53aKen Werner unw_word_t start, end; 5331e644990c9afe9054ba7693929139f298cb3e53aKen Werner#endif /* CONFIG_DEBUG_FRAME*/ 534eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 5351f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm ip = cb_data->ip; 5361f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 537eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm /* Make sure struct dl_phdr_info is at least as big as we need. */ 538eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm if (size < offsetof (struct dl_phdr_info, dlpi_phnum) 539eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm + sizeof (info->dlpi_phnum)) 540eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return -1; 541eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 542e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm Debug (15, "checking %s, base=0x%lx)\n", 543eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm info->dlpi_name, (long) info->dlpi_addr); 544eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 545eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm phdr = info->dlpi_phdr; 546eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm load_base = info->dlpi_addr; 547eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm p_text = NULL; 548eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm p_eh_hdr = NULL; 549eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm p_dynamic = NULL; 550eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 551eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm /* See if PC falls into one of the loaded segments. Find the 552eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm eh-header segment at the same time. */ 553eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm for (n = info->dlpi_phnum; --n >= 0; phdr++) 554eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 555eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm if (phdr->p_type == PT_LOAD) 556eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 557eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm Elf_W(Addr) vaddr = phdr->p_vaddr + load_base; 5581f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 5591f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if (ip >= vaddr && ip < vaddr + phdr->p_memsz) 560eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm p_text = phdr; 5611f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 5621f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if (vaddr + phdr->p_filesz > max_load_addr) 5631f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm max_load_addr = vaddr + phdr->p_filesz; 564eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 565eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm else if (phdr->p_type == PT_GNU_EH_FRAME) 566eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm p_eh_hdr = phdr; 567eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm else if (phdr->p_type == PT_DYNAMIC) 568eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm p_dynamic = phdr; 569eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 5703842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 5713842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (!p_text) 572eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return 0; 573eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 5743842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (p_eh_hdr) 575eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 5763842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (p_dynamic) 5773842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 5783842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* For dynamicly linked executables and shared libraries, 5793842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz DT_PLTGOT is the value that data-relative addresses are 5803842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz relative to for that object. We call this the "gp". */ 5813842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(p_dynamic->p_vaddr + load_base); 5823842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz for (; dyn->d_tag != DT_NULL; ++dyn) 5833842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (dyn->d_tag == DT_PLTGOT) 5843842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 5853842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* Assume that _DYNAMIC is writable and GLIBC has 5863842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz relocated it (true for x86 at least). */ 5873842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->gp = dyn->d_un.d_ptr; 5883842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz break; 5893842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 5903842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 5913842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 5923842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* Otherwise this is a static executable with no _DYNAMIC. Assume 5933842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz that data-relative addresses are relative to 0, i.e., 5943842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz absolute. */ 5953842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->gp = 0; 5963842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz pi->gp = di->gp; 5973842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 5983842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz hdr = (struct dwarf_eh_frame_hdr *) (p_eh_hdr->p_vaddr + load_base); 5993842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (hdr->version != DW_EH_VERSION) 6003842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 6013842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Debug (1, "table `%s' has unexpected version %d\n", 6023842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz info->dlpi_name, hdr->version); 6033842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return 0; 6043842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 6053842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6063842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz a = unw_get_accessors (unw_local_addr_space); 6073842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz addr = (unw_word_t) (uintptr_t) (hdr + 1); 6083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6093842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* (Optionally) read eh_frame_ptr: */ 6103842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, 6113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz &addr, hdr->eh_frame_ptr_enc, pi, 6123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz &eh_frame_start, NULL)) < 0) 6133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return ret; 6143842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* (Optionally) read fde_count: */ 6163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a, 6173842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz &addr, hdr->fde_count_enc, pi, 6183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz &fde_count, NULL)) < 0) 6193842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return ret; 6203842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4)) 6223842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 6233842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* If there is no search table or it has an unsupported 6243842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz encoding, fall back on linear search. */ 6253842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (hdr->table_enc == DW_EH_PE_omit) 626bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* ANDROID support update. */ 627bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris { 628bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* End of ANDROID update. */ 629bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris Debug (4, "table `%s' lacks search table; doing linear search\n", 630bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris info->dlpi_name); 631bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* ANDROID support update. */ 632bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris } 633bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* End of ANDROID update. */ 6343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 635bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* ANDROID support update. */ 636bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris { 637bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* End of ANDROID update. */ 638bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris Debug (4, "table `%s' has encoding 0x%x; doing linear search\n", 639bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris info->dlpi_name, hdr->table_enc); 640bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* ANDROID support update. */ 641bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris } 642bb754471703e806d83d0e6670955dc1d399690b3Christopher Ferris /* End of ANDROID update. */ 6433842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6443842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz eh_frame_end = max_load_addr; /* XXX can we do better? */ 6453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (hdr->fde_count_enc == DW_EH_PE_omit) 6473842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fde_count = ~0UL; 6483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit) 6493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz abort (); 6503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* XXX we know how to build a local binary search table for 6523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz .debug_frame, so we could do that here too. */ 6533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz cb_data->single_fde = 1; 6543842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz found = linear_search (unw_local_addr_space, ip, 6553842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz eh_frame_start, eh_frame_end, fde_count, 6563842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz pi, need_unwind_info, NULL); 6573842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (found != 1) 6583842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz found = 0; 6593842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 6603842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 6613842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 6623842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->format = UNW_INFO_FORMAT_REMOTE_TABLE; 6633842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->start_ip = p_text->p_vaddr + load_base; 6643842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz; 6653842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->u.rti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name; 6663842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->u.rti.table_data = addr; 6673842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz assert (sizeof (struct table_entry) % sizeof (unw_word_t) == 0); 6683842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->u.rti.table_len = (fde_count * sizeof (struct table_entry) 6693842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz / sizeof (unw_word_t)); 6703842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* For the binary-search table in the eh_frame_hdr, data-relative 6713842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz means relative to the start of that section... */ 6723842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz di->u.rti.segbase = (unw_word_t) (uintptr_t) hdr; 6733842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 6743842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz found = 1; 6753842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz Debug (15, "found table `%s': segbase=0x%lx, len=%lu, gp=0x%lx, " 6763842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz "table_data=0x%lx\n", (char *) (uintptr_t) di->u.rti.name_ptr, 6773842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz (long) di->u.rti.segbase, (long) di->u.rti.table_len, 6783842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz (long) di->gp, (long) di->u.rti.table_data); 6793842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 680eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 681eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 682b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov#ifdef CONFIG_DEBUG_FRAME 683059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner /* Find the start/end of the described region by parsing the phdr_info 684059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner structure. */ 685059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner start = (unw_word_t) -1; 686059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner end = 0; 687059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner 688059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner for (n = 0; n < info->dlpi_phnum; n++) 689059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner { 690059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner if (info->dlpi_phdr[n].p_type == PT_LOAD) 691059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner { 692059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner unw_word_t seg_start = info->dlpi_addr + info->dlpi_phdr[n].p_vaddr; 693059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner unw_word_t seg_end = seg_start + info->dlpi_phdr[n].p_memsz; 694059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner 695059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner if (seg_start < start) 696059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner start = seg_start; 697059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner 698059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner if (seg_end > end) 699059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner end = seg_end; 700059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner } 701059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner } 702059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner 703059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner found = dwarf_find_debug_frame (found, &cb_data->di_debug, ip, 704059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner info->dlpi_addr, info->dlpi_name, start, 705059676cb00cfdd3be17dfdeb25547037737f1b68Ken Werner end); 706b56375e76a0e23b6e464d994bc6a790e086b91dbPaul Pluzhnikov#endif /* CONFIG_DEBUG_FRAME */ 7071f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 7083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return found; 709eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm} 710eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 711eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmHIDDEN int 712eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmdwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip, 713eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unw_proc_info_t *pi, int need_unwind_info, void *arg) 714eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm{ 7150b9f591823474c9651acdffec68256e077e4d601Ken Werner struct dwarf_callback_data cb_data; 7161f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm intrmask_t saved_mask; 717d3fad3af128215bbf3b39b289ff396a2126a12b1mostang.com!davidm int ret; 718eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 719eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm Debug (14, "looking for IP=0x%lx\n", (long) ip); 720eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 7213842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz memset (&cb_data, 0, sizeof (cb_data)); 7221f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm cb_data.ip = ip; 7231f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm cb_data.pi = pi; 7241f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm cb_data.need_unwind_info = need_unwind_info; 7253842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz cb_data.di.format = -1; 7263842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz cb_data.di_debug.format = -1; 7271f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 728fc2934aadeff468b751113d56093429fd6bc4832Paul Pluzhnikov SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); 7290b9f591823474c9651acdffec68256e077e4d601Ken Werner ret = dl_iterate_phdr (dwarf_callback, &cb_data); 730fc2934aadeff468b751113d56093429fd6bc4832Paul Pluzhnikov SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); 731d3fad3af128215bbf3b39b289ff396a2126a12b1mostang.com!davidm 732d3fad3af128215bbf3b39b289ff396a2126a12b1mostang.com!davidm if (ret <= 0) 733eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 734eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm Debug (14, "IP=0x%lx not found\n", (long) ip); 735eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return -UNW_ENOINFO; 736eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 737eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 7381f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if (cb_data.single_fde) 7391f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm /* already got the result in *pi */ 7401f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return 0; 7413842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 7423842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* search the table: */ 7433842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (cb_data.di.format != -1) 7443842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz ret = dwarf_search_unwind_table (as, ip, &cb_data.di, 7451f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm pi, need_unwind_info, arg); 7463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 7473842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz ret = -UNW_ENOINFO; 7483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 7493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1) 7503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz ret = dwarf_search_unwind_table (as, ip, &cb_data.di_debug, pi, 7513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz need_unwind_info, arg); 7523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz return ret; 753eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm} 754eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 755eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmstatic inline const struct table_entry * 7563842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzlookup (const struct table_entry *table, size_t table_size, int32_t rel_ip) 757eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm{ 758eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unsigned long table_len = table_size / sizeof (struct table_entry); 759890e23eb9d3ffd9be2a025189a21794b5ed0e0ffTommi Rantala const struct table_entry *e = NULL; 760eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unsigned long lo, hi, mid; 761eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 762eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm /* do a binary search for right entry: */ 763eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm for (lo = 0, hi = table_len; lo < hi;) 764eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 765eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm mid = (lo + hi) / 2; 766eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm e = table + mid; 76743e5ee28c00813fb53f6642304b33a49b70b6d62Arun Sharma Debug (15, "e->start_ip_offset = %lx\n", (long) e->start_ip_offset); 768eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm if (rel_ip < e->start_ip_offset) 769eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm hi = mid; 770eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm else 771271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky lo = mid + 1; 772eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 773271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky if (hi <= 0) 774271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky return NULL; 775271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky e = table + hi - 1; 776271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky return e; 777eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm} 778eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 779eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#endif /* !UNW_REMOTE_ONLY */ 780eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 781eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#ifndef UNW_LOCAL_ONLY 782eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 783eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm/* Lookup an unwind-table entry in remote memory. Returns 1 if an 784eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm entry is found, 0 if no entry is found, negative if an error 785eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm occurred reading remote memory. */ 786eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmstatic int 787eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmremote_lookup (unw_addr_space_t as, 788271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky unw_word_t table, size_t table_size, int32_t rel_ip, 789eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm struct table_entry *e, void *arg) 790eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm{ 791eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unsigned long table_len = table_size / sizeof (struct table_entry); 792eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unw_accessors_t *a = unw_get_accessors (as); 793eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unsigned long lo, hi, mid; 794e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm unw_word_t e_addr = 0; 795271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky int32_t start; 796eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm int ret; 797eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 798eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm /* do a binary search for right entry: */ 799eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm for (lo = 0, hi = table_len; lo < hi;) 800eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 801eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm mid = (lo + hi) / 2; 802eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm e_addr = table + mid * sizeof (struct table_entry); 803e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm if ((ret = dwarf_reads32 (as, a, &e_addr, &start, arg)) < 0) 804eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return ret; 805eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 806eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm if (rel_ip < start) 807eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm hi = mid; 808eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm else 809271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky lo = mid + 1; 810eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 811271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky if (hi <= 0) 812eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return 0; 813271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky e_addr = table + (hi - 1) * sizeof (struct table_entry); 814271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky if ((ret = dwarf_reads32 (as, a, &e_addr, &e->start_ip_offset, arg)) < 0 815271f7069440b03152a957b5a79abb12e5f2bd605com[davidm]!marky || (ret = dwarf_reads32 (as, a, &e_addr, &e->fde_offset, arg)) < 0) 816eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return ret; 817eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return 1; 818eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm} 819eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 820e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm#endif /* !UNW_LOCAL_ONLY */ 821eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 82221595821bfe3b1a5b353d92104b14812242c58behp.com!davidmPROTECTED int 823eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmdwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, 824eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unw_dyn_info_t *di, unw_proc_info_t *pi, 825eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm int need_unwind_info, void *arg) 826eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm{ 8273842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz const struct table_entry *e = NULL, *table; 828eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unw_word_t segbase = 0, fde_addr; 829eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unw_accessors_t *a; 830eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#ifndef UNW_LOCAL_ONLY 831eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm struct table_entry ent; 832eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#endif 8331f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm int ret; 8343842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz unw_word_t debug_frame_base; 8353842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz size_t table_len; 836eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 8373842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifdef UNW_REMOTE_ONLY 8383842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE); 8393842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#else 840eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE 8413842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz || di->format == UNW_INFO_FORMAT_TABLE); 8423842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif 8433842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz assert (ip >= di->start_ip && ip < di->end_ip); 8443842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 8453842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (di->format == UNW_INFO_FORMAT_REMOTE_TABLE) 8463842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 8473842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz table = (const struct table_entry *) (uintptr_t) di->u.rti.table_data; 8483842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz table_len = di->u.rti.table_len * sizeof (unw_word_t); 8493842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz debug_frame_base = 0; 8503842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 8513842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 8523842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 8533842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#ifndef UNW_REMOTE_ONLY 8543842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data; 8553842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 85646e10c5abeeb93345367a70db2af3aba4440a49eArun Sharma /* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address 85746e10c5abeeb93345367a70db2af3aba4440a49eArun Sharma space. Both the index and the unwind tables live in local memory, but 85846e10c5abeeb93345367a70db2af3aba4440a49eArun Sharma the address space to check for properties like the address size and 85946e10c5abeeb93345367a70db2af3aba4440a49eArun Sharma endianness is the target one. */ 86046e10c5abeeb93345367a70db2af3aba4440a49eArun Sharma as = unw_local_addr_space; 8613842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz table = fdesc->index; 8623842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz table_len = fdesc->index_size * sizeof (struct table_entry); 8633842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz debug_frame_base = (uintptr_t) fdesc->debug_frame; 8643842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz#endif 8653842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 866eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 867eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm a = unw_get_accessors (as); 868eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 869eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#ifndef UNW_REMOTE_ONLY 870eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm if (as == unw_local_addr_space) 871eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 872eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm segbase = di->u.rti.segbase; 8733842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz e = lookup (table, table_len, ip - segbase); 874eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 875eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm else 876eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#endif 877eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 878eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#ifndef UNW_LOCAL_ONLY 879eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm segbase = di->u.rti.segbase; 8803842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if ((ret = remote_lookup (as, (uintptr_t) table, table_len, 881eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm ip - segbase, &ent, arg)) < 0) 882eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return ret; 883eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm if (ret) 884eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm e = &ent; 885eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm else 886eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm e = NULL; /* no info found */ 887eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm#endif 888eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 889eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm if (!e) 890eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm { 891250382c56d2c84fc3976cf8a4c834433bb68990dLassi Tuura Debug (1, "IP %lx inside range %lx-%lx, but no explicit unwind info found\n", 892250382c56d2c84fc3976cf8a4c834433bb68990dLassi Tuura (long) ip, (long) di->start_ip, (long) di->end_ip); 893eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm /* IP is inside this table's range, but there is no explicit 894eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm unwind info. */ 895eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return -UNW_ENOINFO; 896eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm } 897e9045e3cca8cbffbb449bf544bea7263b4701b47homeip.net!davidm Debug (15, "ip=0x%lx, start_ip=0x%lx\n", 8983842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz (long) ip, (long) (e->start_ip_offset)); 8993842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (debug_frame_base) 9003842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fde_addr = e->fde_offset + debug_frame_base; 9013842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz else 9023842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz fde_addr = e->fde_offset + segbase; 903250382c56d2c84fc3976cf8a4c834433bb68990dLassi Tuura Debug (1, "e->fde_offset = %lx, segbase = %lx, debug_frame_base = %lx, " 904250382c56d2c84fc3976cf8a4c834433bb68990dLassi Tuura "fde_addr = %lx\n", (long) e->fde_offset, (long) segbase, 905250382c56d2c84fc3976cf8a4c834433bb68990dLassi Tuura (long) debug_frame_base, (long) fde_addr); 9061f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi, 9073842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz need_unwind_info, 9083842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz debug_frame_base, arg)) < 0) 9091f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return ret; 9101f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 9113842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz /* .debug_frame uses an absolute encoding that does not know about any 9123842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz shared library relocation. */ 9133842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz if (di->format == UNW_INFO_FORMAT_TABLE) 9143842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz { 9153842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz pi->start_ip += segbase; 9163842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz pi->end_ip += segbase; 91746e10c5abeeb93345367a70db2af3aba4440a49eArun Sharma pi->flags = UNW_PI_FLAG_DEBUG_FRAME; 9183842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz } 9193842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitz 9201f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm if (ip < pi->start_ip || ip >= pi->end_ip) 921d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris { 922d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris /* ANDROID support update. */ 923d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris if (need_unwind_info && pi->unwind_info && pi->format == UNW_INFO_FORMAT_TABLE) 924d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris { 925d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris /* Free the memory used if the call fails. Otherwise, when there 926d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris * is a mix of dwarf and other unwind data, the memory allocated 927d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris * will be leaked. 928d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris */ 929d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris mempool_free (&dwarf_cie_info_pool, pi->unwind_info); 930d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris pi->unwind_info = NULL; 931d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris } 932d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris /* End of ANDROID support update. */ 933d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris return -UNW_ENOINFO; 934d3bf49b06c7d56b371fe49f13490f7e548a8455aChristopher Ferris } 9351f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm 9361f5ac0f5bd569a99e29b2de36f5600107503399emostang.com!davidm return 0; 937eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm} 938eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm 939eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmHIDDEN void 940eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidmdwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg) 941eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm{ 942eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm return; /* always a nop */ 943eb51b4294aa18ab13c9496378abb25162688235bhp.com!davidm} 944