[ARM] PR ld/20608 Relocation truncated to fit: R_ARM_THM_JUMP24 for relocation to...
authorChristophe Lyon <christophe.lyon@linaro.org>
Tue, 27 Sep 2016 23:37:52 +0000 (01:37 +0200)
committerChristophe Lyon <christophe.lyon@linaro.org>
Tue, 27 Sep 2016 23:41:00 +0000 (01:41 +0200)
2016-09-28  Christophe Lyon  <christophe.lyon@linaro.org>

PR ld/20608
bfd/
* elf32-arm.c (arm_type_of_stub): Handle the case when the pre-PLT
Thumb-ARM stub is too far.

ld
* testsuite/ld-arm/arm-elf.exp: Handle new testcase.
* testsuite/ld-arm/farcall-mixed-app2.d: New file.
* testsuite/ld-arm/farcall-mixed-app2.r: Likewise.
* testsuite/ld-arm/farcall-mixed-app2.s: Likewise.
* testsuite/ld-arm/farcall-mixed-app2.sym: Likewise.

bfd/ChangeLog
bfd/elf32-arm.c
ld/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/farcall-mixed-app2.d [new file with mode: 0644]
ld/testsuite/ld-arm/farcall-mixed-app2.r [new file with mode: 0644]
ld/testsuite/ld-arm/farcall-mixed-app2.s [new file with mode: 0644]
ld/testsuite/ld-arm/farcall-mixed-app2.sym [new file with mode: 0644]

index f332490..03acf6f 100644 (file)
@@ -1,3 +1,9 @@
+2016-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
+
+       PR ld/20608
+       * elf32-arm.c (arm_type_of_stub): Handle the case when the pre-PLT
+       Thumb-ARM stub is too far.
+
 2016-09-27  Nick Clifton  <nickc@redhat.com>
 
        PR ld/20634
index c58b65d..2386a8c 100644 (file)
@@ -3945,17 +3945,43 @@ arm_type_of_stub (struct bfd_link_info *info,
          /* Note when dealing with PLT entries: the main PLT stub is in
             ARM mode, so if the branch is in Thumb mode, another
             Thumb->ARM stub will be inserted later just before the ARM
-            PLT stub. We don't take this extra distance into account
-            here, because if a long branch stub is needed, we'll add a
-            Thumb->Arm one and branch directly to the ARM PLT entry
-            because it avoids spreading offset corrections in several
-            places.  */
+            PLT stub. If a long branch stub is needed, we'll add a
+            Thumb->Arm one and branch directly to the ARM PLT entry.
+            Here, we have to check if a pre-PLT Thumb->ARM stub
+            is needed and if it will be close enough.  */
 
          destination = (splt->output_section->vma
                         + splt->output_offset
                         + root_plt->offset);
          st_type = STT_FUNC;
-         branch_type = ST_BRANCH_TO_ARM;
+
+         /* Thumb branch/call to PLT: it can become a branch to ARM
+            or to Thumb. We must perform the same checks and
+            corrections as in elf32_arm_final_link_relocate.  */
+         if ((r_type == R_ARM_THM_CALL)
+             || (r_type == R_ARM_THM_JUMP24))
+           {
+             if (globals->use_blx
+                 && r_type == R_ARM_THM_CALL
+                 && !thumb_only)
+               {
+                 /* If the Thumb BLX instruction is available, convert
+                    the BL to a BLX instruction to call the ARM-mode
+                    PLT entry.  */
+                 branch_type = ST_BRANCH_TO_ARM;
+               }
+             else
+               {
+                 if (!thumb_only)
+                   /* Target the Thumb stub before the ARM PLT entry.  */
+                   destination -= PLT_THUMB_STUB_SIZE;
+                 branch_type = ST_BRANCH_TO_THUMB;
+               }
+           }
+         else
+           {
+             branch_type = ST_BRANCH_TO_ARM;
+           }
        }
     }
   /* Calls to STT_GNU_IFUNC symbols should go through a PLT.  */
