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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR 10474, linker relaxation vs bfd_elf_discard_info


This patch reorganizes the linker a little, moving relaxation and
other backend sizing and placement to ldemul_after_allocation.
Previously, relaxation was done prior to ldemul_after_allocation and
some sizing and placement in ldemul_finish.  To say the least, this
was a little messy.

In the case of powerpc, the late sizing and placement changes
performed in ldemul_finish by bfd_elf_discard_info (.eh_frame_hdr
increase in size from zero to actual size) and map_segments, affect
branches to the old-style bss plt.  So ppc_elf_relax_section was
trying to work with incorrect information and failed to insert some
necessary long branch trampolines.  To fix this, bfd_elf_discard_info
must run before relaxation, or at least provide an initial estimate.
I chose to simply run bfd_elf_discard_info first as none of its
actions depend on having sections sized exactly.

Furthermore, map_segments can move sections if it changes the number
of headers.  This may affect relaxation, so relaxation ought to be
done again any time map_segments loops.  I realize this has the
potential to significantly slow down the linker, but there isn't any
way to correctly relax code otherwise, unless you are prepared to
accept some slop factor in all the sizing.  (For anyone concered about
multiple iterations of relaxation, we already do so.
lang_size_sections runs section sizing up to three times to handle
relro segment placement.)  Of course, if the number of headers is
estimated correctly there will be no looping in map_segments.

I hope this cleanup doesn't break too many targets..

	PR 10474
	* ldemul.c (after_allocation_default): Run lang_relax_sections.
	* ldlang.h (lang_relax_sections): Declare.
	* ldlang.c (relax_sections): Delete.
	(lang_relax_sections): New function.
	(lang_process): Don't relax directly from here.
	* emultempl/alphaelf.em (alpha_finish): Call finish_default.
	* emultempl/armelf.em (arm_elf_after_allocation): Delete.  Move body..
	(gld${EMULATION_NAME}_finish): ..to here.  Move existing code..
	(gld${EMULATION_NAME}_after_allocation): ..to here.  New function.
	(LDEMUL_AFTER_ALLOCATION): Update.
	* emultempl/avrelf.em (avr_elf_finish, LDEMUL_FINISH): Delete.
	(avr_elf_after_allocation): New function.
	(LDEMUL_AFTER_ALLOCATION): Define.
	* emultempl/elf-generic.em (gld${EMULATION_NAME}_map_segments): Call
	lang_relax_sections.
	* emultempl/elf32.em (gld${EMULATION_NAME}_finish): Delete.  Move..
	(gld${EMULATION_NAME}_after_allocation): ..code to here.  New function.
	(LDEMUL_AFTER_ALLOCATION, LDEMUL_FINISH): Update.
	* emultempl/genelf.em (gld${EMULATION_NAME}_finish): Delete.  Move..
	(gld${EMULATION_NAME}_after_allocation): ..code to here.  New function.
	(LDEMUL_FINISH): Delete.
	(LDEMUL_AFTER_ALLOCATION): Define.
	* emultempl/hppaelf.em (gld${EMULATION_NAME}_finish): Delete.  Move..
	(gld${EMULATION_NAME}_after_allocation): ..to here.  New function.
	(LDEMUL_FINISH): Delete.
	(LDEMUL_AFTER_ALLOCATION): Define.
	* emultempl/m68hc1xelf.em (m68hc11elf_finish): Delete.  Move..
	(m68hc11elf_after_allocation): ..to here.  New function.
	(LDEMUL_FINISH): Delete.
	(LDEMUL_AFTER_ALLOCATION): Define.
	* emultempl/m68kelf.em (m68k_elf_after_allocation): Call
	gld${EMULATION_NAME}_after_allocation.
	* emultempl/mmix-elfnmmo.em (mmix_after_allocation): Call
	gld${EMULATION_NAME}_after_allocation.
	* emultempl/mmo.em (mmo_finish): Delete.  Move body..
	(gld${EMULATION_NAME}_after_allocation): ..to here.  New function.
	(LDEMUL_FINISH): Define.
	* emultempl/ppc64elf.em (ppc_layout_sections_again): Set elf_gp.
	(gld${EMULATION_NAME}_finish): Move code sizing sections..
	(gld${EMULATION_NAME}_after_allocation): ..to here.
	* emultempl/sh64elf.em (sh64_elf_${EMULATION_NAME}_after_allocation):
	Call gld${EMULATION_NAME}_after_allocation.
	* emultempl/spuelf.em (gld${EMULATION_NAME}_finish): Delete
	bfd_elf_discard_info and map_segments call.

