public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Slow _bfd_strip_section_from_output
@ 2005-04-30 23:49 H. J. Lu
  2005-05-03  0:35 ` Alan Modra
  0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2005-04-30 23:49 UTC (permalink / raw)
  To: binutils; +Cc: gcc

_bfd_strip_section_from_output is known to be very slow:

http://sourceware.org/ml/binutils/2005-03/msg00826.html

It scans every section in all input files to find a match. We do
have link_order_head/link_order_tail. But they aren't available
when _bfd_strip_section_from_output is called. Can we build them
when we assign the output sections and fix them up before we need
them for output?


H.J.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Slow _bfd_strip_section_from_output
  2005-04-30 23:49 Slow _bfd_strip_section_from_output H. J. Lu
@ 2005-05-03  0:35 ` Alan Modra
  2005-05-03  0:45   ` H. J. Lu
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Modra @ 2005-05-03  0:35 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Sat, Apr 30, 2005 at 12:50:29PM -0700, H. J. Lu wrote:
> _bfd_strip_section_from_output is known to be very slow:
> 
> http://sourceware.org/ml/binutils/2005-03/msg00826.html
> 
> It scans every section in all input files to find a match. We do
> have link_order_head/link_order_tail. But they aren't available
> when _bfd_strip_section_from_output is called. Can we build them
> when we assign the output sections and fix them up before we need
> them for output?

Yes, that's what I suggested in
http://sourceware.org/ml/binutils/2005-03/msg00827.html

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Slow _bfd_strip_section_from_output
  2005-05-03  0:35 ` Alan Modra
