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: PR ld/6931: COMDAT group is broken


The elf.c and elflink.c patches below teach the ELF backend linker to
handle group signature symbols for ld -r.  The genelf.em patch does
the same for ELF targets that use the generic linker.

The linker.c change fixes the group section contents for the generic
linker, a nasty hack but nothing else seemed nice either.  Prior to
this change, the generic linker simply copied group section contents
to output for ld -r, which, since section indices almost always
change, broke groups.  The generic linker also mashed together group
sections due to lack of unique sections for groups.  Moving this logic
from elf32.em into ldlang.c cures that particular problem.

Finally, I tweaked the various emulation's place_orphan code to not
use an existing output section statement if it did not already have a
bfd section.  This is because a new bfd section will be created after
all other existing sections, which is probably the wrong ordering.
lang_place_orphan knows how to rearrange sections.

bfd/
	* elf.c (bfd_elf_set_group_contents): Assign sh_info for ld -r when
	the signature symbol is global.
	* elflink.c (elf_link_input_bfd): Ensure group signature symbol
	is output when ld -r.  Set group sh_info when local.
	* linker.c (default_indirect_link_order): Handle group sections
	specially.
ld/
	* ldemul.c (ldemul_place_orphan): Add "name" param.
	* ldemul.h (ldemul_place_orphan): Update prototype.
	(struct ld_emulation_xfer_struct <place_orphan>): Likewise.
	* ldlang.c (lang_place_orphans): Generate unique section names here..
	* emultempl/elf32.em (place_orphan): ..rather than here.  Don't
	directly use an existing output section statement that has no
	bfd section.
	* emultempl/pe.em (place_orphan): Likewise.
	* emultempl/pep.em (place_orphan): Likewise.
	* emultempl/beos.em (place_orphan): Adjust.
	* emultempl/spuelf.em (spu_place_special_section): Adjust
	place_orphan call.
	* emultempl/genelf.em (gld${EMULATION_NAME}_after_open): New function.
	(LDEMUL_AFTER_OPEN): Define.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.464
diff -u -p -r1.464 elf.c
--- bfd/elf.c	29 Sep 2008 14:12:02 -0000	1.464
+++ bfd/elf.c	3 Oct 2008 08:38:51 -0000
@@ -2681,13 +2681,15 @@ elf_fake_sections (bfd *abfd, asection *
     *failedptr = TRUE;
 }
 
