PR 2257
authorNick Clifton <nickc@redhat.com>
Tue, 18 Apr 2006 09:41:36 +0000 (09:41 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 18 Apr 2006 09:41:36 +0000 (09:41 +0000)
* elfcode.h (elf_object_p): Allow files with corrupt e_shstrndx fields to
  still be handled as ELF files.
* readelf.c (SECTION_NAME): Cope with a missing string table.
  (process_file_header): Cope with a corrupt e_shstrndx field.
  (process_section_headers): Correctly handle an e_shstrndx value of SHF_UNDEF.

bfd/ChangeLog
bfd/elfcode.h
binutils/ChangeLog
binutils/readelf.c

index d6069baafbcc16071c4f377f5a59e392373e013e..2938fa0fe45a83eeeee84ebe744e94f6a04c43d5 100644 (file)
@@ -1,3 +1,9 @@
+2006-04-18  Nick Clifton  <nickc@redhat.com>
+
+       PR 2257
+       * elfcode.h (elf_object_p): Allow files with corrupt e_shstrndx
+       fields to still be handled as ELF files.
+
 2006-04-16  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * po/SRC-POTFILES.in: Regenerated.
index f7f85ba2056cd786e90fa68413bb7d356a05a51c..9bb66e11c0cf8f329708420da1909319bb025947 100644 (file)
@@ -742,9 +742,18 @@ elf_object_p (bfd *abfd)
       if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)
          || (i_ehdrp->e_shstrndx >= SHN_LORESERVE
              && i_ehdrp->e_shstrndx <= SHN_HIRESERVE))
-       goto got_wrong_format_error;
+       {
+         /* PR 2257:
+            We used to just goto got_wrong_format_error here
+            but there are binaries in existance for which this test
+            will prevent the binutils from working with them at all.
+            So we are kind, and reset the string index value to 0
+            so that at least some processing can be done.  */
+         i_ehdrp->e_shstrndx = SHN_UNDEF;
+         _bfd_error_handler (_("warning: %s has a corrupt string table index - ignoring"), abfd->filename);
+       }
     }
-  else if (i_ehdrp->e_shstrndx != 0)
+  else if (i_ehdrp->e_shstrndx != SHN_UNDEF)
     goto got_wrong_format_error;
 
   /* Read in the program headers.  */
index fdb3934a3d9d7a11d208cfe6293ba9397f79f6e0..2f25dc99cae4613a432e0d4b9f488ca45f17f70c 100644 (file)
@@ -1,3 +1,11 @@
+2006-04-18  Nick Clifton  <nickc@redhat.com>
+
+       PR 2257
+       * readelf.c (SECTION_NAME): Cope with a missing string table.
+       (process_file_header): Cope with a corrupt e_shstrndx field.
+       (process_section_headers): Correctly handle an e_shstrndx value of
+       SHF_UNDEF.
+
 2006-04-12  Nick Clifton  <nickc@redhat.com>
 
        * objdump.c (objdump_symbol_at_address): Fix typo in comment.
index d8bd54f440f316b67b6acc328d7ab4285f8faf5e..09f1d513cd7369b61a13a9959f05530fe02995d6 100644 (file)
@@ -222,9 +222,11 @@ static void (*byte_put) (unsigned char *, bfd_vma, int);
 
 #define UNKNOWN -1
 
-#define SECTION_NAME(X)        ((X) == NULL ? "<none>" : \
-                        ((X)->sh_name >= string_table_length \
-                         ? "<corrupt>" : string_table + (X)->sh_name))
+#define SECTION_NAME(X)        \
+  ((X) == NULL ? "<none>" \
+  : string_table == NULL ? "<no-name>" \
+  : ((X)->sh_name >= string_table_length ? "<corrupt>" \
+  : string_table + (X)->sh_name))
 
 /* Given st_shndx I, map to section_headers index.  */
 #define SECTION_HEADER_INDEX(I)                                \
@@ -3142,6 +3144,11 @@ process_file_header (void)
              (long) elf_header.e_shstrndx);
       if (section_headers != NULL && elf_header.e_shstrndx == SHN_XINDEX)
        printf (" (%ld)", (long) section_headers[0].sh_link);
+      else if (elf_header.e_shstrndx != SHN_UNDEF
+              && (elf_header.e_shstrndx >= elf_header.e_shnum
+                  || (elf_header.e_shstrndx >= SHN_LORESERVE
+                      && elf_header.e_shstrndx <= SHN_HIRESERVE)))
+       printf (" <corrupt: out of range>");
       putc ('\n', stdout);
     }
 
@@ -3151,6 +3158,11 @@ process_file_header (void)
        elf_header.e_shnum = section_headers[0].sh_size;
       if (elf_header.e_shstrndx == SHN_XINDEX)
        elf_header.e_shstrndx = section_headers[0].sh_link;
+      else if (elf_header.e_shstrndx != SHN_UNDEF
+              && (elf_header.e_shstrndx >= elf_header.e_shnum
+                  || (elf_header.e_shstrndx >= SHN_LORESERVE
+                      && elf_header.e_shstrndx <= SHN_HIRESERVE)))
+       elf_header.e_shstrndx = SHN_UNDEF;
       free (section_headers);
       section_headers = NULL;
     }
@@ -3920,7 +3932,8 @@ process_section_headers (FILE *file)
     return 0;
 
   /* Read in the string table, so that we have names to display.  */
-  if (SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
+  if (elf_header.e_shstrndx != SHN_UNDEF
+       && SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
     {
       section = SECTION_HEADER (elf_header.e_shstrndx);