Index: ld/ldemul.c
===================================================================
RCS file: /cvs/src/src/ld/ldemul.c,v
retrieving revision 1.30
diff -u -p -r1.30 ldemul.c
--- ld/ldemul.c	20 Oct 2008 12:14:29 -0000	1.30
+++ ld/ldemul.c	8 Aug 2009 12:02:43 -0000
@@ -1,6 +1,6 @@
 /* ldemul.c -- clearing house for ld emulation states
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2005, 2007, 2008
+   2001, 2002, 2003, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
@@ -205,6 +205,7 @@ after_open_default (void)
 void
 after_allocation_default (void)
 {
+  lang_relax_sections (FALSE);
 }
 
 void
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.313
diff -u -p -r1.313 ldlang.c
--- ld/ldlang.c	23 Jul 2009 00:08:22 -0000	1.313
+++ ld/ldlang.c	8 Aug 2009 12:02:49 -0000
@@ -6159,35 +6159,58 @@ lang_find_relro_sections (void)
 
 /* Relax all sections until bfd_relax_section gives up.  */
 
-static void
-relax_sections (void)
+void
+lang_relax_sections (bfd_boolean need_layout)
 {
-  /* Keep relaxing until bfd_relax_section gives up.  */
-  bfd_boolean relax_again;
-
-  link_info.relax_trip = -1;
-  do
+  if (command_line.relax)
     {
-      relax_again = FALSE;
-      link_info.relax_trip++;
+      /* We may need more than one relaxation pass.  */
+      int i = link_info.relax_pass;
 
-      /* Note: pe-dll.c does something like this also.  If you find
-	 you need to change this code, you probably need to change
-	 pe-dll.c also.  DJ  */
+      /* The backend can use it to determine the current pass.  */
+      link_info.relax_pass = 0;
 
-      /* Do all the assignments with our current guesses as to
-	 section sizes.  */
-      lang_do_assignments ();
+      while (i--)
+	{
+	  /* Keep relaxing until bfd_relax_section gives up.  */
+	  bfd_boolean relax_again;
 
-      /* We must do this after lang_do_assignments, because it uses
-	 size.  */
-      lang_reset_memory_regions ();
+	  link_info.relax_trip = -1;
+	  do
+	    {
+	      link_info.relax_trip++;
+
+	      /* Note: pe-dll.c does something like this also.  If you find
+		 you need to change this code, you probably need to change
+		 pe-dll.c also.  DJ  */
+
+	      /* Do all the assignments with our current guesses as to
+		 section sizes.  */
+	      lang_do_assignments ();
+
+	      /* We must do this after lang_do_assignments, because it uses
+		 size.  */
+	      lang_reset_memory_regions ();
+
+	      /* Perform another relax pass - this time we know where the
+		 globals are, so can make a better guess.  */
+	      relax_again = FALSE;
+	      lang_size_sections (&relax_again, FALSE);
+	    }
+	  while (relax_again);
 
-      /* Perform another relax pass - this time we know where the
-	 globals are, so can make a better guess.  */
-      lang_size_sections (&relax_again, FALSE);
+	  link_info.relax_pass++;
+	}
+      need_layout = TRUE;
+    }
+
+  if (need_layout)
+    {
+      /* Final extra sizing to report errors.  */
+      lang_do_assignments ();
+      lang_reset_memory_regions ();
+      lang_size_sections (NULL, TRUE);
     }
-  while (relax_again);
 }
 
 void
