[PATCH] ld: add switch to disable use of BLX instructions

Meador Inge meadori@codesourcery.com
Fri Apr 13 15:07:00 GMT 2012


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



More information about the Binutils mailing list