@ 2005-05-03  0:45   ` H. J. Lu
  2005-05-03  4:16     ` Alan Modra
  2005-05-03 20:45     ` Hans-Peter Nilsson
  0 siblings, 2 replies; 8+ messages in thread
From: H. J. Lu @ 2005-05-03  0:45 UTC (permalink / raw)
  To: binutils

On Tue, May 03, 2005 at 10:04:51AM +0930, Alan Modra wrote:
> On Sat, Apr 30, 2005 at 12:50:29PM -0700, H. J. Lu wrote:
> > _bfd_strip_section_from_output is known to be very slow:
> > 
> > http://sourceware.org/ml/binutils/2005-03/msg00826.html
> > 
> > It scans every section in all input files to find a match. We do
> > have link_order_head/link_order_tail. But they aren't available
> > when _bfd_strip_section_from_output is called. Can we build them
> > when we assign the output sections and fix them up before we need
> > them for output?
> 
> Yes, that's what I suggested in
> http://sourceware.org/ml/binutils/2005-03/msg00827.html
> 

This is what I come up with. I added link_order_input so that I
don't have to seatch the whole list to find a bfd_input_link_order.
Otherwise, bfd_new_link_order will be as slow as the old
_bfd_strip_section_from_output.

Everything seems OK on ia32, ia64 and x86_64. But I did get some
failures on "cris-elf". I don't know if they are harmless.


H.J.
-----
bfd/

2005-04-30  H.J. Lu  <hongjiu.lu@intel.com>

	* linker.c (bfd_new_link_order): Reuse link_order_input.
	(bfd_new_input_link_order): New.
	(_bfd_default_link_order): Ignore bfd_input_link_order.

	* section.c (bfd_section): Add link_order_input.
	(STD_SECTION): Initialize link_order_input.
	(_bfd_strip_section_from_output): Scan bfd_input_link_order
	for input sections.
	* bfd-in2.h: Regenerated.

include/

2005-04-30  H.J. Lu  <hongjiu.lu@intel.com>

	* bfdlink.h (bfd_link_order_type): Add bfd_input_link_order.
	(bfd_new_input_link_order): New.

ld/

2005-04-30  H.J. Lu  <hongjiu.lu@intel.com>

	* ldlang.c (lang_add_section): Call bfd_new_input_link_order
	to set up link_order_input.

--- binutils/bfd/linker.c.input	2005-04-30 15:00:46.000000000 -0700
+++ binutils/bfd/linker.c	2005-04-30 15:00:46.000000000 -0700
@@ -2648,9 +2648,20 @@ _bfd_generic_reloc_link_order (bfd *abfd
 struct bfd_link_order *
 bfd_new_link_order (bfd *abfd, asection *section)
 {
-  bfd_size_type amt = sizeof (struct bfd_link_order);
+  bfd_size_type amt;
   struct bfd_link_order *new;
 
+  new = section->link_order_input;
+  if (new)
+    {
+      if (new->type != bfd_input_link_order)
+	abort ();
+      section->link_order_input = new->next;
+      new->type = bfd_undefined_link_order;
+      return new;
+    }
+
+  amt = sizeof (struct bfd_link_order);
   new = bfd_zalloc (abfd, amt);
   if (!new)
     return NULL;
@@ -2666,6 +2677,36 @@ bfd_new_link_order (bfd *abfd, asection 
   return new;
 }
 
+/* Allocate a new bfd_input_link_order for a section.  */
+
+struct bfd_link_order *
+bfd_new_input_link_order (bfd *abfd, asection *section)
+{
+  bfd_size_type amt = sizeof (struct bfd_link_order);
+  struct bfd_link_order *new;
+  asection *output_section;
+
+  new = bfd_zalloc (abfd, amt);
+  if (!new)
+    return NULL;
+
+  output_section = section->output_section;
+
+  new->type = bfd_input_link_order;
+  new->u.indirect.section = section;
+
+  if (output_section->link_order_tail != NULL)
+    output_section->link_order_tail->next = new;
+  else
+    {
+      output_section->link_order_head = new;
+      output_section->link_order_input = new;
+    }
+  output_section->link_order_tail = new;
+
+  return new;
+}
+
 /* Default link order processing routine.  Note that we can not handle
    the reloc_link_order types here, since they depend upon the details
    of how the particular backends generates relocs.  */
@@ -2678,6 +2719,8 @@ _bfd_default_link_order (bfd *abfd,
 {
   switch (link_order->type)
     {
+    case bfd_input_link_order:
+      return TRUE;
     case bfd_undefined_link_order:
     case bfd_section_reloc_link_order:
     case bfd_symbol_reloc_link_order:
--- binutils/bfd/section.c.input	2005-04-30 15:00:46.000000000 -0700
+++ binutils/bfd/section.c	2005-04-30 15:00:46.000000000 -0700
@@ -500,6 +500,7 @@ CODE_FRAGMENT
 .
 .  struct bfd_link_order *link_order_head;
 .  struct bfd_link_order *link_order_tail;
+.  struct bfd_link_order *link_order_input;
 .} asection;
 .
 .{* These sections are global, and are managed by BFD.  The application
@@ -639,8 +640,8 @@ static const asymbol global_syms[] =
     /* symbol_ptr_ptr,                                               */	\
        (struct bfd_symbol **) &SYM,					\
 									\
-    /* link_order_head, link_order_tail                              */	\
-       NULL,            NULL						\
+    /* link_order_head, link_order_tail, link_order_input            */	\
+       NULL,            NULL,		 NULL				\
     }
 
 STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
@@ -1412,11 +1413,12 @@ DESCRIPTION
 	to remove sections.
 */
 void
-_bfd_strip_section_from_output (struct bfd_link_info *info, asection *s)
+_bfd_strip_section_from_output
+  (struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *s)
 {
   asection *os;
   asection *is;
-  bfd *abfd;
+  struct bfd_link_order *p;
 
   s->flags |= SEC_EXCLUDE;
 
@@ -1429,10 +1431,18 @@ _bfd_strip_section_from_output (struct b
 
   /* 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;
+  for (p = os->link_order_head; p; p = p->next)
+    switch (p->type)
+      {
+      default:
+	abort ();
+	break;
+      case bfd_input_link_order:
+	is = p->u.indirect.section;
+	if ((is->flags & SEC_EXCLUDE) == 0)
+	  return;
+	break;
+      }
 
   /* If the output section is empty, flag it for removal too.
      See ldlang.c:strip_excluded_output_sections for the action.  */
--- binutils/include/bfdlink.h.input	2005-03-22 06:09:08.000000000 -0800
+++ binutils/include/bfdlink.h	2005-04-30 15:00:46.000000000 -0700
@@ -546,6 +546,7 @@ enum bfd_link_order_type
 {
   bfd_undefined_link_order,	/* Undefined.  */
   bfd_indirect_link_order,	/* Built from a section.  */
+  bfd_input_link_order,		/* bfd_indirect_link_order.  */
   bfd_data_link_order,		/* Set to explicit data.  */
   bfd_section_reloc_link_order,	/* Relocate against a section.  */
   bfd_symbol_reloc_link_order	/* Relocate against a symbol.  */
@@ -636,6 +637,10 @@ struct bfd_link_order_reloc
 /* Allocate a new link_order for a section.  */
 extern struct bfd_link_order *bfd_new_link_order (bfd *, asection *);
 
+/* Allocate a new bfd_input_link_order for a section.  */
+extern struct bfd_link_order *bfd_new_input_link_order
+  (bfd *, asection *);
+
 /* These structures are used to describe version information for the
    ELF linker.  These structures could be manipulated entirely inside
    BFD, but it would be a pain.  Instead, the regular linker sets up
--- binutils/ld/ldlang.c.input	2005-04-30 15:00:46.000000000 -0700
+++ binutils/ld/ldlang.c	2005-04-30 15:19:33.000000000 -0700
@@ -1728,6 +1728,8 @@ lang_add_section (lang_statement_list_ty
       new->ifile = file;
       section->output_section = output->bfd_section;
 
+      ASSERT (bfd_new_input_link_order (output_bfd, section) != NULL);
+
       flags = section->flags;
 
       /* We don't copy the SEC_NEVER_LOAD flag from an input section

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Slow _bfd_strip_section_from_output
  2005-05-03  0:45   ` H. J. Lu
