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

Re: Slow _bfd_strip_section_from_output


On Tue, May 03, 2005 at 01:46:45PM +0930, Alan Modra wrote:
> Hmm, I might take a look at this one myself.  Here's the idea:  Change
> the type of link_order_head and link_order_tail to be a union, either a
> struct bfd_link_order *, or asection *.  Use these pointers to build
> lists of input sections attached to an output section.  Change
> _bfd_strip_section_from_output to only set SEC_EXCLUDE on the input
> section (or better, remove the function entirely).  In
> strip_excluded_output_sections, traverse the lists and strip any output
> section that has all its input sections marked SEC_EXCLUDE.  Also reset
> the output section link_order pointers to NULL.

Applying mainline.

bfd/
	* section.c (struct bfd_section): Replace link_order_head and
	link_order_tail with map_head and map_tail union.
	(STD_SECTION): Update.
	(_bfd_strip_section_from_output): Delete.
	* aoutx.h: Update throughout for above changes.
	* coff-ppc.c: Likewise.
	* cofflink.c: Likewise.
	* ecoff.c: Likewise.
	* elf-eh-frame.c: Likewise.
	* elf-m10300.c: Likewise.
	* elf.c: Likewise.
	* elf32-arm.c: Likewise.
	* elf32-cris.c: Likewise.
	* elf32-hppa.c: Likewise.
	* elf32-i386.c: Likewise.
	* elf32-m32r.c: Likewise.
	* elf32-m68hc1x.c: Likewise.
	* elf32-m68k.c: Likewise.
	* elf32-ppc.c: Likewise.
	* elf32-s390.c: Likewise.
	* elf32-sh.c: Likewise.
	* elf32-vax.c: Likewise.
	* elf32-xtensa.c: Likewise.
	* elf64-alpha.c: Likewise.
	* elf64-hppa.c: Likewise.
	* elf64-ppc.c: Likewise.
	* elf64-s390.c: Likewise.
	* elf64-sh64.c: Likewise.
	* elf64-x86-64.c: Likewise.
	* elflink.c: Likewise.
	* elfxx-ia64.c: Likewise.
	* elfxx-mips.c: Likewise.
	* elfxx-sparc.c: Likewise.
	* linker.c: Likewise.
	* merge.c: Likewise.
	* pdp11.c: Likewise.
	* xcofflink.c: Likewise.
	* elflink.c (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Split
	out from bfd_elf_size_dynamic_sections.
	* bfd-in.h (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Declare.
	* bfd-in2.h: Regenerate.

ld/
	* ldemul.c: Include bfdlink.h.
	(ldemul_before_allocation): Assume before_allocation is non-zero.
	(before_allocation_default): Call strip_excluded_output_sections.
	* ldlang.c (stripped_excluded_sections): New variable.
	(lang_add_section): Build input section list for each output
	section, attached via map_head and map_tail pointers.
	(strip_excluded_output_sections): Make global.  Traverse the
	input section lists to find which output sections can go.  Clear
	link_order pointers and set stripped_excluded_sections.
	(lang_process): Call strip_excluded_output_sections.
	* ldlang.h (strip_excluded_output_sections): Declare.
	* ldwrite.c: Update throuhout for link_order_head -> map_head change.
	* emultempl/aix.em (before_allocation): Call
	strip_excluded_output_sections.
	* emultempl/armcoff.em (before_allocation): Likewise.
	* emultempl/beos.em (before_allocation): Likewise.
	* emultempl/linux.em (before_allocation): Likewise.
	* emultempl/pe.em (before_allocation): Likewise.
	* emultempl/sunos.em (before_allocation): Likewise.
	* emultempl/elf32.em (before_allocation): Likewise.  Call
	bfd_elf_size_dynsym_hash_dynstr too.
	* emultempl/lnk960.em (lnk960_before_allocation): Delete.
	(ld_lnk960): Use before_allocation_default.

Index: bfd/aoutx.h
===================================================================
RCS file: /cvs/src/src/bfd/aoutx.h,v
retrieving revision 1.54
diff -u -p -r1.54 aoutx.h
--- bfd/aoutx.h	11 Apr 2005 08:23:00 -0000	1.54
+++ bfd/aoutx.h	3 May 2005 17:29:02 -0000
@@ -5318,11 +5318,11 @@ NAME (aout, final_link) (bfd *abfd,
     {
       if (obj_textsec (abfd) != NULL)
 	trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
-						 ->link_order_head)
+						 ->map_head.link_order)
 		   * obj_reloc_entry_size (abfd));
       if (obj_datasec (abfd) != NULL)
 	drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
-						 ->link_order_head)
+						 ->map_head.link_order)
 		   * obj_reloc_entry_size (abfd));
     }
 
@@ -5414,7 +5414,7 @@ NAME (aout, final_link) (bfd *abfd,
      include.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	if (p->type == bfd_indirect_link_order)
 	  p->u.indirect.section->linker_mark = TRUE;
     }
