2009-02-26 Christophe Lyon <christophe.lyon@st.com>
authorChristophe Lyon <christophe.lyon@st.com>
Thu, 26 Feb 2009 15:37:53 +0000 (15:37 +0000)
committerChristophe Lyon <christophe.lyon@st.com>
Thu, 26 Feb 2009 15:37:53 +0000 (15:37 +0000)
bfd/
* elf32-arm.c (stub_reloc_type): Removed.
(insn_sequence): Renamed reloc_type field to r_type.
(elf32_arm_stub_long_branch_v4t_arm_thumb_pic): New stub.
(elf32_arm_stub_long_branch_v4t_thumb_arm_pic): Likewise.
(elf32_arm_stub_long_branch_thumb_only_pic): Likewise.
(elf32_arm_stub_type): Add new enum entries for the new stubs.
(arm_stub_is_thumb): Catch new stubs.
(arm_type_of_stub): Handle new stubs.
(arm_size_one_stub): Use ARRAY_SIZE. Handle new stubs.
(bfd_elf32_arm_process_before_allocation): Remove useless
condition.

testsuite/
* ld-arm/arm-elf.exp: Add 3 tests for the 3 new stubs.
* ld-arm/farcall-thumb-arm-pic-veneer.d: New expected result, the
test is now expected to pass.
* ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Likewise.
* ld-arm/farcall-thumb-thumb-pic-veneer.d: Likewise.

bfd/ChangeLog
bfd/elf32-arm.c
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/farcall-thumb-arm-pic-veneer.d
ld/testsuite/ld-arm/farcall-thumb-thumb-m-pic-veneer.d
ld/testsuite/ld-arm/farcall-thumb-thumb-pic-veneer.d

index 4d3b31b9235cd75e8eea2748f514f85cf71fa6c7..bdd2f80226046718261acd1fa9104dd98c1148d5 100644 (file)
@@ -1,3 +1,17 @@
+2009-02-26  Christophe Lyon  <christophe.lyon@st.com>
+
+       * elf32-arm.c (stub_reloc_type): Removed.
+       (insn_sequence): Renamed reloc_type field to r_type.
+       (elf32_arm_stub_long_branch_v4t_arm_thumb_pic): New stub.
+       (elf32_arm_stub_long_branch_v4t_thumb_arm_pic): Likewise.
+       (elf32_arm_stub_long_branch_thumb_only_pic): Likewise.
+       (elf32_arm_stub_type): Add new enum entries for the new stubs.
+       (arm_stub_is_thumb): Catch new stubs.
+       (arm_type_of_stub): Handle new stubs.
+       (arm_size_one_stub): Use ARRAY_SIZE. Handle new stubs.
+       (bfd_elf32_arm_process_before_allocation): Remove useless
+       condition.
+
 2009-02-25  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf.c (elf_find_function): Use is_function_type to check
index 7499f803524723daacebe008928e09ef3cc72911..2527e5e8425714d8dd1d96aa6242c08f64b020cd 100644 (file)
@@ -2018,13 +2018,6 @@ enum stub_insn_type
     DATA_TYPE
   };
 
-enum stub_reloc_type
-  {
-    STUB_RELOC_NONE = 0,
-    STUB_RELOC_ABS,
-    STUB_RELOC_PIC,
-  };
-
 #define THUMB16_INSN(X)    {(X), THUMB16_TYPE, R_ARM_NONE, 0}
 #define THUMB32_INSN(X)    {(X), THUMB32_TYPE, R_ARM_NONE, 0}
 #define ARM_INSN(X)        {(X), ARM_TYPE, R_ARM_NONE, 0}
@@ -2035,7 +2028,7 @@ typedef struct
 {
   bfd_vma data;
   enum stub_insn_type type;
-  enum stub_reloc_type reloc_type;
+  unsigned int r_type;
   int reloc_addend;
 }  insn_sequence;
 
@@ -2110,6 +2103,39 @@ static const insn_sequence elf32_arm_stub_long_branch_any_thumb_pic[] =
     DATA_WORD(0, R_ARM_REL32, 0),     /* dcd   R_ARM_REL32(X) */
   };
 
