From: Paul Brook Date: Tue, 20 Mar 2007 20:19:07 +0000 (+0000) Subject: 2007-03-20 Paul Brook X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=27e55c4d0b94f5d358385b9641d26b84ee611768;p=binutils-gdb.git 2007-03-20 Paul Brook 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 863640b929b..004bfe7436d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2007-03-20 Paul Brook + + * 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 * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add "bfd *" diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 1e6dc12323b..617aa07ec55 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 d0af00b8f33..ca5810cbede 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 3be85b1cdd7..be109232235 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 dbb1f2a7c5c..16c45a5ecef 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2007-03-20 Paul Brook + + * 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 * ld.texinfo: Document --no-enum-size-warning. diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index f1c797bd043..e9f663f494a 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 1ffabf46916..abcf5c0b011 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 d6fb6531cc1..20f932a434c 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-03-20 Paul Brook + + * 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 * 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 b4e84381de6..5844266323c 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 00000000000..cbd582277d9 --- /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 : + 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 00000000000..9e09ed63337 --- /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 +