-/* Fill in the contents of a SHT_GROUP section.  */
+/* Fill in the contents of a SHT_GROUP section.  Called from
+   _bfd_elf_compute_section_file_positions for gas, objcopy, and
+   when ELF targets use the generic linker, ld.  Called for ld -r
+   from bfd_elf_final_link.  */
 
 void
 bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
 {
   bfd_boolean *failedptr = failedptrarg;
-  unsigned long symindx;
   asection *elt, *first;
   unsigned char *loc;
   bfd_boolean gas;
@@ -2698,20 +2700,49 @@ bfd_elf_set_group_contents (bfd *abfd, a
       || *failedptr)
     return;
 
-  symindx = 0;
-  if (elf_group_id (sec) != NULL)
-    symindx = elf_group_id (sec)->udata.i;
-
-  if (symindx == 0)
-    {
-      /* If called from the assembler, swap_out_syms will have set up
-	 elf_section_syms;  If called for "ld -r", use target_index.  */
-      if (elf_section_syms (abfd) != NULL)
-	symindx = elf_section_syms (abfd)[sec->index]->udata.i;
-      else
-	symindx = sec->target_index;
+  if (elf_section_data (sec)->this_hdr.sh_info == 0)
+    {
+      unsigned long symindx = 0;
+
+      /* elf_group_id will have been set up by objcopy and the
+	 generic linker.  */
+      if (elf_group_id (sec) != NULL)
+	symindx = elf_group_id (sec)->udata.i;
+
+      if (symindx == 0)
+	{
+	  /* If called from the assembler, swap_out_syms will have set up
+	     elf_section_syms.  */
+	  BFD_ASSERT (elf_section_syms (abfd) != NULL);
+	  symindx = elf_section_syms (abfd)[sec->index]->udata.i;
+	}
+      elf_section_data (sec)->this_hdr.sh_info = symindx;
+    }
+  else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
+    {
+      /* The ELF backend linker sets sh_info to -2 when the group
+	 signature symbol is global, and thus the index can't be
+	 set until all local symbols are output.  */
+      asection *igroup = elf_sec_group (elf_next_in_group (sec));
+      struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
+      unsigned long symndx = sec_data->this_hdr.sh_info;
+      unsigned long extsymoff = 0;
+      struct elf_link_hash_entry *h;
+
+      if (!elf_bad_symtab (igroup->owner))
+	{
+	  Elf_Internal_Shdr *symtab_hdr;
+
+	  symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
+	  extsymoff = symtab_hdr->sh_info;
+	}
+      h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
+      while (h->root.type == bfd_link_hash_indirect
+	     || h->root.type == bfd_link_hash_warning)
+	h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+      elf_section_data (sec)->this_hdr.sh_info = h->indx;
     }
-  elf_section_data (sec)->this_hdr.sh_info = symindx;
 
   /* The contents won't be allocated for "ld -r" or objcopy.  */
   gas = TRUE;
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.312
diff -u -p -r1.312 elflink.c
--- bfd/elflink.c	30 Sep 2008 04:47:50 -0000	1.312
+++ bfd/elflink.c	3 Oct 2008 08:38:58 -0000
@@ -9062,6 +9062,63 @@ elf_link_input_bfd (struct elf_final_lin
 	  continue;
 	}
 
+      if (finfo->info->relocatable
+	  && (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP)
+	{
+	  /* Deal with the group signature symbol.  */
+	  struct bfd_elf_section_data *sec_data = elf_section_data (o);
+	  unsigned long symndx = sec_data->this_hdr.sh_info;
+	  asection *osec = o->output_section;
+
+	  if (symndx >= locsymcount
+	      || (elf_bad_symtab (input_bfd)
+		  && finfo->sections[symndx] == NULL))
+	    {
+	      struct elf_link_hash_entry *h = sym_hashes[symndx - extsymoff];
+	      while (h->root.type == bfd_link_hash_indirect
+		     || h->root.type == bfd_link_hash_warning)
+		h = (struct elf_link_hash_entry *) h->root.u.i.link;
+	      /* Arrange for symbol to be output.  */
+	      h->indx = -2;
+	      elf_section_data (osec)->this_hdr.sh_info = -2;
+	    }
+	  else if (ELF_ST_TYPE (isymbuf[symndx].st_info) == STT_SECTION)
+	    {
+	      /* We'll use the output section target_index.  */
+	      asection *sec = finfo->sections[symndx]->output_section;
+	      elf_section_data (osec)->this_hdr.sh_info = sec->target_index;
+	    }
+	  else
+	    {
+	      if (finfo->indices[symndx] == -1)
+		{
+		  /* Otherwise output the local symbol now.  */
+		  Elf_Internal_Sym sym = isymbuf[symndx];
+		  asection *sec = finfo->sections[symndx]->output_section;
+		  const char *name;
+
+		  name = bfd_elf_string_from_elf_section (input_bfd,
+							  symtab_hdr->sh_link,
+							  sym.st_name);
+		  if (name == NULL)
+		    return FALSE;
+
+		  sym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
+								    sec);
+		  if (sym.st_shndx == SHN_BAD)
+		    return FALSE;
+
+		  sym.st_value += o->output_offset;
+
+		  finfo->indices[symndx] = bfd_get_symcount (output_bfd);
+		  if (! elf_link_output_sym (finfo, name, &sym, o, NULL))
+		    return FALSE;
+		}
+	      elf_section_data (osec)->this_hdr.sh_info
+		= finfo->indices[symndx];
+	    }
+	}
+
       if ((o->flags & SEC_HAS_CONTENTS) == 0
 	  || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
 	continue;
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.65
diff -u -p -r1.65 linker.c
--- bfd/linker.c	17 Aug 2008 03:12:49 -0000	1.65
+++ bfd/linker.c	3 Oct 2008 08:38:59 -0000
@@ -2796,18 +2796,36 @@ default_indirect_link_order (bfd *output
 	}
     }
 
-  /* Get and relocate the section contents.  */
-  sec_size = (input_section->rawsize > input_section->size
-	      ? input_section->rawsize
-	      : input_section->size);
-  contents = bfd_malloc (sec_size);
-  if (contents == NULL && sec_size != 0)
-    goto error_return;
-  new_contents = (bfd_get_relocated_section_contents
-		  (output_bfd, info, link_order, contents, info->relocatable,
-		   _bfd_generic_link_get_symbols (input_bfd)));
-  if (!new_contents)
-    goto error_return;
+  if ((output_section->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP
+      && input_section->size != 0)
+    {
+      /* Group section contents are set by bfd_elf_set_group_contents.  */
+      if (!output_bfd->output_has_begun)
+	{
+	  /* FIXME: This hack ensures bfd_elf_set_group_contents is called.  */
+	  if (!bfd_set_section_contents (output_bfd, output_section, "", 0, 1))
+	    goto error_return;
+	}
+      new_contents = output_section->contents;
+      BFD_ASSERT (new_contents != NULL);
+      BFD_ASSERT (input_section->output_offset == 0);
+    }
+  else
+    {
+      /* Get and relocate the section contents.  */
+      sec_size = (input_section->rawsize > input_section->size
+		  ? input_section->rawsize
+		  : input_section->size);
+      contents = bfd_malloc (sec_size);
+      if (contents == NULL && sec_size != 0)
+	goto error_return;
+      new_contents = (bfd_get_relocated_section_contents
+		      (output_bfd, info, link_order, contents,
+		       info->relocatable,
+		       _bfd_generic_link_get_symbols (input_bfd)));
+      if (!new_contents)
+	goto error_return;
+    }
 
   /* Output the section contents.  */
   loc = input_section->output_offset * bfd_octets_per_byte (output_bfd);
Index: ld/ldemul.c
===================================================================
RCS file: /cvs/src/src/ld/ldemul.c,v
retrieving revision 1.27
diff -u -p -r1.27 ldemul.c
--- ld/ldemul.c	15 Feb 2008 03:35:53 -0000	1.27
+++ ld/ldemul.c	3 Oct 2008 08:39:00 -0000
@@ -120,10 +120,10 @@ ldemul_open_dynamic_archive (const char 
 }
 
 bfd_boolean
-ldemul_place_orphan (asection *s)
+ldemul_place_orphan (asection *s, const char *name)
 {
   if (ld_emulation->place_orphan)
-    return (*ld_emulation->place_orphan) (s);
+    return (*ld_emulation->place_orphan) (s, name);
   return FALSE;
 }
 
Index: ld/ldemul.h
===================================================================
RCS file: /cvs/src/src/ld/ldemul.h,v
retrieving revision 1.19
diff -u -p -r1.19 ldemul.h
--- ld/ldemul.h	6 Jul 2007 14:09:41 -0000	1.19
+++ ld/ldemul.h	3 Oct 2008 08:39:00 -0000
@@ -59,7 +59,7 @@ extern void ldemul_set_symbols
 extern void ldemul_create_output_section_statements
   (void);
 extern bfd_boolean ldemul_place_orphan
-  (asection *);
+  (asection *, const char *);
 extern bfd_boolean ldemul_parse_args
   (int, char **);
 extern void ldemul_add_options
@@ -152,7 +152,7 @@ typedef struct ld_emulation_xfer_struct 
      the default action should be taken.  This field may be NULL, in
      which case the default action will always be taken.  */
   bfd_boolean (*place_orphan)
-    (asection *);
+    (asection *, const char *);
 
   /* Run after assigning parsing with the args, but before
      reading the script.  Used to initialize symbols used in the script.  */
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.292
diff -u -p -r1.292 ldlang.c
--- ld/ldlang.c	7 Sep 2008 04:02:30 -0000	1.292
+++ ld/ldlang.c	3 Oct 2008 08:39:04 -0000
@@ -5652,14 +5652,29 @@ lang_place_orphans (void)
 					default_common_section);
 		    }
 		}
