2009-04-17 Christophe Lyon <christophe.lyon@st.com>
authorChristophe Lyon <christophe.lyon@st.com>
Fri, 17 Apr 2009 13:04:41 +0000 (13:04 +0000)
committerChristophe Lyon <christophe.lyon@st.com>
Fri, 17 Apr 2009 13:04:41 +0000 (13:04 +0000)
bfd/
* elf32-arm.c (elf32_arm_size_stubs): Handle long branches through
PLT entries to an undefined symbol when generating a shared
library.

testsuite/
* ld-arm/arm-elf.exp: Add new test farcall-mixed-lib.
* ld-arm/farcall-mixed-lib.d: Update expected output.
* ld-arm/farcall-mixed-lib1.s: New file.
* ld-arm/farcall-mixed-lib2.s: New file.

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

index 07393676784000a8bb60598e72bff26e572d743d..894c497e97c15a839fae73f2cc6a1ffc111bd871 100644 (file)
@@ -1,3 +1,9 @@
+2009-04-17  Christophe Lyon  <christophe.lyon@st.com>
+
+       * elf32-arm.c (elf32_arm_size_stubs): Handle long branches through
+       PLT entries to an undefined symbol when generating a shared
+       library.
+
 2009-04-17  Nick Clifton  <nickc@redhat.com>
 
        PR 9909
index 99beb9e63cc8c123ff22da7c61ab3ee2fcb728e4..2f49b7ee96801da211893c0ca5e12ecab469ccc3 100644 (file)
@@ -3832,12 +3832,29 @@ elf32_arm_size_stubs (bfd *output_bfd,
                                           + sym_sec->output_offset
                                           + sym_sec->output_section->vma);
                        }
-                     else if (hash->root.root.type == bfd_link_hash_undefweak
-                              || hash->root.root.type == bfd_link_hash_undefined)
-                       /* For a shared library, these will need a PLT stub,
-                          which is treated separately.
-                          For absolute code, they cannot be handled.  */
-                       continue;
+                     else if ((hash->root.root.type == bfd_link_hash_undefined)
+                              || (hash->root.root.type == bfd_link_hash_undefweak))
+                       {
+                         /* For a shared library, use the PLT stub as
+                            target address to decide whether a long
+                            branch stub is needed.
+                            For absolute code, they cannot be handled.  */
+                         struct elf32_arm_link_hash_table *globals =
+                           elf32_arm_hash_table (info);
+
+                         if (globals->splt != NULL && hash != NULL
+                             && hash->root.plt.offset != (bfd_vma) -1)
+                           {
+                             sym_sec = globals->splt;
+                             sym_value = hash->root.plt.offset;
+                             if (sym_sec->output_section != NULL)
+                               destination = (sym_value
+                                              + sym_sec->output_offset
+                                              + sym_sec->output_section->vma);
+                           }
+                         else
+                           continue;
+                       }
                      else
                        {
                          bfd_set_error (bfd_error_bad_value);
index 75b90500268dd139b94a8eb67ae603412acfb35d..175ca0aecc89b4e59aa0ca84c30fa8cd0e6262a4 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-17  Christophe Lyon  <christophe.lyon@st.com>
+
+       * ld-arm/arm-elf.exp: Add new test farcall-mixed-lib.
+       * ld-arm/farcall-mixed-lib.d: Update expected output.
+       * ld-arm/farcall-mixed-lib1.s: New file.
+       * ld-arm/farcall-mixed-lib2.s: New file.
+
 2009-04-16  Richard Sandiford  <r.sandiford@uk.ibm.com>
 
        * ld-powerpc/aix-export-2.s, ld-powerpc/aix-export-2.nd: New test.
index 94002a1aea057fa4470f7455916d6ecfb023a913..b524cceef89274a731bc16e6479610494a7fdae5 100644 (file)
@@ -353,6 +353,12 @@ set armeabitests {
      {{objdump -fdw farcall-mixed-app-v5.d} {objdump -Rw farcall-mixed-app.r}
       {readelf -Ds farcall-mixed-app.sym}}
      "farcall-mixed-app-v5"}
+
+    {"Mixed ARM/Thumb shared library with long branches" "-shared -T arm-lib.ld" ""
+     {farcall-mixed-lib1.s farcall-mixed-lib2.s}
+     {{objdump -fdw farcall-mixed-lib.d}}
+     "farcall-mixed-lib.so"}
+
 }
 
 run_ld_link_tests $armeabitests
