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 <[email protected]>
---
 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  <[email protected]>
+
+       * 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  <[email protected]>
 
        * 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

Reply via email to