-	      else if (ldemul_place_orphan (s))
-		;
 	      else
 		{
-		  lang_output_section_statement_type *os;
+		  const char *name = s->name;
 
-		  os = lang_output_section_statement_lookup (s->name, 0, TRUE);
-		  lang_add_section (&os->children, s, os);
+		  if ((config.unique_orphan_sections
+		       || unique_section_p (s))
+		      && bfd_get_section_by_name (link_info.output_bfd,
+						  name) != NULL)
+		    {
+		      static int count = 1;
+		      name = bfd_get_unique_section_name (link_info.output_bfd,
+							  name, &count);
+		      if (name == NULL)
+			einfo ("%F%P: place_orphan failed: %E\n");
+		    }
+
+		  if (!ldemul_place_orphan (s, name))
+		    {
+		      lang_output_section_statement_type *os;
+		      os = lang_output_section_statement_lookup (name, 0,
+								 TRUE);
+		      lang_add_section (&os->children, s, os);
+		    }
 		}
 	    }
 	}
Index: ld/emultempl/beos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/beos.em,v
retrieving revision 1.40
diff -u -p -r1.40 beos.em
--- ld/emultempl/beos.em	8 Sep 2008 16:07:46 -0000	1.40
+++ ld/emultempl/beos.em	3 Oct 2008 08:39:04 -0000
@@ -665,9 +665,8 @@ gld_${EMULATION_NAME}_before_allocation 
    which are not mentioned in the linker script.  */
 
 static bfd_boolean
