This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PR 10474, linker relaxation vs bfd_elf_discard_info
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Mon, 10 Aug 2009 17:21:39 +0930
- Subject: 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