index ab498e4f9a393d6b2b966d032050f62b36e794ff..db2243fcab8eb7a425e0d2c928d10a86d3432d84 100644 (file)
@@ -14,24 +14,56 @@ Disassembly of section .plt:
  .*:   e28fc6.*        add     ip, pc, #.*     ; 0x.*
  .*:   e28cca.*        add     ip, ip, #.*     ; 0x.*
  .*:   e5bcf.*         ldr     pc, \[ip, #.*\]!
+ .*:   e28fc6.*        add     ip, pc, #.*     ; 0x.*
+ .*:   e28cca.*        add     ip, ip, #.*     ; 0x.*
+ .*:   e5bcf.*         ldr     pc, \[ip, #.*\]!
 Disassembly of section .text:
 
 .* <lib_func1>:
  .*:   e1a0c00d        mov     ip, sp
  .*:   e92dd800        push    {fp, ip, lr, pc}
  .*:   ebfffff.        bl      .* <lib_func1-0x..?>
+ .*:   ebfffff.        bl      .* <lib_func1-0x..?>
  .*:   e89d6800        ldm     sp, {fp, sp, lr}
  .*:   e12fff1e        bx      lr
- .*:   e1a00000        nop                     \(mov r0,r0\)
- .*:   e1a00000        nop                     \(mov r0,r0\)
- .*:   e1a00000        nop                     \(mov r0,r0\)
+       ...
+ .*:   e1a00000        .word   0xe1a00000
+ .*:   e1a00000        .word   0xe1a00000
 
 .* <lib_func2>:
+ .*:   f000 e80c       blx     100030c <__app_func_from_thumb>
+ .*:   f000 e804       blx     1000300 <__app_func_weak_from_thumb>
  .*:   4770            bx      lr
  .*:   46c0            nop                     \(mov r8, r8\)
  .*:   46c0            nop                     \(mov r8, r8\)
  .*:   46c0            nop                     \(mov r8, r8\)
+
+.* <__app_func_weak_from_thumb>:
+ .*:   e59fc000        ldr     ip, \[pc, #0\]  ; 1000308 <__app_func_weak_from_thumb\+0x8>
+ .*:   e08ff00c        add     pc, pc, ip
+ .*:   feffffb4        .word   0xfeffffb4
+
+.* <__app_func_from_thumb>:
+ .*:   e59fc000        ldr     ip, \[pc, #0\]  ; 1000314 <__app_func_from_thumb\+0x8>
+ .*:   e08ff00c        add     pc, pc, ip
+ .*:   feffff9c        .word   0xfeffff9c
+       ...
+
+.* <lib_func3>:
+ .*:   f000 e80c       blx     200033c <__app_func_from_thumb>
+ .*:   f000 e804       blx     2000330 <__app_func_weak_from_thumb>
+ .*:   4770            bx      lr
  .*:   46c0            nop                     \(mov r8, r8\)
  .*:   46c0            nop                     \(mov r8, r8\)
  .*:   46c0            nop                     \(mov r8, r8\)
- .*:   46c0            nop                     \(mov r8, r8\)
+
+.* <__app_func_weak_from_thumb>:
+ .*:   e59fc000        ldr     ip, \[pc, #0\]  ; 2000338 <__app_func_weak_from_thumb\+0x8>
+ .*:   e08ff00c        add     pc, pc, ip
+ .*:   fdffff84        .word   0xfdffff84
+
+.* <__app_func_from_thumb>:
+ .*:   e59fc000        ldr     ip, \[pc, #0\]  ; 2000344 <__app_func_from_thumb\+0x8>
+ .*:   e08ff00c        add     pc, pc, ip
+ .*:   fdffff6c        .word   0xfdffff6c
+       ...
diff --git a/ld/testsuite/ld-arm/farcall-mixed-lib1.s b/ld/testsuite/ld-arm/farcall-mixed-lib1.s
new file mode 100644 (file)
index 0000000..a64c0bb
--- /dev/null
@@ -0,0 +1,31 @@
+@ Create a large shared library so that calls through PLT to an undef
+@ symbol require insertion of a long branch stub.
+@ Check also calls to an undef weak symbol.
+
+       .text
+       .arch armv5t
+
+       .p2align 4
+       .globl lib_func1
+       .type lib_func1, %function
+lib_func1:
+       mov     ip, sp
+       stmdb   sp!, {r11, ip, lr, pc}
+       bl      app_func
+       .weak   app_func_weak
+       bl      app_func_weak
+       ldmia   sp, {r11, sp, lr}
+       bx lr
+       .size lib_func1, . - lib_func1
+
+       .space 0x1000000
+       .p2align 4
+       .globl lib_func2
+       .type lib_func2, %function
+       .thumb_func
+       .code 16
+lib_func2:
+       bl      app_func
+       bl      app_func_weak
+       bx lr
+       .size lib_func2, . - lib_func2
diff --git a/ld/testsuite/ld-arm/farcall-mixed-lib2.s b/ld/testsuite/ld-arm/farcall-mixed-lib2.s
new file mode 100644 (file)
index 0000000..cd5a71f
--- /dev/null
@@ -0,0 +1,19 @@
+@ Create a large shared library so that calls through PLT to an undef
+@ symbol require insertion of a long branch stub.
+@ Check also calls to an undef weak symbol.
+
+       .text
+       .arch armv5t
+
+       .space 0x1000000
+       .p2align 4
+       .globl lib_func3
+       .type lib_func3, %function
+       .thumb_func
+       .code 16
+lib_func3:
+       bl      app_func
+       .weak   app_func_weak
+       bl      app_func_weak
+       bx lr
+       .size lib_func3, . - lib_func3