@@ -5422,7 +5422,7 @@ NAME (aout, final_link) (bfd *abfd,
   have_link_order_relocs = FALSE;
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head;
+      for (p = o->map_head.link_order;
 	   p != NULL;
 	   p = p->next)
 	{
@@ -5467,7 +5467,7 @@ NAME (aout, final_link) (bfd *abfd,
     {
       for (o = abfd->sections; o != NULL; o = o->next)
 	{
-	  for (p = o->link_order_head;
+	  for (p = o->map_head.link_order;
 	       p != NULL;
 	       p = p->next)
 	    {
Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.98
diff -u -p -r1.98 bfd-in.h
--- bfd/bfd-in.h	15 Apr 2005 16:37:45 -0000	1.98
+++ bfd/bfd-in.h	3 May 2005 17:29:03 -0000
@@ -637,7 +637,10 @@ extern bfd_boolean bfd_elf_get_bfd_neede
   (bfd *, struct bfd_link_needed_list **);
 extern bfd_boolean bfd_elf_size_dynamic_sections
   (bfd *, const char *, const char *, const char *, const char * const *,
-   struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
+   struct bfd_link_info *, struct bfd_section **,
+   struct bfd_elf_version_tree *);
+extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
+  (bfd *, struct bfd_link_info *);
 extern void bfd_elf_set_dt_needed_name
   (bfd *, const char *);
 extern const char *bfd_elf_get_dt_soname
Index: bfd/coff-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-ppc.c,v
retrieving revision 1.25
diff -u -p -r1.25 coff-ppc.c
--- bfd/coff-ppc.c	3 Mar 2005 11:40:57 -0000	1.25
+++ bfd/coff-ppc.c	3 May 2005 17:29:08 -0000
@@ -2113,7 +2113,7 @@ ppc_bfd_coff_final_link (abfd, info)
       o->reloc_count = 0;
       o->lineno_count = 0;
 
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  if (p->type == bfd_indirect_link_order)
 	    {
@@ -2295,7 +2295,7 @@ ppc_bfd_coff_final_link (abfd, info)
 
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  if (p->type == bfd_indirect_link_order
 	      && (bfd_get_flavour (p->u.indirect.section->owner)
Index: bfd/cofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/cofflink.c,v
retrieving revision 1.53
diff -u -p -r1.53 cofflink.c
--- bfd/cofflink.c	20 Feb 2005 14:59:06 -0000	1.53
+++ bfd/cofflink.c	3 May 2005 17:29:08 -0000
@@ -693,7 +693,7 @@ _bfd_coff_final_link (bfd *abfd,
     {
       o->reloc_count = 0;
       o->lineno_count = 0;
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  if (p->type == bfd_indirect_link_order)
 	    {
@@ -888,7 +888,7 @@ _bfd_coff_final_link (bfd *abfd,
 
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  if (p->type == bfd_indirect_link_order
 	      && bfd_family_coff (p->u.indirect.section->owner))
Index: bfd/ecoff.c
===================================================================
RCS file: /cvs/src/src/bfd/ecoff.c,v
retrieving revision 1.42
diff -u -p -r1.42 ecoff.c
--- bfd/ecoff.c	3 May 2005 01:05:00 -0000	1.42
+++ bfd/ecoff.c	3 May 2005 17:29:11 -0000
@@ -76,8 +76,8 @@ static asection bfd_debug_section =
      NULL,
   /* symbol_ptr_ptr,                                               */
      NULL,
-  /* link_order_head, link_order_tail                              */
-     NULL,            NULL
+  /* map_head, map_tail                                            */
+     { NULL }, { NULL }
 };
 
 /* Create an ECOFF object.  */
@@ -4523,7 +4523,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, st
       for (o = abfd->sections; o != NULL; o = o->next)
 	{
 	  o->reloc_count = 0;
-	  for (p = o->link_order_head;
+	  for (p = o->map_head.link_order;
 	       p != NULL;
 	       p = p->next)
 	    if (p->type == bfd_indirect_link_order)
@@ -4593,7 +4593,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, st
 
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head;
+      for (p = o->map_head.link_order;
 	   p != NULL;
 	   p = p->next)
 	{
Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.44
diff -u -p -r1.44 elf-eh-frame.c
--- bfd/elf-eh-frame.c	20 Feb 2005 14:59:06 -0000	1.44
+++ bfd/elf-eh-frame.c	3 May 2005 17:29:11 -0000
@@ -853,8 +853,8 @@ _bfd_elf_discard_section_eh_frame_hdr (b
 
 /* This function is called from size_dynamic_sections.
    It needs to decide whether .eh_frame_hdr should be output or not,
-   because later on it is too late for calling _bfd_strip_section_from_output,
-   since dynamic symbol table has been sized.  */
+   because when the dynamic symbol table has been sized it is too late
+   to strip sections.  */
 
 bfd_boolean
 _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
@@ -888,7 +888,7 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struc
 
   if (abfd == NULL)
     {
-      _bfd_strip_section_from_output (info, hdr_info->hdr_sec);
+      hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
       hdr_info->hdr_sec = NULL;
       return TRUE;
     }
Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.60
diff -u -p -r1.60 elf-m10300.c
--- bfd/elf-m10300.c	24 Feb 2005 13:34:38 -0000	1.60
+++ bfd/elf-m10300.c	3 May 2005 17:29:13 -0000
@@ -4291,7 +4291,7 @@ _bfd_mn10300_elf_size_dynamic_sections (
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.284
diff -u -p -r1.284 elf.c
--- bfd/elf.c	3 May 2005 17:05:50 -0000	1.284
+++ bfd/elf.c	3 May 2005 17:29:20 -0000
@@ -2499,7 +2499,7 @@ elf_fake_sections (bfd *abfd, asection *
 	  struct bfd_link_order *l;
 	  asection *elt;
 
-	  for (l = asect->link_order_head; l != NULL; l = l->next)
+	  for (l = asect->map_head.link_order; l != NULL; l = l->next)
 	    if (l->type == bfd_indirect_link_order
 		&& (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
 	      do
@@ -2616,7 +2616,7 @@ elf_fake_sections (bfd *abfd, asection *
 	  struct bfd_link_order *o;
 
 	  this_hdr->sh_size = 0;
-	  for (o = asect->link_order_head; o != NULL; o = o->next)
+	  for (o = asect->map_head.link_order; o != NULL; o = o->next)
 	    if (this_hdr->sh_size < o->offset + o->size)
 	      this_hdr->sh_size = o->offset + o->size;
 	  if (this_hdr->sh_size)
@@ -2722,7 +2722,7 @@ bfd_elf_set_group_contents (bfd *abfd, a
   /* If this is a relocatable link, then the above did nothing because
      SEC is the output section.  Look through the input sections
      instead.  */
-  for (l = sec->link_order_head; l != NULL; l = l->next)
+  for (l = sec->map_head.link_order; l != NULL; l = l->next)
     if (l->type == bfd_indirect_link_order
 	&& (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
       do
@@ -2924,7 +2924,7 @@ assign_section_numbers (bfd *abfd, struc
 
 	      /* Find out what the corresponding section in output
 		 is.  */
-	      for (p = sec->link_order_head; p != NULL; p = p->next)
+	      for (p = sec->map_head.link_order; p != NULL; p = p->next)
 		{
 		  s = p->u.indirect.section;
 		  if (p->type == bfd_indirect_link_order
@@ -4295,7 +4295,7 @@ assign_file_positions_for_segments (bfd 
 		  struct bfd_link_order *o;
 		  bfd_vma tbss_size = 0;
 
-		  for (o = sec->link_order_head; o != NULL; o = o->next)
+		  for (o = sec->map_head.link_order; o != NULL; o = o->next)
 		    if (tbss_size < o->offset + o->size)
 		      tbss_size = o->offset + o->size;
 
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.33
diff -u -p -r1.33 elf32-arm.c
--- bfd/elf32-arm.c	1 May 2005 23:57:21 -0000	1.33
+++ bfd/elf32-arm.c	3 May 2005 17:29:21 -0000
@@ -5505,7 +5505,7 @@ elf32_arm_size_dynamic_sections (bfd * o
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.62
diff -u -p -r1.62 elf32-cris.c
--- bfd/elf32-cris.c	1 Feb 2005 01:11:10 -0000	1.62
+++ bfd/elf32-cris.c	3 May 2005 17:29:23 -0000
@@ -2991,7 +2991,7 @@ elf_cris_size_dynamic_sections (output_b
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.127
diff -u -p -r1.127 elf32-hppa.c
--- bfd/elf32-hppa.c	7 Mar 2005 06:01:17 -0000	1.127
+++ bfd/elf32-hppa.c	3 May 2005 17:29:25 -0000
@@ -2270,7 +2270,7 @@ elf32_hppa_size_dynamic_sections (bfd *o
 	     adjust_dynamic_symbol is called, and it is that
 	     function which decides whether anything needs to go
 	     into these sections.  */
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
@@ -2376,7 +2376,7 @@ elf32_hppa_setup_section_lists (bfd *out
 
   /* We can't use output_bfd->section_count here to find the top output
      section index as some sections may have been removed, and
-     _bfd_strip_section_from_output doesn't renumber the indices.  */
+     strip_excluded_output_sections doesn't renumber the indices.  */
   for (section = output_bfd->sections, top_index = 0;
        section != NULL;
        section = section->next)
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.132
diff -u -p -r1.132 elf32-i386.c
--- bfd/elf32-i386.c	6 Feb 2005 18:11:29 -0000	1.132
+++ bfd/elf32-i386.c	3 May 2005 17:29:27 -0000
@@ -1862,7 +1862,7 @@ elf_i386_size_dynamic_sections (bfd *out
 	     function which decides whether anything needs to go
 	     into these sections.  */
 
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.57
diff -u -p -r1.57 elf32-m32r.c
--- bfd/elf32-m32r.c	11 Feb 2005 17:18:41 -0000	1.57
+++ bfd/elf32-m32r.c	3 May 2005 17:29:29 -0000
@@ -2448,7 +2448,7 @@ printf("m32r_elf_size_dynamic_sections()
              adjust_dynamic_symbol is called, and it is that
              function which decides whether anything needs to go
              into these sections.  */
-          _bfd_strip_section_from_output (info, s);
+          s->flags |= SEC_EXCLUDE;
           continue;
         }
 
Index: bfd/elf32-m68hc1x.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68hc1x.c,v
retrieving revision 1.20
diff -u -p -r1.20 elf32-m68hc1x.c
--- bfd/elf32-m68hc1x.c	3 Mar 2005 11:40:59 -0000	1.20
+++ bfd/elf32-m68hc1x.c	3 May 2005 17:29:30 -0000
@@ -265,7 +265,7 @@ elf32_m68hc11_setup_section_lists (bfd *
 
   /* We can't use output_bfd->section_count here to find the top output
      section index as some sections may have been removed, and
-     _bfd_strip_section_from_output doesn't renumber the indices.  */
+     strip_excluded_output_sections doesn't renumber the indices.  */
   for (section = output_bfd->sections, top_index = 0;
        section != NULL;
        section = section->next)
Index: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.74
diff -u -p -r1.74 elf32-m68k.c
--- bfd/elf32-m68k.c	18 Mar 2005 17:20:29 -0000	1.74
+++ bfd/elf32-m68k.c	3 May 2005 17:29:31 -0000
@@ -1241,7 +1241,7 @@ elf_m68k_size_dynamic_sections (output_b
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.149
diff -u -p -r1.149 elf32-ppc.c
--- bfd/elf32-ppc.c	27 Apr 2005 20:16:07 -0000	1.149
+++ bfd/elf32-ppc.c	3 May 2005 17:29:34 -0000
@@ -4084,7 +4205,7 @@ ppc_elf_size_dynamic_sections (bfd *outp
 
       if (s->size == 0)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.68
diff -u -p -r1.68 elf32-s390.c
--- bfd/elf32-s390.c	11 Jan 2005 09:32:50 -0000	1.68
+++ bfd/elf32-s390.c	3 May 2005 17:29:37 -0000
@@ -2124,7 +2124,7 @@ elf_s390_size_dynamic_sections (output_b
 	     function which decides whether anything needs to go
 	     into these sections.  */
 
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.120
diff -u -p -r1.120 elf32-sh.c
--- bfd/elf32-sh.c	20 Feb 2005 14:59:06 -0000	1.120
+++ bfd/elf32-sh.c	3 May 2005 17:29:39 -0000
@@ -4389,7 +4389,7 @@ sh_elf_size_dynamic_sections (bfd *outpu
 	     function which decides whether anything needs to go
 	     into these sections.  */
 
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-vax.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-vax.c,v
retrieving revision 1.26
diff -u -p -r1.26 elf32-vax.c
--- bfd/elf32-vax.c	11 Jan 2005 09:32:51 -0000	1.26
+++ bfd/elf32-vax.c	3 May 2005 17:29:40 -0000
@@ -1273,7 +1273,7 @@ elf_vax_size_dynamic_sections (output_bf
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.42
diff -u -p -r1.42 elf32-xtensa.c
--- bfd/elf32-xtensa.c	24 Feb 2005 13:34:38 -0000	1.42
+++ bfd/elf32-xtensa.c	3 May 2005 17:29:45 -0000
@@ -1462,7 +1462,7 @@ elf_xtensa_size_dynamic_sections (bfd *o
 	}
 
       if (strip)
-	_bfd_strip_section_from_output (info, s);
+	s->flags |= SEC_EXCLUDE;
       else
 	{
 	  /* Allocate memory for the section contents.  */
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.127
diff -u -p -r1.127 elf64-alpha.c
--- bfd/elf64-alpha.c	20 Mar 2005 23:36:18 -0000	1.127
+++ bfd/elf64-alpha.c	3 May 2005 17:29:48 -0000
@@ -4058,7 +4058,7 @@ elf64_alpha_size_dynamic_sections (outpu
 	}
 
       if (strip)
-	_bfd_strip_section_from_output (info, s);
+	s->flags |= SEC_EXCLUDE;
       else
 	{
 	  /* Allocate memory for the section contents.  */
@@ -5184,7 +5184,7 @@ elf64_alpha_final_link (abfd, info)
 		}
 	    }
 
-	  for (p = o->link_order_head;
+	  for (p = o->map_head.link_order;
 	       p != (struct bfd_link_order *) NULL;
 	       p = p->next)
 	    {
@@ -5305,7 +5305,7 @@ elf64_alpha_final_link (abfd, info)
 
 	  /* Skip this section later on (I don't think this currently
 	     matters, but someday it might).  */
-	  o->link_order_head = (struct bfd_link_order *) NULL;
+	  o->map_head.link_order = (struct bfd_link_order *) NULL;
 
 	  mdebug_sec = o;
 	}
Index: bfd/elf64-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-hppa.c,v
retrieving revision 1.54
diff -u -p -r1.54 elf64-hppa.c
--- bfd/elf64-hppa.c	20 Mar 2005 23:36:18 -0000	1.54
+++ bfd/elf64-hppa.c	3 May 2005 17:29:49 -0000
@@ -1808,7 +1808,7 @@ elf64_hppa_size_dynamic_sections (output
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.199
diff -u -p -r1.199 elf64-ppc.c
--- bfd/elf64-ppc.c	27 Apr 2005 20:16:07 -0000	1.199
+++ bfd/elf64-ppc.c	3 May 2005 17:29:54 -0000
@@ -5539,7 +5539,7 @@ ppc64_elf_func_desc_adjust (bfd *obfd AT
   elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
 
   if (htab->sfpr->size == 0)
-    _bfd_strip_section_from_output (info, htab->sfpr);
+    htab->sfpr->flags |= SEC_EXCLUDE;
 
   return TRUE;
 }
@@ -7687,7 +7687,7 @@ ppc64_elf_size_dynamic_sections (bfd *ou
 
       if (s->size == 0)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
@@ -7716,7 +7716,7 @@ ppc64_elf_size_dynamic_sections (bfd *ou
       if (s != NULL && s != htab->got)
 	{
 	  if (s->size == 0)
-	    _bfd_strip_section_from_output (info, s);
+	    s->flags |= SEC_EXCLUDE;
 	  else
 	    {
 	      s->contents = bfd_zalloc (ibfd, s->size);
@@ -7728,7 +7728,7 @@ ppc64_elf_size_dynamic_sections (bfd *ou
       if (s != NULL)
 	{
 	  if (s->size == 0)
-	    _bfd_strip_section_from_output (info, s);
+	    s->flags |= SEC_EXCLUDE;
 	  else
 	    {
 	      s->contents = bfd_zalloc (ibfd, s->size);
@@ -8336,7 +8336,7 @@ ppc64_elf_setup_section_lists (bfd *outp
 
   /* We can't use output_bfd->section_count here to find the top output
      section index as some sections may have been removed, and
-     _bfd_strip_section_from_output doesn't renumber the indices.  */
+     strip_excluded_output_sections doesn't renumber the indices.  */
   for (section = output_bfd->sections, top_index = 0;
        section != NULL;
        section = section->next)
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.68
diff -u -p -r1.68 elf64-s390.c
--- bfd/elf64-s390.c	11 Jan 2005 09:32:52 -0000	1.68
+++ bfd/elf64-s390.c	3 May 2005 17:29:56 -0000
@@ -2095,7 +2095,7 @@ elf_s390_size_dynamic_sections (output_b
 	     function which decides whether anything needs to go
 	     into these sections.  */
 
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf64-sh64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-sh64.c,v
retrieving revision 1.52
diff -u -p -r1.52 elf64-sh64.c
--- bfd/elf64-sh64.c	20 Feb 2005 14:59:06 -0000	1.52
+++ bfd/elf64-sh64.c	3 May 2005 17:29:58 -0000
@@ -3640,7 +3640,7 @@ sh64_elf64_size_dynamic_sections (bfd *o
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.90
diff -u -p -r1.90 elf64-x86-64.c
--- bfd/elf64-x86-64.c	20 Mar 2005 23:36:18 -0000	1.90
+++ bfd/elf64-x86-64.c	3 May 2005 17:29:59 -0000
@@ -1654,7 +1654,7 @@ elf64_x86_64_size_dynamic_sections (bfd 
 	     function which decides whether anything needs to go
 	     into these sections.  */
 
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.152
diff -u -p -r1.152 elflink.c
--- bfd/elflink.c	2 May 2005 03:12:21 -0000	1.152
+++ bfd/elflink.c	4 May 2005 09:45:00 -0000
@@ -5289,12 +5289,8 @@ bfd_elf_size_dynamic_sections (bfd *outp
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
-      bfd_size_type dynsymcount;
       unsigned long section_sym_count;
       asection *s;
-      size_t bucketcount = 0;
-      size_t hash_entry_size;
-      unsigned int dtagcount;
 
       /* Set up the version definition section.  */
       s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
@@ -5309,7 +5305,7 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	verdefs = verdefs->next;
 
       if (verdefs == NULL && !info->create_default_symver)
-	_bfd_strip_section_from_output (info, s);
+	s->flags |= SEC_EXCLUDE;
       else
 	{
 	  unsigned int cdefs;
@@ -5563,7 +5559,7 @@ bfd_elf_size_dynamic_sections (bfd *outp
 				&sinfo);
 
 	if (elf_tdata (output_bfd)->verref == NULL)
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	else
 	  {
 	    Elf_Internal_Verneed *t;
@@ -5652,6 +5648,37 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	  }
       }
 
+      if ((elf_tdata (output_bfd)->cverrefs == 0
+	   && elf_tdata (output_bfd)->cverdefs == 0)
+	  || _bfd_elf_link_renumber_dynsyms (output_bfd, info,
+					     &section_sym_count) == 0)
+	{
+	  s = bfd_get_section_by_name (dynobj, ".gnu.version");
+	  s->flags |= SEC_EXCLUDE;
+	}
+    }
+  return TRUE;
+}
+
+bfd_boolean
+bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
+{
+  if (!is_elf_hash_table (info->hash))
+    return TRUE;
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      bfd *dynobj;
+      const struct elf_backend_data *bed;
+      asection *s;
+      bfd_size_type dynsymcount;
+      unsigned long section_sym_count;
+      size_t bucketcount = 0;
+      size_t hash_entry_size;
+      unsigned int dtagcount;
+
+      dynobj = elf_hash_table (info)->dynobj;
+
       /* Assign dynsym indicies.  In a shared library we generate a
 	 section symbol for each output section, which come first.
 	 Next come all of the back-end allocated local dynamic syms,
@@ -5663,17 +5690,8 @@ bfd_elf_size_dynamic_sections (bfd *outp
       /* Work out the size of the symbol version section.  */
       s = bfd_get_section_by_name (dynobj, ".gnu.version");
       BFD_ASSERT (s != NULL);
-      if (dynsymcount == 0
-	  || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL
-	      && !info->create_default_symver))
-	{
-	  _bfd_strip_section_from_output (info, s);
-	  /* The DYNSYMCOUNT might have changed if we were going to
-	     output a dynamic symbol table entry for S.  */
-	  dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info,
-							&section_sym_count);
-	}
-      else
+      if (dynsymcount != 0
+	  && (s->flags & SEC_EXCLUDE) == 0)
 	{
 	  s->size = dynsymcount * sizeof (Elf_External_Versym);
 	  s->contents = bfd_zalloc (output_bfd, s->size);
@@ -5692,6 +5710,7 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	 section as we went along in elf_link_add_object_symbols.  */
       s = bfd_get_section_by_name (dynobj, ".dynsym");
       BFD_ASSERT (s != NULL);
+      bed = get_elf_backend_data (output_bfd);
       s->size = dynsymcount * bed->s->sizeof_sym;
 
       if (dynsymcount != 0)
@@ -5957,7 +5976,7 @@ elf_link_sort_relocs (bfd *abfd, struct 
   count = reldyn->size / ext_size;
 
   size = 0;
-  for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
+  for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next)
     if (lo->type == bfd_indirect_link_order)
       {
 	asection *o = lo->u.indirect.section;
@@ -5982,7 +6001,7 @@ elf_link_sort_relocs (bfd *abfd, struct 
   else
     r_sym_mask = ~(bfd_vma) 0xffffffff;
 
-  for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
+  for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next)
     if (lo->type == bfd_indirect_link_order)
       {
 	bfd_byte *erel, *erelend;
@@ -6032,7 +6051,7 @@ elf_link_sort_relocs (bfd *abfd, struct 
 
   qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
 
-  for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
+  for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next)
     if (lo->type == bfd_indirect_link_order)
       {
 	bfd_byte *erel, *erelend;
@@ -7655,7 +7674,7 @@ elf_fixup_link_order (bfd *abfd, asectio
   
   seen_other = 0;
   seen_linkorder = 0;
-  for (p = o->link_order_head; p != NULL; p = p->next)
+  for (p = o->map_head.link_order; p != NULL; p = p->next)
     {
       if (p->type == bfd_indirect_link_order
 	  && (bfd_get_flavour ((sub = p->u.indirect.section->owner))
@@ -7689,7 +7708,7 @@ elf_fixup_link_order (bfd *abfd, asectio
     xmalloc (seen_linkorder * sizeof (struct bfd_link_order *));
   seen_linkorder = 0;
   
-  for (p = o->link_order_head; p != NULL; p = p->next)
+  for (p = o->map_head.link_order; p != NULL; p = p->next)
     {
       sections[seen_linkorder++] = p;
     }
@@ -7803,7 +7822,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
       struct bfd_elf_section_data *esdo = elf_section_data (o);
       o->reloc_count = 0;
 
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  unsigned int reloc_count = 0;
 	  struct bfd_elf_section_data *esdi = NULL;
@@ -8143,7 +8162,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
 	    {
 	      struct bfd_link_order *o;
 
-	      for (o = sec->link_order_head; o != NULL; o = o->next)
+	      for (o = sec->map_head.link_order; o != NULL; o = o->next)
 		if (size < o->offset + o->size)
 		  size = o->offset + o->size;
 	    }
@@ -8185,7 +8204,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
     sub->output_has_begun = FALSE;
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  if (p->type == bfd_indirect_link_order
 	      && (bfd_get_flavour ((sub = p->u.indirect.section->owner))
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.155
diff -u -p -r1.155 elfxx-ia64.c
--- bfd/elfxx-ia64.c	3 May 2005 17:05:50 -0000	1.155
+++ bfd/elfxx-ia64.c	3 May 2005 17:30:07 -0000
@@ -1558,7 +1558,7 @@ elfNN_ia64_modify_segment_map (abfd, inf
 	int i;
 	for (i = m->count - 1; i >= 0; --i)
 	  {
-	    struct bfd_link_order *order = m->sections[i]->link_order_head;
+	    struct bfd_link_order *order = m->sections[i]->map_head.link_order;
 	    while (order)
 	      {
 		if (order->type == bfd_indirect_link_order)
@@ -3052,7 +3052,7 @@ elfNN_ia64_size_dynamic_sections (output
 	}
 
       if (strip)
-	_bfd_strip_section_from_output (info, sec);
+	sec->flags |= SEC_EXCLUDE;
       else
 	{
 	  /* Allocate memory for the section contents.  */
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.133
diff -u -p -r1.133 elfxx-mips.c
--- bfd/elfxx-mips.c	3 May 2005 01:05:02 -0000	1.133
+++ bfd/elfxx-mips.c	3 May 2005 17:30:13 -0000
@@ -962,7 +962,7 @@ mips_elf_create_procedure_table (void *h
 
   /* Skip this section later on (I don't think this currently
      matters, but someday it might).  */
-  s->link_order_head = NULL;
+  s->map_head.link_order = NULL;
 
   if (epdr != NULL)
     free (epdr);
@@ -6796,7 +6796,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
@@ -8986,7 +8986,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 	  /* We have found the .reginfo section in the output file.
 	     Look through all the link_orders comprising it and merge
 	     the information together.  */
-	  for (p = o->link_order_head; p != NULL; p = p->next)
+	  for (p = o->map_head.link_order; p != NULL; p = p->next)
 	    {
 	      asection *input_section;
 	      bfd *input_bfd;
@@ -9029,7 +9029,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 
 	  /* Skip this section later on (I don't think this currently
 	     matters, but someday it might).  */
-	  o->link_order_head = NULL;
+	  o->map_head.link_order = NULL;
 
 	  reginfo_sec = o;
 	}
@@ -9102,7 +9102,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 		return FALSE;
 	    }
 
-	  for (p = o->link_order_head; p != NULL; p = p->next)
+	  for (p = o->map_head.link_order; p != NULL; p = p->next)
 	    {
 	      asection *input_section;
 	      bfd *input_bfd;
@@ -9242,7 +9242,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 
 	  /* Skip this section later on (I don't think this currently
 	     matters, but someday it might).  */
-	  o->link_order_head = NULL;
+	  o->map_head.link_order = NULL;
 
 	  mdebug_sec = o;
 	}
@@ -9261,7 +9261,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 	     not used in executables files.  */
 	  if (! info->relocatable)
 	    {
-	      for (p = o->link_order_head; p != NULL; p = p->next)
+	      for (p = o->map_head.link_order; p != NULL; p = p->next)
 		{
 		  asection *input_section;
 
@@ -9281,7 +9281,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 
 	      /* Skip this section later on (I don't think this
 		 currently matters, but someday it might).  */
-	      o->link_order_head = NULL;
+	      o->map_head.link_order = NULL;
 
 	      /* Really remove the section.  */
 	      bfd_section_list_remove (abfd, o);
@@ -9331,7 +9331,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 	  tab[0].gt_header.gt_unused = 0;
 
 	  /* Combine the input sections.  */
-	  for (p = o->link_order_head; p != NULL; p = p->next)
+	  for (p = o->map_head.link_order; p != NULL; p = p->next)
 	    {
 	      asection *input_section;
 	      bfd *input_bfd;
@@ -9454,7 +9454,7 @@ _bfd_mips_elf_final_link (bfd *abfd, str
 
 	  /* Skip this section later on (I don't think this currently
 	     matters, but someday it might).  */
-	  o->link_order_head = NULL;
+	  o->map_head.link_order = NULL;
 	}
     }
 
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.4
diff -u -p -r1.4 elfxx-sparc.c
--- bfd/elfxx-sparc.c	25 Apr 2005 21:53:38 -0000	1.4
+++ bfd/elfxx-sparc.c	3 May 2005 17:30:15 -0000
@@ -2181,7 +2181,7 @@ _bfd_sparc_elf_size_dynamic_sections (bf
 
       if (strip)
 	{
-	  _bfd_strip_section_from_output (info, s);
+	  s->flags |= SEC_EXCLUDE;
 	  continue;
 	}
 
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.46
diff -u -p -r1.46 linker.c
--- bfd/linker.c	11 Apr 2005 22:21:23 -0000	1.46
+++ bfd/linker.c	3 May 2005 17:30:17 -0000
@@ -309,7 +309,7 @@ SUBSUBSECTION
 	of the <<bfd>> structure.
 
 	Each section in the output file will have a list of
-	<<link_order>> structures attached to the <<link_order_head>>
+	<<link_order>> structures attached to the <<map_head.link_order>>
 	field (the <<link_order>> structure is defined in
 	<<bfdlink.h>>).  These structures describe how to create the
 	contents of the output section in terms of the contents of
@@ -2009,7 +2009,7 @@ _bfd_generic_final_link (bfd *abfd, stru
 
   /* Mark all sections which will be included in the output file.  */
   for (o = abfd->sections; o != NULL; o = o->next)
-    for (p = o->link_order_head; p != NULL; p = p->next)
+    for (p = o->map_head.link_order; p != NULL; p = p->next)
       if (p->type == bfd_indirect_link_order)
 	p->u.indirect.section->linker_mark = TRUE;
 
@@ -2038,7 +2038,7 @@ _bfd_generic_final_link (bfd *abfd, stru
       for (o = abfd->sections; o != NULL; o = o->next)
 	{
 	  o->reloc_count = 0;
-	  for (p = o->link_order_head; p != NULL; p = p->next)
+	  for (p = o->map_head.link_order; p != NULL; p = p->next)
 	    {
 	      if (p->type == bfd_section_reloc_link_order
 		  || p->type == bfd_symbol_reloc_link_order)
@@ -2094,7 +2094,7 @@ _bfd_generic_final_link (bfd *abfd, stru
   /* Handle all the link order information for the sections.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  switch (p->type)
 	    {
@@ -2614,11 +2614,11 @@ bfd_new_link_order (bfd *abfd, asection 
 
   new->type = bfd_undefined_link_order;
 
-  if (section->link_order_tail != NULL)
-    section->link_order_tail->next = new;
+  if (section->map_tail.link_order != NULL)
+    section->map_tail.link_order->next = new;
   else
-    section->link_order_head = new;
-  section->link_order_tail = new;
+    section->map_head.link_order = new;
+  section->map_tail.link_order = new;
 
   return new;
 }
Index: bfd/merge.c
===================================================================
RCS file: /cvs/src/src/bfd/merge.c,v
retrieving revision 1.25
diff -u -p -r1.25 merge.c
--- bfd/merge.c	2 May 2005 13:59:16 -0000	1.25
+++ bfd/merge.c	3 May 2005 17:30:17 -0000
@@ -697,8 +697,10 @@ alloc_failure:
    with _bfd_merge_section.  */
 
 bfd_boolean
-_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info,
-		     void *xsinfo, void (*remove_hook) (bfd *, asection *))
+_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED,
+		     struct bfd_link_info *info ATTRIBUTE_UNUSED,
+		     void *xsinfo,
+		     void (*remove_hook) (bfd *, asection *))
 {
   struct sec_merge_info *sinfo;
 
@@ -763,7 +765,7 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE
 	   the hash table at all.  */
 	for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
 	  if (secinfo->first_str == NULL)
-	    _bfd_strip_section_from_output (info, secinfo->sec);
+	    secinfo->sec->flags |= SEC_EXCLUDE;
     }
 
   return TRUE;
Index: bfd/pdp11.c
===================================================================
RCS file: /cvs/src/src/bfd/pdp11.c,v
retrieving revision 1.29
diff -u -p -r1.29 pdp11.c
--- bfd/pdp11.c	11 Apr 2005 08:23:03 -0000	1.29
+++ bfd/pdp11.c	3 May 2005 17:30:20 -0000
@@ -3726,11 +3726,11 @@ NAME (aout, final_link) (bfd *abfd,
     {
       if (obj_textsec (abfd) != NULL)
 	trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
-						 ->link_order_head)
+						 ->map_head.link_order)
 		   * obj_reloc_entry_size (abfd));
       if (obj_datasec (abfd) != NULL)
 	drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
-						 ->link_order_head)
+						 ->map_head.link_order)
 		   * obj_reloc_entry_size (abfd));
     }
 
@@ -3821,7 +3821,7 @@ NAME (aout, final_link) (bfd *abfd,
      include.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	if (p->type == bfd_indirect_link_order)
 	  p->u.indirect.section->linker_mark = TRUE;
     }
@@ -3829,7 +3829,7 @@ NAME (aout, final_link) (bfd *abfd,
   have_link_order_relocs = FALSE;
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head;
+      for (p = o->map_head.link_order;
 	   p != NULL;
 	   p = p->next)
 	{
@@ -3872,7 +3872,7 @@ NAME (aout, final_link) (bfd *abfd,
     {
       for (o = abfd->sections; o != NULL; o = o->next)
 	{
-	  for (p = o->link_order_head;
+	  for (p = o->map_head.link_order;
 	       p != NULL;
 	       p = p->next)
 	    {
Index: bfd/section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.83
diff -u -p -r1.83 section.c
--- bfd/section.c	3 May 2005 17:05:49 -0000	1.83
+++ bfd/section.c	3 May 2005 17:30:21 -0000
@@ -497,8 +497,14 @@ CODE_FRAGMENT
 .  struct bfd_symbol *symbol;
 .  struct bfd_symbol **symbol_ptr_ptr;
 .
-.  struct bfd_link_order *link_order_head;
-.  struct bfd_link_order *link_order_tail;
+.  {* Early in the link process, map_head and map_tail are used to build
+.     a list of input sections attached to an output section.  Later,
+.     output sections use these fields for a list of bfd_link_order
+.     structs.  *}
+.  union {
+.    struct bfd_link_order *link_order;
+.    struct bfd_section *s;
+.  } map_head, map_tail;
 .} asection;
 .
 .{* These sections are global, and are managed by BFD.  The application
@@ -692,8 +698,8 @@ static const asymbol global_syms[] =
     /* symbol_ptr_ptr,                                               */	\
        (struct bfd_symbol **) &SYM,					\
 									\
-    /* link_order_head, link_order_tail                              */	\
-       NULL,            NULL						\
+    /* map_head, map_tail                                            */	\
+       { NULL }, { NULL }						\
     }
 
 STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
@@ -1443,50 +1449,6 @@ DESCRIPTION
 
 /*
 FUNCTION
-	_bfd_strip_section_from_output
-
-SYNOPSIS
-	void _bfd_strip_section_from_output
-	  (struct bfd_link_info *info, asection *section);
-
-DESCRIPTION
-	Remove @var{section} from the output.  If the output section
-	becomes empty, remove it from the output bfd.
-
-	This function won't actually do anything except twiddle flags
-	if called too late in the linking process, when it's not safe
-	to remove sections.
-*/
-void
-_bfd_strip_section_from_output (struct bfd_link_info *info, asection *s)
-{
-  asection *os;
-  asection *is;
-  bfd *abfd;
-
-  s->flags |= SEC_EXCLUDE;
-
-  /* If the section wasn't assigned to an output section, or the
-     section has been discarded by the linker script, there's nothing
-     more to do.  */
-  os = s->output_section;
-  if (os == NULL || os->owner == NULL)
-    return;
-
-  /* If the output section has other (non-excluded) input sections, we
-     can't remove it.  */
-  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
-    for (is = abfd->sections; is != NULL; is = is->next)
-      if (is->output_section == os && (is->flags & SEC_EXCLUDE) == 0)
-	return;
-
-  /* If the output section is empty, flag it for removal too.
-     See ldlang.c:strip_excluded_output_sections for the action.  */
-  os->flags |= SEC_EXCLUDE;
-}
-
-/*
-FUNCTION
 	bfd_generic_is_group_section
 
 SYNOPSIS
Index: bfd/xcofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/xcofflink.c,v
retrieving revision 1.40
diff -u -p -r1.40 xcofflink.c
--- bfd/xcofflink.c	3 May 2005 17:05:50 -0000	1.40
+++ bfd/xcofflink.c	3 May 2005 17:30:26 -0000
@@ -5380,7 +5380,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, st
     {
       o->reloc_count = 0;
       o->lineno_count = 0;
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  if (p->type == bfd_indirect_link_order)
 	    {
@@ -5669,7 +5669,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, st
      for a single input file at once.  */
   for (o = abfd->sections; o != NULL; o = o->next)
     {
-      for (p = o->link_order_head; p != NULL; p = p->next)
+      for (p = o->map_head.link_order; p != NULL; p = p->next)
 	{
 	  if (p->type == bfd_indirect_link_order
 	      && p->u.indirect.section->owner->xvec == abfd->xvec)
Index: ld/ldemul.c
===================================================================
RCS file: /cvs/src/src/ld/ldemul.c,v
retrieving revision 1.18
diff -u -p -r1.18 ldemul.c
--- ld/ldemul.c	28 Apr 2005 23:54:32 -0000	1.18
+++ ld/ldemul.c	3 May 2005 17:31:03 -0000
@@ -24,6 +24,7 @@ Software Foundation, 59 Temple Place - S
 #include "bfd.h"
 #include "sysdep.h"
 #include "getopt.h"
+#include "bfdlink.h"
 
 #include "ld.h"
 #include "ldmisc.h"
@@ -75,8 +76,7 @@ ldemul_after_allocation (void)
 void
 ldemul_before_allocation (void)
 {
-  if (ld_emulation->before_allocation)
-    ld_emulation->before_allocation ();
+  ld_emulation->before_allocation ();
 }
 
 void
@@ -212,6 +212,8 @@ after_allocation_default (void)
 void
 before_allocation_default (void)
 {
+  if (!link_info.relocatable)
+    strip_excluded_output_sections ();
 }
 
 void
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.46
diff -u -p -r1.46 ldlang.h
--- ld/ldlang.h	28 Apr 2005 23:54:33 -0000	1.46
+++ ld/ldlang.h	3 May 2005 17:31:07 -0000
@@ -549,6 +549,8 @@ extern void lang_for_each_statement
   (void (*) (lang_statement_union_type *));
 extern void *stat_alloc
   (size_t);
+extern void strip_excluded_output_sections
+  (void);
 extern void dprint_statement
   (lang_statement_union_type *, int);
 extern bfd_vma lang_size_sections
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.179
diff -u -p -r1.179 ldlang.c
--- ld/ldlang.c	3 May 2005 01:04:51 -0000	1.179
+++ ld/ldlang.c	4 May 2005 07:48:51 -0000
@@ -54,6 +54,7 @@ static struct obstack map_obstack;
 static const char *startup_file;
 static lang_statement_list_type input_file_chain;
 static bfd_boolean placed_commons = FALSE;
+static bfd_boolean stripped_excluded_sections = FALSE;
 static lang_output_section_statement_type *default_common_section;
 static bfd_boolean map_option_f;
 static bfd_vma print_dot;
@@ -1721,6 +1722,19 @@ lang_add_section (lang_statement_list_ty
       first = ! output->bfd_section->linker_has_input;
       output->bfd_section->linker_has_input = 1;
 
+      if (!link_info.relocatable
+	  && !stripped_excluded_sections)
+	{
+	  asection *s = output->bfd_section->map_tail.s;
+	  output->bfd_section->map_tail.s = section;
+	  section->map_head.s = NULL;
+	  section->map_tail.s = s;
+	  if (s != NULL)
+	    s->map_head.s = section;
+	  else
+	    output->bfd_section->map_head.s = section;
+	}
+
       /* Add a section reference to the list.  */
       new = new_stat (lang_input_section, ptr);
 
@@ -3029,7 +3043,7 @@ map_input_to_output_sections
    added.  For example, ldemul_before_allocation can remove dynamic
    sections if they turn out to be not needed.  Clean them up here.  */
 
-static void
+void
 strip_excluded_output_sections (void)
 {
   lang_output_section_statement_type *os;
@@ -3042,9 +3056,20 @@ strip_excluded_output_sections (void)
 
       if (os->constraint == -1)
 	continue;
-      s = os->bfd_section;
-      if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
+
+      if (os->bfd_section == NULL || os->bfd_section->map_head.s == NULL)
+	continue;
+
+      for (s = os->bfd_section->map_head.s; s != NULL; s = s->map_head.s)
+	if ((s->flags & SEC_EXCLUDE) == 0)
+	  break;
+
+      os->bfd_section->map_head.link_order = NULL;
+      os->bfd_section->map_tail.link_order = NULL;
+
+      if (s == NULL)
 	{
+	  s = os->bfd_section;
 	  os->bfd_section = NULL;
 	  if (!bfd_section_removed_from_list (output_bfd, s))
 	    {
@@ -3053,6 +3078,10 @@ strip_excluded_output_sections (void)
 	    }
 	}
     }
+
+  /* Stop future calls to lang_add_section from messing with map_head
+     and map_tail link_order fields.  */
+  stripped_excluded_sections = TRUE;
 }
 
 static void
@@ -5226,9 +5255,6 @@ lang_process (void)
      and other back-ends size dynamic sections.  */
   ldemul_before_allocation ();
 
-  if (!link_info.relocatable)
-    strip_excluded_output_sections ();
-
   /* We must record the program headers before we try to fix the
      section positions, since they will affect SIZEOF_HEADERS.  */
   lang_record_phdrs ();
Index: ld/ldwrite.c
===================================================================
RCS file: /cvs/src/src/ld/ldwrite.c,v
retrieving revision 1.19
diff -u -p -r1.19 ldwrite.c
--- ld/ldwrite.c	22 Feb 2005 13:00:25 -0000	1.19
+++ ld/ldwrite.c	4 May 2005 07:48:51 -0000
@@ -378,7 +378,7 @@ clone_section (bfd *abfd, asection *s, c
 static void
 ds (asection *s)
 {
-  struct bfd_link_order *l = s->link_order_head;
+  struct bfd_link_order *l = s->map_head.link_order;
   printf ("vma %x size %x\n", s->vma, s->size);
   while (l)
     {
@@ -410,7 +410,7 @@ sanity_check (bfd *abfd)
     {
       struct bfd_link_order *p;
       bfd_vma prev = 0;
-      for (p = s->link_order_head; p; p = p->next)
+      for (p = s->map_head.link_order; p; p = p->next)
 	{
 	  if (p->offset > 100000)
 	    abort ();
@@ -447,7 +447,7 @@ split_sections (bfd *abfd, struct bfd_li
 
       /* Count up the relocations and line entries to see if anything
 	 would be too big to fit.  Accumulate section size too.  */
-      for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next)
+      for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next)
 	{
 	  unsigned int thislines = 0;
 	  unsigned int thisrelocs = 0;
@@ -488,9 +488,9 @@ split_sections (bfd *abfd, struct bfd_li
 
 	      /* Attach the link orders to the new section and snip
 		 them off from the old section.  */
-	      n->link_order_head = p;
-	      n->link_order_tail = cursor->link_order_tail;
-	      cursor->link_order_tail = l;
+	      n->map_head.link_order = p;
+	      n->map_tail.link_order = cursor->map_tail.link_order;
+	      cursor->map_tail.link_order = l;
 	      l->next = NULL;
 	      l = p;
 
Index: ld/emultempl/aix.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/aix.em,v
retrieving revision 1.36
diff -u -p -r1.36 aix.em
--- ld/emultempl/aix.em	3 Mar 2005 11:52:03 -0000	1.36
+++ ld/emultempl/aix.em	3 May 2005 17:31:08 -0000
@@ -10,7 +10,7 @@ cat >e${EMULATION_NAME}.c <<EOF
 
 /* AIX emulation code for ${EMULATION_NAME}
    Copyright 1991, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004
+   2003, 2004, 2005
    Free Software Foundation, Inc.
    Written by Steve Chamberlain <sac@cygnus.com>
    AIX support by Ian Lance Taylor <ian@cygnus.com>
@@ -787,6 +787,9 @@ gld${EMULATION_NAME}_before_allocation (
 				 &is->header.next);
 	}
     }
+
+  if (!link_info.relocatable)
+    strip_excluded_output_sections ();
 }
 
 static char *
Index: ld/emultempl/armcoff.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armcoff.em,v
retrieving revision 1.18
diff -u -p -r1.18 armcoff.em
--- ld/emultempl/armcoff.em	3 Jan 2004 11:09:07 -0000	1.18
+++ ld/emultempl/armcoff.em	3 May 2005 17:31:08 -0000
@@ -125,6 +125,9 @@ gld${EMULATION_NAME}_before_allocation (
 
   /* We have seen it all. Allocate it, and carry on */
   bfd_arm_allocate_interworking_sections (& link_info);
+
+  if (!link_info.relocatable)
+    strip_excluded_output_sections ();
 }
 
 static void
Index: ld/emultempl/beos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/beos.em,v
retrieving revision 1.27
diff -u -p -r1.27 beos.em
--- ld/emultempl/beos.em	3 Mar 2005 11:52:04 -0000	1.27
+++ ld/emultempl/beos.em	3 May 2005 17:31:09 -0000
@@ -661,6 +661,9 @@ gld_${EMULATION_NAME}_before_allocation 
 #endif /* TARGET_IS_ppcpe */
 
   sort_sections (stat_ptr->head);
+
+  if (!link_info.relocatable)
+    strip_excluded_output_sections ();
 }
 
 /* Place an orphan section.  We use this to put sections with a '\$' in them
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.141
diff -u -p -r1.141 elf32.em
--- ld/emultempl/elf32.em	3 May 2005 01:04:51 -0000	1.141
+++ ld/emultempl/elf32.em	3 May 2005 17:31:10 -0000
@@ -1069,6 +1069,7 @@ gld${EMULATION_NAME}_before_allocation (
 	  (const char * const *) command_line.auxiliary_filters,
 	  &link_info, &sinterp, lang_elf_version_info)))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
 ${ELF_INTERPRETER_SET_DEFAULT}
   /* Let the user override the dynamic linker we are using.  */
   if (command_line.interpreter != NULL
@@ -1125,6 +1126,12 @@ ${ELF_INTERPRETER_SET_DEFAULT}
 	s->flags |= SEC_EXCLUDE;
       }
   }
+
+  if (!link_info.relocatable)
+    strip_excluded_output_sections ();
+
+  if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info))
+    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
 }
 
 EOF
Index: ld/emultempl/linux.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/linux.em,v
retrieving revision 1.15
diff -u -p -r1.15 linux.em
--- ld/emultempl/linux.em	3 Mar 2005 11:52:04 -0000	1.15
+++ ld/emultempl/linux.em	3 May 2005 17:31:10 -0000
@@ -10,7 +10,7 @@ cat >e${EMULATION_NAME}.c <<EOF
 
 /* Linux a.out emulation code for ${EMULATION_NAME}
    Copyright 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2005 Free Software Foundation, Inc.
    Written by Steve Chamberlain <sac@cygnus.com>
    Linux support by Eric Youngdale <ericy@cais.cais.com>
 
@@ -121,6 +121,8 @@ gld${EMULATION_NAME}_before_allocation (
      dynamic linking.  */
   if (! bfd_${EMULATION_NAME}_size_dynamic_sections (output_bfd, &link_info))
     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
+  strip_excluded_output_sections ();
 }
 
 static char *
Index: ld/emultempl/lnk960.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/lnk960.em,v
retrieving revision 1.15
diff -u -p -r1.15 lnk960.em
--- ld/emultempl/lnk960.em	24 Feb 2005 20:11:05 -0000	1.15
+++ ld/emultempl/lnk960.em	3 May 2005 17:31:11 -0000
@@ -130,11 +130,6 @@ lnk960_after_parse (void)
 }
 
 static void
-lnk960_before_allocation (void)
-{
-}
-
-static void
 lnk960_after_allocation (void)
 {
   if (!link_info.relocatable)
@@ -273,7 +268,7 @@ struct ld_emulation_xfer_struct ld_lnk96
   lnk960_after_allocation,
   lnk960_set_output_arch,
   lnk960_choose_target,
-  lnk960_before_allocation,
+  before_allocation_default,
   lnk960_get_script,
   "lnk960",
   "",
Index: ld/emultempl/m68kcoff.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/m68kcoff.em,v
retrieving revision 1.11
diff -u -p -r1.11 m68kcoff.em
--- ld/emultempl/m68kcoff.em	7 Apr 2005 14:07:33 -0000	1.11
+++ ld/emultempl/m68kcoff.em	3 May 2005 17:31:11 -0000
@@ -4,7 +4,7 @@ cat >e${EMULATION_NAME}.c <<EOF
 /* This file is is generated by a shell script.  DO NOT EDIT! */
 
 /* Handle embedded relocs for m68k.
-   Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Written by Michael Sokolov <msokolov@ivan.Harhan.ORG>, based on generic.em
    by Steve Chamberlain <steve@cygnus.com>, embedded relocs code based on
    mipsecoff.em by Ian Lance Taylor <ian@cygnus.com>.
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.103
diff -u -p -r1.103 pe.em
--- ld/emultempl/pe.em	3 Mar 2005 11:52:04 -0000	1.103
+++ ld/emultempl/pe.em	3 May 2005 17:31:12 -0000
@@ -1287,6 +1287,9 @@ gld_${EMULATION_NAME}_before_allocation 
   /* We have seen it all. Allocate it, and carry on.  */
   bfd_arm_pe_allocate_interworking_sections (& link_info);
 #endif /* TARGET_IS_armpe */
+
+  if (!link_info.relocatable)
+    strip_excluded_output_sections ();
 }
 
 #ifdef DLL_SUPPORT
Index: ld/emultempl/sunos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/sunos.em,v
retrieving revision 1.20
diff -u -p -r1.20 sunos.em
--- ld/emultempl/sunos.em	3 Mar 2005 11:52:04 -0000	1.20
+++ ld/emultempl/sunos.em	3 May 2005 17:31:12 -0000
@@ -809,6 +809,8 @@ gld${EMULATION_NAME}_before_allocation (
 	hdyn->u.def.section = sdyn;
       else
 	hdyn->u.def.section = bfd_abs_section_ptr;
+
+      strip_excluded_output_sections ();
     }
 }
 

-- 
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]