diff options
author | Tamar Christina <tamar.christina@arm.com> | 2020-04-01 10:47:18 +0100 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2020-04-01 10:52:33 +0100 |
commit | a7618269b727da9cf56727c22cb538ff5f0e4d25 (patch) | |
tree | 87615d7d18619600f5bfc60c2b3c924ac0ccdb76 /bfd/elf32-arm.c | |
parent | 15ccbdd717530f81f545a716f0df1de62aee1157 (diff) | |
download | gdb-a7618269b727da9cf56727c22cb538ff5f0e4d25.zip gdb-a7618269b727da9cf56727c22cb538ff5f0e4d25.tar.gz gdb-a7618269b727da9cf56727c22cb538ff5f0e4d25.tar.bz2 |
Arm: Fix LSB of GOT for Thumb2 only PLT.
When you have a Thumb only PLT then the address in the GOT for PLT0 needs to
have the Thumb bit set since the instruction used in PLTn to get there is
`ldr.w pc` which is an inter-working instruction:
the PLT sequence in question is
00000120 <foo@plt>:
120: f240 0c98 movw ip, #152 ; 0x98
124: f2c0 0c01 movt ip, #1
128: 44fc add ip, pc
12a: f8dc f000 ldr.w pc, [ip]
12e: e7fc b.n 12a <foo@plt+0xa>
Disassembly of section .text:
00000130 <bar>:
130: b580 push {r7, lr}
132: af00 add r7, sp, #0
134: f7ff fff4 bl 120 <foo@plt>
and previously the linker would generate
Hex dump of section '.got':
...
0x000101b8 40010100 00000000 00000000 10010000 @...............
Which would make it jump and transition out of thumb mode and crash since you
only have thumb mode on such cores.
Now it correctly generates
Hex dump of section '.got':
...
0x000101b8 40010100 00000000 00000000 11010000 @...............
Thanks to Amol for testing patch and to rgujju for reporting it.
bfd/ChangeLog:
PR ld/16017
* elf32-arm.c (elf32_arm_populate_plt_entry): Set LSB of the PLT0
address in the GOT if in thumb only mode.
ld/ChangeLog:
PR ld/16017
* testsuite/ld-arm/arm-elf.exp (thumb-plt-got): New.
* testsuite/ld-arm/thumb-plt-got.d: New test.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r-- | bfd/elf32-arm.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 0036ff9..02d43a8 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -10001,6 +10001,12 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, rel.r_info = ELF32_R_INFO (dynindx, R_ARM_JUMP_SLOT); initial_got_entry = (splt->output_section->vma + splt->output_offset); + + /* PR ld/16017 + When thumb only we need to set the LSB for any address that + will be used with an interworking branch instruction. */ + if (using_thumb_only (htab)) + initial_got_entry |= 1; } } |