@@ -6293,29 +6316,8 @@ lang_process (void)
   /* Size up the sections.  */
   lang_size_sections (NULL, !command_line.relax);
 
-  /* Now run around and relax if we can.  */
-  if (command_line.relax)
-    {
-      /* We may need more than one relaxation pass.  */
-      int i = link_info.relax_pass;
-
-      /* The backend can use it to determine the current pass.  */
-      link_info.relax_pass = 0;
-
-      while (i--)
-	{
-	  relax_sections ();
-	  link_info.relax_pass++;
-	}
-
-      /* Final extra sizing to report errors.  */
-      lang_do_assignments ();
-      lang_reset_memory_regions ();
-      lang_size_sections (NULL, TRUE);
-    }
-
   /* See if anything special should be done now we know how big
-     everything is.  */
+     everything is.  This is where relaxation is done.  */
   ldemul_after_allocation ();
 
   /* Fix any .startof. or .sizeof. symbols.  */
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.83
diff -u -p -r1.83 ldlang.h
--- ld/ldlang.h	15 May 2009 14:22:35 -0000	1.83
+++ ld/ldlang.h	8 Aug 2009 12:02:49 -0000
@@ -483,6 +483,8 @@ extern lang_output_section_statement_typ
    etree_type *, int);
 extern void lang_final
   (void);
+extern void lang_relax_sections
+  (bfd_boolean);
 extern void lang_process
   (void);
 extern void lang_section_start
Index: ld/emultempl/alphaelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/alphaelf.em,v
retrieving revision 1.12
diff -u -p -r1.12 alphaelf.em
--- ld/emultempl/alphaelf.em	15 Feb 2008 09:03:02 -0000	1.12
+++ ld/emultempl/alphaelf.em	8 Aug 2009 12:02:50 -0000
@@ -98,7 +98,7 @@ alpha_finish (void)
   if (limit_32bit)
     elf_elfheader (link_info.output_bfd)->e_flags |= EF_ALPHA_32BIT;
 
-  gld${EMULATION_NAME}_finish ();
+  finish_default ();
 }
 EOF
 
Index: ld/emultempl/armelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armelf.em,v
retrieving revision 1.74
diff -u -p -r1.74 armelf.em
--- ld/emultempl/armelf.em	12 Jun 2009 14:27:21 -0000	1.74
+++ ld/emultempl/armelf.em	8 Aug 2009 12:02:52 -0000
@@ -89,22 +89,6 @@ arm_elf_before_allocation (void)
   gld${EMULATION_NAME}_before_allocation ();
 }
 
-static void
-arm_elf_after_allocation (void)
-{
-  /* Call the standard elf routine.  */
-  after_allocation_default ();
-
-  {
-    LANG_FOR_EACH_INPUT_STATEMENT (is)
-      {
-        /* Figure out where VFP11 erratum veneers (and the labels returning
-           from same) have been placed.  */
-        bfd_elf32_arm_vfp11_fix_veneer_locations (is->the_bfd, &link_info);
-      }
-  }
-}
-
 /* Fake input file for stubs.  */
 static lang_input_statement_type *stub_file;
 
@@ -285,17 +269,16 @@ compare_output_sec_vma (const void *a, c
 }
 
 static void
