aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2009-08-10 07:50:56 +0000
committerAlan Modra <amodra@gmail.com>2009-08-10 07:50:56 +0000
commiteaeb0a9d5c65fd8dc19878b068e17f90a93a19c2 (patch)
tree2fd5546de6a8a46159d292b109e46dd1d525f53a /ld
parenta8ad78a74eb4e3bf77cf6174e5c10a3c30212b3a (diff)
downloadfsf-binutils-gdb-eaeb0a9d5c65fd8dc19878b068e17f90a93a19c2.zip
fsf-binutils-gdb-eaeb0a9d5c65fd8dc19878b068e17f90a93a19c2.tar.gz
fsf-binutils-gdb-eaeb0a9d5c65fd8dc19878b068e17f90a93a19c2.tar.bz2
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.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog48
-rw-r--r--ld/emultempl/alphaelf.em2
-rw-r--r--ld/emultempl/armelf.em44
-rw-r--r--ld/emultempl/avrelf.em35
-rw-r--r--ld/emultempl/elf-generic.em17
-rw-r--r--ld/emultempl/elf32.em13
-rw-r--r--ld/emultempl/genelf.em15
-rw-r--r--ld/emultempl/hppaelf.em13
-rw-r--r--ld/emultempl/m68hc1xelf.em9
-rw-r--r--ld/emultempl/m68kelf.em2
-rw-r--r--ld/emultempl/mmix-elfnmmo.em8
-rw-r--r--ld/emultempl/mmo.em6
-rw-r--r--ld/emultempl/ppc64elf.em45
-rw-r--r--ld/emultempl/sh64elf.em13
-rw-r--r--ld/emultempl/spuelf.em6
-rw-r--r--ld/ldemul.c3
-rw-r--r--ld/ldlang.c90
-rw-r--r--ld/ldlang.h2
18 files changed, 197 insertions, 174 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 554687f..e6897fc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,51 @@
+2009-08-10 Alan Modra <amodra@bigpond.net.au>
+
+ 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.
+
2009-08-06 Michael Eager <eager@eagercon.com>
* Makefile.am: Add eelf32mb_linux.o, eelf32microblaze.o to
diff --git a/ld/emultempl/alphaelf.em b/ld/emultempl/alphaelf.em
index d6766ba..a2f460f 100644
--- a/ld/emultempl/alphaelf.em
+++ b/ld/emultempl/alphaelf.em
@@ -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
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 0713c72..fffffd9 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -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, const void *b)
}
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.
diff --git a/ld/emultempl/avrelf.em b/ld/emultempl/avrelf.em
index 1bd7bb3..9ab5a46 100644
--- a/ld/emultempl/avrelf.em
+++ b/ld/emultempl/avrelf.em
@@ -144,29 +144,24 @@ avr_elf_create_output_section_statements (void)
/* 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
diff --git a/ld/emultempl/elf-generic.em b/ld/emultempl/elf-generic.em
index d286bb8..0f19135 100644
--- a/ld/emultempl/elf-generic.em
+++ b/ld/emultempl/elf-generic.em
@@ -31,21 +31,8 @@ gld${EMULATION_NAME}_map_segments (bfd_boolean need_layout)
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)
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 2d7a88d..cd7f2d4 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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 (asection *s,
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_${EMULATION_NAME}_emulation =
${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},
diff --git a/ld/emultempl/genelf.em b/ld/emultempl/genelf.em
index e6e8841..cfb8f11 100644
--- a/ld/emultempl/genelf.em
+++ b/ld/emultempl/genelf.em
@@ -29,13 +29,6 @@ source_em ${srcdir}/emultempl/elf-generic.em
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
diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em
index 6186cb9..a38fc84 100644
--- a/ld/emultempl/hppaelf.em
+++ b/ld/emultempl/hppaelf.em
@@ -237,14 +237,13 @@ build_section_lists (lang_statement_union_type *statement)
}
-/* 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
diff --git a/ld/emultempl/m68hc1xelf.em b/ld/emultempl/m68hc1xelf.em
index 0c1305b..01d2d83 100644
--- a/ld/emultempl/m68hc1xelf.em
+++ b/ld/emultempl/m68hc1xelf.em
@@ -284,11 +284,10 @@ m68hc11elf_add_stub_section (const char *stub_sec_name,
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
diff --git a/ld/emultempl/m68kelf.em b/ld/emultempl/m68kelf.em
index 441b489..38d8ec5 100644
--- a/ld/emultempl/m68kelf.em
+++ b/ld/emultempl/m68kelf.em
@@ -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
diff --git a/ld/emultempl/mmix-elfnmmo.em b/ld/emultempl/mmix-elfnmmo.em
index 909c3c4..be4a279 100644
--- a/ld/emultempl/mmix-elfnmmo.em
+++ b/ld/emultempl/mmix-elfnmmo.em
@@ -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,
diff --git a/ld/emultempl/mmo.em b/ld/emultempl/mmo.em
index f5ba6dd..9568be3 100644
--- a/ld/emultempl/mmo.em
+++ b/ld/emultempl/mmo.em
@@ -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, asection *sec, void *ptr ATTRIBUTE_UNUSED)
/* 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
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index eff8dff..1518dac 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -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_union_type *statement)
}
-/* 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)
{
diff --git a/ld/emultempl/sh64elf.em b/ld/emultempl/sh64elf.em
index 5c588ce..a2b82f9 100644
--- a/ld/emultempl/sh64elf.em
+++ b/ld/emultempl/sh64elf.em
@@ -244,12 +244,12 @@ sh64_elf_${EMULATION_NAME}_after_allocation (void)
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_allocation (void)
}
}
- /* 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);
diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em
index 1f4fbec..2ea760a 100644
--- a/ld/emultempl/spuelf.em
+++ b/ld/emultempl/spuelf.em
@@ -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)
diff --git a/ld/ldemul.c b/ld/ldemul.c
index 826129d..3436c61 100644
--- a/ld/ldemul.c
+++ b/ld/ldemul.c
@@ -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
diff --git a/ld/ldlang.c b/ld/ldlang.c
index bc03374..a1bd2e3 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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);
+
+ link_info.relax_pass++;
+ }
+ need_layout = TRUE;
+ }
- /* Perform another relax pass - this time we know where the
- globals are, so can make a better guess. */
- lang_size_sections (&relax_again, FALSE);
+ 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. */
diff --git a/ld/ldlang.h b/ld/ldlang.h
index f9a1143..4629883 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -483,6 +483,8 @@ extern lang_output_section_statement_type *lang_enter_output_section_statement
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