This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH for uninitialized junk in .dynsym



The MIPS back-end uses mips_elf_size_dynamic_sections to create
dynamic symbol table entries for every section in the output file.
These include the .gnu.version, .gnu.version_d, and .gnu.version_r
sections.  These sections are removed by
bfd_elfXX_size_dynamic_sections if they are not needed, but the
corresponding dynamic symbol table entries are not removed, resulting
in uninitialized junk in the output file.

This patch fixes the problem.  OK to check in?

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-06-13  Mark Mitchell  <mark@codesourcery.com>

	* elflink.h (elf_link_adjust_dynindx): New function.
	(elf_link_remove_section_and_adjust_dynindices): Likewise.
	(bfd_elf_size_dynamic_sections): Use them.

Index: elflink.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elflink.h,v
retrieving revision 1.2
diff -u -p -r1.2 elflink.h
--- elflink.h	1999/06/13 01:13:24	1.2
+++ elflink.h	1999/06/13 20:41:40
@@ -54,6 +54,10 @@ 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 boolean elf_link_adjust_dynindx 
+  PARAMS ((struct elf_link_hash_entry *, PTR));
+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 +2405,65 @@ compute_bucket_count (info)
   return best_size;
 }
 
+/* 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.  */
+
+static boolean
+elf_link_adjust_dynindx (h, increment)
+     struct elf_link_hash_entry *h;
+     PTR increment;
+{
+  if (h->dynindx != -1)
+    h->dynindx += *((int *) increment);
+    
+  return true;
+}
+
+/* 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),
+			      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 +2665,9 @@ NAME(bfd_elf,size_dynamic_sections) (out
       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 +2860,9 @@ NAME(bfd_elf,size_dynamic_sections) (out
 				(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 +2962,12 @@ NAME(bfd_elf,size_dynamic_sections) (out
       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
 	{

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]