summaryrefslogtreecommitdiff
path: root/src/elfxx.c
diff options
context:
space:
mode:
authorDavid Mosberger-Tang <davidm@panda.mostang.com>2007-08-22 13:02:09 -0600
committerDavid Mosberger-Tang <davidm@panda.mostang.com>2007-08-22 13:02:09 -0600
commite6b9f350f78ecd9ef3b8a3e721f9435c94fc2562 (patch)
tree1e90fcdf7c0049f85d26f91f0d714e38c77b5bfc /src/elfxx.c
parent03e05b41386fd5797cb8cd62eff7f0ba77c4e07e (diff)
downloadlibunwind-e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562.tar.gz
Introduce a tdep_get_func_addr_hook() in the ELF lookup_symbol()
routine and add address-space argument. This is needed because on PPC64, a the function-name symbol refers to a function descriptor (unlike, for example, on ia64, where the @fptr() operator is needed to refer to a function descriptor). Thus, in order to look up the name of a function, we need to dereference the function descriptor. To make matters more "interesting", the function descriptors are normally resolved by the dynamic linker, so we can't get their values from the ELF file. Instead, we have to read them from the running image, hence the need for the address-space argument.
Diffstat (limited to 'src/elfxx.c')
-rw-r--r--src/elfxx.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/src/elfxx.c b/src/elfxx.c
index 7b135067..05b99438 100644
--- a/src/elfxx.c
+++ b/src/elfxx.c
@@ -1,6 +1,7 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2003-2005 Hewlett-Packard Co
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ Copyright (C) 2007 David Mosberger-Tang
+ Contributed by David Mosberger-Tang <dmosberger@gmail.com>
This file is part of libunwind.
@@ -39,7 +40,8 @@ elf_w (valid_object) (struct elf_image *ei)
static int
-elf_w (lookup_symbol) (unw_word_t ip, struct elf_image *ei,
+elf_w (lookup_symbol) (unw_addr_space_t as,
+ unw_word_t ip, struct elf_image *ei,
Elf_W (Addr) load_offset,
char *buf, size_t buf_len, unw_word_t *offp)
{
@@ -98,7 +100,8 @@ elf_w (lookup_symbol) (unw_word_t ip, struct elf_image *ei,
if (ELF_W (ST_TYPE) (sym->st_info) == STT_FUNC
&& sym->st_shndx != SHN_UNDEF)
{
- val = sym->st_value;
+ if (tdep_get_func_addr (as, sym->st_value, &val) < 0)
+ continue;
if (sym->st_shndx != SHN_ABS)
val += load_offset;
Debug (16, "0x%016lx info=0x%02x %s\n",
@@ -134,8 +137,8 @@ elf_w (lookup_symbol) (unw_word_t ip, struct elf_image *ei,
sensitive to the performance of this routine, why bother... */
HIDDEN int
-elf_w (get_proc_name) (pid_t pid, unw_word_t ip, char *buf, size_t buf_len,
- unw_word_t *offp)
+elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip,
+ char *buf, size_t buf_len, unw_word_t *offp)
{
unsigned long segbase, mapoff;
Elf_W (Addr) load_offset = 0;
@@ -158,7 +161,7 @@ elf_w (get_proc_name) (pid_t pid, unw_word_t ip, char *buf, size_t buf_len,
break;
}
- ret = elf_w (lookup_symbol) (ip, &ei, load_offset, buf, buf_len, offp);
+ ret = elf_w (lookup_symbol) (as, ip, &ei, load_offset, buf, buf_len, offp);
munmap (ei.image, ei.size);
ei.image = NULL;