This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

Re: [PATCH] Fix section symbols in objcopy when removing sections with relocations from Elf objects


On Thu, May 25, 2006 at 02:31:07PM +0930, Alan Modra wrote:
> On Wed, May 24, 2006 at 02:35:14PM +0100, Julian Brown wrote:
> >     * objcopy.c (filter_symbols): Filter out section symbols for
> >     sections which are being stripped and their associated relocation
> >     sections. Call bfd_copy_private_symbol_data for each symbol which
> >     passes the filter.
> 
> I think this should be fixed in elf.c:elf_map_symbols by throwing away
> any bad section syms.  That way we keep (more) elf specific code out of
> objcopy.c.  I'll take a look at it.

Like this.  Tested with "make all check" on practically all elf
targets.  I wouldn't rush to put a change like this one on the 2.17
branch, not that I think there's anything wrong with it, but we seem to
have code in elf.c that goes to great lengths to support objcopy of
symbols in unlikely sections like .strtab.  This was no doubt because
the assembler at one stage did output section syms for all these special
sections, and you could argue that objcopy ought to make minimal changes
for "objcopy foo.o new.o".  Nowadays the assembler doesn't output these
rather silly symbols, so new object files should pass thru objcopy
relatively unchanged.  However, "objcopy old_object.o new.o" will strip
out some section symbols with this patch.  I can't see this being a
problem, but it's probably best not to make this change on a release
branch.

	* elf.c (sym_is_global): Return a bfd_boolean.
	(ignore_section_sym): New function.
	(elf_map_symbols): Use ignore_section_sym to discard some syms.
	(_bfd_elf_symbol_from_bfd_symbol): Ensure section belongs to
	bfd before using elf_section_syms.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.338
diff -u -p -r1.338 elf.c
--- bfd/elf.c	19 May 2006 00:51:28 -0000	1.338
+++ bfd/elf.c	25 May 2006 12:51:45 -0000
@@ -3280,7 +3280,7 @@ assign_section_numbers (bfd *abfd, struc
 /* Map symbol from it's internal number to the external number, moving
    all local symbols to be at the head of the list.  */
 
-static int
+static bfd_boolean
 sym_is_global (bfd *abfd, asymbol *sym)
 {
   /* If the backend has a special mapping, use it.  */
@@ -3293,6 +3293,20 @@ sym_is_global (bfd *abfd, asymbol *sym)
 	  || bfd_is_com_section (bfd_get_section (sym)));
 }
 
+/* Don't output section symbols for sections that are not going to be
+   output.  Also, don't output section symbols for reloc and other
+   special sections.  */
+
+static bfd_boolean
+ignore_section_sym (bfd *abfd, asymbol *sym)
+{
+  return ((sym->flags & BSF_SECTION_SYM) != 0
+	  && (sym->value != 0
+	      || (sym->section->owner != abfd
+		  && (sym->section->output_section->owner != abfd
+		      || sym->section->output_offset != 0))));
+}
+
 static bfd_boolean
 elf_map_symbols (bfd *abfd)
 {
@@ -3333,51 +3347,29 @@ elf_map_symbols (bfd *abfd)
       asymbol *sym = syms[idx];
 
       if ((sym->flags & BSF_SECTION_SYM) != 0
-	  && sym->value == 0)
+	  && !ignore_section_sym (abfd, sym))
 	{
-	  asection *sec;
-
-	  sec = sym->section;
+	  asection *sec = sym->section;
 
-	  if (sec->owner != NULL)
-	    {
-	      if (sec->owner != abfd)
-		{
-		  if (sec->output_offset != 0)
-		    continue;
-
-		  sec = sec->output_section;
+	  if (sec->owner != abfd)
+	    sec = sec->output_section;
 
-		  /* Empty sections in the input files may have had a
-		     section symbol created for them.  (See the comment
-		     near the end of _bfd_generic_link_output_symbols in
-		     linker.c).  If the linker script discards such
-		     sections then we will reach this point.  Since we know
-		     that we cannot avoid this case, we detect it and skip
-		     the abort and the assignment to the sect_syms array.
-		     To reproduce this particular case try running the
-		     linker testsuite test ld-scripts/weak.exp for an ELF
-		     port that uses the generic linker.  */
-		  if (sec->owner == NULL)
-		    continue;
-
-		  BFD_ASSERT (sec->owner == abfd);
-		}
-	      sect_syms[sec->index] = syms[idx];
-	    }
+	  sect_syms[sec->index] = syms[idx];
 	}
     }
 
   /* Classify all of the symbols.  */
   for (idx = 0; idx < symcount; idx++)
     {
+      if (ignore_section_sym (abfd, syms[idx]))
+	continue;
       if (!sym_is_global (abfd, syms[idx]))
 	num_locals++;
       else
 	num_globals++;
     }
 
-  /* We will be adding a section symbol for each BFD section.  Most normal
+  /* We will be adding a section symbol for each normal BFD section.  Most
      sections will already have a section symbol in outsymbols, but
      eg. SHT_GROUP sections will not, and we need the section symbol mapped
      at least in that case.  */
@@ -3403,6 +3395,8 @@ elf_map_symbols (bfd *abfd)
       asymbol *sym = syms[idx];
       unsigned int i;
 
+      if (ignore_section_sym (abfd, sym))
+	continue;
       if (!sym_is_global (abfd, sym))
 	i = num_locals2++;
       else
@@ -5130,13 +5124,14 @@ _bfd_elf_symbol_from_bfd_symbol (bfd *ab
       && (flags & BSF_SECTION_SYM)
       && asym_ptr->section)
     {
+      asection *sec;
       int indx;
 
-      if (asym_ptr->section->output_section != NULL)
-	indx = asym_ptr->section->output_section->index;
-      else
-	indx = asym_ptr->section->index;
-      if (indx < elf_num_section_syms (abfd)
+      sec = asym_ptr->section;
+      if (sec->owner != abfd && sec->output_section != NULL)
+	sec = sec->output_section;
+      if (sec->owner == abfd
+	  && (indx = sec->index) < elf_num_section_syms (abfd)
 	  && elf_section_syms (abfd)[indx] != NULL)
 	asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
     }


-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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