summaryrefslogtreecommitdiff
path: root/libdwfl/dwfl_report_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdwfl/dwfl_report_elf.c')
-rw-r--r--libdwfl/dwfl_report_elf.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index d7061704..08ad37c8 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -41,7 +41,8 @@
Dwfl_Module *
internal_function
__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
- int fd, Elf *elf, GElf_Addr base, bool sanity)
+ int fd, Elf *elf, GElf_Addr base, bool base_is_bias,
+ bool sanity)
{
GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
if (ehdr == NULL)
@@ -181,11 +182,19 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
{
vaddr = ph->p_vaddr & -ph->p_align;
address_sync = ph->p_vaddr + ph->p_memsz;
- start = base + vaddr;
break;
}
}
- bias = base;
+ if (base_is_bias)
+ {
+ start = base + vaddr;
+ bias = base;
+ }
+ else
+ {
+ start = base;
+ bias = base - vaddr;
+ }
for (size_t i = phnum; i-- > 0;)
{
@@ -195,7 +204,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
if (ph->p_type == PT_LOAD
&& ph->p_vaddr + ph->p_memsz > 0)
{
- end = base + (ph->p_vaddr + ph->p_memsz);
+ end = bias + (ph->p_vaddr + ph->p_memsz);
break;
}
}
@@ -246,8 +255,9 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
}
Dwfl_Module *
-dwfl_report_elf (Dwfl *dwfl, const char *name,
- const char *file_name, int fd, GElf_Addr base)
+internal_function
+__libdwfl_report_elf_open (Dwfl *dwfl, const char *name, const char *file_name,
+ int fd, GElf_Addr base, bool base_is_bias)
{
bool closefd = false;
if (fd < 0)
@@ -270,7 +280,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name,
}
Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name,
- fd, elf, base, true);
+ fd, elf, base, base_is_bias, true);
if (mod == NULL)
{
elf_end (elf);
@@ -280,4 +290,19 @@ dwfl_report_elf (Dwfl *dwfl, const char *name,
return mod;
}
+
+Dwfl_Module *
+dwfl_report_elf (Dwfl *dwfl, const char *name,
+ const char *file_name, int fd, GElf_Addr base)
+{
+ return __libdwfl_report_elf_open (dwfl, name, file_name, fd, base, true);
+}
INTDEF (dwfl_report_elf)
+
+Dwfl_Module *
+dwfl_report_elf_baseaddr (Dwfl *dwfl, const char *name,
+ const char *file_name, int fd, GElf_Addr base)
+{
+ return __libdwfl_report_elf_open (dwfl, name, file_name, fd, base, false);
+}
+INTDEF (dwfl_report_elf_baseaddr)