2009-05-26 Nathan Sidwell 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. Index: bfd/bout.c =================================================================== RCS file: /cvs/src/src/bfd/bout.c,v retrieving revision 1.32 diff -c -3 -p -r1.32 bout.c *** bfd/bout.c 16 Apr 2009 23:06:58 -0000 1.32 --- bfd/bout.c 27 May 2009 13:17:30 -0000 *************** b_out_bfd_relax_section (bfd *abfd, *** 1145,1150 **** --- 1145,1154 ---- 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; Index: bfd/elf-m10300.c =================================================================== RCS file: /cvs/src/src/bfd/elf-m10300.c,v retrieving revision 1.96 diff -c -3 -p -r1.96 elf-m10300.c *** bfd/elf-m10300.c 25 Nov 2008 13:03:54 -0000 1.96 --- bfd/elf-m10300.c 27 May 2009 13:17:34 -0000 *************** mn10300_elf_relax_section (bfd *abfd, *** 2073,2078 **** --- 2073,2082 ---- 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; Index: bfd/elf32-avr.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-avr.c,v retrieving revision 1.40 diff -c -3 -p -r1.40 elf32-avr.c *** bfd/elf32-avr.c 18 Feb 2009 15:28:56 -0000 1.40 --- bfd/elf32-avr.c 27 May 2009 13:17:35 -0000 *************** elf32_avr_relax_section (bfd *abfd, *** 1634,1639 **** --- 1634,1643 ---- 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; Index: bfd/elf32-frv.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-frv.c,v retrieving revision 1.63 diff -c -3 -p -r1.63 elf32-frv.c *** bfd/elf32-frv.c 30 Jul 2008 04:34:56 -0000 1.63 --- bfd/elf32-frv.c 27 May 2009 13:17:41 -0000 *************** elf32_frvfdpic_relax_section (bfd *abfd *** 5738,5743 **** --- 5738,5747 ---- { 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; Index: bfd/elf32-ppc.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-ppc.c,v retrieving revision 1.253 diff -c -3 -p -r1.253 elf32-ppc.c *** bfd/elf32-ppc.c 21 Mar 2009 02:35:27 -0000 1.253 --- bfd/elf32-ppc.c 27 May 2009 13:17:46 -0000 *************** ppc_elf_relax_section (bfd *abfd, *** 5661,5666 **** --- 5661,5672 ---- || 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; *************** ppc_elf_relax_section (bfd *abfd, *** 5726,5732 **** } isym = isymbuf + ELF32_R_SYM (irel->r_info); if (isym->st_shndx == SHN_UNDEF) ! continue; /* We can't do anything with undefined symbols. */ else if (isym->st_shndx == SHN_ABS) tsec = bfd_abs_section_ptr; else if (isym->st_shndx == SHN_COMMON) --- 5732,5738 ---- } isym = isymbuf + ELF32_R_SYM (irel->r_info); if (isym->st_shndx == SHN_UNDEF) ! tsec = bfd_und_section_ptr; else if (isym->st_shndx == SHN_ABS) tsec = bfd_abs_section_ptr; else if (isym->st_shndx == SHN_COMMON) *************** ppc_elf_relax_section (bfd *abfd, *** 5779,5784 **** --- 5785,5796 ---- 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; *************** ppc_elf_relax_section (bfd *abfd, *** 5838,5844 **** 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) continue; /* Look for an existing fixup to this address. */ --- 5850,5861 ---- reladdr = isec->output_section->vma + isec->output_offset + roff; /* If the branch is in range, no need to do anything. */ ! 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. */ *************** ppc_elf_relax_section (bfd *abfd, *** 6048,6053 **** --- 6065,6091 ---- 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: Index: bfd/elf32-xtensa.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v retrieving revision 1.114 diff -c -3 -p -r1.114 elf32-xtensa.c *** bfd/elf32-xtensa.c 3 Apr 2009 16:06:40 -0000 1.114 --- bfd/elf32-xtensa.c 27 May 2009 13:17:54 -0000 *************** elf_xtensa_relax_section (bfd *abfd, *** 6638,6643 **** --- 6638,6647 ---- 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. */ Index: bfd/elf64-mmix.c =================================================================== RCS file: /cvs/src/src/bfd/elf64-mmix.c,v retrieving revision 1.58 diff -c -3 -p -r1.58 elf64-mmix.c *** bfd/elf64-mmix.c 21 May 2009 14:15:49 -0000 1.58 --- bfd/elf64-mmix.c 27 May 2009 13:17:56 -0000 *************** mmix_elf_relax_section (abfd, sec, link_ *** 2590,2595 **** --- 2590,2599 ---- /* 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 Index: bfd/elfxx-ia64.c =================================================================== RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v retrieving revision 1.209 diff -c -3 -p -r1.209 elfxx-ia64.c *** bfd/elfxx-ia64.c 15 Jan 2009 12:42:52 -0000 1.209 --- bfd/elfxx-ia64.c 27 May 2009 13:18:00 -0000 *************** elfNN_ia64_relax_section (bfd *abfd, ase *** 786,791 **** --- 786,795 ---- 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; Index: bfd/elfxx-sparc.c =================================================================== RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v retrieving revision 1.42 diff -c -3 -p -r1.42 elfxx-sparc.c *** bfd/elfxx-sparc.c 25 Nov 2008 13:03:56 -0000 1.42 --- bfd/elfxx-sparc.c 27 May 2009 13:18:02 -0000 *************** _bfd_sparc_elf_relax_section (bfd *abfd *** 2453,2458 **** --- 2453,2462 ---- 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; Index: bfd/reloc.c =================================================================== RCS file: /cvs/src/src/bfd/reloc.c,v retrieving revision 1.185 diff -c -3 -p -r1.185 reloc.c *** bfd/reloc.c 4 Mar 2009 05:50:49 -0000 1.185 --- bfd/reloc.c 27 May 2009 13:18:06 -0000 *************** bfd_generic_relax_section (bfd *abfd ATT *** 5291,5296 **** --- 5291,5300 ---- 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; } Index: bfd/reloc16.c =================================================================== RCS file: /cvs/src/src/bfd/reloc16.c,v retrieving revision 1.18 diff -c -3 -p -r1.18 reloc16.c *** bfd/reloc16.c 25 Apr 2008 16:02:43 -0000 1.18 --- bfd/reloc16.c 27 May 2009 13:18:06 -0000 *************** bfd_coff_reloc16_relax_section (abfd, in *** 157,162 **** --- 157,166 ---- 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; Index: bfd/vms.c =================================================================== RCS file: /cvs/src/src/bfd/vms.c,v retrieving revision 1.47 diff -c -3 -p -r1.47 vms.c *** bfd/vms.c 16 Apr 2009 23:06:59 -0000 1.47 --- bfd/vms.c 27 May 2009 13:18:07 -0000 *************** vms_bfd_relax_section (bfd * abfd ATTRIB *** 1914,1919 **** --- 1914,1923 ---- 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); Index: ld/ld.texinfo =================================================================== RCS file: /cvs/src/src/ld/ld.texinfo,v retrieving revision 1.245 diff -c -3 -p -r1.245 ld.texinfo *** ld/ld.texinfo 22 May 2009 11:58:44 -0000 1.245 --- ld/ld.texinfo 27 May 2009 13:18:21 -0000 *************** displacement, which may result in @comma *** 6284,6290 **** @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. @cindex PowerPC ELF32 options @table @option --- 6284,6293 ---- @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. 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 Index: ld/ldmain.c =================================================================== RCS file: /cvs/src/src/ld/ldmain.c,v retrieving revision 1.135 diff -c -3 -p -r1.135 ldmain.c *** ld/ldmain.c 6 Apr 2009 00:47:09 -0000 1.135 --- ld/ldmain.c 27 May 2009 13:18:21 -0000 *************** main (int argc, char **argv) *** 294,301 **** { 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")); } --- 294,299 ---- Index: ld/testsuite/ld-powerpc/powerpc.exp =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/powerpc.exp,v retrieving revision 1.25 diff -c -3 -p -r1.25 powerpc.exp *** ld/testsuite/ld-powerpc/powerpc.exp 4 Mar 2009 05:50:50 -0000 1.25 --- ld/testsuite/ld-powerpc/powerpc.exp 27 May 2009 13:18:26 -0000 *************** if {[istarget "*-*-vxworks"]} { *** 54,59 **** --- 54,64 ---- "-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" Index: ld/testsuite/ld-powerpc/vxworks-relax-2.rd =================================================================== RCS file: ld/testsuite/ld-powerpc/vxworks-relax-2.rd diff -N ld/testsuite/ld-powerpc/vxworks-relax-2.rd *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-powerpc/vxworks-relax-2.rd 27 May 2009 13:18:26 -0000 *************** *** 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 Index: ld/testsuite/ld-powerpc/vxworks-relax-2.s =================================================================== RCS file: ld/testsuite/ld-powerpc/vxworks-relax-2.s diff -N ld/testsuite/ld-powerpc/vxworks-relax-2.s *** /dev/null 1 Jan 1970 00:00:00 -0000 --- ld/testsuite/ld-powerpc/vxworks-relax-2.s 27 May 2009 13:18:26 -0000 *************** *** 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