Arm: Fix LSB of GOT for Thumb2 only PLT.
authorTamar Christina <tamar.christina@arm.com>
Wed, 1 Apr 2020 09:47:18 +0000 (10:47 +0100)
committerTamar Christina <tamar.christina@arm.com>
Wed, 1 Apr 2020 09:52:33 +0000 (10:52 +0100)
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.

bfd/ChangeLog
bfd/elf32-arm.c
ld/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/thumb-plt-got.d [new file with mode: 0644]

index 1998e227d6da2cd9e1eb6210e029e42b839e711b..bea9526d2a1201db1977cfeaa9a7640d6b214637 100644 (file)
@@ -1,3 +1,9 @@
+2020-04-01  Tamar Christina  <tamar.christina@arm.com>
+
+       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.
+
 2020-04-01  Tamar Christina  <tamar.christina@arm.com>
 
        * elf32-arm.c (elf32_thumb2_plt_entry): Fix PC-rel offset.
index 0036ff96e593456e602c47775f1695fc0e629ea7..02d43a86195bd527fec24c845c2e925bc5a45346 100644 (file)
@@ -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;
            }
        }
 
index ef4045aeea9916c103f8cd2fcd0f6bf4aa79393b..16ffc3034885e6313e2594e29a1af1bc1ff8f4b0 100644 (file)
@@ -1,3 +1,9 @@
+2020-04-01  Tamar Christina  <tamar.christina@arm.com>
+
+       PR ld/16017
+       * testsuite/ld-arm/arm-elf.exp (thumb-plt-got): New.
+       * testsuite/ld-arm/thumb-plt-got.d: New test.
+
 2020-04-01  Tamar Christina  <tamar.christina@arm.com>
 
        * testsuite/ld-arm/arm-elf.exp (thumb-plt): New.
index 99a313999e7327fbeb0c344af4a66d2ee73771b6..59e68de800bdcd53b51fd44b28972e53f7f141c8 100644 (file)
@@ -1270,3 +1270,4 @@ run_dump_test "non-contiguous-arm5"
 run_dump_test "non-contiguous-arm6"
 
 run_dump_test "thumb-plt"
+run_dump_test "thumb-plt-got"
diff --git a/ld/testsuite/ld-arm/thumb-plt-got.d b/ld/testsuite/ld-arm/thumb-plt-got.d
new file mode 100644 (file)
index 0000000..e65aba9
--- /dev/null
@@ -0,0 +1,14 @@
+#source: thumb-plt.s
+#name: Thumb only PLT and GOT LSB Symbol
+#ld: -shared -e0
+#readelf: -rx .got
+#skip: *-*-pe *-*-wince *-*-vxworks armeb-*-* *-*-gnueabihf
+
+Relocation section '.rel.plt' at offset 0x108 contains 1 entry:
+ Offset     Info    Type            Sym.Value  Sym. Name
+000101c4  00000116 R_ARM_JUMP_SLOT   00000000   foo
+
+Hex dump of section '.got':
+ NOTE: This section has relocations against it, but these have NOT been applied to this dump.
+  0x000101b8 40010100 00000000 00000000 11010000 @...............
+