mirror of
https://github.com/libunwind/libunwind.git
synced 2026-01-12 00:04:03 +08:00
Revert "Fix unwinding of pre-linked libraries"
This reverts commit a4014f3377. The
implementation of the pre-linking support is wrong. It assumes that only
pre-linked libraries will have the virtual address of the LOAD ELF section set
to non-zero.
On arm-linux-gnueabi, without pre-linking, we have:
LOAD 0x000000 0x00010000 0x00010000 0x267fc 0x267fc R E 0x10000
Which means that load_offset is set to 0x10000 and incorrectly substracted
from ip - ip_base. It also seems that pre-linking support is vastly
deprecated.
Reverting that one fixes .debug_frame based unwinding of arm-linux-gnueabi.
This commit is contained in:
committed by
Stephen M. Webb
parent
5b195ffd50
commit
62dfb32339
@@ -371,8 +371,6 @@ struct unw_debug_frame_list
|
||||
/* The start (inclusive) and end (exclusive) of the described region. */
|
||||
unw_word_t start;
|
||||
unw_word_t end;
|
||||
/* ELF load offset */
|
||||
unw_word_t load_offset;
|
||||
/* The debug frame itself. */
|
||||
char *debug_frame;
|
||||
size_t debug_frame_size;
|
||||
|
||||
@@ -141,7 +141,6 @@ typedef struct unw_dyn_info
|
||||
unw_word_t gp; /* global-pointer in effect for this entry */
|
||||
int32_t format; /* real type: unw_dyn_info_format_t */
|
||||
int32_t pad;
|
||||
unw_word_t load_offset; /* ELF load offset */
|
||||
union
|
||||
{
|
||||
unw_dyn_proc_info_t pi;
|
||||
|
||||
@@ -107,17 +107,13 @@ linear_search (unw_addr_space_t as, unw_word_t ip,
|
||||
/* XXX: Could use mmap; but elf_map_image keeps tons mapped in. */
|
||||
|
||||
static int
|
||||
load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, unw_word_t *load_offset)
|
||||
load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local)
|
||||
{
|
||||
struct elf_image ei;
|
||||
Elf_W (Ehdr) *ehdr;
|
||||
Elf_W (Phdr) *phdr;
|
||||
Elf_W (Shdr) *shdr;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
ei.image = NULL;
|
||||
*load_offset = 0;
|
||||
|
||||
ret = elf_w (load_debuginfo) (file, &ei, is_local);
|
||||
if (ret != 0)
|
||||
@@ -192,20 +188,6 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local, u
|
||||
#if defined(SHF_COMPRESSED)
|
||||
}
|
||||
#endif
|
||||
|
||||
ehdr = ei.image;
|
||||
phdr = (Elf_W (Phdr) *) ((char *) ei.image + ehdr->e_phoff);
|
||||
|
||||
for (i = 0; i < ehdr->e_phnum; ++i)
|
||||
if (phdr[i].p_type == PT_LOAD)
|
||||
{
|
||||
*load_offset = phdr[i].p_vaddr;
|
||||
|
||||
Debug (4, "%s load offset is 0x%zx\n", file, *load_offset);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mi_munmap(ei.image, ei.size);
|
||||
return 0;
|
||||
}
|
||||
@@ -258,7 +240,6 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
|
||||
int err;
|
||||
char *buf;
|
||||
size_t bufsize;
|
||||
unw_word_t load_offset;
|
||||
|
||||
/* First, see if we loaded this frame already. */
|
||||
|
||||
@@ -285,7 +266,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
|
||||
else
|
||||
name = (char*) dlname;
|
||||
|
||||
err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space, &load_offset);
|
||||
err = load_debug_frame (name, &buf, &bufsize, as == unw_local_addr_space);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
@@ -298,7 +279,6 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
|
||||
|
||||
fdesc->start = start;
|
||||
fdesc->end = end;
|
||||
fdesc->load_offset = load_offset;
|
||||
fdesc->debug_frame = buf;
|
||||
fdesc->debug_frame_size = bufsize;
|
||||
fdesc->index = NULL;
|
||||
@@ -494,7 +474,6 @@ dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip,
|
||||
di->format = UNW_INFO_FORMAT_TABLE;
|
||||
di->start_ip = fdesc->start;
|
||||
di->end_ip = fdesc->end;
|
||||
di->load_offset = fdesc->load_offset;
|
||||
di->u.ti.name_ptr = (unw_word_t) (uintptr_t) obj_name;
|
||||
di->u.ti.table_data = (unw_word_t *) fdesc;
|
||||
di->u.ti.table_len = sizeof (*fdesc) / sizeof (unw_word_t);
|
||||
@@ -957,14 +936,12 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||
ip_base = segbase;
|
||||
}
|
||||
|
||||
Debug (6, "lookup IP 0x%lx\n", (long) (ip - ip_base - di->load_offset));
|
||||
|
||||
#ifndef UNW_REMOTE_ONLY
|
||||
if (as == unw_local_addr_space)
|
||||
{
|
||||
e = lookup (table, table_len, ip - ip_base - di->load_offset);
|
||||
e = lookup (table, table_len, ip - ip_base);
|
||||
if (e && &e[1] < &table[table_len / sizeof (struct table_entry)])
|
||||
last_ip = e[1].start_ip_offset + ip_base + di->load_offset;
|
||||
last_ip = e[1].start_ip_offset + ip_base;
|
||||
else
|
||||
last_ip = di->end_ip;
|
||||
}
|
||||
@@ -972,7 +949,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||
#endif
|
||||
{
|
||||
#ifndef UNW_LOCAL_ONLY
|
||||
int32_t last_ip_offset = (int32_t) (di->end_ip - ip_base - di->load_offset);
|
||||
int32_t last_ip_offset = (int32_t) (di->end_ip - ip_base);
|
||||
segbase = di->u.rti.segbase;
|
||||
if ((ret = remote_lookup (as, (uintptr_t) table, table_len,
|
||||
(int32_t) (ip - ip_base), &ent, &last_ip_offset, arg)) < 0)
|
||||
@@ -980,7 +957,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||
if (ret)
|
||||
{
|
||||
e = &ent;
|
||||
last_ip = last_ip_offset + ip_base + di->load_offset;
|
||||
last_ip = last_ip_offset + ip_base;
|
||||
}
|
||||
else
|
||||
e = NULL; /* no info found */
|
||||
@@ -994,8 +971,8 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||
unwind info. */
|
||||
return -UNW_ENOINFO;
|
||||
}
|
||||
Debug (15, "ip=0x%lx, load_offset=0x%lx, start_ip=0x%lx\n",
|
||||
(long) ip, (long) di->load_offset, (long) (e->start_ip_offset));
|
||||
Debug (15, "ip=0x%lx, start_ip=0x%lx\n",
|
||||
(long) ip, (long) (e->start_ip_offset));
|
||||
if (debug_frame_base)
|
||||
fde_addr = e->fde_offset + debug_frame_base;
|
||||
else
|
||||
@@ -1019,9 +996,6 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
|
||||
pi->flags = UNW_PI_FLAG_DEBUG_FRAME;
|
||||
}
|
||||
|
||||
pi->start_ip += di->load_offset;
|
||||
pi->end_ip += di->load_offset;
|
||||
|
||||
#if defined(NEED_LAST_IP)
|
||||
pi->last_ip = last_ip;
|
||||
#else
|
||||
|
||||
@@ -206,7 +206,6 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi,
|
||||
|
||||
edi->di_cache.start_ip = start_ip;
|
||||
edi->di_cache.end_ip = end_ip;
|
||||
edi->di_cache.load_offset = 0;
|
||||
edi->di_cache.format = UNW_INFO_FORMAT_REMOTE_TABLE;
|
||||
edi->di_cache.u.rti.name_ptr = 0;
|
||||
/* two 32-bit values (ip_offset/fde_offset) per table-entry: */
|
||||
|
||||
Reference in New Issue
Block a user