-gld${EMULATION_NAME}_place_orphan (asection *s)
+gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
 {
-  const char *secname;
   char *output_secname, *ps;
   lang_output_section_statement_type *os;
   lang_statement_union_type *l;
@@ -682,8 +681,6 @@ gld${EMULATION_NAME}_place_orphan (asect
   if (link_info.relocatable)
     return FALSE;
 
-  secname = bfd_get_section_name (s->owner, s);
-
   /* Everything from the '\$' on gets deleted so don't allow '\$' as the
      first character.  */
   if (*secname == '\$')
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.192
diff -u -p -r1.192 elf32.em
--- ld/emultempl/elf32.em	7 Sep 2008 04:02:31 -0000	1.192
+++ ld/emultempl/elf32.em	3 Oct 2008 08:39:05 -0000
@@ -62,7 +62,7 @@ fragment <<EOF
 static void gld${EMULATION_NAME}_before_parse (void);
 static void gld${EMULATION_NAME}_after_open (void);
 static void gld${EMULATION_NAME}_before_allocation (void);
-static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *s);
+static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *, const char *);
 static void gld${EMULATION_NAME}_finish (void);
 
 EOF
@@ -1635,7 +1635,7 @@ output_rel_find (asection *sec, int isdy
    sections in the right segment.  */
 
 static bfd_boolean
-gld${EMULATION_NAME}_place_orphan (asection *s)
+gld${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
 {
   static struct orphan_save hold[] =
     {
@@ -1673,15 +1673,12 @@ gld${EMULATION_NAME}_place_orphan (asect
     };
   static int orphan_init_done = 0;
   struct orphan_save *place;
-  const char *secname;
   lang_output_section_statement_type *after;
   lang_output_section_statement_type *os;
   int isdyn = 0;
   int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
   unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
 
-  secname = bfd_get_section_name (s->owner, s);
-
   if (! link_info.relocatable
       && link_info.combreloc
       && (s->flags & SEC_ALLOC))
@@ -1707,28 +1704,24 @@ gld${EMULATION_NAME}_place_orphan (asect
 	}
     }
 
-  if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
-    {
-      /* Look through the script to see where to place this section.  */
-      os = lang_output_section_find (secname);
+  /* Look through the script to see where to place this section.  */
+  os = lang_output_section_find (secname);
 
-      if (os != NULL
-	  && (os->bfd_section == NULL
-	      || os->bfd_section->flags == 0
-	      || (_bfd_elf_match_sections_by_type (link_info.output_bfd,
-						   os->bfd_section,
-						   s->owner, s)
-		  && ((s->flags ^ os->bfd_section->flags)
-		      & (SEC_LOAD | SEC_ALLOC)) == 0)))
-	{
-	  /* We already have an output section statement with this
-	     name, and its bfd section, if any, has compatible flags.
-	     If the section already exists but does not have any flags
-	     set, then it has been created by the linker, probably as a
-	     result of a --section-start command line switch.  */
-	  lang_add_section (&os->children, s, os);
-	  return TRUE;
-	}
+  if (os != NULL
+      && os->bfd_section != NULL
+      && (os->bfd_section->flags == 0
+	  || (_bfd_elf_match_sections_by_type (link_info.output_bfd,
+					       os->bfd_section, s->owner, s)
+	      && ((s->flags ^ os->bfd_section->flags)
+		  & (SEC_LOAD | SEC_ALLOC)) == 0)))
+    {
+      /* We already have an output section statement with this
+	 name, and its bfd section has compatible flags.
+	 If the section already exists but does not have any flags
+	 set, then it has been created by the linker, probably as a
+	 result of a --section-start command line switch.  */
+      lang_add_section (&os->children, s, os);
+      return TRUE;
     }
 
   if (!orphan_init_done)
@@ -1748,7 +1741,7 @@ gld${EMULATION_NAME}_place_orphan (asect
      sections into the .text section to get them out of the way.  */
   if (link_info.executable
       && ! link_info.relocatable
-      && CONST_STRNEQ (secname, ".gnu.warning.")
+      && CONST_STRNEQ (s->name, ".gnu.warning.")
       && hold[orphan_text].os != NULL)
     {
       lang_add_section (&hold[orphan_text].os->children, s,
@@ -1803,18 +1796,6 @@ gld${EMULATION_NAME}_place_orphan (asect
 	after = &lang_output_section_statement.head->output_section_statement;
     }
 
-  /* Choose a unique name for the section.  This will be needed if the
-     same section name appears in the input file with different
-     loadable or allocatable characteristics.  */
-  if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
-    {
-      static int count = 1;
-      secname = bfd_get_unique_section_name (link_info.output_bfd,
-					     secname, &count);
-      if (secname == NULL)
-	einfo ("%F%P: place_orphan failed: %E\n");
-    }
-
   lang_insert_orphan (s, secname, after, place, NULL, NULL);
 
   return TRUE;
Index: ld/emultempl/genelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/genelf.em,v
retrieving revision 1.3
diff -u -p -r1.3 genelf.em
--- ld/emultempl/genelf.em	19 Jul 2007 19:56:10 -0000	1.3
+++ ld/emultempl/genelf.em	3 Oct 2008 08:39:05 -0000
@@ -34,7 +34,27 @@ gld${EMULATION_NAME}_finish (void)
   gld${EMULATION_NAME}_map_segments (FALSE);
   finish_default ();
 }
+
+static void
+gld${EMULATION_NAME}_after_open (void)
+{
+  bfd *ibfd;
+  asection *sec;
+  asymbol **syms;
+
+  if (link_info.relocatable)
+    for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+      if ((syms = bfd_get_outsymbols (ibfd)) != NULL
+	  && bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+	for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+	  if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP)
+	    {
+	      struct bfd_elf_section_data *sec_data = elf_section_data (sec);
+	      elf_group_id (sec) = syms[sec_data->this_hdr.sh_info - 1];
+	    }
+}
 EOF
 # Put these extra routines in ld_${EMULATION_NAME}_emulation
 #
 LDEMUL_FINISH=gld${EMULATION_NAME}_finish
+LDEMUL_AFTER_OPEN=gld${EMULATION_NAME}_after_open
Index: ld/emultempl/mmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmo.em,v
retrieving revision 1.22
diff -u -p -r1.22 mmo.em
--- ld/emultempl/mmo.em	15 Feb 2008 03:35:53 -0000	1.22
+++ ld/emultempl/mmo.em	3 Oct 2008 08:39:05 -0000
@@ -47,7 +47,7 @@ fragment <<EOF
    from elf32.em.  */
 
 static bfd_boolean
-mmo_place_orphan (asection *s)
+mmo_place_orphan (asection *s, const char *secname)
 {
   static struct orphan_save hold_text =
     {
@@ -56,7 +56,6 @@ mmo_place_orphan (asection *s)
       0, 0, 0, 0
     };
   struct orphan_save *place;
-  const char *secname;
   lang_output_section_statement_type *after;
   lang_output_section_statement_type *os;
 
@@ -66,7 +65,6 @@ mmo_place_orphan (asection *s)
     return FALSE;
 
   /* Only care for sections we're going to load.  */
-  secname = s->name;
   os = lang_output_section_find (secname);
 
   /* We have an output section by this name.  Place the section inside it
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.134
diff -u -p -r1.134 pe.em
--- ld/emultempl/pe.em	9 Sep 2008 09:45:31 -0000	1.134
+++ ld/emultempl/pe.em	3 Oct 2008 08:39:06 -0000
@@ -1613,24 +1613,20 @@ gld_${EMULATION_NAME}_finish (void)
    sort_sections.  */
 
 static bfd_boolean
-gld_${EMULATION_NAME}_place_orphan (asection *s)
+gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
 {
-  const char *secname;
-  const char *orig_secname;
+  const char *orig_secname = secname;
   char *dollar = NULL;
   lang_output_section_statement_type *os;
   lang_statement_list_type add_child;
 
-  secname = bfd_get_section_name (s->owner, s);
-
   /* Look through the script to see where to place this section.  */
-  orig_secname = secname;
   if (!link_info.relocatable
       && (dollar = strchr (secname, '$')) != NULL)
     {
-      size_t len = dollar - orig_secname;
+      size_t len = dollar - secname;
       char *newname = xmalloc (len + 1);
-      memcpy (newname, orig_secname, len);
+      memcpy (newname, secname, len);
       newname[len] = '\0';
       secname = newname;
     }
@@ -1640,13 +1636,13 @@ gld_${EMULATION_NAME}_place_orphan (asec
   lang_list_init (&add_child);
 
   if (os != NULL
-      && (os->bfd_section == NULL
-	  || os->bfd_section->flags == 0
+      && os->bfd_section != NULL
+      && (os->bfd_section->flags == 0
 	  || ((s->flags ^ os->bfd_section->flags)
 	      & (SEC_LOAD | SEC_ALLOC)) == 0))
     {
       /* We already have an output section statement with this
-	 name, and its bfd section, if any, has compatible flags.
+	 name, and its bfd section has compatible flags.
 	 If the section already exists but does not have any flags set,
 	 then it has been created by the linker, probably as a result of
 	 a --section-start command line switch.  */
@@ -1723,18 +1719,6 @@ gld_${EMULATION_NAME}_place_orphan (asec
 		     ->output_section_statement);
 	}
 
-      /* Choose a unique name for the section.  This will be needed if the
-	 same section name appears in the input file with different
-	 loadable or allocatable characteristics.  */
-      if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
-	{
-	  static int count = 1;
-	  secname = bfd_get_unique_section_name (link_info.output_bfd,
-						 secname, &count);
-	  if (secname == NULL)
-	    einfo ("%F%P: place_orphan failed: %E\n");
-	}
-
       /* All sections in an executable must be aligned to a page boundary.  */
       address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
       os = lang_insert_orphan (s, secname, after, place, address, &add_child);
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.13
diff -u -p -r1.13 pep.em
--- ld/emultempl/pep.em	9 Sep 2008 09:45:31 -0000	1.13
+++ ld/emultempl/pep.em	3 Oct 2008 08:39:08 -0000
@@ -1372,24 +1372,20 @@ gld_${EMULATION_NAME}_finish (void)
    sort_sections.  */
 
 static bfd_boolean
-gld_${EMULATION_NAME}_place_orphan (asection *s)
+gld_${EMULATION_NAME}_place_orphan (asection *s, const char *secname)
 {
-  const char *secname;
-  const char *orig_secname;
+  const char *orig_secname = secname;
   char *dollar = NULL;
   lang_output_section_statement_type *os;
   lang_statement_list_type add_child;
 
-  secname = bfd_get_section_name (s->owner, s);
-
   /* Look through the script to see where to place this section.  */
-  orig_secname = secname;
   if (!link_info.relocatable
       && (dollar = strchr (secname, '$')) != NULL)
     {
-      size_t len = dollar - orig_secname;
+      size_t len = dollar - secname;
       char *newname = xmalloc (len + 1);
-      memcpy (newname, orig_secname, len);
+      memcpy (newname, secname, len);
       newname[len] = '\0';
       secname = newname;
     }
@@ -1399,13 +1395,13 @@ gld_${EMULATION_NAME}_place_orphan (asec
   lang_list_init (&add_child);
 
   if (os != NULL
-      && (os->bfd_section == NULL
-	  || os->bfd_section->flags == 0
+      && os->bfd_section != NULL
+      && (os->bfd_section->flags == 0
 	  || ((s->flags ^ os->bfd_section->flags)
 	      & (SEC_LOAD | SEC_ALLOC)) == 0))
     {
       /* We already have an output section statement with this
-	 name, and its bfd section, if any, has compatible flags.
+	 name, and its bfd section has compatible flags.
 	 If the section already exists but does not have any flags set,
 	 then it has been created by the linker, probably as a result of
 	 a --section-start command line switch.  */
@@ -1482,18 +1478,6 @@ gld_${EMULATION_NAME}_place_orphan (asec
 		     ->output_section_statement);
 	}
 
-      /* Choose a unique name for the section.  This will be needed if the
-	 same section name appears in the input file with different
-	 loadable or allocatable characteristics.  */
-      if (bfd_get_section_by_name (link_info.output_bfd, secname) != NULL)
-	{
-	  static int count = 1;
-	  secname = bfd_get_unique_section_name (link_info.output_bfd,
-						 secname, &count);
-	  if (secname == NULL)
-	    einfo ("%F%P: place_orphan failed: %E\n");
-	}
-
       /* All sections in an executable must be aligned to a page boundary.  */
       address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
       os = lang_insert_orphan (s, secname, after, place, address, &add_child);
Index: ld/emultempl/spuelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/spuelf.em,v
retrieving revision 1.26
diff -u -p -r1.26 spuelf.em
--- ld/emultempl/spuelf.em	2 Aug 2008 16:25:44 -0000	1.26
+++ ld/emultempl/spuelf.em	3 Oct 2008 08:39:08 -0000
@@ -114,12 +114,7 @@ spu_place_special_section (asection *s, 
 
   os = lang_output_section_find (o != NULL ? o->name : output_name);
   if (os == NULL)
-    {
-      const char *save = s->name;
-      s->name = output_name;
-      gld${EMULATION_NAME}_place_orphan (s);
-      s->name = save;
-    }
+    gld${EMULATION_NAME}_place_orphan (s, output_name);
   else if (o != NULL && os->children.head != NULL)
     {
       lang_statement_list_type add;

-- 
Alan Modra
Australia Development Lab, IBM


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