From eaeb0a9d5c65fd8dc19878b068e17f90a93a19c2 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 10 Aug 2009 07:50:56 +0000 Subject: [PATCH] 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. --- ld/ChangeLog | 48 +++++++++++++++++++ ld/emultempl/alphaelf.em | 2 +- ld/emultempl/armelf.em | 44 +++++++++--------- ld/emultempl/avrelf.em | 35 ++++++-------- ld/emultempl/elf-generic.em | 17 +------ ld/emultempl/elf32.em | 13 ++---- ld/emultempl/genelf.em | 15 +++--- ld/emultempl/hppaelf.em | 13 ++---- ld/emultempl/m68hc1xelf.em | 9 ++-- ld/emultempl/m68kelf.em | 2 +- ld/emultempl/mmix-elfnmmo.em | 8 ++-- ld/emultempl/mmo.em | 6 +-- ld/emultempl/ppc64elf.em | 45 ++++++++++-------- ld/emultempl/sh64elf.em | 13 ++---- ld/emultempl/spuelf.em | 6 --- ld/ldemul.c | 3 +- ld/ldlang.c | 90 ++++++++++++++++++------------------ ld/ldlang.h | 2 + 18 files changed, 197 insertions(+), 174 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 554687f457e..e6897fc3047 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,51 @@ +2009-08-10 Alan Modra + + 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 * Makefile.am: Add eelf32mb_linux.o, eelf32microblaze.o to diff --git a/ld/emultempl/alphaelf.em b/ld/emultempl/alphaelf.em index d6766ba51ff..a2f460f14ae 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 0713c728d2b..fffffd9ced2 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 1bd7bb3cae4..9ab5a460479 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 d286bb837c6..0f191351de3 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 2d7a88d3bfa..cd7f2d4e38d 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -62,10 +62,9 @@ fragment <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 6186cb97213..a38fc840d50 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 0c1305b62d1..01d2d83aa88 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 441b4897fc8..38d8ec5fa16 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 909c3c46dd2..be4a279b7dd 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 f5ba6dd974c..9568be328b0 100644 --- a/ld/emultempl/mmo.em +++ b/ld/emultempl/mmo.em @@ -35,6 +35,8 @@ fragment <contents != NULL) free (cranges->contents); diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index 1f4fbec66a1..2ea760a7f0b 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 826129d0a15..3436c6100c6 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 bc03374a6dc..a1bd2e3fe93 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 f9a11433539..4629883bcc4 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 -- 2.30.2