This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] ld: add switch to disable use of BLX instructions
- From: Allen Martin <amartin at nvidia dot com>
- To: <binutils at sourceware dot org>
- Cc: Allen Martin <amartin at nvidia dot com>
- Date: Fri, 13 Apr 2012 00:12:00 -0700
- Subject: [PATCH] ld: add switch to disable use of BLX instructions
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;
--
1.7.5.4