+/* V4T ARM -> ARM long branch stub, PIC.  */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] =
+  {
+    ARM_INSN(0xe59fc004),             /* ldr   ip, [pc, #4] */
+    ARM_INSN(0xe08fc00c),             /* add   ip, pc, ip */
+    ARM_INSN(0xe12fff1c),             /* bx    ip */
+    DATA_WORD(0, R_ARM_REL32, 0),     /* dcd   R_ARM_REL32(X) */
+  };
+
+/* V4T Thumb -> ARM long branch stub, PIC.  */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] =
+  {
+    THUMB16_INSN(0x4778),             /* bx   pc */
+    THUMB16_INSN(0x46c0),             /* nop  */
+    ARM_INSN(0xe59fc000),             /* ldr  ip, [pc, #0] */
+    ARM_INSN(0xe08cf00f),             /* add  pc, ip, pc */
+    DATA_WORD(0, R_ARM_REL32, -4),     /* dcd  R_ARM_REL32(X) */
+  };
+
+/* Thumb -> Thumb long branch stub, PIC. Used on architectures which
+   support only this mode, or on V4T where it is expensive to switch
+   to ARM.  */
+static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] =
+  {
+    THUMB16_INSN(0xb401),             /* push {r0} */
+    THUMB16_INSN(0x4802),             /* ldr  r0, [pc, #8] */
+    THUMB16_INSN(0x46fc),             /* mov  ip, pc */
+    THUMB16_INSN(0x4484),             /* add  ip, r0 */
+    THUMB16_INSN(0xbc01),             /* pop  {r0} */
+    THUMB16_INSN(0x4760),             /* bx   ip */
+    DATA_WORD(0, R_ARM_REL32, 4),     /* dcd  R_ARM_REL32(X) */
+  };
+
 /* Section name for stubs is the associated section name plus this
    string.  */
 #define STUB_SUFFIX ".stub"
@@ -2124,6 +2150,9 @@ enum elf32_arm_stub_type
   arm_stub_short_branch_v4t_thumb_arm,
   arm_stub_long_branch_any_arm_pic,
   arm_stub_long_branch_any_thumb_pic,
+  arm_stub_long_branch_v4t_arm_thumb_pic,
+  arm_stub_long_branch_v4t_thumb_arm_pic,
+  arm_stub_long_branch_thumb_only_pic,
 };
 
 struct elf32_arm_stub_hash_entry
@@ -2796,6 +2825,8 @@ arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
     case arm_stub_long_branch_thumb_only:
     case arm_stub_long_branch_v4t_thumb_arm:
     case arm_stub_short_branch_v4t_thumb_arm:
+    case arm_stub_long_branch_v4t_thumb_arm_pic:
+    case arm_stub_long_branch_thumb_only_pic:
       return TRUE;
     case arm_stub_none:
       BFD_FAIL ();
