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 <m...@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 <m...@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 <m...@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