We already checked this in all other cases except for the special case
of relocs in statically_linked executables. Found with afl.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 6 +++++
src/readelf.c | 77 +++++++++++++++++++++++++++++++++++++++++------------------
2 files changed, 60 insertions(+), 23 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index a6d18b5..072146a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-28 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (handle_relocs_rel): Print INVALID SECTION if destshdr
+ is NULL also for statically_linked relocations.
+ (handle_relocs_rela): Likewise.
+
2014-11-26 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (print_debug_aranges_section): Cast Dwarf_Word length
diff --git a/src/readelf.c b/src/readelf.c
index cd15e4c..6060851 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1857,17 +1857,32 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
GElf_Shdr *shdr)
}
if (is_statically_linked > 0 && shdr->sh_link == 0)
- printf ("\
- %#0*" PRIx64 " %-20s %*s %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : gettext ("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, "",
- elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ {
+ if (unlikely (destshdr == NULL))
+ printf (" %#0*" PRIx64 " %-20s %*s <%s %ld>\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ gettext ("INVALID SECTION"),
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+ printf (" %#0*" PRIx64 " %-20s %*s %s\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ }
else
printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
@@ -2045,18 +2060,34 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
GElf_Shdr *shdr)
}
if (is_statically_linked > 0 && shdr->sh_link == 0)
- printf ("\
- %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : gettext ("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, "",
- rel->r_addend,
- elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ {
+ if (unlikely (destshdr == NULL))
+ printf (" %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " <%s
%ld>\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ rel->r_addend,
+ gettext ("INVALID SECTION"),
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+ printf (" %#0*" PRIx64 " %-15s %*s %#6" PRIx64 "
%s\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ rel->r_addend,
+ elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ }
else
printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
--
1.9.3