-gld${EMULATION_NAME}_finish (void)
+gld${EMULATION_NAME}_after_allocation (void)
 {
-  struct bfd_link_hash_entry * h;
-  unsigned int list_size = 10;
-  asection **sec_list = xmalloc (list_size * sizeof (asection *));
-  unsigned int sec_count = 0;
-
   if (!link_info.relocatable)
     {
       /* Build a sorted list of input text sections, then use that to process
 	 the unwind table index.  */
+      unsigned int list_size = 10;
+      asection **sec_list = xmalloc (list_size * sizeof (asection *));
+      unsigned int sec_count = 0;
+
       LANG_FOR_EACH_INPUT_STATEMENT (is)
 	{
 	  bfd *abfd = is->the_bfd;
@@ -375,6 +358,21 @@ gld${EMULATION_NAME}_finish (void)
 
   if (need_laying_out != -1)
     gld${EMULATION_NAME}_map_segments (need_laying_out);
+}
+
+static void
+gld${EMULATION_NAME}_finish (void)
+{
+  struct bfd_link_hash_entry * h;
+
+  {
+    LANG_FOR_EACH_INPUT_STATEMENT (is)
+      {
+        /* Figure out where VFP11 erratum veneers (and the labels returning
+           from same) have been placed.  */
+        bfd_elf32_arm_vfp11_fix_veneer_locations (is->the_bfd, &link_info);
+      }
+  }
 
   if (! link_info.relocatable)
     {
@@ -659,7 +657,7 @@ PARSE_AND_LIST_ARGS_CASES='
 # We have our own before_allocation etc. functions, but they call
 # the standard routines, so give them a different name.
 LDEMUL_BEFORE_ALLOCATION=arm_elf_before_allocation
-LDEMUL_AFTER_ALLOCATION=arm_elf_after_allocation
+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=arm_elf_create_output_section_statements
 
 # Replace the elf before_parse function with our own.
Index: ld/emultempl/avrelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/avrelf.em,v
retrieving revision 1.7
diff -u -p -r1.7 avrelf.em
--- ld/emultempl/avrelf.em	7 Jul 2008 00:46:51 -0000	1.7
+++ ld/emultempl/avrelf.em	8 Aug 2009 12:02:52 -0000
@@ -144,29 +144,24 @@ avr_elf_create_output_section_statements
 /* Re-calculates the size of the stubs so that we won't waste space.  */
 
 static void
-avr_elf_finish (void)
+avr_elf_after_allocation (void)
 {
-  if (!avr_no_stubs)
+  if (!avr_no_stubs && !command_line.relax)
     {
-      /* Now build the linker stubs.  */
-      if (stub_file->the_bfd->sections != NULL)
-       {
-         /* Call again the trampoline analyzer to initialize the trampoline
-            stubs with the correct symbol addresses.  Since there could have
-            been relaxation, the symbol addresses that were found during
-            first call may no longer be correct.  */
-         if (!elf32_avr_size_stubs (link_info.output_bfd, &link_info, FALSE))
-           {
-             einfo ("%X%P: can not size stub section: %E\n");
-             return;
-           }
-
-         if (!elf32_avr_build_stubs (&link_info))
-           einfo ("%X%P: can not build stubs: %E\n");
-       }
+      /* If relaxing, elf32_avr_size_stubs will be called from
+	 elf32_avr_relax_section.  */
+      if (!elf32_avr_size_stubs (link_info.output_bfd, &link_info, FALSE))
+	einfo ("%X%P: can not size stub section: %E\n");
     }
 
-  gld${EMULATION_NAME}_finish ();
+  gld${EMULATION_NAME}_after_allocation ();
+
+  /* Now build the linker stubs.  */
+  if (!avr_no_stubs)
+    {
+      if (!elf32_avr_build_stubs (&link_info))
+	einfo ("%X%P: can not build stubs: %E\n");
+    }
 }
 
 
@@ -266,5 +261,5 @@ PARSE_AND_LIST_ARGS_CASES='
 # Put these extra avr-elf routines in ld_${EMULATION_NAME}_emulation
 #
 LDEMUL_BEFORE_ALLOCATION=avr_elf_${EMULATION_NAME}_before_allocation
-LDEMUL_FINISH=avr_elf_finish
+LDEMUL_AFTER_ALLOCATION=avr_elf_after_allocation
 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=avr_elf_create_output_section_statements
Index: ld/emultempl/elf-generic.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf-generic.em,v
retrieving revision 1.7
diff -u -p -r1.7 elf-generic.em
--- ld/emultempl/elf-generic.em	15 Feb 2008 03:35:53 -0000	1.7
+++ ld/emultempl/elf-generic.em	8 Aug 2009 12:02:52 -0000
@@ -31,21 +31,8 @@ gld${EMULATION_NAME}_map_segments (bfd_b
 
   do
     {
-      if (need_layout)
-	{
-	  lang_reset_memory_regions ();
-
-	  /* Resize the sections.  */
-	  lang_size_sections (NULL, TRUE);
-
-	  /* Redo special stuff.  */
-	  ldemul_after_allocation ();
-
-	  /* Do the assignments again.  */
-	  lang_do_assignments ();
-
-	  need_layout = FALSE;
-	}
+      lang_relax_sections (need_layout);
+      need_layout = FALSE;
 
       if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour
 	  && !link_info.relocatable)
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.197
diff -u -p -r1.197 elf32.em
--- ld/emultempl/elf32.em	15 May 2009 14:22:35 -0000	1.197
+++ ld/emultempl/elf32.em	8 Aug 2009 12:02:53 -0000
@@ -62,10 +62,9 @@ fragment <<EOF
 static void gld${EMULATION_NAME}_before_parse (void);
 static void gld${EMULATION_NAME}_after_open (void);
 static void gld${EMULATION_NAME}_before_allocation (void);
+static void gld${EMULATION_NAME}_after_allocation (void);
 static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
   (asection *, const char *, int);
-static void gld${EMULATION_NAME}_finish (void);
-
 EOF
 
 if [ "x${USE_LIBPATH}" = xyes ] ; then
@@ -1830,17 +1829,15 @@ gld${EMULATION_NAME}_place_orphan (asect
 EOF
 fi
 
-if test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then
+if test x"$LDEMUL_AFTER_ALLOCATION" != xgld"$EMULATION_NAME"_after_allocation; then
 fragment <<EOF
 
 static void
-gld${EMULATION_NAME}_finish (void)
+gld${EMULATION_NAME}_after_allocation (void)
 {
   bfd_boolean need_layout = bfd_elf_discard_info (link_info.output_bfd,
 						  &link_info);
-
   gld${EMULATION_NAME}_map_segments (need_layout);
-  finish_default ();
 }
 EOF
 fi
@@ -2327,14 +2324,14 @@ struct ld_emulation_xfer_struct ld_${EMU
   ${LDEMUL_HLL-hll_default},
   ${LDEMUL_AFTER_PARSE-after_parse_default},
   ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
-  ${LDEMUL_AFTER_ALLOCATION-after_allocation_default},
+  ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
   ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
   ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
   ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
   ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
   "${EMULATION_NAME}",
   "${OUTPUT_FORMAT}",
-  ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish},
+  ${LDEMUL_FINISH-finish_default},
   ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
   ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
   ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
Index: ld/emultempl/genelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/genelf.em,v
retrieving revision 1.4
diff -u -p -r1.4 genelf.em
--- ld/emultempl/genelf.em	3 Oct 2008 09:40:49 -0000	1.4
+++ ld/emultempl/genelf.em	8 Aug 2009 12:02:53 -0000
@@ -29,13 +29,6 @@ source_em ${srcdir}/emultempl/elf-generi
 fragment <<EOF
 
 static void
-gld${EMULATION_NAME}_finish (void)
-{
-  gld${EMULATION_NAME}_map_segments (FALSE);
-  finish_default ();
-}
-
-static void
 gld${EMULATION_NAME}_after_open (void)
 {
   bfd *ibfd;
@@ -53,8 +46,14 @@ gld${EMULATION_NAME}_after_open (void)
 	      elf_group_id (sec) = syms[sec_data->this_hdr.sh_info - 1];
 	    }
 }
+
+static void
+gld${EMULATION_NAME}_after_allocation (void)
+{
+  gld${EMULATION_NAME}_map_segments (FALSE);
+}
 EOF
 # Put these extra routines in ld_${EMULATION_NAME}_emulation
 #
-LDEMUL_FINISH=gld${EMULATION_NAME}_finish
 LDEMUL_AFTER_OPEN=gld${EMULATION_NAME}_after_open
+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
Index: ld/emultempl/hppaelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/hppaelf.em,v
retrieving revision 1.52
diff -u -p -r1.52 hppaelf.em
--- ld/emultempl/hppaelf.em	7 Jul 2008 00:46:51 -0000	1.52
+++ ld/emultempl/hppaelf.em	8 Aug 2009 12:02:54 -0000
@@ -237,14 +237,13 @@ build_section_lists (lang_statement_unio
 }
 
 
-/* Final emulation specific call.  For the PA we use this opportunity
-   to build linker stubs.  */
+/* For the PA we use this opportunity to size and build linker stubs.  */
 
 static void
-gld${EMULATION_NAME}_finish (void)
+gld${EMULATION_NAME}_after_allocation (void)
 {
-  /* bfd_elf_discard_info just plays with debugging sections,
-     ie. doesn't affect any code, so we can delay resizing the
+  /* bfd_elf_discard_info just plays with data and debugging sections,
+     ie. doesn't affect code size, so we can delay resizing the
      sections.  It's likely we'll resize everything in the process of
      adding stubs.  */
   if (bfd_elf_discard_info (link_info.output_bfd, &link_info))
@@ -301,8 +300,6 @@ gld${EMULATION_NAME}_finish (void)
 	    einfo ("%X%P: can not build stubs: %E\n");
 	}
     }
-
-  finish_default ();
 }
 
 
@@ -376,5 +373,5 @@ PARSE_AND_LIST_ARGS_CASES='
 # Put these extra hppaelf routines in ld_${EMULATION_NAME}_emulation
 #
 LDEMUL_AFTER_PARSE=hppaelf_after_parse
-LDEMUL_FINISH=gld${EMULATION_NAME}_finish
+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=hppaelf_create_output_section_statements
Index: ld/emultempl/m68hc1xelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/m68hc1xelf.em,v
retrieving revision 1.12
diff -u -p -r1.12 m68hc1xelf.em
--- ld/emultempl/m68hc1xelf.em	7 Jul 2008 00:46:51 -0000	1.12
+++ ld/emultempl/m68hc1xelf.em	8 Aug 2009 12:02:54 -0000
@@ -284,11 +284,10 @@ m68hc11elf_add_stub_section (const char 
   return NULL;
 }
 
-/* Final emulation specific call.  For the 68HC12 we use this opportunity
-   to build linker stubs.  */
+/* For the 68HC12 we use this opportunity to build linker stubs.  */
 
 static void
-m68hc11elf_finish (void)
+m68hc11elf_after_allocation (void)
 {
   /* Now build the linker stubs.  */
   if (stub_file->the_bfd->sections != NULL)
@@ -308,7 +307,7 @@ m68hc11elf_finish (void)
 	einfo ("%X%P: can not build stubs: %E\n");
     }
 
-  gld${EMULATION_NAME}_finish ();
+  gld${EMULATION_NAME}_after_allocation ();
 }
 
 
@@ -370,5 +369,5 @@ PARSE_AND_LIST_ARGS_CASES='
 # Put these extra m68hc11elf routines in ld_${EMULATION_NAME}_emulation
 #
 LDEMUL_BEFORE_ALLOCATION=m68hc11_elf_${EMULATION_NAME}_before_allocation
-LDEMUL_FINISH=m68hc11elf_finish
+LDEMUL_AFTER_ALLOCATION=m68hc11elf_after_allocation
 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=m68hc11elf_create_output_section_statements
Index: ld/emultempl/m68kelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/m68kelf.em,v
retrieving revision 1.12
diff -u -p -r1.12 m68kelf.em
--- ld/emultempl/m68kelf.em	7 Jul 2008 00:46:51 -0000	1.12
+++ ld/emultempl/m68kelf.em	8 Aug 2009 12:02:54 -0000
@@ -143,7 +143,7 @@ static void
 m68k_elf_after_allocation (void)
 {
   /* Call the standard elf routine.  */
-  after_allocation_default ();
+  gld${EMULATION_NAME}_after_allocation ();
 
 #ifdef SUPPORT_EMBEDDED_RELOCS
   if (command_line.embedded_relocs
Index: ld/emultempl/mmix-elfnmmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmix-elfnmmo.em,v
retrieving revision 1.15
diff -u -p -r1.15 mmix-elfnmmo.em
--- ld/emultempl/mmix-elfnmmo.em	15 Feb 2008 03:35:53 -0000	1.15
+++ ld/emultempl/mmix-elfnmmo.em	8 Aug 2009 12:02:54 -0000
@@ -56,11 +56,11 @@ mmix_before_allocation (void)
 static void
 mmix_after_allocation (void)
 {
-  asection *sec
-    = bfd_get_section_by_name (link_info.output_bfd,
-			       MMIX_REG_CONTENTS_SECTION_NAME);
+  asection *sec;
   bfd_signed_vma regvma;
 
+  gld${EMULATION_NAME}_after_allocation ();
+
   /* If there's no register section, we don't need to do anything.  On the
      other hand, if there's a non-standard linker-script without a mapping
      from MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME when that section is
@@ -72,6 +72,8 @@ mmix_after_allocation (void)
      that's expected when you play tricks with linker scripts.  The
      "NOCROSSREFS 2" test does not run the output so it does not matter
      there.  */
+  sec = bfd_get_section_by_name (link_info.output_bfd,
+				 MMIX_REG_CONTENTS_SECTION_NAME);
   if (sec == NULL)
     sec
       = bfd_get_section_by_name (link_info.output_bfd,
Index: ld/emultempl/mmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmo.em,v
retrieving revision 1.24
diff -u -p -r1.24 mmo.em
--- ld/emultempl/mmo.em	20 Oct 2008 12:14:29 -0000	1.24
+++ ld/emultempl/mmo.em	8 Aug 2009 12:02:54 -0000
@@ -35,6 +35,8 @@ fragment <<EOF
    get a weird testcase right; ld-mmix/bpo-22, forcing ELF to be
    output from the mmo emulation: -m mmo --oformat elf64-mmix!  */
 #include "elf-bfd.h"
+
+static void gld${EMULATION_NAME}_after_allocation (void);
 EOF
 
 source_em ${srcdir}/emultempl/elf-generic.em
@@ -119,11 +121,10 @@ mmo_wipe_sec_reloc_flag (bfd *abfd, asec
 /* Iterate with bfd_map_over_sections over mmo_wipe_sec_reloc_flag... */
 
 static void
-mmo_finish (void)
+gld${EMULATION_NAME}_after_allocation (void)
 {
   bfd_map_over_sections (link_info.output_bfd, mmo_wipe_sec_reloc_flag, NULL);
   gld${EMULATION_NAME}_map_segments (FALSE);
-  finish_default ();
 }
 
 /* To get on-demand global register allocation right, we need to parse the
@@ -154,5 +155,4 @@ mmo_after_open (void)
 EOF
 
 LDEMUL_PLACE_ORPHAN=mmo_place_orphan
-LDEMUL_FINISH=mmo_finish
 LDEMUL_AFTER_OPEN=mmo_after_open
Index: ld/emultempl/ppc64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/ppc64elf.em,v
retrieving revision 1.61
diff -u -p -r1.61 ppc64elf.em
--- ld/emultempl/ppc64elf.em	26 Nov 2008 01:04:17 -0000	1.61
+++ ld/emultempl/ppc64elf.em	8 Aug 2009 12:02:54 -0000
@@ -258,18 +258,12 @@ ppc_layout_sections_again (void)
      to recalculate all the section offsets.  This may mean we need to
      add even more stubs.  */
   gld${EMULATION_NAME}_map_segments (TRUE);
-  need_laying_out = -1;
-}
-
 
-/* Call the back-end function to set TOC base after we have placed all
-   the sections.  */
-static void
-gld${EMULATION_NAME}_after_allocation (void)
-{
   if (!link_info.relocatable)
     _bfd_set_gp_value (link_info.output_bfd,
 		       ppc64_elf_toc (link_info.output_bfd));
+
+  need_laying_out = -1;
 }
 
 
@@ -307,18 +301,13 @@ build_section_lists (lang_statement_unio
 }
 
 
-/* Final emulation specific call.  */
-
+/* Call the back-end function to set TOC base after we have placed all
+   the sections.  */
 static void
-gld${EMULATION_NAME}_finish (void)
+gld${EMULATION_NAME}_after_allocation (void)
 {
-  /* e_entry on PowerPC64 points to the function descriptor for
-     _start.  If _start is missing, default to the first function
-     descriptor in the .opd section.  */
-  entry_section = ".opd";
-
-  /* bfd_elf_discard_info just plays with debugging sections,
-     ie. doesn't affect any code, so we can delay resizing the
+  /* bfd_elf_discard_info just plays with data and debugging sections,
+     ie. doesn't affect code size, so we can delay resizing the
      sections.  It's likely we'll resize everything in the process of
      adding stubs.  */
   if (bfd_elf_discard_info (link_info.output_bfd, &link_info))
@@ -354,7 +343,25 @@ gld${EMULATION_NAME}_finish (void)
     }
 
   if (need_laying_out != -1)
-    gld${EMULATION_NAME}_map_segments (need_laying_out);
+    {
+      gld${EMULATION_NAME}_map_segments (need_laying_out);
+
+      if (!link_info.relocatable)
+	_bfd_set_gp_value (link_info.output_bfd,
+			   ppc64_elf_toc (link_info.output_bfd));
+    }
+}
+
+
+/* Final emulation specific call.  */
+
+static void
+gld${EMULATION_NAME}_finish (void)
+{
+  /* e_entry on PowerPC64 points to the function descriptor for
+     _start.  If _start is missing, default to the first function
+     descriptor in the .opd section.  */
+  entry_section = ".opd";
 
   if (link_info.relocatable)
     {
Index: ld/emultempl/sh64elf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/sh64elf.em,v
retrieving revision 1.14
diff -u -p -r1.14 sh64elf.em
--- ld/emultempl/sh64elf.em	7 Jul 2008 00:46:51 -0000	1.14
+++ ld/emultempl/sh64elf.em	8 Aug 2009 12:02:55 -0000
@@ -244,12 +244,12 @@ sh64_elf_${EMULATION_NAME}_after_allocat
   bfd_vma cranges_growth = 0;
   asection *osec;
   bfd_byte *crangesp;
+  asection *cranges;
 
-  asection *cranges = bfd_get_section_by_name (link_info.output_bfd,
-					       SH64_CRANGES_SECTION_NAME);
+  gld${EMULATION_NAME}_after_allocation ();
 
-  /* If this ever starts doing something, we will pick it up.  */
-  after_allocation_default ();
+  cranges = bfd_get_section_by_name (link_info.output_bfd,
+				     SH64_CRANGES_SECTION_NAME);
 
   /* If there is no .cranges section, it is because it was seen earlier on
      that none was needed.  Otherwise it must have been created then, or
@@ -376,11 +376,6 @@ sh64_elf_${EMULATION_NAME}_after_allocat
       }
     }
 
-  /* ldemul_after_allocation may be called twice.  First directly from
-     lang_process, and the second time when lang_process calls ldemul_finish,
-     which calls gld${EMULATION_NAME}_finish, e.g. gldshelf32_finish, which
-     is defined in emultempl/elf32.em and calls ldemul_after_allocation,
-     if bfd_elf_discard_info returned true.  */
   if (cranges->contents != NULL)
     free (cranges->contents);
 
Index: ld/emultempl/spuelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/spuelf.em,v
retrieving revision 1.40
diff -u -p -r1.40 spuelf.em
--- ld/emultempl/spuelf.em	5 Aug 2009 20:40:33 -0000	1.40
+++ ld/emultempl/spuelf.em	8 Aug 2009 15:06:30 -0000
@@ -406,12 +406,6 @@ spu_elf_relink (void)
 static void
 gld${EMULATION_NAME}_finish (void)
 {
-  int need_laying_out;
-
-  need_laying_out = bfd_elf_discard_info (link_info.output_bfd, &link_info);
-
-  gld${EMULATION_NAME}_map_segments (need_laying_out);
-
   if (is_spu_target ())
     {
       if (params.local_store_lo < params.local_store_hi)

-- 
Alan Modra
Australia Development Lab, IBM


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