[binutils-gdb] Arm: Fix LSB of GOT for Thumb2 only PLT.

Tamar Christina tnfchris@sourceware.org
Wed Apr 1 09:53:51 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a7618269b727da9cf56727c22cb538ff5f0e4d25

commit a7618269b727da9cf56727c22cb538ff5f0e4d25
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Wed Apr 1 10:47:18 2020 +0100

    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.

Diff:
---
 bfd/ChangeLog                       |  6 ++++++
 bfd/elf32-arm.c                     |  6 ++++++
 ld/ChangeLog                        |  6 ++++++
 ld/testsuite/ld-arm/arm-elf.exp     |  1 +
 ld/testsuite/ld-arm/thumb-plt-got.d | 14 ++++++++++++++
 5 files changed, 33 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1998e227d6d..bea9526d2a1 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 0036ff96e59..02d43a86195 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;
 	    }
 	}
 
diff --git a/ld/ChangeLog b/ld/ChangeLog
index ef4045aeea9..16ffc303488 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 99a313999e7..59e68de800b 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -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
index 00000000000..e65aba9e2f8
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb-plt-got.d
@@ -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 @...............
+


More information about the Binutils-cvs mailing list