From fbbc375958301d22e296eccef0ff31b36c75d9ca Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 6 Apr 2006 18:52:46 +0000 Subject: [PATCH] bfd/ 2006-04-06 H.J. Lu * elfxx-ia64.c (elfNN_ia64_relax_section): Skip unneeded passes with the skip_relax_pass_0 and skip_relax_pass_1 bits in the section structure. include/ 2006-04-06 H.J. Lu * bfdlink.h (bfd_link_info): Replace need_relax_finalize with relax_pass. ld/ 2006-04-06 H.J. Lu * emultempl/ia64elf.em: Set link_info.relax_pass to 2. Remove link_info.need_relax_finalize. * ldlang.c (relax_sections): New. (lang_process): Use. Call relax_sections link_info.relax_pass times. * ldmain.c (main): Set link_info.relax_pass to 1. Remove link_info.need_relax_finalize. --- bfd/ChangeLog | 6 ++++ bfd/elfxx-ia64.c | 48 ++++++++++++++++++----------- include/ChangeLog | 5 +++ include/bfdlink.h | 9 ++++-- ld/ChangeLog | 12 ++++++++ ld/emultempl/ia64elf.em | 2 +- ld/ldlang.c | 68 +++++++++++++++++++++++------------------ ld/ldmain.c | 2 +- 8 files changed, 100 insertions(+), 52 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 97794afeb4b..30fec772e67 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2006-04-06 H.J. Lu + + * elfxx-ia64.c (elfNN_ia64_relax_section): Skip unneeded passes + with the skip_relax_pass_0 and skip_relax_pass_1 bits in the + section structure. + 2006-04-05 Bernd Schmidt * elf32-bfin.c (bfinfdpic_relocs_info_hash): Sprinkle casts to diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 8d3d5d7e53e..6b3257afdf1 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -863,6 +863,12 @@ elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off) bfd_putl64 (t0, hit_addr); bfd_putl64 (t1, hit_addr + 8); } + +/* Rename some of the generic section flags to better document how they + are used here. */ +#define skip_relax_pass_0 need_finalize_relax +#define skip_relax_pass_1 has_gp_reloc + /* These functions do relaxation for IA-64 ELF. */ @@ -891,6 +897,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) bfd_boolean changed_contents = FALSE; bfd_boolean changed_relocs = FALSE; bfd_boolean changed_got = FALSE; + bfd_boolean skip_relax_pass_0 = TRUE; + bfd_boolean skip_relax_pass_1 = TRUE; bfd_vma gp = 0; /* Assume we're not going to change any sizes, and we'll only need @@ -902,11 +910,11 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) return FALSE; /* Nothing to do if there are no relocations or there is no need for - the relax finalize pass. */ + the current pass. */ if ((sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0 - || (!link_info->need_relax_finalize - && sec->need_finalize_relax == 0)) + || (link_info->relax_pass == 0 && sec->skip_relax_pass_0) + || (link_info->relax_pass == 1 && sec->skip_relax_pass_1)) return TRUE; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; @@ -947,20 +955,19 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) case R_IA64_PCREL21BI: case R_IA64_PCREL21M: case R_IA64_PCREL21F: - /* In the finalize pass, all br relaxations are done. We can - skip it. */ - if (!link_info->need_relax_finalize) + /* In pass 1, all br relaxations are done. We can skip it. */ + if (link_info->relax_pass == 1) continue; + skip_relax_pass_0 = FALSE; is_branch = TRUE; break; case R_IA64_PCREL60B: - /* We can't optimize brl to br before the finalize pass since - br relaxations will increase the code size. Defer it to - the finalize pass. */ - if (link_info->need_relax_finalize) + /* We can't optimize brl to br in pass 0 since br relaxations + will increase the code size. Defer it to pass 1. */ + if (link_info->relax_pass == 0) { - sec->need_finalize_relax = 1; + skip_relax_pass_1 = FALSE; continue; } is_branch = TRUE; @@ -968,12 +975,11 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) case R_IA64_LTOFF22X: case R_IA64_LDXMOV: - /* We can't relax ldx/mov before the finalize pass since - br relaxations will increase the code size. Defer it to - the finalize pass. */ - if (link_info->need_relax_finalize) + /* We can't relax ldx/mov in pass 0 since br relaxations will + increase the code size. Defer it to pass 1. */ + if (link_info->relax_pass == 0) { - sec->need_finalize_relax = 1; + skip_relax_pass_1 = FALSE; continue; } is_branch = FALSE; @@ -1363,8 +1369,12 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) } } - if (!link_info->need_relax_finalize) - sec->need_finalize_relax = 0; + if (link_info->relax_pass == 0) + { + /* Pass 0 is only needed to relax br. */ + sec->skip_relax_pass_0 = skip_relax_pass_0; + sec->skip_relax_pass_1 = skip_relax_pass_1; + } *again = changed_contents || changed_relocs; return TRUE; @@ -1380,6 +1390,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again) free (internal_relocs); return FALSE; } +#undef skip_relax_pass_0 +#undef skip_relax_pass_1 static void elfNN_ia64_relax_ldxmov (contents, off) diff --git a/include/ChangeLog b/include/ChangeLog index 4af593fb88c..af4eb6d7586 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2006-04-06 H.J. Lu + + * bfdlink.h (bfd_link_info): Replace need_relax_finalize with + relax_pass. + 2006-03-25 Bernd Schmidt * elf/bfin.h (R_BFIN_GOT17M4, R_BFIN_GOTHI, R_BFIN_GOTLO, diff --git a/include/bfdlink.h b/include/bfdlink.h index 3c978e80bfa..f4b7aa7cfa4 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -301,9 +301,6 @@ struct bfd_link_info /* TRUE if global symbols in discarded sections should be stripped. */ unsigned int strip_discarded: 1; - /* TRUE if the final relax pass is needed. */ - unsigned int need_relax_finalize: 1; - /* TRUE if generating a position independent executable. */ unsigned int pie: 1; @@ -398,6 +395,12 @@ struct bfd_link_info unloaded. */ const char *fini_function; + /* Number of relaxation passes. Usually only one relaxation pass + is needed. But a backend can have as many relaxation passes as + necessary. During bfd_relax_section call, it is set to the + current pass, starting from 0. */ + int relax_pass; + /* Non-zero if auto-import thunks for DATA items in pei386 DLLs should be generated/linked against. Set to 1 if this feature is explicitly requested by the user, -1 if enabled by default. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 300fb6b5ee2..f68e6a334ed 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2006-04-06 H.J. Lu + + * emultempl/ia64elf.em: Set link_info.relax_pass to 2. Remove + link_info.need_relax_finalize. + + * ldlang.c (relax_sections): New. + (lang_process): Use. Call relax_sections link_info.relax_pass + times. + + * ldmain.c (main): Set link_info.relax_pass to 1. Remove + link_info.need_relax_finalize. + 2006-04-05 Alan Modra * Makefile.am (GENSCRIPTS): Pass prefix. diff --git a/ld/emultempl/ia64elf.em b/ld/emultempl/ia64elf.em index d41fa00441a..ddc5370bfd9 100644 --- a/ld/emultempl/ia64elf.em +++ b/ld/emultempl/ia64elf.em @@ -32,7 +32,7 @@ static int itanium = 0; static void gld${EMULATION_NAME}_after_parse (void) { - link_info.need_relax_finalize = TRUE; + link_info.relax_pass = 2; bfd_elf${ELFSIZE}_ia64_after_parse (itanium); } diff --git a/ld/ldlang.c b/ld/ldlang.c index 66219f0bc3f..8d4d9e9572b 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -5411,6 +5411,37 @@ lang_gc_sections (void) bfd_gc_sections (output_bfd, &link_info); } +/* Relax all sections until bfd_relax_section gives up. */ + +static void +relax_sections (void) +{ + /* Keep relaxing until bfd_relax_section gives up. */ + bfd_boolean relax_again; + + do + { + relax_again = FALSE; + + /* 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. */ + lang_size_sections (&relax_again, FALSE); + } + while (relax_again); +} + void lang_process (void) { @@ -5507,38 +5538,17 @@ lang_process (void) /* Now run around and relax if we can. */ if (command_line.relax) { - /* Keep relaxing until bfd_relax_section gives up. */ - bfd_boolean relax_again; + /* We may need more than one relaxation pass. */ + int i = link_info.relax_pass; - do + /* The backend can use it to determine the current pass. */ + link_info.relax_pass = 0; + + while (i--) { - relax_again = FALSE; - - /* 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. */ - lang_size_sections (&relax_again, FALSE); - - /* If the normal relax is done and the relax finalize pass - is not performed yet, we perform another relax pass. */ - if (!relax_again && link_info.need_relax_finalize) - { - link_info.need_relax_finalize = FALSE; - relax_again = TRUE; - } + relax_sections (); + link_info.relax_pass++; } - while (relax_again); /* Final extra sizing to report errors. */ lang_do_assignments (); diff --git a/ld/ldmain.c b/ld/ldmain.c index 3093bdb00c5..db87a40b6aa 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -313,7 +313,7 @@ main (int argc, char **argv) link_info.spare_dynamic_tags = 5; link_info.flags = 0; link_info.flags_1 = 0; - link_info.need_relax_finalize = FALSE; + link_info.relax_pass = 1; link_info.warn_shared_textrel = FALSE; link_info.gc_sections = FALSE;