OSDN Git Service

PR 9934
authornickc <nickc>
Fri, 13 Mar 2009 11:34:42 +0000 (11:34 +0000)
committernickc <nickc>
Fri, 13 Mar 2009 11:34:42 +0000 (11:34 +0000)
        * elf-bfd.h (NUM_SHDR_ENTRIES): Cope with an empty section.
        * elflink.c (elf_link_read_relocs_from_section): Use
        NUM_SHDR_ENTRIES.  Gracefully handle the case where there are
        relocs but no symbol table.
        * elf32-arm.c (elf32_arm_check_relocs): Likewise.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-arm.c
bfd/elflink.c

index 9841e5d..7cbe0a2 100644 (file)
@@ -1,3 +1,12 @@
+2009-03-13  Nick Clifton  <nickc@redhat.com>
+
+       PR 9934
+       * elf-bfd.h (NUM_SHDR_ENTRIES): Cope with an empty section.
+       * elflink.c (elf_link_read_relocs_from_section): Use
+       NUM_SHDR_ENTRIES.  Gracefully handle the case where there are
+       relocs but no symbol table.
+       * elf32-arm.c (elf32_arm_check_relocs): Likewise.
+
 2009-03-12  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/9938
index 7b8fa69..865388c 100644 (file)
 
 /* The number of entries in a section is its size divided by the size
    of a single entry.  This is normally only applicable to reloc and
-   symbol table sections.  */
-#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_size / (shdr)->sh_entsize)
+   symbol table sections.
+   PR 9934: It is possible to have relocations that do not refer to
+   symbols, thus it is also possible to have a relocation section in
+   an object file, but no symbol table.  */
+#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_entsize > 0 ? (shdr)->sh_size / (shdr)->sh_entsize : 0)
 
 /* If size isn't specified as 64 or 32, NAME macro should fail.  */
 #ifndef NAME
index f534290..226434a 100644 (file)
@@ -9597,6 +9597,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
   bfd_vma *local_got_offsets;
   struct elf32_arm_link_hash_table *htab;
   bfd_boolean needs_plt;
+  unsigned long nsyms;
 
   if (info->relocatable)
     return TRUE;
@@ -9620,7 +9621,8 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
   symtab_hdr = & elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
-
+  nsyms = NUM_SHDR_ENTRIES (symtab_hdr);
+  
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
@@ -9633,14 +9635,18 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
       r_type = ELF32_R_TYPE (rel->r_info);
       r_type = arm_real_reloc_type (htab, r_type);
 
-      if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+      if (r_symndx >= nsyms
+         /* PR 9934: It is possible to have relocations that do not
+            refer to symbols, thus it is also possible to have an
+            object file containing relocations but no symbol table.  */
+         && (r_symndx > 0 || nsyms > 0))
        {
          (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
-                                r_symndx);
+                                  r_symndx);
          return FALSE;
        }
 
-      if (r_symndx < symtab_hdr->sh_info)
+      if (nsyms == 0 || r_symndx < symtab_hdr->sh_info)
         h = NULL;
       else
        {
index d0e4534..c635cb0 100644 (file)
@@ -2202,7 +2202,7 @@ elf_link_read_relocs_from_section (bfd *abfd,
     return FALSE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  nsyms = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
+  nsyms = NUM_SHDR_ENTRIES (symtab_hdr);
 
   bed = get_elf_backend_data (abfd);
 
@@ -2228,11 +2228,24 @@ elf_link_read_relocs_from_section (bfd *abfd,
       r_symndx = ELF32_R_SYM (irela->r_info);
       if (bed->s->arch_size == 64)
        r_symndx >>= 24;
-      if ((size_t) r_symndx >= nsyms)
+      if (nsyms > 0)
+       {
+         if ((size_t) r_symndx >= nsyms)
+           {
+             (*_bfd_error_handler)
+               (_("%B: bad reloc symbol index (0x%lx >= 0x%lx)"
+                  " for offset 0x%lx in section `%A'"),
+                abfd, sec,
+                (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset);
+             bfd_set_error (bfd_error_bad_value);
+             return FALSE;
+           }
+       }
+      else if (r_symndx != 0)
        {
          (*_bfd_error_handler)
-           (_("%B: bad reloc symbol index (0x%lx >= 0x%lx)"
-              " for offset 0x%lx in section `%A'"),
+           (_("%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A'"
+              " when the object file has no symbol table"),
             abfd, sec,
             (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset);
          bfd_set_error (bfd_error_bad_value);