2006-04-05 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 5 Apr 2006 13:37:32 +0000 (13:37 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 5 Apr 2006 13:37:32 +0000 (13:37 +0000)
PR ld/2411
* elflink.c (check_dynsym): New.
(elf_link_output_extsym): Use it.
(bfd_elf_final_link): Likewise.

bfd/ChangeLog
bfd/elflink.c

index 9f371a802d25ef578cd2c548cb01a85a602a596c..ae9a4a70eb802b2c4c3951f4623a726ae763baac 100644 (file)
@@ -1,3 +1,10 @@
+2006-04-05  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/2411
+       * elflink.c (check_dynsym): New.
+       (elf_link_output_extsym): Use it.
+       (bfd_elf_final_link): Likewise.
+
 2006-04-05  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/2404
index f3098aedfdf4e77b979ba03c8cb62fabfc094855..0900220dbcac5b1b14ef11c6367cb0b5d0a62cdb 100644 (file)
@@ -6204,6 +6204,24 @@ elf_link_output_sym (struct elf_final_link_info *finfo,
   return TRUE;
 }
 
+/* Return TRUE if the dynamic symbol SYM in ABFD is supported.  */
+
+static bfd_boolean
+check_dynsym (bfd *abfd, Elf_Internal_Sym *sym)
+{
+  if (sym->st_shndx > SHN_HIRESERVE)
+    {
+      /* The gABI doesn't support dynamic symbols in output sections
+         beyond 64k.  */
+      (*_bfd_error_handler)
+       (_("%B: Too many sections: %d (>= %d)"),
+        abfd, bfd_count_sections (abfd), SHN_LORESERVE);
+      bfd_set_error (bfd_error_nonrepresentable_section);
+      return FALSE;
+    }
+  return TRUE;
+}
+
 /* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in
    allowing an unsatisfied unversioned symbol in the DSO to match a
    versioned symbol that would normally require an explicit version.
@@ -6636,6 +6654,11 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
 
       sym.st_name = h->dynstr_index;
       esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym;
+      if (! check_dynsym (finfo->output_bfd, &sym))
+       {
+         eoinfo->failed = TRUE;
+         return FALSE;
+       }
       bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0);
 
       bucketcount = elf_hash_table (finfo->info)->bucketcount;
@@ -8313,6 +8336,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
              indx = elf_section_data (s)->this_idx;
              BFD_ASSERT (indx > 0);
              sym.st_shndx = indx;
+             if (! check_dynsym (abfd, &sym))
+               return FALSE;
              sym.st_value = s->vma;
              dest = dynsym + dynindx * bed->s->sizeof_sym;
              if (last_local < dynindx)
@@ -8347,6 +8372,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
                  sym.st_shndx =
                    elf_section_data (s->output_section)->this_idx;
+                 if (! check_dynsym (abfd, &sym))
+                   return FALSE;
                  sym.st_value = (s->output_section->vma
                                  + s->output_offset
                                  + e->isym.st_value);