aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2008-02-20 15:17:56 +0000
committerPaul Brook <paul@codesourcery.com>2008-02-20 15:17:56 +0000
commit845b51d665a3e63aa3a830d1cda6c4803fd35484 (patch)
tree1c85c13fa283997ffca62a41a41a73adf7c8a2c5 /gas/config
parent40887e1a6e8bc0dfb421662f40c1a2c356c8b36d (diff)
downloadgdb-845b51d665a3e63aa3a830d1cda6c4803fd35484.zip
gdb-845b51d665a3e63aa3a830d1cda6c4803fd35484.tar.gz
gdb-845b51d665a3e63aa3a830d1cda6c4803fd35484.tar.bz2
2008-02-20 Paul Brook <paul@codesourcery.com>
ld/ * emultempl/armelf.em (OPTION_FIX_V4BX_INTERWORKING): Define. (PARSE_AND_LIST_LONGOPTS): Add fix-v4bx-interworking. (PARSE_AND_LIST_OPTIONS): Ditto. (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_FIX_V4BX_INTERWORKING. * emulparams/armelf.sh (OTHER_TEXT_SECTIONS): Add .v4_bx. * emulparams/armelf_linux.sh (OTHER_TEXT_SECTIONS): Ditto. * emulparams/armnto.sh (OTHER_TEXT_SECTIONS): Ditto. * ld.texinfo: Document --fix-v4bx-interworking. ld/testsuite/ * ld-arm/armv4-bx.d: New test. * ld-arm/armv4-bx.s: New test. * ld-arm/arm.ld: Add .v4bx. * ld-arm/arm-elf.exp: Add armv4-bx. gas/testsuite/ * gas/arm/thumb.d: Exclude EABI targets. * gas/arm/arch4t.d: Exclude EABI targts. * gas/arm/v4bx.d: New test. * gas/arm/v4bx.s: New test. * gas/arm/thumb-eabi.d: New test. * gas/arm/arch4t-eabi.d: New test. gas/ * config/tc-arm.c (fix_v4bx): New variable. (do_bx): Generate V4BX relocations. (md_assemble): Allow bx on v4 codes when fix_v4bx. (md_apply_fix): Handle BFD_RELOC_ARM_V4BX. (tc_gen_reloc): Ditto. (OPTION_FIX_V4BX): Define. (md_longopts): Add fix-v4bx. (md_parse_option): Handle OPTION_FIX_V4BX. (md_show_usage): Document --fix-v4bx. * doc/c-arm.texi: Document --fix-v4bx. bfd/ * reloc.c: Add BFD_RELOC_ARM_V4BX. * elf32-arm.c (elf32_arm_reloc_map): Add BFD_RELOC_ARM_V4BX. (ARM_BX_GLUE_SECTION_NAME, ARM_BX_GLUE_SECTION_NAME): Define. (elf32_arm_link_hash_table): Add bx_glue_size and bx_glue_offset. Update comment for fix_v4bx. (elf32_arm_link_hash_table_create): Zero bx_glue_size and bx_glue_offset. (ARM_BX_VENEER_SIZE, armbx1_tst_insn, armbx2_moveq_insn, armbx3_bx_insn): New. (bfd_elf32_arm_allocate_interworking_sections): Allocate BX veneer section. (bfd_elf32_arm_add_glue_sections_to_bfd): Ditto. (bfd_elf32_arm_process_before_allocation): Record BX veneers. (record_arm_bx_glue, elf32_arm_bx_glue): New functions. (elf32_arm_final_link_relocate): Handle BX veneers. (elf32_arm_output_arch_local_syms): Output mapping symbol for .v4_bx. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-arm.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 412db5f..4d8eb42 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -143,6 +143,7 @@ static int atpcs = FALSE;
static int support_interwork = FALSE;
static int uses_apcs_float = FALSE;
static int pic_code = FALSE;
+static int fix_v4bx = FALSE;
/* Variables that we set while parsing command-line options. Once all
options have been read we re-process these values to set the real
@@ -6760,10 +6761,23 @@ do_blx (void)
static void
do_bx (void)
{
+ bfd_boolean want_reloc;
+
if (inst.operands[0].reg == REG_PC)
as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
inst.instruction |= inst.operands[0].reg;
+ /* Output R_ARM_V4BX relocations if is an EABI object that looks like
+ it is for ARMv4t or earlier. */
+ want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
+ if (object_arch && !ARM_CPU_HAS_FEATURE (*object_arch, arm_ext_v5))
+ want_reloc = TRUE;
+
+ if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
+ want_reloc = FALSE;
+
+ if (want_reloc)
+ inst.reloc.type = BFD_RELOC_ARM_V4BX;
}
@@ -14272,9 +14286,15 @@ md_assemble (char *str)
}
else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
{
+ bfd_boolean is_bx;
+
+ /* bx is allowed on v5 cores, and sometimes on v4 cores. */
+ is_bx = (opcode->aencode == do_bx);
+
/* Check that this instruction is supported for this CPU. */
- if (!opcode->avariant ||
- !ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant))
+ if (!(is_bx && fix_v4bx)
+ && !(opcode->avariant &&
+ ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
{
as_bad (_("selected processor does not support `%s'"), str);
return;
@@ -14296,8 +14316,7 @@ md_assemble (char *str)
opcode->aencode ();
/* Arm mode bx is marked as both v4T and v5 because it's still required
on a hypothetical non-thumb v5 core. */
- if (ARM_CPU_HAS_FEATURE (*opcode->avariant, arm_ext_v4t)
- || ARM_CPU_HAS_FEATURE (*opcode->avariant, arm_ext_v5))
+ if (is_bx)
ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
else
ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
@@ -18969,6 +18988,11 @@ md_apply_fix (fixS * fixP,
}
break;
+ case BFD_RELOC_ARM_V4BX:
+ /* This will need to go in the object file. */
+ fixP->fx_done = 0;
+ break;
+
case BFD_RELOC_UNUSED:
default:
as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -19119,6 +19143,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
case BFD_RELOC_ARM_LDC_SB_G0:
case BFD_RELOC_ARM_LDC_SB_G1:
case BFD_RELOC_ARM_LDC_SB_G2:
+ case BFD_RELOC_ARM_V4BX:
code = fixp->fx_r_type;
break;
@@ -19806,6 +19831,7 @@ const char * md_shortopts = "m:k";
#define OPTION_EL (OPTION_MD_BASE + 1)
#endif
#endif
+#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
struct option md_longopts[] =
{
@@ -19815,6 +19841,7 @@ struct option md_longopts[] =
#ifdef OPTION_EL
{"EL", no_argument, NULL, OPTION_EL},
#endif
+ {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
{NULL, no_argument, NULL, 0}
};
@@ -20430,6 +20457,10 @@ md_parse_option (int c, char * arg)
break;
#endif
+ case OPTION_FIX_V4BX:
+ fix_v4bx = TRUE;
+ break;
+
case 'a':
/* Listing option. Just ignore these, we don't support additional
ones. */
@@ -20527,6 +20558,9 @@ md_show_usage (FILE * fp)
fprintf (fp, _("\
-EL assemble code for a little-endian cpu\n"));
#endif
+
+ fprintf (fp, _("\
+ --fix-v4bx Allow BX in ARMv4 code\n"));
}