1 /* libunwind - a platform-independent unwind library
2 Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of libunwind.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
26 /* Locate an FDE via the ELF data-structures defined by LSB v1.3
27 (http://www.linuxbase.org/spec/). */
29 #ifndef UNW_REMOTE_ONLY
31 #endif /* !UNW_REMOTE_ONLY */
38 #include "libunwind_i.h"
42 int32_t start_ip_offset;
46 #ifndef UNW_REMOTE_ONLY
53 linear_search (unw_addr_space_t as, unw_word_t ip,
54 unw_word_t eh_frame_start, unw_word_t eh_frame_end,
56 unw_proc_info_t *pi, int need_unwind_info, void *arg)
58 unw_accessors_t *a = unw_get_accessors (unw_local_addr_space);
59 unw_word_t i = 0, fde_addr, addr = eh_frame_start;
62 while (i++ < fde_count && addr < eh_frame_end)
65 if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, 0, 0, arg))
69 if (ip >= pi->start_ip && ip < pi->end_ip)
71 if (!need_unwind_info)
74 if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi,
84 #endif /* !UNW_REMOTE_ONLY */
86 #ifdef CONFIG_DEBUG_FRAME
87 /* Load .debug_frame section from FILE. Allocates and returns space
88 in *BUF, and sets *BUFSIZE to its size. IS_LOCAL is 1 if using the
89 local process, in which case we can search the system debug file
90 directory; 0 for other address spaces, in which case we do not; or
91 -1 for recursive calls following .gnu_debuglink. Returns 0 on
92 success, 1 on error. Succeeds even if the file contains no
94 /* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */
97 load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
101 Elf_W (Half) shstrndx;
102 Elf_W (Shdr) *sec_hdrs = NULL;
103 char *stringtab = NULL;
106 char *linkbuf = NULL;
111 f = fopen (file, "r");
116 if (fread (&ehdr, sizeof (Elf_W (Ehdr)), 1, f) != 1)
119 shstrndx = ehdr.e_shstrndx;
121 Debug (4, "opened file '%s'. Section header at offset %d\n",
122 file, (int) ehdr.e_shoff);
124 fseek (f, ehdr.e_shoff, SEEK_SET);
125 sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr)));
126 if (fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f) != ehdr.e_shnum)
129 Debug (4, "loading string table of size %zd\n",
130 sec_hdrs[shstrndx].sh_size);
131 stringtab = malloc (sec_hdrs[shstrndx].sh_size);
132 fseek (f, sec_hdrs[shstrndx].sh_offset, SEEK_SET);
133 if (fread (stringtab, 1, sec_hdrs[shstrndx].sh_size, f) != sec_hdrs[shstrndx].sh_size)
136 for (i = 1; i < ehdr.e_shnum && *buf == NULL; i++)
138 char *secname = &stringtab[sec_hdrs[i].sh_name];
140 if (strcmp (secname, ".debug_frame") == 0)
142 *bufsize = sec_hdrs[i].sh_size;
143 *buf = malloc (*bufsize);
145 fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
146 if (fread (*buf, 1, *bufsize, f) != *bufsize)
149 Debug (4, "read %zd bytes of .debug_frame from offset %zd\n",
150 *bufsize, sec_hdrs[i].sh_offset);
152 else if (strcmp (secname, ".gnu_debuglink") == 0)
154 linksize = sec_hdrs[i].sh_size;
155 linkbuf = malloc (linksize);
157 fseek (f, sec_hdrs[i].sh_offset, SEEK_SET);
158 if (fread (linkbuf, 1, linksize, f) != linksize)
161 Debug (4, "read %zd bytes of .gnu_debuglink from offset %zd\n",
162 linksize, sec_hdrs[i].sh_offset);
171 /* Ignore separate debug files which contain a .gnu_debuglink section. */
172 if (linkbuf && is_local == -1)
178 if (*buf == NULL && linkbuf != NULL && memchr (linkbuf, 0, linksize) != NULL)
180 char *newname, *basedir, *p;
181 static const char *debugdir = "/usr/lib/debug";
184 /* XXX: Don't bother with the checksum; just search for the file. */
185 basedir = malloc (strlen (file) + 1);
186 newname = malloc (strlen (linkbuf) + strlen (debugdir)
187 + strlen (file) + 9);
189 p = strrchr (file, '/');
192 memcpy (basedir, file, p - file);
193 basedir[p - file] = '\0';
198 strcpy (newname, basedir);
199 strcat (newname, "/");
200 strcat (newname, linkbuf);
201 ret = load_debug_frame (newname, buf, bufsize, -1);
205 strcpy (newname, basedir);
206 strcat (newname, "/.debug/");
207 strcat (newname, linkbuf);
208 ret = load_debug_frame (newname, buf, bufsize, -1);
211 if (ret == 1 && is_local == 1)
213 strcpy (newname, debugdir);
214 strcat (newname, basedir);
215 strcat (newname, "/");
216 strcat (newname, linkbuf);
217 ret = load_debug_frame (newname, buf, bufsize, -1);
227 /* An error reading image file. Release resources and return error code */
237 /* Locate the binary which originated the contents of address ADDR. Return
238 the name of the binary in *name (space is allocated by the caller)
239 Returns 0 if a binary is successfully found, or 1 if an error occurs. */
242 find_binary_for_address (unw_word_t ip, char *name, size_t name_size)
244 #if defined(__linux) && (!UNW_REMOTE_ONLY)
245 struct map_iterator mi;
248 unsigned long segbase, mapoff, hi;
250 maps_init (&mi, pid);
251 while (maps_next (&mi, &segbase, &hi, &mapoff))
252 if (ip >= segbase && ip < hi)
254 size_t len = strlen (mi.path);
256 if (len + 1 <= name_size)
258 memcpy (name, mi.path, len + 1);
270 /* Locate and/or try to load a debug_frame section for address ADDR. Return
271 pointer to debug frame descriptor, or zero if not found. */
273 static struct unw_debug_frame_list *
274 locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
275 unw_word_t start, unw_word_t end)
277 struct unw_debug_frame_list *w, *fdesc = 0;
284 /* First, see if we loaded this frame already. */
286 for (w = as->debug_frames; w; w = w->next)
288 Debug (4, "checking %p: %lx-%lx\n", w, (long)w->start, (long)w->end);
289 if (addr >= w->start && addr < w->end)
293 /* If the object name we receive is blank, there's still a chance of locating
294 the file by parsing /proc/self/maps. */
296 if (strcmp (dlname, "") == 0)
298 err = find_binary_for_address (addr, name, sizeof(path));
301 Debug (15, "tried to locate binary for 0x%" PRIx64 ", but no luck\n",
307 name = (char*) dlname;
309 err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space);
313 fdesc = malloc (sizeof (struct unw_debug_frame_list));
315 fdesc->start = start;
317 fdesc->debug_frame = buf;
318 fdesc->debug_frame_size = bufsize;
320 fdesc->next = as->debug_frames;
322 as->debug_frames = fdesc;
328 struct debug_frame_tab
330 struct table_entry *tab;
336 debug_frame_tab_append (struct debug_frame_tab *tab,
337 unw_word_t fde_offset, unw_word_t start_ip)
339 unsigned int length = tab->length;
341 if (length == tab->size)
344 tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->size);
347 tab->tab[length].fde_offset = fde_offset;
348 tab->tab[length].start_ip_offset = start_ip;
350 tab->length = length + 1;
354 debug_frame_tab_shrink (struct debug_frame_tab *tab)
356 if (tab->size > tab->length)
358 tab->tab = realloc (tab->tab, sizeof (struct table_entry) * tab->length);
359 tab->size = tab->length;
364 debug_frame_tab_compare (const void *a, const void *b)
366 const struct table_entry *fa = a, *fb = b;
368 if (fa->start_ip_offset > fb->start_ip_offset)
370 else if (fa->start_ip_offset < fb->start_ip_offset)
377 dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip,
378 unw_word_t segbase, const char* obj_name,
379 unw_word_t start, unw_word_t end)
382 struct unw_debug_frame_list *fdesc = 0;
386 Debug (15, "Trying to find .debug_frame for %s\n", obj_name);
389 fdesc = locate_debug_info (unw_local_addr_space, ip, obj_name, start, end);
393 Debug (15, "couldn't load .debug_frame\n");
400 unw_word_t item_start, item_end = 0;
403 struct debug_frame_tab tab;
405 Debug (15, "loaded .debug_frame\n");
407 buf = fdesc->debug_frame;
408 bufsize = fdesc->debug_frame_size;
412 Debug (15, "zero-length .debug_frame\n");
416 /* Now create a binary-search table, if it does not already exist. */
419 addr = (unw_word_t) (uintptr_t) buf;
421 a = unw_get_accessors (unw_local_addr_space);
423 /* Find all FDE entries in debug_frame, and make into a sorted
428 tab.tab = calloc (tab.size, sizeof (struct table_entry));
430 while (addr < (unw_word_t) (uintptr_t) (buf + bufsize))
435 dwarf_readu32 (unw_local_addr_space, a, &addr, &u32val, NULL);
439 else if (u32val != 0xffffffff)
441 uint32_t cie_id32 = 0;
442 item_end = addr + u32val;
443 dwarf_readu32 (unw_local_addr_space, a, &addr, &cie_id32,
446 id_for_cie = 0xffffffff;
451 /* Extended length. */
452 dwarf_readu64 (unw_local_addr_space, a, &addr, &u64val, NULL);
453 item_end = addr + u64val;
455 dwarf_readu64 (unw_local_addr_space, a, &addr, &cie_id, NULL);
456 id_for_cie = 0xffffffffffffffffull;
459 /*Debug (1, "CIE/FDE id = %.8x\n", (int) cie_id);*/
461 if (cie_id == id_for_cie)
463 /*Debug (1, "Found CIE at %.8x.\n", item_start);*/
466 unw_word_t fde_addr = item_start;
467 unw_proc_info_t this_pi;
470 /*Debug (1, "Found FDE at %.8x\n", item_start);*/
472 err = dwarf_extract_proc_info_from_fde (unw_local_addr_space,
479 Debug (15, "start_ip = %lx, end_ip = %lx\n",
480 (long) this_pi.start_ip, (long) this_pi.end_ip);
481 debug_frame_tab_append (&tab,
482 item_start - (unw_word_t) (uintptr_t) buf,
486 Debug (1, "FDE parse failed\n");*/
492 debug_frame_tab_shrink (&tab);
493 qsort (tab.tab, tab.length, sizeof (struct table_entry),
494 debug_frame_tab_compare);
495 /* for (i = 0; i < tab.length; i++)
497 fprintf (stderr, "ip %x, fde offset %x\n",
498 (int) tab.tab[i].start_ip_offset,
499 (int) tab.tab[i].fde_offset);
501 fdesc->index = tab.tab;
502 fdesc->index_size = tab.length;
505 di->format = UNW_INFO_FORMAT_TABLE;
506 di->start_ip = fdesc->start;
507 di->end_ip = fdesc->end;
508 di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name;
509 di->u.ti.table_data = (unw_word_t *) fdesc;
510 di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t);
511 di->u.ti.segbase = segbase;
514 Debug (15, "found debug_frame table `%s': segbase=0x%lx, len=%lu, "
515 "gp=0x%lx, table_data=0x%lx\n",
516 (char *) (uintptr_t) di->u.ti.name_ptr,
517 (long) di->u.ti.segbase, (long) di->u.ti.table_len,
518 (long) di->gp, (long) di->u.ti.table_data);
523 #endif /* CONFIG_DEBUG_FRAME */
525 #ifndef UNW_REMOTE_ONLY
527 /* ptr is a pointer to a dwarf_callback_data structure and, on entry,
528 member ip contains the instruction-pointer we're looking
531 dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
533 struct dwarf_callback_data *cb_data = ptr;
534 unw_dyn_info_t *di = &cb_data->di;
535 const Elf_W(Phdr) *phdr, *p_eh_hdr, *p_dynamic, *p_text;
536 unw_word_t addr, eh_frame_start, eh_frame_end, fde_count, ip;
537 Elf_W(Addr) load_base, max_load_addr = 0;
538 int ret, need_unwind_info = cb_data->need_unwind_info;
539 unw_proc_info_t *pi = cb_data->pi;
540 struct dwarf_eh_frame_hdr *hdr;
544 #ifdef CONFIG_DEBUG_FRAME
545 unw_word_t start, end;
546 #endif /* CONFIG_DEBUG_FRAME*/
550 /* Make sure struct dl_phdr_info is at least as big as we need. */
551 if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
552 + sizeof (info->dlpi_phnum))
555 Debug (15, "checking %s, base=0x%lx)\n",
556 info->dlpi_name, (long) info->dlpi_addr);
558 phdr = info->dlpi_phdr;
559 load_base = info->dlpi_addr;
564 /* See if PC falls into one of the loaded segments. Find the
565 eh-header segment at the same time. */
566 for (n = info->dlpi_phnum; --n >= 0; phdr++)
568 if (phdr->p_type == PT_LOAD)
570 Elf_W(Addr) vaddr = phdr->p_vaddr + load_base;
572 if (ip >= vaddr && ip < vaddr + phdr->p_memsz)
575 if (vaddr + phdr->p_filesz > max_load_addr)
576 max_load_addr = vaddr + phdr->p_filesz;
578 else if (phdr->p_type == PT_GNU_EH_FRAME)
580 else if (phdr->p_type == PT_DYNAMIC)
591 /* For dynamicly linked executables and shared libraries,
592 DT_PLTGOT is the value that data-relative addresses are
593 relative to for that object. We call this the "gp". */
594 Elf_W(Dyn) *dyn = (Elf_W(Dyn) *)(p_dynamic->p_vaddr + load_base);
595 for (; dyn->d_tag != DT_NULL; ++dyn)
596 if (dyn->d_tag == DT_PLTGOT)
598 /* Assume that _DYNAMIC is writable and GLIBC has
599 relocated it (true for x86 at least). */
600 di->gp = dyn->d_un.d_ptr;
605 /* Otherwise this is a static executable with no _DYNAMIC. Assume
606 that data-relative addresses are relative to 0, i.e.,
611 hdr = (struct dwarf_eh_frame_hdr *) (p_eh_hdr->p_vaddr + load_base);
612 if (hdr->version != DW_EH_VERSION)
614 Debug (1, "table `%s' has unexpected version %d\n",
615 info->dlpi_name, hdr->version);
619 a = unw_get_accessors (unw_local_addr_space);
620 addr = (unw_word_t) (uintptr_t) (hdr + 1);
622 /* (Optionally) read eh_frame_ptr: */
623 if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
624 &addr, hdr->eh_frame_ptr_enc, pi,
625 &eh_frame_start, NULL)) < 0)
628 /* (Optionally) read fde_count: */
629 if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,
630 &addr, hdr->fde_count_enc, pi,
631 &fde_count, NULL)) < 0)
634 if (hdr->table_enc != (DW_EH_PE_datarel | DW_EH_PE_sdata4))
636 /* If there is no search table or it has an unsupported
637 encoding, fall back on linear search. */
638 if (hdr->table_enc == DW_EH_PE_omit)
639 Debug (4, "table `%s' lacks search table; doing linear search\n",
642 Debug (4, "table `%s' has encoding 0x%x; doing linear search\n",
643 info->dlpi_name, hdr->table_enc);
645 eh_frame_end = max_load_addr; /* XXX can we do better? */
647 if (hdr->fde_count_enc == DW_EH_PE_omit)
649 if (hdr->eh_frame_ptr_enc == DW_EH_PE_omit)
652 /* XXX we know how to build a local binary search table for
653 .debug_frame, so we could do that here too. */
654 cb_data->single_fde = 1;
655 found = linear_search (unw_local_addr_space, ip,
656 eh_frame_start, eh_frame_end, fde_count,
657 pi, need_unwind_info, NULL);
663 di->format = UNW_INFO_FORMAT_REMOTE_TABLE;
664 di->start_ip = p_text->p_vaddr + load_base;
665 di->end_ip = p_text->p_vaddr + load_base + p_text->p_memsz;
666 di->u.rti.name_ptr = (unw_word_t) (uintptr_t) info->dlpi_name;
667 di->u.rti.table_data = addr;
668 assert (sizeof (struct table_entry) % sizeof (unw_word_t) == 0);
669 di->u.rti.table_len = (fde_count * sizeof (struct table_entry)
670 / sizeof (unw_word_t));
671 /* For the binary-search table in the eh_frame_hdr, data-relative
672 means relative to the start of that section... */
673 di->u.rti.segbase = (unw_word_t) (uintptr_t) hdr;
676 Debug (15, "found table `%s': segbase=0x%lx, len=%lu, gp=0x%lx, "
677 "table_data=0x%lx\n", (char *) (uintptr_t) di->u.rti.name_ptr,
678 (long) di->u.rti.segbase, (long) di->u.rti.table_len,
679 (long) di->gp, (long) di->u.rti.table_data);
683 #ifdef CONFIG_DEBUG_FRAME
684 /* Find the start/end of the described region by parsing the phdr_info
686 start = (unw_word_t) -1;
689 for (n = 0; n < info->dlpi_phnum; n++)
691 if (info->dlpi_phdr[n].p_type == PT_LOAD)
693 unw_word_t seg_start = info->dlpi_addr + info->dlpi_phdr[n].p_vaddr;
694 unw_word_t seg_end = seg_start + info->dlpi_phdr[n].p_memsz;
696 if (seg_start < start)
704 found = dwarf_find_debug_frame (found, &cb_data->di_debug, ip,
705 info->dlpi_addr, info->dlpi_name, start,
707 #endif /* CONFIG_DEBUG_FRAME */
713 dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
714 unw_proc_info_t *pi, int need_unwind_info, void *arg)
716 struct dwarf_callback_data cb_data;
717 intrmask_t saved_mask;
720 Debug (14, "looking for IP=0x%lx\n", (long) ip);
722 memset (&cb_data, 0, sizeof (cb_data));
725 cb_data.need_unwind_info = need_unwind_info;
726 cb_data.di.format = -1;
727 cb_data.di_debug.format = -1;
729 SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask);
730 ret = dl_iterate_phdr (dwarf_callback, &cb_data);
731 SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
735 Debug (14, "IP=0x%lx not found\n", (long) ip);
739 if (cb_data.single_fde)
740 /* already got the result in *pi */
743 /* search the table: */
744 if (cb_data.di.format != -1)
745 ret = dwarf_search_unwind_table (as, ip, &cb_data.di,
746 pi, need_unwind_info, arg);
750 if (ret == -UNW_ENOINFO && cb_data.di_debug.format != -1)
751 ret = dwarf_search_unwind_table (as, ip, &cb_data.di_debug, pi,
752 need_unwind_info, arg);
756 static inline const struct table_entry *
757 lookup (const struct table_entry *table, size_t table_size, int32_t rel_ip)
759 unsigned long table_len = table_size / sizeof (struct table_entry);
760 const struct table_entry *e = NULL;
761 unsigned long lo, hi, mid;
763 /* do a binary search for right entry: */
764 for (lo = 0, hi = table_len; lo < hi;)
768 Debug (15, "e->start_ip_offset = %lx\n", (long) e->start_ip_offset);
769 if (rel_ip < e->start_ip_offset)
780 #endif /* !UNW_REMOTE_ONLY */
782 #ifndef UNW_LOCAL_ONLY
784 /* Lookup an unwind-table entry in remote memory. Returns 1 if an
785 entry is found, 0 if no entry is found, negative if an error
786 occurred reading remote memory. */
788 remote_lookup (unw_addr_space_t as,
789 unw_word_t table, size_t table_size, int32_t rel_ip,
790 struct table_entry *e, void *arg)
792 unsigned long table_len = table_size / sizeof (struct table_entry);
793 unw_accessors_t *a = unw_get_accessors (as);
794 unsigned long lo, hi, mid;
795 unw_word_t e_addr = 0;
799 /* do a binary search for right entry: */
800 for (lo = 0, hi = table_len; lo < hi;)
803 e_addr = table + mid * sizeof (struct table_entry);
804 if ((ret = dwarf_reads32 (as, a, &e_addr, &start, arg)) < 0)
814 e_addr = table + (hi - 1) * sizeof (struct table_entry);
815 if ((ret = dwarf_reads32 (as, a, &e_addr, &e->start_ip_offset, arg)) < 0
816 || (ret = dwarf_reads32 (as, a, &e_addr, &e->fde_offset, arg)) < 0)
821 #endif /* !UNW_LOCAL_ONLY */
824 dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
825 unw_dyn_info_t *di, unw_proc_info_t *pi,
826 int need_unwind_info, void *arg)
828 const struct table_entry *e = NULL, *table;
829 unw_word_t segbase = 0, fde_addr;
831 #ifndef UNW_LOCAL_ONLY
832 struct table_entry ent;
835 unw_word_t debug_frame_base;
838 #ifdef UNW_REMOTE_ONLY
839 assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE);
841 assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE
842 || di->format == UNW_INFO_FORMAT_TABLE);
844 assert (ip >= di->start_ip && ip < di->end_ip);
846 if (di->format == UNW_INFO_FORMAT_REMOTE_TABLE)
848 table = (const struct table_entry *) (uintptr_t) di->u.rti.table_data;
849 table_len = di->u.rti.table_len * sizeof (unw_word_t);
850 debug_frame_base = 0;
854 #ifndef UNW_REMOTE_ONLY
855 struct unw_debug_frame_list *fdesc = (void *) di->u.ti.table_data;
857 /* UNW_INFO_FORMAT_TABLE (i.e. .debug_frame) is read from local address
858 space. Both the index and the unwind tables live in local memory, but
859 the address space to check for properties like the address size and
860 endianness is the target one. */
861 as = unw_local_addr_space;
862 table = fdesc->index;
863 table_len = fdesc->index_size * sizeof (struct table_entry);
864 debug_frame_base = (uintptr_t) fdesc->debug_frame;
868 a = unw_get_accessors (as);
870 #ifndef UNW_REMOTE_ONLY
871 if (as == unw_local_addr_space)
873 segbase = di->u.rti.segbase;
874 e = lookup (table, table_len, ip - segbase);
879 #ifndef UNW_LOCAL_ONLY
880 segbase = di->u.rti.segbase;
881 if ((ret = remote_lookup (as, (uintptr_t) table, table_len,
882 ip - segbase, &ent, arg)) < 0)
887 e = NULL; /* no info found */
892 Debug (1, "IP %lx inside range %lx-%lx, but no explicit unwind info found\n",
893 (long) ip, (long) di->start_ip, (long) di->end_ip);
894 /* IP is inside this table's range, but there is no explicit
898 Debug (15, "ip=0x%lx, start_ip=0x%lx\n",
899 (long) ip, (long) (e->start_ip_offset));
900 if (debug_frame_base)
901 fde_addr = e->fde_offset + debug_frame_base;
903 fde_addr = e->fde_offset + segbase;
904 Debug (1, "e->fde_offset = %lx, segbase = %lx, debug_frame_base = %lx, "
905 "fde_addr = %lx\n", (long) e->fde_offset, (long) segbase,
906 (long) debug_frame_base, (long) fde_addr);
907 if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi,
909 debug_frame_base, arg)) < 0)
912 /* .debug_frame uses an absolute encoding that does not know about any
913 shared library relocation. */
914 if (di->format == UNW_INFO_FORMAT_TABLE)
916 pi->start_ip += segbase;
917 pi->end_ip += segbase;
918 pi->flags = UNW_PI_FLAG_DEBUG_FRAME;
921 if (ip < pi->start_ip || ip >= pi->end_ip)
928 dwarf_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *pi, void *arg)
930 return; /* always a nop */