ppc476 linker workaround shared lib fixes
When building a shared lib from non-PIC objects, we'll get dynamic text relocations. These need to move with any insns we move. Otherwise the dynamic reloc will modify the branch, resulting in crashes and other unpleasant behaviour. Also, ld -r --ppc476-workaround used with sufficiently aligned PIC objects needs a fix for emitted REL16 relocs. bfd/ * elf64-ppc.c (ppc_elf_relocate_section): Move dynamic text relocs with insns moved by --ppc476-workaround. Correct output of REL16 relocs. ld/testsuite/ * ld-powerpc/ppc476-shared.s, * ld-powerpc/ppc476-shared.lnk, * ld-powerpc/ppc476-shared.d, * ld-powerpc/ppc476-shared2.d: New tests. * ld-powerpc/powerpc.exp: Run them.
This commit is contained in:
parent
bdd2d2b7e6
commit
f8b447819b
@ -1,3 +1,9 @@
|
||||
2015-06-05 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf64-ppc.c (ppc_elf_relocate_section): Move dynamic text
|
||||
relocs with insns moved by --ppc476-workaround. Correct
|
||||
output of REL16 relocs.
|
||||
|
||||
2015-06-01 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* elfnn-aarch64.c (aarch64_reloc_got_type): Support
|
||||
|
@ -9608,6 +9608,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
&& rel->r_offset >= offset
|
||||
&& rel->r_offset < offset + 4)
|
||||
{
|
||||
asection *sreloc;
|
||||
|
||||
/* If the insn we are patching had a reloc, adjust the
|
||||
reloc r_offset so that the reloc applies to the moved
|
||||
location. This matters for -r and --emit-relocs. */
|
||||
@ -9620,6 +9622,56 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
relend[-1] = tmp;
|
||||
}
|
||||
relend[-1].r_offset += patch_off - offset;
|
||||
|
||||
/* Adjust REL16 addends too. */
|
||||
switch (ELF32_R_TYPE (relend[-1].r_info))
|
||||
{
|
||||
case R_PPC_REL16:
|
||||
case R_PPC_REL16_LO:
|
||||
case R_PPC_REL16_HI:
|
||||
case R_PPC_REL16_HA:
|
||||
relend[-1].r_addend += patch_off - offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we are building a PIE or shared library with
|
||||
non-PIC objects, perhaps we had a dynamic reloc too?
|
||||
If so, the dynamic reloc must move with the insn. */
|
||||
sreloc = elf_section_data (input_section)->sreloc;
|
||||
if (sreloc != NULL)
|
||||
{
|
||||
bfd_byte *slo, *shi, *srelend;
|
||||
bfd_vma soffset;
|
||||
|
||||
slo = sreloc->contents;
|
||||
shi = srelend
|
||||
= slo + sreloc->reloc_count * sizeof (Elf32_External_Rela);
|
||||
soffset = (offset + input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
while (slo < shi)
|
||||
{
|
||||
bfd_byte *srel = slo + (shi - slo) / 2;
|
||||
bfd_elf32_swap_reloca_in (output_bfd, srel, &outrel);
|
||||
if (outrel.r_offset < soffset)
|
||||
slo = srel + 1;
|
||||
else if (outrel.r_offset > soffset + 3)
|
||||
shi = srel;
|
||||
else
|
||||
{
|
||||
bfd_byte *nextr = srel + sizeof (Elf32_External_Rela);
|
||||
if (nextr != srelend)
|
||||
{
|
||||
memmove (srel, nextr, srelend - nextr);
|
||||
srel = srelend - sizeof (Elf32_External_Rela);
|
||||
}
|
||||
outrel.r_offset += patch_off - offset;
|
||||
bfd_elf32_swap_reloca_out (output_bfd, &outrel, srel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rel = NULL;
|
||||
|
@ -1,3 +1,11 @@
|
||||
2015-06-05 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ld-powerpc/ppc476-shared.s,
|
||||
* ld-powerpc/ppc476-shared.lnk,
|
||||
* ld-powerpc/ppc476-shared.d,
|
||||
* ld-powerpc/ppc476-shared2.d: New tests.
|
||||
* ld-powerpc/powerpc.exp: Run them.
|
||||
|
||||
2015-06-02 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* ld-aarch64/emit-relocs-313.s: Use gotpage_lo15.
|
||||
|
@ -325,3 +325,6 @@ run_dump_test "attr-gnu-12-11"
|
||||
run_dump_test "attr-gnu-12-21"
|
||||
|
||||
run_dump_test "vle-multiseg-6"
|
||||
|
||||
run_dump_test "ppc476-shared"
|
||||
run_dump_test "ppc476-shared2"
|
||||
|
30
ld/testsuite/ld-powerpc/ppc476-shared.d
Normal file
30
ld/testsuite/ld-powerpc/ppc476-shared.d
Normal file
@ -0,0 +1,30 @@
|
||||
#source: ppc476-shared.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -q -shared --ppc476-workaround -T ppc476-shared.lnk
|
||||
#objdump: -dr
|
||||
#target: powerpc*-*-*
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+fffc <\.text>:
|
||||
fffc: (48 01 00 04|04 00 01 48) b 20000 .*
|
||||
10000: (38 63 00 00|00 00 63 38) addi r3,r3,0
|
||||
1000[02]: R_PPC_ADDR16_LO .bss
|
||||
\.\.\.
|
||||
1fff0: (42 9f 00 05|05 00 9f 42) bcl .*
|
||||
1fff4: (7d 28 02 a6|a6 02 28 7d) mflr r9
|
||||
1fff8: (3d 29 00 00|00 00 29 3d) addis r9,r9,0
|
||||
1fff[8a]: R_PPC_REL16_HA .bss\+0x[46]
|
||||
1fffc: (48 00 00 14|14 00 00 48) b 20010 .*
|
||||
20000: (3c 60 00 00|00 00 60 3c) lis r3,0
|
||||
2000[02]: R_PPC_ADDR16_HA .bss
|
||||
20004: (4b fe ff fc|fc ff fe 4b) b 10000 .*
|
||||
20008: (48 00 00 02|02 00 00 48) ba 0 .*
|
||||
2000c: (48 00 00 02|02 00 00 48) ba 0 .*
|
||||
20010: (39 29 01 00|00 01 29 39) addi r9,r9,256
|
||||
2001[02]: R_PPC_REL16_LO .bss\+0x1[ce]
|
||||
20014: (4b ff ff ec|ec ff ff 4b) b 20000 .*
|
||||
20018: (48 00 00 02|02 00 00 48) ba 0 .*
|
||||
2001c: (48 00 00 02|02 00 00 48) ba 0 .*
|
6
ld/testsuite/ld-powerpc/ppc476-shared.lnk
Normal file
6
ld/testsuite/ld-powerpc/ppc476-shared.lnk
Normal file
@ -0,0 +1,6 @@
|
||||
SECTIONS
|
||||
{
|
||||
. = 0xfffc;
|
||||
.text : { *(.text) }
|
||||
.bss : { *(.bss) }
|
||||
}
|
13
ld/testsuite/ld-powerpc/ppc476-shared.s
Normal file
13
ld/testsuite/ld-powerpc/ppc476-shared.s
Normal file
@ -0,0 +1,13 @@
|
||||
.text
|
||||
lis 3,x@ha
|
||||
addi 3,3,x@l
|
||||
|
||||
.org 0xfff4
|
||||
bcl 20,31,.+4
|
||||
0:
|
||||
mflr 9
|
||||
addis 9,9,x-0b@ha
|
||||
addi 9,9,x-0b@l
|
||||
|
||||
.section .bss,"aw",@nobits
|
||||
x: .space 4
|
12
ld/testsuite/ld-powerpc/ppc476-shared2.d
Normal file
12
ld/testsuite/ld-powerpc/ppc476-shared2.d
Normal file
@ -0,0 +1,12 @@
|
||||
#source: ppc476-shared.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -shared --ppc476-workaround -T ppc476-shared.lnk
|
||||
#objdump: -R
|
||||
#target: powerpc*-*-*
|
||||
|
||||
.*: file format .*
|
||||
|
||||
DYNAMIC RELOCATION RECORDS
|
||||
OFFSET TYPE VALUE
|
||||
0001000[02] R_PPC_ADDR16_LO \.text\+0x000200f4
|
||||
0002000[02] R_PPC_ADDR16_HA \.text\+0x000200f4
|
Loading…
Reference in New Issue
Block a user