@ 2005-05-03  4:16     ` Alan Modra
  2005-05-04 12:08       ` Alan Modra
  2005-05-03 20:45     ` Hans-Peter Nilsson
  1 sibling, 1 reply; 8+ messages in thread
From: Alan Modra @ 2005-05-03  4:16 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Mon, May 02, 2005 at 05:44:47PM -0700, H. J. Lu wrote:
> 	* bfdlink.h (bfd_link_order_type): Add bfd_input_link_order.
> 	(bfd_new_input_link_order): New.

Why ever did you need this?  bfd_indirect_link_order is the one that's
used for input sections.  Oh, I see.  You're effectively making an
entirely new list which wastes memory using bfd_link_order structs.  No,
I don't like it.  Too quick and dirty.  How about striving for some
elegance?

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.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Slow _bfd_strip_section_from_output
  2005-05-03  0:45   ` H. J. Lu
  2005-05-03  4:16     ` Alan Modra
@ 2005-05-03 20:45     ` Hans-Peter Nilsson
  2005-05-03 20:49       ` H. J. Lu
  1 sibling, 1 reply; 8+ messages in thread
From: Hans-Peter Nilsson @ 2005-05-03 20:45 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Mon, 2 May 2005, H. J. Lu wrote:
> This is what I come up with. I added link_order_input so that I
> don't have to seatch the whole list to find a bfd_input_link_order.
> Otherwise, bfd_new_link_order will be as slow as the old
> _bfd_strip_section_from_output.
>
> Everything seems OK on ia32, ia64 and x86_64. But I did get some
> failures on "cris-elf". I don't know if they are harmless.

Probably not, but there's no way to tell without details.
FWIW, my autotester shows clean results here.

brgds, H-P

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Slow _bfd_strip_section_from_output
  2005-05-03 20:45     ` Hans-Peter Nilsson
@ 2005-05-03 20:49       ` H. J. Lu
  2005-05-03 21:06         ` Hans-Peter Nilsson
  0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2005-05-03 20:49 UTC (permalink / raw)
  To: Hans-Peter Nilsson; +Cc: binutils

On Tue, May 03, 2005 at 03:59:05PM -0400, Hans-Peter Nilsson wrote:
> On Mon, 2 May 2005, H. J. Lu wrote:
> > This is what I come up with. I added link_order_input so that I
> > don't have to seatch the whole list to find a bfd_input_link_order.
> > Otherwise, bfd_new_link_order will be as slow as the old
> > _bfd_strip_section_from_output.
> >
> > Everything seems OK on ia32, ia64 and x86_64. But I did get some
> > failures on "cris-elf". I don't know if they are harmless.
> 
> Probably not, but there's no way to tell without details.
> FWIW, my autotester shows clean results here.

With my patch applied?


H.J.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Slow _bfd_strip_section_from_output
  2005-05-03 20:49       ` H. J. Lu
@ 2005-05-03 21:06         ` Hans-Peter Nilsson
  0 siblings, 0 replies; 8+ messages in thread
From: Hans-Peter Nilsson @ 2005-05-03 21:06 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Tue, 3 May 2005, H. J. Lu wrote:
> On Tue, May 03, 2005 at 03:59:05PM -0400, Hans-Peter Nilsson wrote:
> > On Mon, 2 May 2005, H. J. Lu wrote:
> > > This is what I come up with. I added link_order_input so that I
> > > don't have to seatch the whole list to find a bfd_input_link_order.
> > > Otherwise, bfd_new_link_order will be as slow as the old
> > > _bfd_strip_section_from_output.
> > >
> > > Everything seems OK on ia32, ia64 and x86_64. But I did get some
> > > failures on "cris-elf". I don't know if they are harmless.
> > Probably not, but there's no way to tell without details.
> > FWIW, my autotester shows clean results here.
> With my patch applied?

No, I only test what's checked in. If you get failures with your
patch, then your patch is likely flawed (but without details, no
knowing), if it's not meant to actually change the output.
(And if it is, you'd know and wouldn't make the "don't know"
comment.)

brgds, H-P
PS. BTW, thanks a bunch for taking on the sec64k slowness!

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Slow _bfd_strip_section_from_output
  2005-05-03  4:16     ` Alan Modra
@ 2005-05-04 12:08       ` Alan Modra
  0 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2005-05-04 12:08 UTC (permalink / raw)
  To: binutils

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 ();
 }
 \f
 /* 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 ();
 }
 \f
 #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

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2005-05-04 10:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-30 23:49 Slow _bfd_strip_section_from_output H. J. Lu
2005-05-03  0:35 ` Alan Modra
2005-05-03  0:45   ` H. J. Lu
2005-05-03  4:16     ` Alan Modra
2005-05-04 12:08       ` Alan Modra
2005-05-03 20:45     ` Hans-Peter Nilsson
2005-05-03 20:49       ` H. J. Lu
2005-05-03 21:06         ` Hans-Peter Nilsson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).