+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 *"
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 *);
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 *);
/* 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;
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;
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;
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;
}
--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. */
+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.
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)
{
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
#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
{ "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='
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='
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
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
+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
{"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
--- /dev/null
+
+.*: 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
--- /dev/null
+.text
+.arm
+.global _start
+.type _start, %function
+_start:
+b foo
+
+.thumb
+.global foo
+.type foo, %function
+foo:
+nop
+bx lr
+