2007-03-20 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Tue, 20 Mar 2007 20:19:07 +0000 (20:19 +0000)
committerPaul Brook <paul@codesourcery.com>
Tue, 20 Mar 2007 20:19:07 +0000 (20:19 +0000)
ld/
* emultempl/armelf.em (pic_veneer): New variable.
(PARSE_AND_LIST_PROLOGUE): Add OPTION_PIC_VENEER.
(PARSE_AND_LIST_ARGS_CASES): Ditto.
(PARSE_AND_LIST_LONGOPTS): Add "pic-veneer".
(PARSE_AND_LIST_OPTIONS): Ditto.
* ld.texinfo: Document --pic-veneer.

ld/testsuite/
* ld-arm/arm-elf.exp (ld-arm/arm-elf.exp): Add arm-pic-veneer.
* ld-arm/arm-pic-veneer.d: New test.
* ld-arm/arm-pic-veneer.s: New test.

bfd/
* bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
* bfd-in2.h: Regenerate.
* elf32-arm.c (elf32_arm_link_hash_table): Add pic_veneer.
(record_arm_to_thumb_glue): Use globals->pic_veneer.
(elf32_arm_create_thumb_stub): Ditto.
(bfd_elf32_arm_set_target_relocs): Set globals->pic_veneer.

bfd/ChangeLog
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/elf32-arm.c
ld/ChangeLog
ld/emultempl/armelf.em
ld/ld.texinfo
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/arm-pic-veneer.d [new file with mode: 0644]
ld/testsuite/ld-arm/arm-pic-veneer.s [new file with mode: 0644]

index 863640b929be0049a743b8125050114f6960ff87..004bfe7436da8a78c1dc35ec15e618aed0722952 100644 (file)
@@ -1,3 +1,12 @@
+2007-03-20  Paul Brook  <paul@codesourcery.com>
+
+       * bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+       * bfd-in2.h: Regenerate.
+       * elf32-arm.c (elf32_arm_link_hash_table): Add pic_veneer.
+       (record_arm_to_thumb_glue): Use globals->pic_veneer.
+       (elf32_arm_create_thumb_stub): Ditto.
+       (bfd_elf32_arm_set_target_relocs): Set globals->pic_veneer.
+
 2007-03-18  Mark Shinwell  <shinwell@codesourcery.com>
 
        * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add "bfd *"
index 1e6dc12323b2334e3fc18a69c36a0c31c3aba3d0..617aa07ec550239853d856632d5275944da2a18c 100644 (file)
@@ -903,7 +903,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int);
+   int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
index d0af00b8f33520f1df74436cab0bd2df1ae24bd5..ca5810cbede7fc8786dcc40fcfe08ebca61892dc 100644 (file)
@@ -910,7 +910,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int);
+   int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
index 3be85b1cdd7a40b6a8d51025ba245a26aa9969bf..be10923223550f3935816247c276b5aa2212702c 100644 (file)
@@ -2191,6 +2191,9 @@ struct elf32_arm_link_hash_table
     /* Global counter for the number of fixes we have emitted.  */
     int num_vfp11_fixes;
 
+    /* Nonzero to force PIC branch veneers.  */
+    int pic_veneer;
+
     /* The number of bytes in the initial entry in the PLT.  */
     bfd_size_type plt_header_size;
 
@@ -2714,7 +2717,8 @@ record_arm_to_thumb_glue (struct bfd_link_info * link_info,
 
   free (tmp_name);
 
-  if ((link_info->shared || globals->root.is_relocatable_executable))
+  if (link_info->shared || globals->root.is_relocatable_executable
+      || globals->pic_veneer)
     size = ARM2THUMB_PIC_GLUE_SIZE;
   else
     size = ARM2THUMB_STATIC_GLUE_SIZE;
@@ -3868,7 +3872,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
                                  int fix_v4bx,
                                 int use_blx,
                                  bfd_arm_vfp11_fix vfp11_fix,
-                                int no_enum_warn)
+                                int no_enum_warn, int pic_veneer)
 {
   struct elf32_arm_link_hash_table *globals;
 
@@ -3889,6 +3893,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
   globals->fix_v4bx = fix_v4bx;
   globals->use_blx |= use_blx;
   globals->vfp11_fix = vfp11_fix;
+  globals->pic_veneer = pic_veneer;
 
   elf32_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
 }
@@ -4127,7 +4132,8 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
       --my_offset;
       myh->root.u.def.value = my_offset;
 
-      if ((info->shared || globals->root.is_relocatable_executable))
+      if (info->shared || globals->root.is_relocatable_executable
+         || globals->pic_veneer)
        {
          /* For relocatable objects we can't use absolute addresses,
             so construct the address from a relative offset.  */
index dbb1f2a7c5c08b4dc03a17c11461bf40d623e23c..16c45a5ecef6fe33715ef65b5db904cccc55e4ab 100644 (file)
@@ -1,3 +1,12 @@
+2007-03-20  Paul Brook  <paul@codesourcery.com>
+
+       * emultempl/armelf.em (pic_veneer): New variable.
+       (PARSE_AND_LIST_PROLOGUE): Add OPTION_PIC_VENEER.
+       (PARSE_AND_LIST_ARGS_CASES): Ditto.
+       (PARSE_AND_LIST_LONGOPTS): Add "pic-veneer".
+       (PARSE_AND_LIST_OPTIONS): Ditto.
+       * ld.texinfo: Document --pic-veneer.
+
 2007-03-18  Mark Shinwell  <shinwell@codesourcery.com>
 
        * ld.texinfo: Document --no-enum-size-warning.
index f1c797bd043c360d470aa1d3878023dd567d2d35..e9f663f494a5c3b46539ebbbb5dcd32f146a1a69 100644 (file)
@@ -37,6 +37,7 @@ static int fix_v4bx = 0;
 static int use_blx = 0;
 static bfd_arm_vfp11_fix vfp11_denorm_fix = BFD_ARM_VFP11_FIX_DEFAULT;
 static int no_enum_size_warning = 0;
+static int pic_veneer = 0;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -241,7 +242,8 @@ arm_elf_create_output_section_statements (void)
 {
   bfd_elf32_arm_set_target_relocs (output_bfd, &link_info, target1_is_rel,
                                   target2_type, fix_v4bx, use_blx,
-                                  vfp11_denorm_fix, no_enum_size_warning);
+                                  vfp11_denorm_fix, no_enum_size_warning,
+                                  pic_veneer);
 }
 
 EOF
