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.
This commit is contained in:
parent
40887e1a6e
commit
845b51d665
21 changed files with 527 additions and 20 deletions
|
@ -3089,6 +3089,9 @@ pc-relative or some form of GOT-indirect relocation. */
|
|||
BFD_RELOC_ARM_LDC_SB_G1,
|
||||
BFD_RELOC_ARM_LDC_SB_G2,
|
||||
|
||||
/* Annotation of BX instructions. */
|
||||
BFD_RELOC_ARM_V4BX,
|
||||
|
||||
/* These relocs are only used within the ARM assembler. They are not
|
||||
(at present) written to any object files. */
|
||||
BFD_RELOC_ARM_IMMEDIATE,
|
||||
|
|
208
bfd/elf32-arm.c
208
bfd/elf32-arm.c
|
@ -1773,7 +1773,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
|
|||
{BFD_RELOC_ARM_LDRS_SB_G2, R_ARM_LDRS_SB_G2},
|
||||
{BFD_RELOC_ARM_LDC_SB_G0, R_ARM_LDC_SB_G0},
|
||||
{BFD_RELOC_ARM_LDC_SB_G1, R_ARM_LDC_SB_G1},
|
||||
{BFD_RELOC_ARM_LDC_SB_G2, R_ARM_LDC_SB_G2}
|
||||
{BFD_RELOC_ARM_LDC_SB_G2, R_ARM_LDC_SB_G2},
|
||||
{BFD_RELOC_ARM_V4BX, R_ARM_V4BX}
|
||||
};
|
||||
|
||||
static reloc_howto_type *
|
||||
|
@ -1904,6 +1905,9 @@ typedef unsigned short int insn16;
|
|||
#define VFP11_ERRATUM_VENEER_SECTION_NAME ".vfp11_veneer"
|
||||
#define VFP11_ERRATUM_VENEER_ENTRY_NAME "__vfp11_veneer_%x"
|
||||
|
||||
#define ARM_BX_GLUE_SECTION_NAME ".v4_bx"
|
||||
#define ARM_BX_GLUE_ENTRY_NAME "__bx_r%d"
|
||||
|
||||
/* The name of the dynamic interpreter. This is put in the .interp
|
||||
section. */
|
||||
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
|
||||
|
@ -2171,6 +2175,13 @@ struct elf32_arm_link_hash_table
|
|||
/* The size in bytes of the section containing the ARM-to-Thumb glue. */
|
||||
bfd_size_type arm_glue_size;
|
||||
|
||||
/* The size in bytes of section containing the ARMv4 BX veneers. */
|
||||
bfd_size_type bx_glue_size;
|
||||
|
||||
/* Offsets of ARMv4 BX veneers. Bit1 set if present, and Bit0 set when
|
||||
veneer has been populated. */
|
||||
bfd_vma bx_glue_offset[15];
|
||||
|
||||
/* The size in bytes of the section containing glue for VFP11 erratum
|
||||
veneers. */
|
||||
bfd_size_type vfp11_erratum_glue_size;
|
||||
|
@ -2188,7 +2199,9 @@ struct elf32_arm_link_hash_table
|
|||
/* The relocation to use for R_ARM_TARGET2 relocations. */
|
||||
int target2_reloc;
|
||||
|
||||
/* Nonzero to fix BX instructions for ARMv4 targets. */
|
||||
/* 0 = Ignore R_ARM_V4BX.
|
||||
1 = Convert BX to MOV PC.
|
||||
2 = Generate v4 interworing stubs. */
|
||||
int fix_v4bx;
|
||||
|
||||
/* Nonzero if the ARM/Thumb BLX instructions are available for use. */
|
||||
|
@ -2469,6 +2482,8 @@ elf32_arm_link_hash_table_create (bfd *abfd)
|
|||
ret->srelplt2 = NULL;
|
||||
ret->thumb_glue_size = 0;
|
||||
ret->arm_glue_size = 0;
|
||||
ret->bx_glue_size = 0;
|
||||
memset (ret->bx_glue_offset, 0, sizeof(ret->bx_glue_offset));
|
||||
ret->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
|
||||
ret->vfp11_erratum_glue_size = 0;
|
||||
ret->num_vfp11_fixes = 0;
|
||||
|
@ -2626,6 +2641,11 @@ static const insn32 t2a3_b_insn = 0xea000000;
|
|||
|
||||
#define VFP11_ERRATUM_VENEER_SIZE 8
|
||||
|
||||
#define ARM_BX_VENEER_SIZE 12
|
||||
static const insn32 armbx1_tst_insn = 0xe3100001;
|
||||
static const insn32 armbx2_moveq_insn = 0x01a0f000;
|
||||
static const insn32 armbx3_bx_insn = 0xe12fff10;
|
||||
|
||||
#ifndef ELFARM_NABI_C_INCLUDED
|
||||
bfd_boolean
|
||||
bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
|
||||
|
@ -2684,6 +2704,21 @@ bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
|
|||
s->contents = foo;
|
||||
}
|
||||
|
||||
if (globals->bx_glue_size != 0)
|
||||
{
|
||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
||||
|
||||
s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
|
||||
ARM_BX_GLUE_SECTION_NAME);
|
||||
|
||||
BFD_ASSERT (s != NULL);
|
||||
|
||||
foo = bfd_alloc (globals->bfd_of_glue_owner, globals->bx_glue_size);
|
||||
|
||||
BFD_ASSERT (s->size == globals->bx_glue_size);
|
||||
s->contents = foo;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2835,6 +2870,64 @@ record_thumb_to_arm_glue (struct bfd_link_info *link_info,
|
|||
}
|
||||
|
||||
|
||||
/* Allocate space for ARMv4 BX veneers. */
|
||||
|
||||
static void
|
||||
record_arm_bx_glue (struct bfd_link_info * link_info, int reg)
|
||||
{
|
||||
asection * s;
|
||||
struct elf32_arm_link_hash_table *globals;
|
||||
char *tmp_name;
|
||||
struct elf_link_hash_entry *myh;
|
||||
struct bfd_link_hash_entry *bh;
|
||||
bfd_vma val;
|
||||
|
||||
/* BX PC does not need a veneer. */
|
||||
if (reg == 15)
|
||||
return;
|
||||
|
||||
globals = elf32_arm_hash_table (link_info);
|
||||
|
||||
BFD_ASSERT (globals != NULL);
|
||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
||||
|
||||
/* Check if this veneer has already been allocated. */
|
||||
if (globals->bx_glue_offset[reg])
|
||||
return;
|
||||
|
||||
s = bfd_get_section_by_name
|
||||
(globals->bfd_of_glue_owner, ARM_BX_GLUE_SECTION_NAME);
|
||||
|
||||
BFD_ASSERT (s != NULL);
|
||||
|
||||
/* Add symbol for veneer. */
|
||||
tmp_name = bfd_malloc ((bfd_size_type) strlen (ARM_BX_GLUE_ENTRY_NAME) + 1);
|
||||
|
||||
BFD_ASSERT (tmp_name);
|
||||
|
||||
sprintf (tmp_name, ARM_BX_GLUE_ENTRY_NAME, reg);
|
||||
|
||||
myh = elf_link_hash_lookup
|
||||
(&(globals)->root, tmp_name, FALSE, FALSE, FALSE);
|
||||
|
||||
BFD_ASSERT (myh == NULL);
|
||||
|
||||
bh = NULL;
|
||||
val = globals->bx_glue_size;
|
||||
_bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
|
||||
tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
|
||||
NULL, TRUE, FALSE, &bh);
|
||||
|
||||
myh = (struct elf_link_hash_entry *) bh;
|
||||
myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
|
||||
myh->forced_local = 1;
|
||||
|
||||
s->size += ARM_BX_VENEER_SIZE;
|
||||
globals->bx_glue_offset[reg] = globals->bx_glue_size | 2;
|
||||
globals->bx_glue_size += ARM_BX_VENEER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/* Add an entry to the code/data map for section SEC. */
|
||||
|
||||
static void
|
||||
|
@ -3058,6 +3151,24 @@ bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
|
|||
sec->gc_mark = 1;
|
||||
}
|
||||
|
||||
sec = bfd_get_section_by_name (abfd, ARM_BX_GLUE_SECTION_NAME);
|
||||
|
||||
if (sec == NULL)
|
||||
{
|
||||
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
|
||||
| SEC_CODE | SEC_READONLY);
|
||||
|
||||
sec = bfd_make_section_with_flags (abfd,
|
||||
ARM_BX_GLUE_SECTION_NAME,
|
||||
flags);
|
||||
|
||||
if (sec == NULL
|
||||
|| !bfd_set_section_alignment (abfd, sec, 2))
|
||||
return FALSE;
|
||||
|
||||
sec->gc_mark = 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -3177,7 +3288,8 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
|
|||
&& r_type != R_ARM_CALL
|
||||
&& r_type != R_ARM_JUMP24
|
||||
&& r_type != R_ARM_THM_CALL
|
||||
&& r_type != R_ARM_THM_JUMP24)
|
||||
&& r_type != R_ARM_THM_JUMP24
|
||||
&& (r_type != R_ARM_V4BX || globals->fix_v4bx < 2))
|
||||
continue;
|
||||
|
||||
/* Get the section contents if we haven't done so already. */
|
||||
|
@ -3194,6 +3306,15 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
|
|||
}
|
||||
}
|
||||
|
||||
if (r_type == R_ARM_V4BX)
|
||||
{
|
||||
int reg;
|
||||
|
||||
reg = bfd_get_32 (abfd, contents + irel->r_offset) & 0xf;
|
||||
record_arm_bx_glue (link_info, reg);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the relocation is not against a symbol it cannot concern us. */
|
||||
h = NULL;
|
||||
|
||||
|
@ -4332,6 +4453,43 @@ elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Populate ARMv4 BX veneers. Returns the absolute adress of the veneer. */
|
||||
|
||||
static bfd_vma
|
||||
elf32_arm_bx_glue (struct bfd_link_info * info, int reg)
|
||||
{
|
||||
bfd_byte *p;
|
||||
bfd_vma glue_addr;
|
||||
asection *s;
|
||||
struct elf32_arm_link_hash_table *globals;
|
||||
|
||||
globals = elf32_arm_hash_table (info);
|
||||
|
||||
BFD_ASSERT (globals != NULL);
|
||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
||||
|
||||
s = bfd_get_section_by_name (globals->bfd_of_glue_owner,
|
||||
ARM_BX_GLUE_SECTION_NAME);
|
||||
BFD_ASSERT (s != NULL);
|
||||
BFD_ASSERT (s->contents != NULL);
|
||||
BFD_ASSERT (s->output_section != NULL);
|
||||
|
||||
BFD_ASSERT (globals->bx_glue_offset[reg] & 2);
|
||||
|
||||
glue_addr = globals->bx_glue_offset[reg] & ~(bfd_vma)3;
|
||||
|
||||
if ((globals->bx_glue_offset[reg] & 1) == 0)
|
||||
{
|
||||
p = s->contents + glue_addr;
|
||||
bfd_put_32 (globals->obfd, armbx1_tst_insn + (reg << 16), p);
|
||||
bfd_put_32 (globals->obfd, armbx2_moveq_insn + reg, p + 4);
|
||||
bfd_put_32 (globals->obfd, armbx3_bx_insn + reg, p + 8);
|
||||
globals->bx_glue_offset[reg] |= 1;
|
||||
}
|
||||
|
||||
return glue_addr + s->output_section->vma + s->output_offset;
|
||||
}
|
||||
|
||||
/* Generate Arm stubs for exported Thumb symbols. */
|
||||
static void
|
||||
elf32_arm_begin_write_processing (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
|
@ -5710,18 +5868,32 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
|||
|
||||
case R_ARM_V4BX:
|
||||
if (globals->fix_v4bx)
|
||||
{
|
||||
bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
|
||||
{
|
||||
bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
|
||||
|
||||
/* Ensure that we have a BX instruction. */
|
||||
BFD_ASSERT ((insn & 0x0ffffff0) == 0x012fff10);
|
||||
/* Ensure that we have a BX instruction. */
|
||||
BFD_ASSERT ((insn & 0x0ffffff0) == 0x012fff10);
|
||||
|
||||
/* Preserve Rm (lowest four bits) and the condition code
|
||||
(highest four bits). Other bits encode MOV PC,Rm. */
|
||||
insn = (insn & 0xf000000f) | 0x01a0f000;
|
||||
if (globals->fix_v4bx == 2 && (insn & 0xf) != 0xf)
|
||||
{
|
||||
/* Branch to veneer. */
|
||||
bfd_vma glue_addr;
|
||||
glue_addr = elf32_arm_bx_glue (info, insn & 0xf);
|
||||
glue_addr -= input_section->output_section->vma
|
||||
+ input_section->output_offset
|
||||
+ rel->r_offset + 8;
|
||||
insn = (insn & 0xf0000000) | 0x0a000000
|
||||
| ((glue_addr >> 2) & 0x00ffffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Preserve Rm (lowest four bits) and the condition code
|
||||
(highest four bits). Other bits encode MOV PC,Rm. */
|
||||
insn = (insn & 0xf000000f) | 0x01a0f000;
|
||||
}
|
||||
|
||||
bfd_put_32 (input_bfd, insn, hit_data);
|
||||
}
|
||||
bfd_put_32 (input_bfd, insn, hit_data);
|
||||
}
|
||||
return bfd_reloc_ok;
|
||||
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
|
@ -9732,6 +9904,18 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
|
|||
}
|
||||
}
|
||||
|
||||
/* ARMv4 BX veneers. */
|
||||
if (htab->bx_glue_size > 0)
|
||||
{
|
||||
osi.sec = bfd_get_section_by_name (htab->bfd_of_glue_owner,
|
||||
ARM_BX_GLUE_SECTION_NAME);
|
||||
|
||||
osi.sec_shndx = _bfd_elf_section_from_bfd_section
|
||||
(output_bfd, osi.sec->output_section);
|
||||
|
||||
elf32_arm_ouput_plt_map_sym (&osi, ARM_MAP_ARM, 0);
|
||||
}
|
||||
|
||||
/* Finally, output mapping symbols for the PLT. */
|
||||
if (!htab->splt || htab->splt->size == 0)
|
||||
return TRUE;
|
||||
|
|
|
@ -1282,6 +1282,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|||
"BFD_RELOC_ARM_LDC_SB_G0",
|
||||
"BFD_RELOC_ARM_LDC_SB_G1",
|
||||
"BFD_RELOC_ARM_LDC_SB_G2",
|
||||
"BFD_RELOC_ARM_V4BX",
|
||||
"BFD_RELOC_ARM_IMMEDIATE",
|
||||
"BFD_RELOC_ARM_ADRL_IMMEDIATE",
|
||||
"BFD_RELOC_ARM_T32_IMMEDIATE",
|
||||
|
|
|
@ -2924,6 +2924,11 @@ ENUMX
|
|||
ENUMDOC
|
||||
ARM group relocations.
|
||||
|
||||
ENUM
|
||||
BFD_RELOC_ARM_V4BX
|
||||
ENUMDOC
|
||||
Annotation of BX instructions.
|
||||
|
||||
ENUM
|
||||
BFD_RELOC_ARM_IMMEDIATE
|
||||
ENUMX
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -276,6 +276,11 @@ be marked as being encoded for a little-endian processor.
|
|||
This option specifies that the output of the assembler should be marked
|
||||
as position-independent code (PIC).
|
||||
|
||||
@cindex @code{--fix-v4bx} command line option, ARM
|
||||
@item --fix-v4bx
|
||||
Allow @code{BX} instructions in ARMv4 code. This is intended for use with
|
||||
the linker option of the same name.
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
|
|
40
gas/testsuite/gas/arm/arch4t-eabi.d
Normal file
40
gas/testsuite/gas/arm/arch4t-eabi.d
Normal file
|
@ -0,0 +1,40 @@
|
|||
# name: ARM architecture 4t instructions (EABI)
|
||||
# as: -march=armv4t
|
||||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
# source: arch4t.s
|
||||
# target: *-*-*eabi *-*-symbianelf
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
Disassembly of section .text:
|
||||
0+00 <[^>]+> e12fff10 ? bx r0
|
||||
.*: R_ARM_V4BX.*
|
||||
0+04 <[^>]+> 012fff11 ? bxeq r1
|
||||
.*: R_ARM_V4BX.*
|
||||
0+08 <[^>]+> e15f30b8 ? ldrh r3, \[pc, #-8\] ; 0+08 <[^>]+>
|
||||
0+0c <[^>]+> e1d540f0 ? ldrsh r4, \[r5\]
|
||||
0+10 <[^>]+> e19140d3 ? ldrsb r4, \[r1, r3\]
|
||||
0+14 <[^>]+> e1b410f4 ? ldrsh r1, \[r4, r4\]!
|
||||
0+18 <[^>]+> 011510d3 ? ldrsbeq r1, \[r5, -r3\]
|
||||
0+1c <[^>]+> 109620b7 ? ldrhne r2, \[r6\], r7
|
||||
0+20 <[^>]+> 309720f8 ? ldrshcc r2, \[r7\], r8
|
||||
0+24 <[^>]+> e1d32fdf ? ldrsb r2, \[r3, #255\]
|
||||
0+28 <[^>]+> e1541ffa ? ldrsh r1, \[r4, #-250\]
|
||||
0+2c <[^>]+> e1d51fd0 ? ldrsb r1, \[r5, #240\]
|
||||
0+30 <[^>]+> e1cf23b0 ? strh r2, \[pc, #48\] ; 0+68 <[^>]+>
|
||||
0+34 <[^>]+> 11c330b0 ? strhne r3, \[r3\]
|
||||
0+38 <[^>]+> e328f002 ? msr CPSR_f, #2 ; 0x2
|
||||
0+3c <[^>]+> e121f003 ? msr CPSR_c, r3
|
||||
0+40 <[^>]+> e122f004 ? msr CPSR_x, r4
|
||||
0+44 <[^>]+> e124f005 ? msr CPSR_s, r5
|
||||
0+48 <[^>]+> e128f006 ? msr CPSR_f, r6
|
||||
0+4c <[^>]+> e129f007 ? msr CPSR_fc, r7
|
||||
0+50 <[^>]+> e368f004 ? msr SPSR_f, #4 ; 0x4
|
||||
0+54 <[^>]+> e161f008 ? msr SPSR_c, r8
|
||||
0+58 <[^>]+> e162f009 ? msr SPSR_x, r9
|
||||
0+5c <[^>]+> e164f00a ? msr SPSR_s, sl
|
||||
0+60 <[^>]+> e168f00b ? msr SPSR_f, fp
|
||||
0+64 <[^>]+> e169f00c ? msr SPSR_fc, ip
|
||||
0+68 <[^>]+> e1a00000 ? nop \(mov r0,r0\)
|
||||
0+6c <[^>]+> e1a00000 ? nop \(mov r0,r0\)
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
# name: ARM architecture 4t instructions
|
||||
# as: -march=armv4t
|
||||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
# EABI targets have their own variant.
|
||||
# not-target: *-*-*eabi *-*-symbianelf
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
|
|
165
gas/testsuite/gas/arm/thumb-eabi.d
Normal file
165
gas/testsuite/gas/arm/thumb-eabi.d
Normal file
|
@ -0,0 +1,165 @@
|
|||
# name: Thumb instructions (EABI)
|
||||
# as: -mcpu=arm7t
|
||||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
# source: thumb.s
|
||||
# target: *-*-*eabi *-*-symbianelf
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
Disassembly of section \.text:
|
||||
0+000 <[^>]+> 00ca lsls r2, r1, #3
|
||||
0+002 <[^>]+> 0fe3 lsrs r3, r4, #31
|
||||
0+004 <[^>]+> 1147 asrs r7, r0, #5
|
||||
0+006 <[^>]+> 0011 lsls r1, r2, #0
|
||||
0+008 <[^>]+> 0023 lsls r3, r4, #0
|
||||
0+00a <[^>]+> 002c lsls r4, r5, #0
|
||||
0+00c <[^>]+> 083e lsrs r6, r7, #32
|
||||
0+00e <[^>]+> 1008 asrs r0, r1, #32
|
||||
0+010 <[^>]+> 18d1 adds r1, r2, r3
|
||||
0+012 <[^>]+> 1ca2 adds r2, r4, #2
|
||||
0+014 <[^>]+> 1beb subs r3, r5, r7
|
||||
0+016 <[^>]+> 1fe2 subs r2, r4, #7
|
||||
0+018 <[^>]+> 24ff movs r4, #255
|
||||
0+01a <[^>]+> 2bfa cmp r3, #250
|
||||
0+01c <[^>]+> 367b adds r6, #123
|
||||
0+01e <[^>]+> 3d80 subs r5, #128
|
||||
0+020 <[^>]+> 402b ands r3, r5
|
||||
0+022 <[^>]+> 4074 eors r4, r6
|
||||
0+024 <[^>]+> 4081 lsls r1, r0
|
||||
0+026 <[^>]+> 40da lsrs r2, r3
|
||||
0+028 <[^>]+> 4134 asrs r4, r6
|
||||
0+02a <[^>]+> 417d adcs r5, r7
|
||||
0+02c <[^>]+> 41a0 sbcs r0, r4
|
||||
0+02e <[^>]+> 41e1 rors r1, r4
|
||||
0+030 <[^>]+> 422a tst r2, r5
|
||||
0+032 <[^>]+> 4249 negs r1, r1
|
||||
0+034 <[^>]+> 429a cmp r2, r3
|
||||
0+036 <[^>]+> 42e1 cmn r1, r4
|
||||
0+038 <[^>]+> 4318 orrs r0, r3
|
||||
0+03a <[^>]+> 436c muls r4, r5
|
||||
0+03c <[^>]+> 43bd bics r5, r7
|
||||
0+03e <[^>]+> 43ed mvns r5, r5
|
||||
0+040 <[^>]+> 4469 add r1, sp
|
||||
0+042 <[^>]+> 4494 add ip, r2
|
||||
0+044 <[^>]+> 44c9 add r9, r9
|
||||
0+046 <[^>]+> 4571 cmp r1, lr
|
||||
0+048 <[^>]+> 4580 cmp r8, r0
|
||||
0+04a <[^>]+> 45f4 cmp ip, lr
|
||||
0+04c <[^>]+> 4648 mov r0, r9
|
||||
0+04e <[^>]+> 46a1 mov r9, r4
|
||||
0+050 <[^>]+> 46c0 nop \(mov r8, r8\)
|
||||
0+052 <[^>]+> 4738 bx r7
|
||||
0+054 <[^>]+> 4740 bx r8
|
||||
0+056 <[^>]+> 46c0 nop \(mov r8, r8\)
|
||||
0+058 <[^>]+> 4778 bx pc
|
||||
0+05a <[^>]+> 4b20 ldr r3, \[pc, #128\] \(0+0dc <[^>]+>\)
|
||||
0+05c <[^>]+> 4c02 ldr r4, \[pc, #8\] \(0+068 <[^>]+>\)
|
||||
0+05e <[^>]+> 5088 str r0, \[r1, r2\]
|
||||
0+060 <[^>]+> 5511 strb r1, \[r2, r4\]
|
||||
0+062 <[^>]+> 59f5 ldr r5, \[r6, r7\]
|
||||
0+064 <[^>]+> 5d62 ldrb r2, \[r4, r5\]
|
||||
0+066 <[^>]+> 46c0 nop \(mov r8, r8\)
|
||||
0+068 <[^>]+> 52d1 strh r1, \[r2, r3\]
|
||||
0+06a <[^>]+> 5a23 ldrh r3, \[r4, r0\]
|
||||
0+06c <[^>]+> 57f1 ldrsb r1, \[r6, r7\]
|
||||
0+06e <[^>]+> 5f42 ldrsh r2, \[r0, r5\]
|
||||
0+070 <[^>]+> 67db str r3, \[r3, #124\]
|
||||
0+072 <[^>]+> 6fe1 ldr r1, \[r4, #124\]
|
||||
0+074 <[^>]+> 682d ldr r5, \[r5, #0\]
|
||||
0+076 <[^>]+> 77e9 strb r1, \[r5, #31\]
|
||||
0+078 <[^>]+> 7161 strb r1, \[r4, #5\]
|
||||
0+07a <[^>]+> 7032 strb r2, \[r6, #0\]
|
||||
0+07c <[^>]+> 87ec strh r4, \[r5, #62\]
|
||||
0+07e <[^>]+> 8885 ldrh r5, \[r0, #4\]
|
||||
0+080 <[^>]+> 8813 ldrh r3, \[r2, #0\]
|
||||
0+082 <[^>]+> 93ff str r3, \[sp, #1020\]
|
||||
0+084 <[^>]+> 990b ldr r1, \[sp, #44\]
|
||||
0+086 <[^>]+> 9a00 ldr r2, \[sp, #0\]
|
||||
0+088 <[^>]+> a7ff add r7, pc, #1020 \(adr r7, 0+488 <[^>]+>\)
|
||||
0+08a <[^>]+> ac80 add r4, sp, #512
|
||||
0+08c <[^>]+> b043 add sp, #268
|
||||
0+08e <[^>]+> b09a sub sp, #104
|
||||
0+090 <[^>]+> b0c3 sub sp, #268
|
||||
0+092 <[^>]+> b01b add sp, #108
|
||||
0+094 <[^>]+> b417 push {r0, r1, r2, r4}
|
||||
0+096 <[^>]+> b5f9 push {r0, r3, r4, r5, r6, r7, lr}
|
||||
0+098 <[^>]+> bc98 pop {r3, r4, r7}
|
||||
0+09a <[^>]+> bdff pop {r0, r1, r2, r3, r4, r5, r6, r7, pc}
|
||||
0+09c <[^>]+> c3f3 stmia r3!, {r0, r1, r4, r5, r6, r7}
|
||||
0+09e <[^>]+> c8fe ldmia r0!, {r1, r2, r3, r4, r5, r6, r7}
|
||||
0+0a0 <[^>]+> d0e2 beq.n 0+068 <[^>]+>
|
||||
0+0a2 <[^>]+> d1e1 bne.n 0+068 <[^>]+>
|
||||
0+0a4 <[^>]+> d2e0 bcs.n 0+068 <[^>]+>
|
||||
0+0a6 <[^>]+> d3df bcc.n 0+068 <[^>]+>
|
||||
0+0a8 <[^>]+> d4de bmi.n 0+068 <[^>]+>
|
||||
0+0aa <[^>]+> d5dd bpl.n 0+068 <[^>]+>
|
||||
0+0ac <[^>]+> d6dc bvs.n 0+068 <[^>]+>
|
||||
0+0ae <[^>]+> d7db bvc.n 0+068 <[^>]+>
|
||||
0+0b0 <[^>]+> d8da bhi.n 0+068 <[^>]+>
|
||||
0+0b2 <[^>]+> d9d9 bls.n 0+068 <[^>]+>
|
||||
0+0b4 <[^>]+> dad8 bge.n 0+068 <[^>]+>
|
||||
0+0b6 <[^>]+> dcd7 bgt.n 0+068 <[^>]+>
|
||||
0+0b8 <[^>]+> dbd6 blt.n 0+068 <[^>]+>
|
||||
0+0ba <[^>]+> dcd5 bgt.n 0+068 <[^>]+>
|
||||
0+0bc <[^>]+> ddd4 ble.n 0+068 <[^>]+>
|
||||
0+0be <[^>]+> d8d3 bhi.n 0+068 <[^>]+>
|
||||
0+0c0 <[^>]+> d3d2 bcc.n 0+068 <[^>]+>
|
||||
0+0c2 <[^>]+> d3d1 bcc.n 0+068 <[^>]+>
|
||||
0+0c4 <[^>]+> e7d0 b.n 0+068 <[^>]+>
|
||||
0+0c6 <[^>]+> 00ac lsls r4, r5, #2
|
||||
0+0c8 <[^>]+> 1c9a adds r2, r3, #2
|
||||
0+0ca <[^>]+> b07f add sp, #508
|
||||
0+0cc <[^>]+> b0ff sub sp, #508
|
||||
0+0ce <[^>]+> a8ff add r0, sp, #1020
|
||||
0+0d0 <[^>]+> a0ff add r0, pc, #1020 \(adr r0, 0+4d0 <[^>]+>\)
|
||||
0+0d2 <[^>]+> b01a add sp, #104
|
||||
0+0d4 <[^>]+> b09a sub sp, #104
|
||||
0+0d6 <[^>]+> a81a add r0, sp, #104
|
||||
0+0d8 <[^>]+> a01a add r0, pc, #104 \(adr r0, 0+144 <[^>]+>\)
|
||||
0+0da <[^>]+> 3168 adds r1, #104
|
||||
0+0dc <[^>]+> 2668 movs r6, #104
|
||||
0+0de <[^>]+> 2f68 cmp r7, #104
|
||||
0+0e0 <[^>]+> 46c0 nop \(mov r8, r8\)
|
||||
0+0e2 <[^>]+> 46c0 nop \(mov r8, r8\)
|
||||
0+0e4 <[^>]+> eafffffe b 0+0e4 <[^>]+>
|
||||
0+0e8 <[^>]+> ea000011 b 0+134 <[^>]+>
|
||||
0+0ec <[^>]+> ebfffffc bl 0+0e4 <[^>]+>
|
||||
0+0f0 <[^>]+> eb00000f bl 0+134 <[^>]+>
|
||||
0+0f4 <[^>]+> e12fff10 bx r0
|
||||
.*: R_ARM_V4BX.*
|
||||
0+0f8 <[^>]+> ef123456 (swi|svc) 0x00123456
|
||||
0+0fc <[^>]+> a004 add r0, pc, #16 \(adr r0, 0+110 <[^>]+>\)
|
||||
0+0fe <[^>]+> e77f b.n 0+000 <[^>]+>
|
||||
0+100 <[^>]+> e018 b.n 0+134 <[^>]+>
|
||||
0+102 <[^>]+> f7ff ff7d bl 0+000 <[^>]+>
|
||||
0+106 <[^>]+> f000 f815 bl 0+134 <[^>]+>
|
||||
0+10a <[^>]+> 4700 bx r0
|
||||
0+10c <[^>]+> dfff (swi|svc) 255
|
||||
0+10e <[^>]+> 46c0 nop \(mov r8, r8\)
|
||||
0+110 <[^>]+> d010 beq.n 0+134 <[^>]+>
|
||||
0+112 <[^>]+> d10f bne.n 0+134 <[^>]+>
|
||||
0+114 <[^>]+> d20e bcs.n 0+134 <[^>]+>
|
||||
0+116 <[^>]+> d30d bcc.n 0+134 <[^>]+>
|
||||
0+118 <[^>]+> d40c bmi.n 0+134 <[^>]+>
|
||||
0+11a <[^>]+> d50b bpl.n 0+134 <[^>]+>
|
||||
0+11c <[^>]+> d60a bvs.n 0+134 <[^>]+>
|
||||
0+11e <[^>]+> d709 bvc.n 0+134 <[^>]+>
|
||||
0+120 <[^>]+> d808 bhi.n 0+134 <[^>]+>
|
||||
0+122 <[^>]+> d907 bls.n 0+134 <[^>]+>
|
||||
0+124 <[^>]+> da06 bge.n 0+134 <[^>]+>
|
||||
0+126 <[^>]+> dc05 bgt.n 0+134 <[^>]+>
|
||||
0+128 <[^>]+> db04 blt.n 0+134 <[^>]+>
|
||||
0+12a <[^>]+> dc03 bgt.n 0+134 <[^>]+>
|
||||
0+12c <[^>]+> dd02 ble.n 0+134 <[^>]+>
|
||||
0+12e <[^>]+> d801 bhi.n 0+134 <[^>]+>
|
||||
0+130 <[^>]+> d300 bcc.n 0+134 <[^>]+>
|
||||
0+132 <[^>]+> d3ff bcc.n 0+134 <[^>]+>
|
||||
0+134 <[^>]+> f000 fc00 bl 0+938 <[^>]+>
|
||||
\.\.\.
|
||||
0+938 <[^>]+> f7ff fbfc bl 0+134 <[^>]+>
|
||||
0+93c <[^>]+> 4801 ldr r0, \[pc, #4\] \(0+944 <[^>]+>\)
|
||||
0+93e <[^>]+> 4801 ldr r0, \[pc, #4\] \(0+944 <[^>]+>\)
|
||||
0+940 <[^>]+> 4801 ldr r0, \[pc, #4\] \(0+948 <[^>]+>\)
|
||||
0+942 <[^>]+> 4801 ldr r0, \[pc, #4\] \(0+948 <[^>]+>\)
|
||||
0+944 <[^>]+> 46c0 nop \(mov r8, r8\)
|
||||
0+946 <[^>]+> 46c0 nop \(mov r8, r8\)
|
|
@ -2,7 +2,8 @@
|
|||
# as: -mcpu=arm7t
|
||||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
# The arm-aout and arm-pe ports do not support Thumb branch relocations.
|
||||
# not-target: *-*-*aout* *-*-pe
|
||||
# EABI targets have their own variant.
|
||||
# not-target: *-*-*aout* *-*-pe *-*-*eabi *-*-symbianelf
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
|
|
10
gas/testsuite/gas/arm/v4bx.d
Normal file
10
gas/testsuite/gas/arm/v4bx.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
# as: -meabi=4 --fix-v4bx
|
||||
# This test is only valid on ELF based ports.
|
||||
#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
Disassembly of section .text:
|
||||
0+00 <[^>]+> e12fff1e bx lr
|
||||
0: R_ARM_V4BX \*ABS\*
|
4
gas/testsuite/gas/arm/v4bx.s
Normal file
4
gas/testsuite/gas/arm/v4bx.s
Normal file
|
@ -0,0 +1,4 @@
|
|||
.arch armv4
|
||||
.text
|
||||
foo:
|
||||
bx lr
|
|
@ -6,7 +6,7 @@ LITTLE_OUTPUT_FORMAT="elf32-littlearm"
|
|||
TEXT_START_ADDR=0x8000
|
||||
TEMPLATE_NAME=elf32
|
||||
EXTRA_EM_FILE=armelf
|
||||
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
|
||||
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)'
|
||||
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
|
||||
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
|
||||
OTHER_END_SYMBOLS='__end__ = . ;'
|
||||
|
|
|
@ -11,7 +11,7 @@ GENERATE_SHLIB_SCRIPT=yes
|
|||
GENERATE_PIE_SCRIPT=yes
|
||||
|
||||
DATA_START_SYMBOLS='__data_start = . ;';
|
||||
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
|
||||
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)'
|
||||
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
|
||||
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
|
||||
OTHER_END_SYMBOLS='__end__ = . ;'
|
||||
|
|
|
@ -6,7 +6,7 @@ LITTLE_OUTPUT_FORMAT="elf32-littlearm"
|
|||
TEXT_START_ADDR=0x00100000
|
||||
TEMPLATE_NAME=elf32
|
||||
EXTRA_EM_FILE=armelf
|
||||
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
|
||||
OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)'
|
||||
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
|
||||
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
|
||||
OTHER_END_SYMBOLS='__end__ = . ;'
|
||||
|
|
|
@ -264,6 +264,7 @@ PARSE_AND_LIST_PROLOGUE='
|
|||
#define OPTION_VFP11_DENORM_FIX 308
|
||||
#define OPTION_NO_ENUM_SIZE_WARNING 309
|
||||
#define OPTION_PIC_VENEER 310
|
||||
#define OPTION_FIX_V4BX_INTERWORKING 311
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_SHORTOPTS=p
|
||||
|
@ -276,6 +277,7 @@ PARSE_AND_LIST_LONGOPTS='
|
|||
{ "target1-abs", no_argument, NULL, OPTION_TARGET1_ABS},
|
||||
{ "target2", required_argument, NULL, OPTION_TARGET2},
|
||||
{ "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},
|
||||
{ "vfp11-denorm-fix", required_argument, NULL, OPTION_VFP11_DENORM_FIX},
|
||||
{ "no-enum-size-warning", no_argument, NULL, OPTION_NO_ENUM_SIZE_WARNING},
|
||||
|
@ -289,6 +291,7 @@ PARSE_AND_LIST_OPTIONS='
|
|||
fprintf (file, _(" --target1=abs Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));
|
||||
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, _(" --vfp11-denorm-fix Specify how to fix VFP11 denorm erratum\n"));
|
||||
fprintf (file, _(" --no-enum-size-warning Don'\''t warn about objects with incompatible"
|
||||
|
@ -325,6 +328,10 @@ PARSE_AND_LIST_ARGS_CASES='
|
|||
fix_v4bx = 1;
|
||||
break;
|
||||
|
||||
case OPTION_FIX_V4BX_INTERWORKING:
|
||||
fix_v4bx = 2;
|
||||
break;
|
||||
|
||||
case OPTION_USE_BLX:
|
||||
use_blx = 1;
|
||||
break;
|
||||
|
|
|
@ -5584,6 +5584,21 @@ linker, which causes v4t @code{BX rM} instructions to be rewritten as
|
|||
In the former case, the switch should not be used, and @samp{R_ARM_V4BX}
|
||||
relocations are ignored.
|
||||
|
||||
@cindex FIX_V4BX_INTERWORKING
|
||||
@kindex --fix-v4bx-interworking
|
||||
Replace @code{BX rM} instructions identified by @samp{R_ARM_V4BX}
|
||||
relocations with a branch to the following veneer:
|
||||
|
||||
@smallexample
|
||||
TST rM, #1
|
||||
MOVEQ PC, rM
|
||||
BX Rn
|
||||
@end smallexample
|
||||
|
||||
This allows generation of libraries/applications that work on ARMv4 cores
|
||||
and are still interworking safe. Note that the above veneer clobbers the
|
||||
condition flags, so may cause incorrect progrm behavior in rare cases.
|
||||
|
||||
@cindex USE_BLX
|
||||
@kindex --use-blx
|
||||
The @samp{--use-blx} switch enables the linker to use ARM/Thumb
|
||||
|
|
|
@ -173,6 +173,9 @@ set armelftests {
|
|||
{"callweak" "-static -T arm.ld" "" {callweak.s}
|
||||
{{objdump -dr callweak.d}}
|
||||
"callweak"}
|
||||
{"ARMv4 interworking" "-static -T arm.ld --fix-v4bx-interworking" "--fix-v4bx -meabi=4" {armv4-bx.s}
|
||||
{{objdump -d armv4-bx.d}}
|
||||
"armv4-bx"}
|
||||
}
|
||||
|
||||
run_ld_link_tests $armelftests
|
||||
|
|
|
@ -11,6 +11,7 @@ SECTIONS
|
|||
*(.text)
|
||||
*(.after)
|
||||
*(.glue_7)
|
||||
*(.v4_bx)
|
||||
} =0
|
||||
. = 0x9000;
|
||||
.got : { *(.got) *(.got.plt)}
|
||||
|
|
19
ld/testsuite/ld-arm/armv4-bx.d
Normal file
19
ld/testsuite/ld-arm/armv4-bx.d
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
.*: .*file format elf32-(big|little)arm
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
00008000 <_start>:
|
||||
8000: ea000001 b 800c \<__bx_r14\>
|
||||
8004: ea000003 b 8018 \<__bx_r0\>
|
||||
8008: 0a000002 beq 8018 \<__bx_r0\>
|
||||
|
||||
0000800c <__bx_r14>:
|
||||
800c: e31e0001 tst lr, #1 ; 0x1
|
||||
8010: 01a0f00e moveq pc, lr
|
||||
8014: e12fff1e bx lr
|
||||
|
||||
00008018 <__bx_r0>:
|
||||
8018: e3100001 tst r0, #1 ; 0x1
|
||||
801c: 01a0f000 moveq pc, r0
|
||||
8020: e12fff10 bx r0
|
8
ld/testsuite/ld-arm/armv4-bx.s
Normal file
8
ld/testsuite/ld-arm/armv4-bx.s
Normal file
|
@ -0,0 +1,8 @@
|
|||
.text
|
||||
.arch armv4
|
||||
.global _start
|
||||
.type _start, %function
|
||||
_start:
|
||||
bx lr
|
||||
bx r0
|
||||
bxeq r0
|
Loading…
Reference in a new issue