summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2012-11-12 15:41:10 +0100
committerJan Kratochvil <jan.kratochvil@redhat.com>2012-11-12 15:41:10 +0100
commit56aa56abd2410b89f116b7fdcdf7e7653be42d55 (patch)
tree611d1efbbfcd9afcce4ed320130f023518b01870
parentcb5dd2fa185e15917f43915f00766f3b05fdc1ae (diff)
+dwfl_report_elf_baseaddr
-rw-r--r--libdwfl/dwfl_report_elf.c39
-rw-r--r--libdwfl/libdwfl.h7
-rw-r--r--libdwfl/libdwflP.h3
-rw-r--r--libdwfl/offline.c3
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