summaryrefslogtreecommitdiffstats
path: root/translate.cxx
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-06-25 23:07:17 +0200
committerMark Wielaard <mjw@redhat.com>2009-06-25 23:15:47 +0200
commitc65358e84b38bc84951a4e3c5e8e4f3cace9f63e (patch)
tree1b8ac066edfc7eea878fc28c059cbe980900af56 /translate.cxx
parentad0e17094017350fc0010b8416579da42ab1d5a3 (diff)
downloadsystemtap-steved-c65358e84b38bc84951a4e3c5e8e4f3cace9f63e.tar.gz
systemtap-steved-c65358e84b38bc84951a4e3c5e8e4f3cace9f63e.tar.xz
systemtap-steved-c65358e84b38bc84951a4e3c5e8e4f3cace9f63e.zip
PR10323 Some ustack exelib.exp tests fail with prelinked shared libs.
For shared libraries (.dynamic sections) we need the eh frame section address offset. This is the sh_addr if the shared library isn't prelinked (since the base load address is zero in that case), otherwise it is the module start address minus the bias (which also works for the non-prelinked case). * translate.cxx (get_unwind_data): Adjust eh_addr for module start and bias if module isn't absolute (has no relocations). * testsuite/systemtap.exelib/ustack.tcl: Accept all prelink tests.
Diffstat (limited to 'translate.cxx')
-rw-r--r--translate.cxx11
1 files changed, 8 insertions, 3 deletions
diff --git a/translate.cxx b/translate.cxx
index cc634555..a0164661 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4438,13 +4438,13 @@ struct unwindsym_dump_context
// Get the .debug_frame end .eh_frame sections for the given module.
// Also returns the lenght of both sections when found, plus the section
-// address of the eh_frame data.
+// address (offset) of the eh_frame data.
static void get_unwind_data (Dwfl_Module *m,
void **debug_frame, void **eh_frame,
size_t *debug_len, size_t *eh_len,
Dwarf_Addr *eh_addr)
{
- Dwarf_Addr bias = 0;
+ Dwarf_Addr start, bias = 0;
GElf_Ehdr *ehdr, ehdr_mem;
GElf_Shdr *shdr, shdr_mem;
Elf_Scn *scn;
@@ -4452,6 +4452,7 @@ static void get_unwind_data (Dwfl_Module *m,
Elf *elf;
// fetch .eh_frame info preferably from main elf file.
+ dwfl_module_info (m, NULL, &start, NULL, NULL, NULL, NULL, NULL);
elf = dwfl_module_getelf(m, &bias);
ehdr = gelf_getehdr(elf, &ehdr_mem);
scn = NULL;
@@ -4464,7 +4465,11 @@ static void get_unwind_data (Dwfl_Module *m,
data = elf_rawdata(scn, NULL);
*eh_frame = data->d_buf;
*eh_len = data->d_size;
- *eh_addr = shdr->sh_addr;
+ // For ".dynamic" sections we want the offset, not absolute addr.
+ if (dwfl_module_relocations (m) > 0)
+ *eh_addr = shdr->sh_addr - start + bias;
+ else
+ *eh_addr = shdr->sh_addr;
break;
}
}