This really is just a robustify patch in case section zero got the
wrong section flags set. In that case __libdwfl_relocate_value might
call dwfl_offline_section_address which might assert (because it isn't
prepared to handle section zero). elf_nextscn will never see section zero.
So be explicit in dwfl_offline_section_address and immediately assert
when shndx is zero. And handle section zero immediately by not relocating
the value in __libdwfl_relocate_value.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdwfl/ChangeLog | 6 ++++++
libdwfl/offline.c | 1 +
libdwfl/relocate.c | 6 ++++++
3 files changed, 13 insertions(+)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 03faecf..6eec018 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2014-12-07 Mark Wielaard <mjw(a)redhat.com>
+
+ * offline.c (dwfl_offline_section_address): Assert shndx is not zero.
+ * relocate.c (__libdwfl_relocate_value): Don't relocate against
+ section zero.
+
2014-11-29 Mark Wielaard <mjw(a)redhat.com>
* relocate.c (relocate_section): Check relocation section and target
diff --git a/libdwfl/offline.c b/libdwfl/offline.c
index 28d2782..982ceab 100644
--- a/libdwfl/offline.c
+++ b/libdwfl/offline.c
@@ -48,6 +48,7 @@ dwfl_offline_section_address (Dwfl_Module *mod,
assert (mod->e_type == ET_REL);
assert (shdr->sh_addr == 0);
assert (shdr->sh_flags & SHF_ALLOC);
+ assert (shndx != 0);
if (mod->debug.elf == NULL)
/* We are only here because sh_addr is zero even though layout is complete.
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 6862189..fc8ae23 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -38,6 +38,12 @@ internal_function
__libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx,
Elf32_Word shndx, GElf_Addr *value)
{
+ /* No adjustment needed for section zero, it is never loaded.
+ Handle it first, just in case the ELF file has strange section
+ zero flags set. */
+ if (shndx == 0)
+ return DWFL_E_NOERROR;
+
Elf_Scn *refscn = elf_getscn (elf, shndx);
GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
if (refshdr == NULL)
--
1.9.3
Show replies by thread