This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
relaxing partial links
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sources dot redhat dot com>
- Date: Tue, 26 May 2009 15:53:40 +0100
- Subject: relaxing partial links
This patch allows partial links to be relaxed on PPC. This is a useful feature
on vxworks, where kernel modules are partially linked object files, and may be
loaded at addresses far away from the targets of branches. Furthermore the
sections within such a kernel module can be arbitrarily placed at load time.
tested on powerpc-vxworks, ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
2009-05-26 Nathan Sidwell <nathan@codesourcery.com>
bfd/
* elf32-ppc.c (ppc_elf_relax_section): Work with a partial
link.
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/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 26 May 2009 14:49:40 -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: 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 26 May 2009 14:49:53 -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 26 May 2009 14:49:54 -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 26 May 2009 14:49:57 -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 26 May 2009 14:49:58 -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 26 May 2009 14:49:58 -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