diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-11-12 15:41:10 +0100 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-11-12 15:41:10 +0100 |
commit | 56aa56abd2410b89f116b7fdcdf7e7653be42d55 (patch) | |
tree | 611d1efbbfcd9afcce4ed320130f023518b01870 | |
parent | cb5dd2fa185e15917f43915f00766f3b05fdc1ae (diff) |
+dwfl_report_elf_baseaddr
-rw-r--r-- | libdwfl/dwfl_report_elf.c | 39 | ||||
-rw-r--r-- | libdwfl/libdwfl.h | 7 | ||||
-rw-r--r-- | libdwfl/libdwflP.h | 3 | ||||
-rw-r--r-- | libdwfl/offline.c | 3 |
4 files changed, 43 insertions, 9 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) diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 8498c0cd..a2ab8246 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -146,6 +146,13 @@ extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, GElf_Addr base); +/* See dwfl_report_elf except that BASE is the page-aligned absolute VMA + address where the ELF file should start. Any possible file prelinking of + the disk file is compensated. */ +extern Dwfl_Module *dwfl_report_elf_baseaddr (Dwfl *dwfl, const char *name, + const char *file_name, int fd, + GElf_Addr base); + /* Similar, but report the module for offline use. All ET_EXEC files being reported must be reported before any relocatable objects. If this is used, dwfl_report_module and dwfl_report_elf may not be diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index ca8be2f2..e5e638c9 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -353,7 +353,8 @@ extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden; Consumes ELF on success, not on failure. */ extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, - Elf *elf, GElf_Addr base, bool sanity) + Elf *elf, GElf_Addr base, + bool base_is_bias, bool sanity) internal_function; /* Meat of dwfl_report_offline. */ diff --git a/libdwfl/offline.c b/libdwfl/offline.c index 26a6bd66..28d2782e 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -127,7 +127,8 @@ process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, Elf *elf) { Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf, - dwfl->offline_next_address, false); + dwfl->offline_next_address, true, + false); if (mod != NULL) { /* If this is an ET_EXEC file with fixed addresses, the address range |