This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] ld: add switch to disable use of BLX instructions
- From: Meador Inge <meadori at codesourcery dot com>
- To: Allen Martin <amartin at nvidia dot com>
- Cc: <binutils at sourceware dot org>
- Date: Fri, 13 Apr 2012 07:34:11 -0500
- Subject: Re: [PATCH] ld: add switch to disable use of BLX instructions
- References: <1334301120-21894-1-git-send-email-amartin@nvidia.com>
On 04/13/2012 02:12 AM, 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.
> ---
> 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"));
If this is moving to a single '[no-]use' option, then why do we need ...
> @@ -625,6 +628,10 @@ PARSE_AND_LIST_ARGS_CASES='
> use_blx = 1;
> break;
>
> + case OPTION_NO_USE_BLX:
> + no_use_blx = 1;
> + break;
> +
... 'use_blx' and 'no_use_blx'. Seems like we just need one of them.
> case OPTION_VFP11_DENORM_FIX:
> if (strcmp (optarg, "none") == 0)
> vfp11_denorm_fix = BFD_ARM_VFP11_FIX_NONE;
--
Meador Inge
CodeSourcery / Mentor Embedded
http://www.mentor.com/embedded-software