* elf-bfd.h (_bfd_elf_link_adjust_dynindx): New function.
authorMark Mitchell <mark@codesourcery.com>
Sun, 13 Jun 1999 14:49:51 +0000 (14:49 +0000)
committerMark Mitchell <mark@codesourcery.com>
Sun, 13 Jun 1999 14:49:51 +0000 (14:49 +0000)
* elflink.c (_bfd_elf_link_adjust_dynindx): Define it.
* elflink.h (elf_link_remove_section_and_adjust_dynindices): New
function.
(bfd_elf_size_dynamic_sections): Use it.

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

index c0d45a5785377e94fdef05417db8a0273869e929..e75acf0cb73bad2863b03264c8de7a943c64b179 100644 (file)
@@ -1,3 +1,11 @@
+1999-06-13  Mark Mitchell  <mark@codesourcery.com>
+
+       * elf-bfd.h (_bfd_elf_link_adjust_dynindx): New function.
+       * elflink.c (_bfd_elf_link_adjust_dynindx): Define it.
+       * elflink.h (elf_link_remove_section_and_adjust_dynindices): New
+       function.
+       (bfd_elf_size_dynamic_sections): Use it.
+
 1999-06-13  Alan Modra  <alan@spri.levels.unisa.edu.au>
 
        * elf32-i386.c (elf_howto_table): Change R_386_PC8 from
index d0042192bb1b3e78ccfd6a98d1ef13d622cc538c..49c5eae60f86aef1b0ca6c4ac2a31c054f1d1c4e 100644 (file)
@@ -927,6 +927,8 @@ boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *,
                                                  struct bfd_link_info *));
 boolean _bfd_elf_create_got_section PARAMS ((bfd *,
                                             struct bfd_link_info *));
+boolean _bfd_elf_link_adjust_dynindx PARAMS ((struct elf_link_hash_entry *,
+                                             PTR));
 
 elf_linker_section_t *_bfd_elf_create_linker_section
   PARAMS ((bfd *abfd,
index 829d977aaeb7fae24071d9e30a86ce5bdd953eae..d644e1b4c2c30876a7d8644f08ef19490b6ecec5 100644 (file)
@@ -259,6 +259,21 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
 
   return true;
 }
+
+/* Increase the index at which H will appear in the dynamic symbol
+   table by INCREMENT (which is really an `int *').  Called via
+   elf_link_hash_traverse.  */
+
+boolean
+_bfd_elf_link_adjust_dynindx (h, increment)
+     struct elf_link_hash_entry *h;
+     PTR increment;
+{
+  if (h->dynindx != -1)
+    h->dynindx += *((int *) increment);
+    
+  return true;
+}
 \f
 /* Create a special linker section, or return a pointer to a linker section already created  */
 
index fcbacf823f1886eb5320f4ec1a89a365d3305e34..88fd05c200f85789821001f498e1686405db3e04 100644 (file)
@@ -54,6 +54,8 @@ static boolean elf_collect_hash_codes
   PARAMS ((struct elf_link_hash_entry *, PTR));
 static boolean elf_link_read_relocs_from_section 
   PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *));
+static void elf_link_remove_section_and_adjust_dynindices 
+  PARAMS ((bfd *, struct bfd_link_info *, asection *));
 
 /* Given an ELF BFD, add symbols to the global hash table as
    appropriate.  */
@@ -2401,6 +2403,50 @@ compute_bucket_count (info)
   return best_size;
 }
 
+/* Remove SECTION from the BFD.  If a symbol for SECTION was going to
+   be put into the dynamic symbol table, remove it, and renumber
+   subsequent entries.  */
+
+static void
+elf_link_remove_section_and_adjust_dynindices (abfd, info, section)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     asection *section;
+{
+  asection **spp;
+
+  /* Remove the section from the output list.  */
+  for (spp = &abfd->sections;
+       *spp != section->output_section;
+       spp = &(*spp)->next)
+    ;
+  *spp = section->output_section->next;
+  --abfd->section_count;
+
+  if (elf_section_data (section->output_section)->dynindx)
+    {
+      asection *s;
+      int increment = -1;
+
+      /* We were going to output an entry in the dynamic symbol table
+        for the symbol corresponding to this section.  Now, the
+        section is gone.  So, we must renumber the dynamic indices of
+        all subsequent sections and all other entries in the dynamic
+        symbol table.  */
+      elf_section_data (section->output_section)->dynindx = 0;
+      for (s = section->output_section->next; s; s = s->next)
+       if (elf_section_data (s)->dynindx)
+         --elf_section_data (s)->dynindx;
+      
+      elf_link_hash_traverse (elf_hash_table (info),
+                             _bfd_elf_link_adjust_dynindx,
+                             &increment);
+
+      /* There is one less dynamic symbol than there was before.  */
+      --elf_hash_table (info)->dynsymcount;
+    }
+}
+
 /* Set up the sizes and contents of the ELF dynamic sections.  This is
    called by the ELF linker emulation before_allocation routine.  We
    must set the sizes of the sections before the linker sets the
@@ -2602,17 +2648,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
       verdefs = asvinfo.verdefs;
 
       if (verdefs == NULL)
-       {
-         asection **spp;
-
-         /* Don't include this section in the output file.  */
-         for (spp = &output_bfd->sections;
-              *spp != s->output_section;
-              spp = &(*spp)->next)
-           ;
-         *spp = s->output_section->next;
-         --output_bfd->section_count;
-       }
+       elf_link_remove_section_and_adjust_dynindices (output_bfd,
+                                                      info,
+                                                      s);
       else
        {
          unsigned int cdefs;
@@ -2805,19 +2843,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
                                (PTR) &sinfo);
 
        if (elf_tdata (output_bfd)->verref == NULL)
-         {
-           asection **spp;
-
-           /* We don't have any version definitions, so we can just
-               remove the section.  */
-
-           for (spp = &output_bfd->sections;
-                *spp != s->output_section;
-                spp = &(*spp)->next)
-             ;
-           *spp = s->output_section->next;
-           --output_bfd->section_count;
-         }
+         elf_link_remove_section_and_adjust_dynindices (output_bfd,
+                                                        info,
+                                                        s);
        else
          {
            Elf_Internal_Verneed *t;
@@ -2917,16 +2945,12 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
       if (dynsymcount == 0
          || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
        {
-         asection **spp;
-
-         /* We don't need any symbol versions; just discard the
-             section.  */
-         for (spp = &output_bfd->sections;
-              *spp != s->output_section;
-              spp = &(*spp)->next)
-           ;
-         *spp = s->output_section->next;
-         --output_bfd->section_count;
+         elf_link_remove_section_and_adjust_dynindices (output_bfd,
+                                                        info,
+                                                        s);
+         /* The DYNSYMCOUNT might have changed if we were going to
+            output a dynamic symbol table entry for S.  */
+         dynsymcount = elf_hash_table (info)->dynsymcount;
        }
       else
        {