@@ -2872,8 +2903,8 @@ arm_type_of_stub (struct bfd_link_info *info,
                    ? ((globals->use_blx)
                       /* V5T and above.  */
                       ? arm_stub_long_branch_any_thumb_pic
-                      /* not yet supported on V4T.  */
-                      : arm_stub_none)
+                      /* On V4T, use Thumb code only.  */
+                      : arm_stub_long_branch_thumb_only_pic)
 
                    /* non-PIC stubs.  */
                    : ((globals->use_blx)
@@ -2885,8 +2916,8 @@ arm_type_of_stub (struct bfd_link_info *info,
              else
                {
                  stub_type = (info->shared | globals->pic_veneer)
-                   /* PIC stub not yet supported on V4T.  */
-                   ? arm_stub_none
+                   /* PIC stub.  */
+                   ? arm_stub_long_branch_thumb_only_pic
                    /* non-PIC stub.  */
                    : arm_stub_long_branch_thumb_only;
                }
@@ -2909,8 +2940,8 @@ arm_type_of_stub (struct bfd_link_info *info,
                ? ((globals->use_blx)
                   /* V5T and above.  */
                   ? arm_stub_long_branch_any_arm_pic
-                  /* not yet supported on V4T.  */
-                  : arm_stub_none)
+                  /* V4T PIC stub.  */
+                  : arm_stub_long_branch_v4t_thumb_arm_pic)
 
                /* non-PIC stubs.  */
                : ((globals->use_blx)
@@ -2951,7 +2982,12 @@ arm_type_of_stub (struct bfd_link_info *info,
            {
              stub_type = (info->shared | globals->pic_veneer)
                /* PIC stubs.  */
-               ? arm_stub_long_branch_any_thumb_pic
+               ? ((globals->use_blx)
+                  /* V5T and above.  */
+                  ? arm_stub_long_branch_any_thumb_pic
+                  /* V4T stub.  */
+                  : arm_stub_long_branch_v4t_arm_thumb_pic)
+
                /* non-PIC stubs.  */
                : ((globals->use_blx)
                   /* V5T and above.  */
@@ -3207,7 +3243,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
          put_arm_insn (globals, stub_bfd, template[i].data, loc + size);
          /* Handle cases where the target is encoded within the
             instruction.  */
-         if (template[i].reloc_type == R_ARM_JUMP24)
+         if (template[i].r_type == R_ARM_JUMP24)
            {
              stub_reloc_idx = i;
              stub_reloc_offset = size;
@@ -3241,7 +3277,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
   /* Assume there is one and only one entry to relocate in each stub.  */
   BFD_ASSERT (stub_reloc_idx != -1);
 
-  _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].reloc_type),
+  _bfd_final_link_relocate (elf32_arm_howto_from_type (template[stub_reloc_idx].r_type),
                            stub_bfd, stub_sec, stub_sec->contents,
                            stub_entry->stub_offset + stub_reloc_offset,
                            sym_value, template[stub_reloc_idx].reloc_addend);
@@ -3271,32 +3307,43 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry,
     {
     case arm_stub_long_branch_any_any:
       template =  elf32_arm_stub_long_branch_any_any;
-      template_size = sizeof (elf32_arm_stub_long_branch_any_any) / sizeof (insn_sequence);
-
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_any);
       break;
     case arm_stub_long_branch_v4t_arm_thumb:
       template =  elf32_arm_stub_long_branch_v4t_arm_thumb;
-      template_size = sizeof (elf32_arm_stub_long_branch_v4t_arm_thumb) / sizeof (insn_sequence);
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb);
       break;
     case arm_stub_long_branch_thumb_only:
       template =  elf32_arm_stub_long_branch_thumb_only;
-      template_size = sizeof (elf32_arm_stub_long_branch_thumb_only) / sizeof (insn_sequence);
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only);
       break;
     case arm_stub_long_branch_v4t_thumb_arm:
       template =  elf32_arm_stub_long_branch_v4t_thumb_arm;
-      template_size = sizeof (elf32_arm_stub_long_branch_v4t_thumb_arm) / sizeof (insn_sequence);
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm);
       break;
     case arm_stub_short_branch_v4t_thumb_arm:
       template =  elf32_arm_stub_short_branch_v4t_thumb_arm;
-      template_size = sizeof (elf32_arm_stub_short_branch_v4t_thumb_arm) / sizeof (insn_sequence);
+      template_size = ARRAY_SIZE (elf32_arm_stub_short_branch_v4t_thumb_arm);
       break;
     case arm_stub_long_branch_any_arm_pic:
       template = elf32_arm_stub_long_branch_any_arm_pic;
-      template_size = sizeof (elf32_arm_stub_long_branch_any_arm_pic) / sizeof (insn_sequence);
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_arm_pic);
       break;
     case arm_stub_long_branch_any_thumb_pic:
       template = elf32_arm_stub_long_branch_any_thumb_pic;
-      template_size = sizeof (elf32_arm_stub_long_branch_any_thumb_pic) / sizeof (insn_sequence);
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_any_thumb_pic);
+      break;
+    case arm_stub_long_branch_v4t_arm_thumb_pic:
+      template = elf32_arm_stub_long_branch_v4t_arm_thumb_pic;
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_arm_thumb_pic);
+      break;
+    case arm_stub_long_branch_v4t_thumb_arm_pic:
+      template = elf32_arm_stub_long_branch_v4t_thumb_arm_pic;
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_v4t_thumb_arm_pic);
+      break;
+    case arm_stub_long_branch_thumb_only_pic:
+      template = elf32_arm_stub_long_branch_thumb_only_pic;
+      template_size = ARRAY_SIZE (elf32_arm_stub_long_branch_thumb_only_pic);
       break;
     default:
       BFD_FAIL ();
@@ -4647,8 +4694,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
              /* This one is a call from arm code.  We need to look up
                 the target of the call.  If it is a thumb target, we
                 insert glue.  */
-             if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC
-                 && !(r_type == R_ARM_CALL && globals->use_blx))
+             if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
                record_arm_to_thumb_glue (link_info, h);
              break;
 
index a214deaf932bcd3bc5d9fc7dc55c7879630ada14..d78062d8b2ab3ac082685eaf06ef6d6675a2eb37 100644 (file)
@@ -1,6 +1,13 @@
+2009-02-26  Christophe Lyon  <christophe.lyon@st.com>
+
+       * ld-arm/arm-elf.exp: Add 3 tests for the 3 new stubs.
+       * ld-arm/farcall-thumb-arm-pic-veneer.d: New expected result, the
+       test is now expected to pass.
+       * ld-arm/farcall-thumb-thumb-m-pic-veneer.d: Likewise.
+       * ld-arm/farcall-thumb-thumb-pic-veneer.d: Likewise.
+
 2009-02-25  Christophe Lyon  <christophe.lyon@st.com>
 
-       testsuite/
        * ld-arm/thumb2-bl-as-thumb1-bad-noeabi.d: Update expected result,
        as stubs are now generated and the end of the .text section.
        * ld-arm/thumb2-bl-bad-noeabi.d: Likewise.
index da63b40d1b42d809a4c72cbf8e6bd9e7a3fa0ec2..48b2b51ea7080787dcb5c999e43e394660719658 100644 (file)
@@ -296,6 +296,12 @@ set armeabitests {
     {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}}
      "farcall-thumb-thumb-blx-pic-veneer"}
