aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/bfd-in.h2
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/elf32-arm.c12
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/emultempl/armelf.em11
-rw-r--r--ld/ld.texinfo7
-rw-r--r--ld/testsuite/ChangeLog6
-rw-r--r--ld/testsuite/ld-arm/arm-elf.exp3
-rw-r--r--ld/testsuite/ld-arm/arm-pic-veneer.d17
-rw-r--r--ld/testsuite/ld-arm/arm-pic-veneer.s14
11 files changed, 86 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 863640b..004bfe7 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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 *"
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 1e6dc12..617aa07 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -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 *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d0af00b..ca5810c 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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 *);
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 3be85b1..be10923 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -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. */
diff --git a/ld/ChangeLog b/ld/ChangeLog
index dbb1f2a..16c45a5 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index f1c797b..e9f663f 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -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
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 1ffabf4..abcf5c0 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index d6fb653..20f932a 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index b4e8438..5844266 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -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
index 0000000..cbd5822
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-pic-veneer.d
@@ -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
index 0000000..9e09ed6
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-pic-veneer.s
@@ -0,0 +1,14 @@
+.text
+.arm
+.global _start
+.type _start, %function
+_start:
+b foo
+
+.thumb
+.global foo
+.type foo, %function
+foo:
+nop
+bx lr
+