Add --no-use-blx switch to force disabling of BLX instructions for thumb interworking. This allows ld to emit code that is armv4t safe even if configured for armv5 or later. --- bfd/bfd-in.h | 4 ++-- bfd/bfd-in2.h | 4 ++-- bfd/elf32-arm.c | 10 +++++++++- ld/emultempl/armelf.em | 11 +++++++++-- 4 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index a477b49..0a81327 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -872,8 +872,8 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation (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, int, int); + (bfd *, struct bfd_link_info *, int, char *, int, int, int, + bfd_arm_vfp11_fix, int, int, 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 22fcdf6..45c5376 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -879,8 +879,8 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation (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, int, int); + (bfd *, struct bfd_link_info *, int, char *, int, int, int, + bfd_arm_vfp11_fix, int, int, 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 1f6c1a0..7cbb5f8 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2782,6 +2782,9 @@ struct elf32_arm_link_hash_table /* Nonzero if the ARM/Thumb BLX instructions are available for use. */ int use_blx;
+ /* Nonzero to prevent BLX instructions from being used. */ + int no_use_blx; + /* What sort of code sequences we should look for which may trigger the VFP11 denorm erratum. */ bfd_arm_vfp11_fix vfp11_fix; @@ -3332,6 +3335,7 @@ elf32_arm_link_hash_table_create (bfd *abfd) #endif ret->fix_v4bx = 0; ret->use_blx = 0; + ret->no_use_blx = 0; ret->vxworks_p = 0; ret->symbian_p = 0; ret->use_rel = 1; @@ -5939,7 +5943,9 @@ check_use_blx (struct elf32_arm_link_hash_table *globals) cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
- if (globals->fix_arm1176) + if (globals->no_use_blx) + globals->use_blx = 0; + else if (globals->fix_arm1176) { if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch > TAG_CPU_ARCH_V6K) globals->use_blx = 1; @@ -6800,6 +6806,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd, char * target2_type, int fix_v4bx, int use_blx, + int no_use_blx, bfd_arm_vfp11_fix vfp11_fix, int no_enum_warn, int no_wchar_warn, int pic_veneer, int fix_cortex_a8, @@ -6825,6 +6832,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd, } globals->fix_v4bx = fix_v4bx; globals->use_blx |= use_blx; + globals->no_use_blx = no_use_blx; globals->vfp11_fix = vfp11_fix; globals->pic_veneer = pic_veneer; globals->fix_cortex_a8 = fix_cortex_a8; diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index d29da59..14a0dcf 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -36,6 +36,7 @@ static int target1_is_rel = 0${TARGET1_IS_REL}; static char *target2_type = "${TARGET2_TYPE}"; static int fix_v4bx = 0; static int use_blx = 0; +static int no_use_blx = 0; static bfd_arm_vfp11_fix vfp11_denorm_fix = BFD_ARM_VFP11_FIX_DEFAULT; static int fix_cortex_a8 = -1; static int no_enum_size_warning = 0; @@ -462,7 +463,7 @@ arm_elf_create_output_section_statements (void)
bfd_elf32_arm_set_target_relocs (link_info.output_bfd, &link_info, target1_is_rel, - target2_type, fix_v4bx, use_blx, + target2_type, fix_v4bx, use_blx, no_use_blx, vfp11_denorm_fix, no_enum_size_warning, no_wchar_size_warning, pic_veneer, fix_cortex_a8, @@ -533,6 +534,7 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_NO_MERGE_EXIDX_ENTRIES 316 #define OPTION_FIX_ARM1176 317 #define OPTION_NO_FIX_ARM1176 318 +#define OPTION_NO_USE_BLX 319 '
PARSE_AND_LIST_SHORTOPTS=p @@ -547,6 +549,7 @@ PARSE_AND_LIST_LONGOPTS=' { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX}, { "fix-v4bx-interworking", no_argument, NULL, OPTION_FIX_V4BX_INTERWORKING}, { "use-blx", no_argument, NULL, OPTION_USE_BLX}, + { "no-use-blx", no_argument, NULL, OPTION_NO_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}, @@ -567,7 +570,7 @@ PARSE_AND_LIST_OPTIONS=' fprintf (file, _(" --target2=<type> Specify definition of R_ARM_TARGET2\n")); fprintf (file, _(" --fix-v4bx Rewrite BX rn as MOV pc, rn for ARMv4\n")); fprintf (file, _(" --fix-v4bx-interworking Rewrite BX rn branch to ARMv4 interworking veneer\n")); - fprintf (file, _(" --use-blx Enable use of BLX instructions\n")); + fprintf (file, _(" --[no-]use-blx Disable/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\n" " enum sizes\n")); @@ -625,6 +628,10 @@ PARSE_AND_LIST_ARGS_CASES=' use_blx = 1; break;
+ case OPTION_NO_USE_BLX: + no_use_blx = 1; + break; + case OPTION_VFP11_DENORM_FIX: if (strcmp (optarg, "none") == 0) vfp11_denorm_fix = BFD_ARM_VFP11_FIX_NONE;
On 13/04/12 16:19, Allen Martin wrote:
Add --no-use-blx switch to force disabling of BLX instructions for thumb interworking. This allows ld to emit code that is armv4t safe even if configured for armv5 or later.
Sorry, this is *not* the right way to solve this problem. You need to find out why the linker thinks you're generating an image with an architecture >= v5.
R.
bfd/bfd-in.h | 4 ++-- bfd/bfd-in2.h | 4 ++-- bfd/elf32-arm.c | 10 +++++++++- ld/emultempl/armelf.em | 11 +++++++++-- 4 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index a477b49..0a81327 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -872,8 +872,8 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation (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, int, int);
- (bfd *, struct bfd_link_info *, int, char *, int, int, int,
- bfd_arm_vfp11_fix, int, int, 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 22fcdf6..45c5376 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -879,8 +879,8 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation (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, int, int);
- (bfd *, struct bfd_link_info *, int, char *, int, int, int,
- bfd_arm_vfp11_fix, int, int, 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 1f6c1a0..7cbb5f8 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2782,6 +2782,9 @@ struct elf32_arm_link_hash_table /* Nonzero if the ARM/Thumb BLX instructions are available for use. */ int use_blx;
- /* Nonzero to prevent BLX instructions from being used. */
- int no_use_blx;
- /* What sort of code sequences we should look for which may trigger the VFP11 denorm erratum. */ bfd_arm_vfp11_fix vfp11_fix;
@@ -3332,6 +3335,7 @@ elf32_arm_link_hash_table_create (bfd *abfd) #endif ret->fix_v4bx = 0; ret->use_blx = 0;
- ret->no_use_blx = 0; ret->vxworks_p = 0; ret->symbian_p = 0; ret->use_rel = 1;
@@ -5939,7 +5943,9 @@ check_use_blx (struct elf32_arm_link_hash_table *globals) cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
- if (globals->fix_arm1176)
- if (globals->no_use_blx)
- globals->use_blx = 0;
- else if (globals->fix_arm1176) { if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch > TAG_CPU_ARCH_V6K) globals->use_blx = 1;
@@ -6800,6 +6806,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd, char * target2_type, int fix_v4bx, int use_blx,
int no_use_blx, bfd_arm_vfp11_fix vfp11_fix, int no_enum_warn, int no_wchar_warn, int pic_veneer, int fix_cortex_a8,
@@ -6825,6 +6832,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd, } globals->fix_v4bx = fix_v4bx; globals->use_blx |= use_blx;
- globals->no_use_blx = no_use_blx; globals->vfp11_fix = vfp11_fix; globals->pic_veneer = pic_veneer; globals->fix_cortex_a8 = fix_cortex_a8;
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index d29da59..14a0dcf 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -36,6 +36,7 @@ static int target1_is_rel = 0${TARGET1_IS_REL}; static char *target2_type = "${TARGET2_TYPE}"; static int fix_v4bx = 0; static int use_blx = 0; +static int no_use_blx = 0; static bfd_arm_vfp11_fix vfp11_denorm_fix = BFD_ARM_VFP11_FIX_DEFAULT; static int fix_cortex_a8 = -1; static int no_enum_size_warning = 0; @@ -462,7 +463,7 @@ arm_elf_create_output_section_statements (void)
bfd_elf32_arm_set_target_relocs (link_info.output_bfd, &link_info, target1_is_rel,
target2_type, fix_v4bx, use_blx,
target2_type, fix_v4bx, use_blx, no_use_blx, vfp11_denorm_fix, no_enum_size_warning, no_wchar_size_warning, pic_veneer, fix_cortex_a8,
@@ -533,6 +534,7 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_NO_MERGE_EXIDX_ENTRIES 316 #define OPTION_FIX_ARM1176 317 #define OPTION_NO_FIX_ARM1176 318 +#define OPTION_NO_USE_BLX 319 '
PARSE_AND_LIST_SHORTOPTS=p @@ -547,6 +549,7 @@ PARSE_AND_LIST_LONGOPTS=' { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX}, { "fix-v4bx-interworking", no_argument, NULL, OPTION_FIX_V4BX_INTERWORKING}, { "use-blx", no_argument, NULL, OPTION_USE_BLX},
- { "no-use-blx", no_argument, NULL, OPTION_NO_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},
@@ -567,7 +570,7 @@ PARSE_AND_LIST_OPTIONS=' fprintf (file, _(" --target2=<type> Specify definition of R_ARM_TARGET2\n")); fprintf (file, _(" --fix-v4bx Rewrite BX rn as MOV pc, rn for ARMv4\n")); fprintf (file, _(" --fix-v4bx-interworking Rewrite BX rn branch to ARMv4 interworking veneer\n"));
- fprintf (file, _(" --use-blx Enable use of BLX instructions\n"));
- fprintf (file, _(" --[no-]use-blx Disable/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\n" " enum sizes\n"));
@@ -625,6 +628,10 @@ PARSE_AND_LIST_ARGS_CASES=' use_blx = 1; break;
- case OPTION_NO_USE_BLX:
no_use_blx = 1;
break;
- case OPTION_VFP11_DENORM_FIX: if (strcmp (optarg, "none") == 0) vfp11_denorm_fix = BFD_ARM_VFP11_FIX_NONE;
-- Richard Earnshaw Email: Richard.Earnshaw@arm.com Engineering Manager Phone: +44 1223 400569 (Direct + VoiceMail) OpenSource Tools Switchboard: +44 1223 400400 ARM Ltd Fax: +44 1223 400410 110 Fulbourn Rd Web: http://www.arm.com/ Cambridge, UK. CB1 9NJ
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
linaro-toolchain@lists.linaro.org