From c8a1f2548b56bc210c8bcb067e91de8132f56d67 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 27 May 2009 13:31:24 +0000 Subject: bfd/ * elf32-ppc.c (ppc_elf_relax_section): Work with a partial link. * bout.c (b_out_bfd_relax_section): Reject relocatable links. * elf32-m10300.c (mn10300_elf_relax_section): Likewise. * elf32-avr.c (elf32_avr_relax_section): Likewise. * elf32-frv.c (elf32_avr_relax_section): Likewise. * elf32-xtensa.c (elf_xtensa_relax_section): Likewise. * elf64-mmix.c (mmix_elf_relax_section): Likewise. * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise. * elfxx-sparc.c (_bfd_sparc_elf_relax_section): Likewise. * reloc.c (bfd_generic_relax_section): Likewise. * reloc16.c (bfd_coff_reloc16_relax_section): Likewise. * vms.c (vms_bfd_relax_section): Likewise. ld/ * ldmain.c (main): Don't reject --relax -r. * ld.texinfo (PowerPC ELF32): Document behaviour of relaxing partial links. ld/testsuite/ * ld-powerpc/vxworks-relax-2.s: New. * ld-powerpc/vxworks-relax-2.rd: New. * ld-powerpc/powerpc.exp: Add it. --- bfd/ChangeLog | 16 ++++++++++++ bfd/bout.c | 4 +++ bfd/elf-m10300.c | 4 +++ bfd/elf32-avr.c | 4 +++ bfd/elf32-frv.c | 4 +++ bfd/elf32-ppc.c | 42 ++++++++++++++++++++++++++++-- bfd/elf32-xtensa.c | 4 +++ bfd/elf64-mmix.c | 4 +++ bfd/elfxx-ia64.c | 4 +++ bfd/elfxx-sparc.c | 4 +++ bfd/reloc.c | 4 +++ bfd/reloc16.c | 4 +++ bfd/vms.c | 4 +++ ld/ChangeLog | 6 +++++ ld/ld.texinfo | 5 +++- ld/ldmain.c | 2 -- ld/testsuite/ChangeLog | 6 +++++ ld/testsuite/ld-powerpc/powerpc.exp | 5 ++++ ld/testsuite/ld-powerpc/vxworks-relax-2.rd | 11 ++++++++ ld/testsuite/ld-powerpc/vxworks-relax-2.s | 14 ++++++++++ 20 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-powerpc/vxworks-relax-2.rd create mode 100644 ld/testsuite/ld-powerpc/vxworks-relax-2.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8d2283e..e7f6f3b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2009-05-27 Nathan Sidwell + + * elf32-ppc.c (ppc_elf_relax_section): Work with a partial + link. + * bout.c (b_out_bfd_relax_section): Reject relocatable links. + * elf32-m10300.c (mn10300_elf_relax_section): Likewise. + * elf32-avr.c (elf32_avr_relax_section): Likewise. + * elf32-frv.c (elf32_avr_relax_section): Likewise. + * elf32-xtensa.c (elf_xtensa_relax_section): Likewise. + * elf64-mmix.c (mmix_elf_relax_section): Likewise. + * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise. + * elfxx-sparc.c (_bfd_sparc_elf_relax_section): Likewise. + * reloc.c (bfd_generic_relax_section): Likewise. + * reloc16.c (bfd_coff_reloc16_relax_section): Likewise. + * vms.c (vms_bfd_relax_section): Likewise. + 2009-05-26 H.J. Lu * elf-bfd.h (_bfd_elf_is_ifunc_symbol): New. diff --git a/bfd/bout.c b/bfd/bout.c index f4800d5..485371d 100644 --- a/bfd/bout.c +++ b/bfd/bout.c @@ -1145,6 +1145,10 @@ b_out_bfd_relax_section (bfd *abfd, arelent **reloc_vector = NULL; long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + if (reloc_size < 0) return FALSE; diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index d41906c..d3270c5 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -2073,6 +2073,10 @@ mn10300_elf_relax_section (bfd *abfd, asection *section = sec; bfd_vma align_gap_adjustment; + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + /* Assume nothing changes. */ *again = FALSE; diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 9190db3..1b66123 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1634,6 +1634,10 @@ elf32_avr_relax_section (bfd *abfd, static Elf_Internal_Rela *last_reloc = NULL; struct elf32_avr_link_hash_table *htab; + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + htab = avr_link_hash_table (link_info); if (htab == NULL) return FALSE; diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index 01e15f9..fdf96a5 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -5738,6 +5738,10 @@ elf32_frvfdpic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, { struct _frvfdpic_dynamic_got_plt_info gpinfo; + if (info->relocatable) + (*info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + /* If we return early, we didn't change anything. */ *again = FALSE; diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index e15f88e..dcf33cc 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5661,6 +5661,12 @@ ppc_elf_relax_section (bfd *abfd, || isec->reloc_count == 0) return TRUE; + /* We cannot represent the required PIC relocs in the output, so don't + do anything. The linker doesn't support mixing -shared and -r + anyway. */ + if (link_info->relocatable && link_info->shared) + return TRUE; + trampoff = (isec->size + 3) & (bfd_vma) -4; /* Space for a branch around any trampolines. */ trampoff += 4; @@ -5726,7 +5732,7 @@ ppc_elf_relax_section (bfd *abfd, } isym = isymbuf + ELF32_R_SYM (irel->r_info); if (isym->st_shndx == SHN_UNDEF) - continue; /* We can't do anything with undefined symbols. */ + tsec = bfd_und_section_ptr; else if (isym->st_shndx == SHN_ABS) tsec = bfd_abs_section_ptr; else if (isym->st_shndx == SHN_COMMON) @@ -5779,6 +5785,12 @@ ppc_elf_relax_section (bfd *abfd, tsec = h->root.u.def.section; toff = h->root.u.def.value; } + else if (h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak) + { + tsec = bfd_und_section_ptr; + toff = 0; + } else continue; @@ -5838,7 +5850,12 @@ ppc_elf_relax_section (bfd *abfd, reladdr = isec->output_section->vma + isec->output_offset + roff; /* If the branch is in range, no need to do anything. */ - if (symaddr - reladdr + max_branch_offset < 2 * max_branch_offset) + if (tsec != bfd_und_section_ptr + && (!link_info->relocatable + /* A relocatable link may have sections moved during + final link, so do not presume they remain in range. */ + || tsec->output_section == isec->output_section) + && symaddr - reladdr + max_branch_offset < 2 * max_branch_offset) continue; /* Look for an existing fixup to this address. */ @@ -6048,6 +6065,27 @@ ppc_elf_relax_section (bfd *abfd, free (internal_relocs); *again = changes != 0; + if (!*again && link_info->relocatable) + { + /* Convert the internal relax relocs to external form. */ + for (irel = internal_relocs; irel < irelend; irel++) + if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX32) + { + unsigned long r_symndx = ELF32_R_SYM (irel->r_info); + + /* Rewrite the reloc and convert one of the trailing nop + relocs to describe this relocation. */ + BFD_ASSERT (ELF32_R_TYPE (irelend[-1].r_info) == R_PPC_NONE); + /* The relocs are at the bottom 2 bytes */ + irel[0].r_offset += 2; + memmove (irel + 1, irel, (irelend - irel - 1) * sizeof (*irel)); + irel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA); + irel[1].r_offset += 4; + irel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO); + irel++; + } + } + return TRUE; error_return: diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 0315c2f..09e81ad 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -6638,6 +6638,10 @@ elf_xtensa_relax_section (bfd *abfd, static bfd_boolean relocations_analyzed = FALSE; xtensa_relax_info *relax_info; + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + if (!relocations_analyzed) { /* Do some overall initialization for relaxation. */ diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 4793047..9669fdb 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -2590,6 +2590,10 @@ mmix_elf_relax_section (abfd, sec, link_info, again) /* Assume nothing changes. */ *again = FALSE; + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + /* We don't have to do anything if this section does not have relocs, or if this is not a code section. */ if ((sec->flags & SEC_RELOC) == 0 diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index b6f103a..c7cfbe9 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -786,6 +786,10 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec, one pass. */ *again = FALSE; + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + /* Don't even try to relax for non-ELF outputs. */ if (!is_elf_hash_table (link_info->hash)) return FALSE; diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 6449f3b..9acdfc4 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2453,6 +2453,10 @@ _bfd_sparc_elf_relax_section (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *link_info ATTRIBUTE_UNUSED, bfd_boolean *again) { + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + *again = FALSE; sec_do_relax (section) = 1; return TRUE; diff --git a/bfd/reloc.c b/bfd/reloc.c index 5e10e7e..66fb672 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -5291,6 +5291,10 @@ bfd_generic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *link_info ATTRIBUTE_UNUSED, bfd_boolean *again) { + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + *again = FALSE; return TRUE; } diff --git a/bfd/reloc16.c b/bfd/reloc16.c index b4087cb..85a39ca 100644 --- a/bfd/reloc16.c +++ b/bfd/reloc16.c @@ -157,6 +157,10 @@ bfd_coff_reloc16_relax_section (abfd, input_section, link_info, again) arelent **reloc_vector = NULL; long reloc_count; + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + /* We only do global relaxation once. It is not safe to do it multiple times (see discussion of the "shrinks" array below). */ *again = FALSE; diff --git a/bfd/vms.c b/bfd/vms.c index ac03480..251b95c 100644 --- a/bfd/vms.c +++ b/bfd/vms.c @@ -1914,6 +1914,10 @@ vms_bfd_relax_section (bfd * abfd ATTRIBUTE_UNUSED, struct bfd_link_info *link_info ATTRIBUTE_UNUSED, bfd_boolean *again ATTRIBUTE_UNUSED) { + if (link_info->relocatable) + (*link_info->callbacks->einfo) + (_("%P%F: --relax and -r may not be used together\n")); + #if VMS_DEBUG vms_debug (1, "vms_bfd_relax_section (%p, %s, %p, )\n", abfd, section->name, link_info); diff --git a/ld/ChangeLog b/ld/ChangeLog index b996d65..9c02e69 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2009-05-26 Nathan Sidwell + + * ldmain.c (main): Don't reject --relax -r. + * ld.texinfo (PowerPC ELF32): Document behaviour of relaxing + partial links. + 2009-05-26 Nick Clifton * po/id.po: Updated Indonesian translation. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index fbda265..57286ba 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -6284,7 +6284,10 @@ displacement, which may result in @command{ld} giving @samp{--relax} enables the generation of trampolines that can access the entire 32-bit address space. These trampolines are inserted at section boundaries, so may not themselves be reachable if an input -section exceeds 33M in size. +section exceeds 33M in size. You may combine @samp{-r} and +@samp{--relax} to add trampolines in a partial link. In that case +both branches to undefined symbols and inter-section branches are also +considered potentially out of range, and trampolines inserted. @cindex PowerPC ELF32 options @table @option diff --git a/ld/ldmain.c b/ld/ldmain.c index 7cb4fc9..3b8fed6 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -294,8 +294,6 @@ main (int argc, char **argv) { if (command_line.check_section_addresses < 0) command_line.check_section_addresses = 0; - if (command_line.relax) - einfo (_("%P%F: --relax and -r may not be used together\n")); if (link_info.shared) einfo (_("%P%F: -r and -shared may not be used together\n")); } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 06b10c3..9d54d03 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-05-26 Nathan Sidwell + + * ld-powerpc/vxworks-relax-2.s: New. + * ld-powerpc/vxworks-relax-2.rd: New. + * ld-powerpc/powerpc.exp: Add it. + 2009-05-22 Hans-Peter Nilsson * ld-scripts/rgn-over7.d: Adjust expected message for recent change. diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index 2ed41f2..bc63a46 100644 --- a/ld/testsuite/ld-powerpc/powerpc.exp +++ b/ld/testsuite/ld-powerpc/powerpc.exp @@ -54,6 +54,11 @@ if {[istarget "*-*-vxworks"]} { "-mregnames" {vxworks-relax.s} {{readelf --relocs vxworks-relax.rd}} "vxworks-relax"} + {"VxWorks relocatable relax test" + "-Tvxworks1.ld -r --relax -q" + "-mregnames" {vxworks-relax-2.s} + {{readelf --relocs vxworks-relax-2.rd}} + "vxworks-relax-2"} } run_ld_link_tests $ppcvxtests run_dump_test "vxworks1-static" diff --git a/ld/testsuite/ld-powerpc/vxworks-relax-2.rd b/ld/testsuite/ld-powerpc/vxworks-relax-2.rd new file mode 100644 index 0000000..02eb964 --- /dev/null +++ b/ld/testsuite/ld-powerpc/vxworks-relax-2.rd @@ -0,0 +1,11 @@ + +Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 8 entries: + Offset Info Type Sym.Value Sym. Name \+ Addend +00000016 00000106 R_PPC_ADDR16_HA 00000000 .text \+ 4000034 +0000001a 00000104 R_PPC_ADDR16_LO 00000000 .text \+ 4000034 +00000006 00000106 R_PPC_ADDR16_HA 00000000 .text \+ 4000034 +0000000a 00000104 R_PPC_ADDR16_LO 00000000 .text \+ 4000034 +00000026 00000506 R_PPC_ADDR16_HA 00000000 undefined \+ 0 +0000002a 00000504 R_PPC_ADDR16_LO 00000000 undefined \+ 0 +0400003e 00000606 R_PPC_ADDR16_HA 00000000 _start \+ 0 +04000042 00000604 R_PPC_ADDR16_LO 00000000 _start \+ 0 diff --git a/ld/testsuite/ld-powerpc/vxworks-relax-2.s b/ld/testsuite/ld-powerpc/vxworks-relax-2.s new file mode 100644 index 0000000..4e58124 --- /dev/null +++ b/ld/testsuite/ld-powerpc/vxworks-relax-2.s @@ -0,0 +1,14 @@ + .globl _start +_start: + bl elsewhere + lis 9,elsewhere@ha + la 0,elsewhere@l(9) + bl undefined + + + .section .far,"ax",@progbits +elsewhere: + bl _start + + .section .pad + .space 0x4000000 -- cgit v1.1