@@ -3991,6 +4017,15 @@ arm_type_of_stub (struct bfd_link_info *info,
                   || (r_type == R_ARM_THM_JUMP19))
              && !use_plt))
        {
+         /* If we need to insert a Thumb-Thumb long branch stub to a
+            PLT, use one that branches directly to the ARM PLT
+            stub. If we pretended we'd use the pre-PLT Thumb->ARM
+            stub, undo this now.  */
+         if ((branch_type == ST_BRANCH_TO_THUMB) && use_plt && !thumb_only) {
+           branch_type = ST_BRANCH_TO_ARM;
+           branch_offset += PLT_THUMB_STUB_SIZE;
+         }
+
          if (branch_type == ST_BRANCH_TO_THUMB)
            {
              /* Thumb to thumb.  */
index 1a443bc..988cb65 100644 (file)
@@ -1,3 +1,12 @@
+2016-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
+
+       PR ld/20608
+       * testsuite/ld-arm/arm-elf.exp: Handle new testcase.
+       * testsuite/ld-arm/farcall-mixed-app2.d: New file.
+       * testsuite/ld-arm/farcall-mixed-app2.r: Likewise.
+       * testsuite/ld-arm/farcall-mixed-app2.s: Likewise.
+       * testsuite/ld-arm/farcall-mixed-app2.sym: Likewise.
+
 2016-09-26  Vlad Zakharov  <vzakhar@synopsys.com>
 
        * Makefile.in: Regenerate.
index 24d0b4c..02a35f4 100644 (file)
@@ -559,6 +559,12 @@ set armeabitests_nonacl {
       {readelf -Ds farcall-mixed-app.sym}}
      "farcall-mixed-app-v5"}
 
+    {"Mixed ARM/Thumb2 dynamic application with farcalls" "tmpdir/mixed-lib.so -T arm-dyn.ld --section-start .mid_thumb=0x10081c0 --section-start .far_arm=0x2100000 --section-start .far_thumb=0x2200000" "" ""
+     {farcall-mixed-app2.s}
+     {{objdump -fdw farcall-mixed-app2.d} {objdump -Rw farcall-mixed-app2.r}
+      {readelf -Ds farcall-mixed-app2.sym}}
+     "farcall-mixed-app2"}
+
     {"Mixed ARM/Thumb shared library with long branches (v4t)" "-shared -T arm-lib.ld" "" "-march=armv4t"
      {farcall-mixed-lib1.s farcall-mixed-lib2.s}
      {{objdump -fdw farcall-mixed-lib-v4t.d}}
diff --git a/ld/testsuite/ld-arm/farcall-mixed-app2.d b/ld/testsuite/ld-arm/farcall-mixed-app2.d
new file mode 100644 (file)
index 0000000..54338d0
--- /dev/null
@@ -0,0 +1,99 @@
+
+tmpdir/farcall-mixed-app2:     file format elf32-(little|big)arm
+architecture: arm.*, flags 0x00000112:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <lib_func2@plt-0x14>:
+ .*:   e52de004        push    {lr}            ; \(str lr, \[sp, #-4\]!\)
+ .*:   e59fe004        ldr     lr, \[pc, #4\]  ; .* <lib_func2@plt-0x4>
+ .*:   e08fe00e        add     lr, pc, lr
+ .*:   e5bef008        ldr     pc, \[lr, #8\]!
+ .*:   .*
+.* <lib_func2@plt>:
+ .*:   4778            bx      pc
+ .*:   46c0            nop                     ; \(mov r8, r8\)
+ .*:   e28fc6.*        add     ip, pc, #.*
+ .*:   e28cca.*        add     ip, ip, #.*     ; 0x.*
+ .*:   e5bcf.*         ldr     pc, \[ip, #.*\]!.*
+.* <lib_func1@plt>:
+ .*:   e28fc6.*        add     ip, pc, #.*
+ .*:   e28cca.*        add     ip, ip, #.*     ; 0x.*
+ .*:   e5bcf.*         ldr     pc, \[ip, #.*\]!.*
+
+Disassembly of section .text:
+
+.* <_start>:
+ .*:   e1a0c00d        mov     ip, sp
+ .*:   e92dd800        push    {fp, ip, lr, pc}
+ .*:   eb000008        bl      .* <__app_func_veneer>
+ .*:   ebfffff6        bl      .* <lib_func1@plt>
+ .*:   ebfffff2        bl      .* <lib_func2@plt\+0x4>
+ .*:   e89d6800        ldm     sp, {fp, sp, lr}
+ .*:   e12fff1e        bx      lr
+ .*:   e1a00000        nop                     ; \(mov r0, r0\)
+
+.* <app_tfunc_close>:
+ .*:   b500            push    {lr}
+ .*:   f7ff efde       blx     81e0 <lib_func2@plt\+0x4>
+ .*:   bd00            pop     {pc}
+ .*:   4770            bx      lr
+ .*:   46c0            nop                     ; \(mov r8, r8\)
+#...
+
+.* <__app_func_veneer>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; 8234 <__app_func_veneer\+0x4>
+ .*:   02100000        .word   0x02100000
+
+Disassembly of section .mid_thumb:
+
+.* <mid_tfunc>:
+#...
+ .*:   f400 9000       b.w     .* <lib_func2@plt>
+ .*:   f000 b800       b.w     .* <__lib_func2_from_thumb>
+
+.* <__lib_func2_from_thumb>:
+ .*:   4778            bx      pc
+ .*:   46c0            nop                     ; \(mov r8, r8\)
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; 10081e8 <__lib_func2_from_thumb\+0x8>
+ .*:   000081e0        .word   0x000081e0
+ .*:   00000000        .word   0x00000000
+
+Disassembly of section .far_arm:
+
+.* <app_func>:
+ .*:   e1a0c00d        mov     ip, sp
+ .*:   e92dd800        push    {fp, ip, lr, pc}
+ .*:   eb000006        bl      .* <__lib_func1_veneer>
+ .*:   eb000007        bl      .* <__lib_func2_veneer>
+ .*:   e89d6800        ldm     sp, {fp, sp, lr}
+ .*:   e12fff1e        bx      lr
+ .*:   e1a00000        nop                     ; \(mov r0, r0\)
+ .*:   e1a00000        nop                     ; \(mov r0, r0\)
+
+.* <app_func2>:
+ .*:   e12fff1e        bx      lr
+#...
+
+.* <__lib_func1_veneer>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func1_veneer\+0x4>
+ .*:   000081ec        .word   0x000081ec
+.* <__lib_func2_veneer>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func2_veneer\+0x4>
+ .*:   000081e0        .word   0x000081e0
+
+Disassembly of section .far_thumb:
+
+.* <app_tfunc>:
+ .*:   b500            push    {lr}
+ .*:   f000 e806       blx     .* <__lib_func2_from_thumb>
+ .*:   bd00            pop     {pc}
+ .*:   4770            bx      lr
+ .*:   46c0            nop                     ; \(mov r8, r8\)
+#...
+
+.* <__lib_func2_from_thumb>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; 2200014 <__lib_func2_from_thumb\+0x4>
+ .*:   000081e0        .word   0x000081e0
diff --git a/ld/testsuite/ld-arm/farcall-mixed-app2.r b/ld/testsuite/ld-arm/farcall-mixed-app2.r
new file mode 100644 (file)
index 0000000..910a361
--- /dev/null
@@ -0,0 +1,10 @@
+
+tmpdir/farcall-mixed-app.*:     file format elf32-(little|big)arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+.* R_ARM_COPY        data_obj
+.* R_ARM_JUMP_SLOT   lib_func2
+.* R_ARM_JUMP_SLOT   lib_func1
+
+
diff --git a/ld/testsuite/ld-arm/farcall-mixed-app2.s b/ld/testsuite/ld-arm/farcall-mixed-app2.s
new file mode 100644 (file)
index 0000000..ee315e9
--- /dev/null
@@ -0,0 +1,76 @@
+       .text
+       .p2align 4
+       .globl _start
+_start:
+       mov     ip, sp
+       stmdb   sp!, {r11, ip, lr, pc}
+       bl      app_func
+       bl      lib_func1
+       bl      lib_func2
+       ldmia   sp, {r11, sp, lr}
+       bx lr
+
+       .p2align 4
+       .globl app_tfunc_close
+       .type app_tfunc_close,%function
+       .thumb_func
+       .code 16
+app_tfunc_close:
+       push    {lr}
+       bl      lib_func2
+       pop     {pc}
+       bx      lr
+
+@ We will place the section .mid_thumb at 0xFFFEF8.
+@ Just far enough for XXXX
+       .section .mid_thumb, "xa"
+
+       .p2align 4
+       .globl mid_tfunc
+       .type mid_tfunc,%function
+       .thumb_func
+       .code 16
+mid_tfunc:
+       .syntax unified
+       .space 24
+       b.w     lib_func2
+       b.w     lib_func2
+
+@ We will place the section .far_arm at 0x2100000.
+       .section .far_arm, "xa"
+
+       .arm
+       .p2align 4
+       .globl app_func
+       .type app_func,%function
+app_func:
+       mov     ip, sp
+       stmdb   sp!, {r11, ip, lr, pc}
+       bl      lib_func1
+       bl      lib_func2
+       ldmia   sp, {r11, sp, lr}
+       bx lr
+
+       .arm
+       .p2align 4
+       .globl app_func2
+       .type app_func2,%function
+app_func2:
+       bx      lr
+
+@ We will place the section .far_thumb at 0x2200000.
+       .section .far_thumb, "xa"
+
+       .p2align 4
+       .globl app_tfunc
+       .type app_tfunc,%function
+       .thumb_func
+       .code 16
+app_tfunc:
+       push    {lr}
+       bl      lib_func2
+       pop     {pc}
+       bx      lr
+
+       .data
+       .long data_obj
diff --git a/ld/testsuite/ld-arm/farcall-mixed-app2.sym b/ld/testsuite/ld-arm/farcall-mixed-app2.sym
new file mode 100644 (file)
index 0000000..1d3bd1d
--- /dev/null
@@ -0,0 +1,15 @@
+
+Symbol table for image:
+ +Num +Buc: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +11 _edata
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 __bss_start__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 _end
+ +.. +..: ........ +4 +OBJECT +GLOBAL +DEFAULT +12 data_obj
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 __bss_end__
+ +.. +..: 0*[^0]*.* +0 +FUNC +GLOBAL +DEFAULT +UND lib_func1
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +11 __data_start
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 __end__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 __bss_start
+ +.. +..: .......0 +0 +FUNC +GLOBAL +DEFAULT +15 app_func2
+ +.. +..: 0*[^0]*.* +0 +FUNC +GLOBAL +DEFAULT +UND lib_func2
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 _bss_end__