@@ -259,6 +261,7 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_USE_BLX                 307
 #define OPTION_VFP11_DENORM_FIX                308
 #define OPTION_NO_ENUM_SIZE_WARNING    309
+#define OPTION_PIC_VENEER              310
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -274,6 +277,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "use-blx", no_argument, NULL, OPTION_USE_BLX},
   { "vfp11-denorm-fix", required_argument, NULL, OPTION_VFP11_DENORM_FIX},
   { "no-enum-size-warning", no_argument, NULL, OPTION_NO_ENUM_SIZE_WARNING},
+  { "pic-veneer", no_argument, NULL, OPTION_PIC_VENEER},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -286,6 +290,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("     --use-blx                Enable use of BLX instructions\n"));
   fprintf (file, _("     --vfp11-denorm-fix       Specify how to fix VFP11 denorm erratum\n"));
   fprintf (file, _("     --no-enum-size-warning   Don'\''t warn about objects with incompatible enum sizes\n"));
+  fprintf (file, _("     --pic-veneer             Always generate PIC interworking veneers\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -335,6 +340,10 @@ PARSE_AND_LIST_ARGS_CASES='
     case OPTION_NO_ENUM_SIZE_WARNING:
       no_enum_size_warning = 1;
       break;
+
+    case OPTION_PIC_VENEER:
+      pic_veneer = 1;
+      break;
 '
 
 # We have our own after_open and before_allocation functions, but they call
index 1ffabf469162877aba3520ab301f2ae0f313543e..abcf5c0b0114d5e3dc470ec4790c7ae3dd6e4b93 100644 (file)
@@ -5406,6 +5406,13 @@ trampoline address instead of the function address. This is typically the
 case when a pointer to a function is taken. The pointer will in fact
 point to the function trampoline.
 
+@cindex PIC_VENEER
+@kindex --pic-veneer
+The @samp{--pic-veneer} switch makes the linker use PIC sequences for
+ARM/Thumb interworking veneers, even if the rest of the binary
+is not PIC.  This avoids problems on uClinux targets where
+@samp{--emit-relocs} is used to generate relocatable binaries.
+
 @ifclear GENERIC
 @lowersections
 @end ifclear
index d6fb6531cc12d38a97cecbd9fe64d57e18eb8545..20f932a434cc8cc47952db284a06bf64aaf87e14 100644 (file)
@@ -1,3 +1,9 @@
+2007-03-20  Paul Brook  <paul@codesourcery.com>
+
+       * ld-arm/arm-elf.exp (ld-arm/arm-elf.exp): Add arm-pic-veneer.
+       * ld-arm/arm-pic-veneer.d: New test.
+       * ld-arm/arm-pic-veneer.s: New test.
+
 2007-03-08  Richard Sandiford  <richard@codesourcery.com>
 
        * ld-elf/extract-symbol-1.ld (data): Explicitly set the start address
index b4e84381de67d3f67621022bfc4772531f4fc749..5844266323c07d597164f66422b962311617ad17 100644 (file)
@@ -156,6 +156,9 @@ set armelftests {
     {"Unwinding and -gc-sections" "-gc-sections" "" {gc-unwind.s}
      {{objdump -sj.data gc-unwind.d}}
      "gc-unwind"}
+    {"arm-pic-veneer" "-static -T arm.ld --pic-veneer" "" {arm-pic-veneer.s}
+     {{objdump -d arm-pic-veneer.d}}
+     "arm-pic-veneer"}
 }
 
 run_ld_link_tests $armelftests
diff --git a/ld/testsuite/ld-arm/arm-pic-veneer.d b/ld/testsuite/ld-arm/arm-pic-veneer.d
new file mode 100644 (file)
index 0000000..cbd5822
--- /dev/null
@@ -0,0 +1,17 @@
+
+.*:     file format.*
+
+Disassembly of section .text:
+
+00008000 <_start>:
+    8000:      ea000000        b       8008 <__foo_from_arm>
+
+00008004 <foo>:
+    8004:      46c0            nop                     \(mov r8, r8\)
+    8006:      4770            bx      lr
+
+00008008 <__foo_from_arm>:
+    8008:      e59fc004        ldr     ip, \[pc, #4\]  ; 8014 <__foo_from_arm\+0xc>
+    800c:      e08cc00f        add     ip, ip, pc
+    8010:      e12fff1c        bx      ip
+    8014:      fffffff1        undefined instruction 0xfffffff1
diff --git a/ld/testsuite/ld-arm/arm-pic-veneer.s b/ld/testsuite/ld-arm/arm-pic-veneer.s
new file mode 100644 (file)
index 0000000..9e09ed6
--- /dev/null
@@ -0,0 +1,14 @@
+.text
+.arm
+.global _start
+.type _start, %function
+_start:
+b foo
+
+.thumb
+.global foo
+.type foo, %function
+foo:
+nop
+bx lr
+