+    {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7m" {farcall-thumb-thumb.s}
+     {{objdump -d farcall-thumb-thumb-m-pic-veneer.d}}
+     "farcall-thumb-thumb-m-pic-veneer"}
+    {"Thumb-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv4t" {farcall-thumb-thumb.s}
+     {{objdump -d farcall-thumb-thumb-pic-veneer.d}}
+     "farcall-thumb-thumb-pic-veneer"}
 
     {"Thumb-ARM farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-W" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
@@ -315,6 +321,9 @@ set armeabitests {
     {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
      "farcall-thumb-arm-blx-pic-veneer"}
+    {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s}
+     {{objdump -d farcall-thumb-arm-pic-veneer.d}}
+     "farcall-thumb-arm-pic-veneer"}
 
     {"Multiple farcalls" "-Ttext 0x1000 --section-start .foo=0x2002020" "" {farcall-mix.s}
      {{objdump -d farcall-mix.d}}
@@ -350,9 +359,6 @@ run_dump_test "attr-merge-wchar-24-nowarn"
 run_dump_test "attr-merge-wchar-40-nowarn"
 run_dump_test "attr-merge-wchar-42-nowarn"
 run_dump_test "attr-merge-wchar-44-nowarn"
-run_dump_test "farcall-thumb-thumb-pic-veneer"
-run_dump_test "farcall-thumb-thumb-m-pic-veneer"
-run_dump_test "farcall-thumb-arm-pic-veneer"
 run_dump_test "farcall-section"
 run_dump_test "attr-merge-unknown-1"
 run_dump_test "attr-merge-unknown-2"
index a2c09d29b4ca6ee31ca1ce8c878312259c029e77..6ac6e5c0f9388d2bb92dedbfd000a0e6889a03ce 100644 (file)
@@ -1,5 +1,20 @@
-#name: Thumb-ARM farcall without BLX (PIC veneer)
-#source: farcall-thumb-arm.s
-#as: -march=armv4t -W
-#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <_start>:
+    1000:      f000 f802       bl      1008 <__bar_from_thumb>
+    1004:      0000            lsls    r0, r0, #0
+       ...
+
+00001008 <__bar_from_thumb>:
+    1008:      4778            bx      pc
+    100a:      46c0            nop                     \(mov r8, r8\)
+    100c:      e59fc000        ldr     ip, \[pc, #0\]  ; 1014 <__bar_from_thumb\+0xc>
+    1010:      e08cf00f        add     pc, ip, pc
+    1014:      01fffffc        .word   0x01fffffc
+
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:      e12fff1e        bx      lr
index f8308ff37dd2decf541dd4065507c623f2b00e37..c96ea3f19a4a3831dd7e48e5344e8864a678de51 100644 (file)
@@ -1,5 +1,22 @@
-#name: Thumb-Thumb farcall M profile (PIC veneer)
-#source: farcall-thumb-thumb.s
-#as: -march=armv4t
-#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <_start>:
+    1000:      f000 f802       bl      1008 <__bar_veneer>
+    1004:      0000            lsls    r0, r0, #0
+       ...
+
+00001008 <__bar_veneer>:
+    1008:      b401            push    {r0}
+    100a:      4802            ldr     r0, \[pc, #8\]  \(1014 <__bar_veneer\+0xc>\)
+    100c:      46fc            mov     ip, pc
+    100e:      4484            add     ip, r0
+    1010:      bc01            pop     {r0}
+    1012:      4760            bx      ip
+    1014:      02000005        .word   0x02000005
+
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:      4770            bx      lr
index f97671bbf022263d314c730de33b030b7ddd45d9..c96ea3f19a4a3831dd7e48e5344e8864a678de51 100644 (file)
@@ -1,5 +1,22 @@
-#name: Thumb-Thumb farcall without BLX (PIC veneer)
-#source: farcall-thumb-thumb.s
-#as: -march=armv4t
-#ld: -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_ARM_THM_CALL against `bar'
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <_start>:
+    1000:      f000 f802       bl      1008 <__bar_veneer>
+    1004:      0000            lsls    r0, r0, #0
+       ...
+
+00001008 <__bar_veneer>:
+    1008:      b401            push    {r0}
+    100a:      4802            ldr     r0, \[pc, #8\]  \(1014 <__bar_veneer\+0xc>\)
+    100c:      46fc            mov     ip, pc
+    100e:      4484            add     ip, r0
+    1010:      bc01            pop     {r0}
+    1012:      4760            bx      ip
+    1014:      02000005        .word   0x02000005
+
+Disassembly of section .foo:
+
+02001014 <bar>:
+ 2001014:      4770            bx      lr