mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
Fix local branches for bl and blx.
This commit is contained in:
@ -1,3 +1,25 @@
|
|||||||
|
2009-05-05 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||||
|
|
||||||
|
* config\tc-arm.h: Fix typo in comment.
|
||||||
|
(ARM_IS_FUNC): New macro.
|
||||||
|
(MD_APPLY_SYM_VALUE): Define.
|
||||||
|
|
||||||
|
* config\tc-arm.c (do_blx): Retain BFD_RELOC_ARM_PCREL_BLX for
|
||||||
|
all versions of EABI.
|
||||||
|
(relax_branch): Do not relax for branches to ARM functions.
|
||||||
|
(md_pcrel_from_section): Set up base correctly for
|
||||||
|
BFD_RELOC_THUMB_PCREL_BLX, BFD_RELOC_THUMB_PCREL_CALL,
|
||||||
|
BFD_RELOC_THUMB_PCREL_BRANCH23, BFD_RELOC_ARM_PCREL_BLX
|
||||||
|
BFD_RELOC_ARM_PCREL_CALL.
|
||||||
|
(md_apply_fix): Flip bl to blx where possible.
|
||||||
|
Flip blx to bl where possible.
|
||||||
|
(arm_force_relocation): Force relocations for
|
||||||
|
BFD_RELOC_ARM_PCREL_JUMP, BFD_RELOC_ARM_PCREL_JUMP,
|
||||||
|
BFD_RELOC_ARM_PCREL_BLX, BFD_RELOC_THUMB_PCREL_BLX,
|
||||||
|
BFD_RELOC_THUMB_PCREL_BRANCH20, BFD_RELOC_THUMB_PCREL_BRANCH23,
|
||||||
|
BFD_RELOC_THUMB_PCREL_BRANCH25.
|
||||||
|
(arm_apply_sym_value): New function.
|
||||||
|
|
||||||
2009-05-04 Tristan Gingold <gingold@adacore.com>
|
2009-05-04 Tristan Gingold <gingold@adacore.com>
|
||||||
|
|
||||||
* config/tc-alpha.c: Also declare alpha_prologue_label for OBJ_EVAX.
|
* config/tc-alpha.c: Also declare alpha_prologue_label for OBJ_EVAX.
|
||||||
|
@ -6735,7 +6735,7 @@ encode_branch (int default_reloc)
|
|||||||
{
|
{
|
||||||
constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32,
|
constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32,
|
||||||
_("the only suffix valid here is '(plt)'"));
|
_("the only suffix valid here is '(plt)'"));
|
||||||
inst.reloc.type = BFD_RELOC_ARM_PLT32;
|
inst.reloc.type = BFD_RELOC_ARM_PLT32;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -6794,15 +6794,12 @@ do_blx (void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Arg is an address; this instruction cannot be executed
|
/* Arg is an address; this instruction cannot be executed
|
||||||
conditionally, and the opcode must be adjusted. */
|
conditionally, and the opcode must be adjusted.
|
||||||
|
We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
|
||||||
|
where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
|
||||||
constraint (inst.cond != COND_ALWAYS, BAD_COND);
|
constraint (inst.cond != COND_ALWAYS, BAD_COND);
|
||||||
inst.instruction = 0xfa000000;
|
inst.instruction = 0xfa000000;
|
||||||
#ifdef OBJ_ELF
|
encode_branch (BFD_RELOC_ARM_PCREL_BLX);
|
||||||
if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
|
|
||||||
encode_branch (BFD_RELOC_ARM_PCREL_CALL);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
encode_branch (BFD_RELOC_ARM_PCREL_BLX);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17461,6 +17458,12 @@ relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
|
|||||||
|| sec != S_GET_SEGMENT (fragp->fr_symbol))
|
|| sec != S_GET_SEGMENT (fragp->fr_symbol))
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
if (S_IS_DEFINED (fragp->fr_symbol)
|
||||||
|
&& ARM_IS_FUNC (fragp->fr_symbol))
|
||||||
|
return 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
val = relaxed_symbol_addr (fragp, stretch);
|
val = relaxed_symbol_addr (fragp, stretch);
|
||||||
addr = fragp->fr_address + fragp->fr_fix + 4;
|
addr = fragp->fr_address + fragp->fr_fix + 4;
|
||||||
val -= addr;
|
val -= addr;
|
||||||
@ -18185,6 +18188,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
|
|||||||
)))
|
)))
|
||||||
base = 0;
|
base = 0;
|
||||||
|
|
||||||
|
|
||||||
switch (fixP->fx_r_type)
|
switch (fixP->fx_r_type)
|
||||||
{
|
{
|
||||||
/* PC relative addressing on the Thumb is slightly odd as the
|
/* PC relative addressing on the Thumb is slightly odd as the
|
||||||
@ -18206,21 +18210,43 @@ md_pcrel_from_section (fixS * fixP, segT seg)
|
|||||||
case BFD_RELOC_THUMB_PCREL_BRANCH9:
|
case BFD_RELOC_THUMB_PCREL_BRANCH9:
|
||||||
case BFD_RELOC_THUMB_PCREL_BRANCH12:
|
case BFD_RELOC_THUMB_PCREL_BRANCH12:
|
||||||
case BFD_RELOC_THUMB_PCREL_BRANCH20:
|
case BFD_RELOC_THUMB_PCREL_BRANCH20:
|
||||||
case BFD_RELOC_THUMB_PCREL_BRANCH23:
|
|
||||||
case BFD_RELOC_THUMB_PCREL_BRANCH25:
|
case BFD_RELOC_THUMB_PCREL_BRANCH25:
|
||||||
return base + 4;
|
return base + 4;
|
||||||
|
|
||||||
|
case BFD_RELOC_THUMB_PCREL_BRANCH23:
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& ARM_IS_FUNC (fixP->fx_addsy)
|
||||||
|
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
|
||||||
|
base = fixP->fx_where + fixP->fx_frag->fr_address;
|
||||||
|
return base + 4;
|
||||||
|
|
||||||
/* BLX is like branches above, but forces the low two bits of PC to
|
/* BLX is like branches above, but forces the low two bits of PC to
|
||||||
zero. */
|
zero. */
|
||||||
case BFD_RELOC_THUMB_PCREL_BLX:
|
case BFD_RELOC_THUMB_PCREL_BLX:
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& THUMB_IS_FUNC (fixP->fx_addsy)
|
||||||
|
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
|
||||||
|
base = fixP->fx_where + fixP->fx_frag->fr_address;
|
||||||
return (base + 4) & ~3;
|
return (base + 4) & ~3;
|
||||||
|
|
||||||
/* ARM mode branches are offset by +8. However, the Windows CE
|
/* ARM mode branches are offset by +8. However, the Windows CE
|
||||||
loader expects the relocation not to take this into account. */
|
loader expects the relocation not to take this into account. */
|
||||||
case BFD_RELOC_ARM_PCREL_BRANCH:
|
|
||||||
case BFD_RELOC_ARM_PCREL_CALL:
|
|
||||||
case BFD_RELOC_ARM_PCREL_JUMP:
|
|
||||||
case BFD_RELOC_ARM_PCREL_BLX:
|
case BFD_RELOC_ARM_PCREL_BLX:
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& ARM_IS_FUNC (fixP->fx_addsy)
|
||||||
|
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
|
||||||
|
base = fixP->fx_where + fixP->fx_frag->fr_address;
|
||||||
|
return base + 8;
|
||||||
|
|
||||||
|
case BFD_RELOC_ARM_PCREL_CALL:
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& THUMB_IS_FUNC (fixP->fx_addsy)
|
||||||
|
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
|
||||||
|
base = fixP->fx_where + fixP->fx_frag->fr_address;
|
||||||
|
return base + 8;
|
||||||
|
|
||||||
|
case BFD_RELOC_ARM_PCREL_BRANCH:
|
||||||
|
case BFD_RELOC_ARM_PCREL_JUMP:
|
||||||
case BFD_RELOC_ARM_PLT32:
|
case BFD_RELOC_ARM_PLT32:
|
||||||
#ifdef TE_WINCE
|
#ifdef TE_WINCE
|
||||||
/* When handling fixups immediately, because we have already
|
/* When handling fixups immediately, because we have already
|
||||||
@ -18239,6 +18265,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
|
|||||||
return base + 8;
|
return base + 8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ARM mode loads relative to PC are also offset by +8. Unlike
|
/* ARM mode loads relative to PC are also offset by +8. Unlike
|
||||||
branches, the Windows CE loader *does* expect the relocation
|
branches, the Windows CE loader *does* expect the relocation
|
||||||
to take this into account. */
|
to take this into account. */
|
||||||
@ -18982,14 +19009,41 @@ md_apply_fix (fixS * fixP,
|
|||||||
|
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
case BFD_RELOC_ARM_PCREL_CALL:
|
case BFD_RELOC_ARM_PCREL_CALL:
|
||||||
newval = md_chars_to_number (buf, INSN_SIZE);
|
|
||||||
if ((newval & 0xf0000000) == 0xf0000000)
|
if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
|
||||||
temp = 1;
|
&& fixP->fx_addsy
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
||||||
|
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
|
||||||
|
&& THUMB_IS_FUNC (fixP->fx_addsy))
|
||||||
|
/* Flip the bl to blx. This is a simple flip
|
||||||
|
bit here because we generate PCREL_CALL for
|
||||||
|
unconditional bls. */
|
||||||
|
{
|
||||||
|
newval = md_chars_to_number (buf, INSN_SIZE);
|
||||||
|
newval = newval | 0x10000000;
|
||||||
|
md_number_to_chars (buf, newval, INSN_SIZE);
|
||||||
|
temp = 1;
|
||||||
|
fixP->fx_done = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
temp = 3;
|
temp = 3;
|
||||||
goto arm_branch_common;
|
goto arm_branch_common;
|
||||||
|
|
||||||
case BFD_RELOC_ARM_PCREL_JUMP:
|
case BFD_RELOC_ARM_PCREL_JUMP:
|
||||||
|
if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
|
||||||
|
&& fixP->fx_addsy
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
||||||
|
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
|
||||||
|
&& THUMB_IS_FUNC (fixP->fx_addsy))
|
||||||
|
{
|
||||||
|
/* This would map to a bl<cond>, b<cond>,
|
||||||
|
b<always> to a Thumb function. We
|
||||||
|
need to force a relocation for this particular
|
||||||
|
case. */
|
||||||
|
newval = md_chars_to_number (buf, INSN_SIZE);
|
||||||
|
fixP->fx_done = 0;
|
||||||
|
}
|
||||||
|
|
||||||
case BFD_RELOC_ARM_PLT32:
|
case BFD_RELOC_ARM_PLT32:
|
||||||
#endif
|
#endif
|
||||||
case BFD_RELOC_ARM_PCREL_BRANCH:
|
case BFD_RELOC_ARM_PCREL_BRANCH:
|
||||||
@ -18997,7 +19051,30 @@ md_apply_fix (fixS * fixP,
|
|||||||
goto arm_branch_common;
|
goto arm_branch_common;
|
||||||
|
|
||||||
case BFD_RELOC_ARM_PCREL_BLX:
|
case BFD_RELOC_ARM_PCREL_BLX:
|
||||||
|
|
||||||
temp = 1;
|
temp = 1;
|
||||||
|
if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
|
||||||
|
&& fixP->fx_addsy
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
||||||
|
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
|
||||||
|
&& ARM_IS_FUNC (fixP->fx_addsy))
|
||||||
|
{
|
||||||
|
/* Flip the blx to a bl and warn. */
|
||||||
|
const char *name = S_GET_NAME (fixP->fx_addsy);
|
||||||
|
newval = 0xeb000000;
|
||||||
|
as_warn_where (fixP->fx_file, fixP->fx_line,
|
||||||
|
_("blx to '%s' an ARM ISA state function changed to bl"),
|
||||||
|
name);
|
||||||
|
md_number_to_chars (buf, newval, INSN_SIZE);
|
||||||
|
temp = 3;
|
||||||
|
fixP->fx_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
|
||||||
|
fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
|
||||||
|
#endif
|
||||||
|
|
||||||
arm_branch_common:
|
arm_branch_common:
|
||||||
/* We are going to store value (shifted right by two) in the
|
/* We are going to store value (shifted right by two) in the
|
||||||
instruction, in a 24 bit, signed field. Bits 26 through 32 either
|
instruction, in a 24 bit, signed field. Bits 26 through 32 either
|
||||||
@ -19084,6 +19161,16 @@ md_apply_fix (fixS * fixP,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_THUMB_PCREL_BRANCH20:
|
case BFD_RELOC_THUMB_PCREL_BRANCH20:
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
||||||
|
&& S_IS_DEFINED (fixP->fx_addsy)
|
||||||
|
&& ARM_IS_FUNC (fixP->fx_addsy)
|
||||||
|
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
|
||||||
|
{
|
||||||
|
/* Force a relocation for a branch 20 bits wide. */
|
||||||
|
fixP->fx_done = 0;
|
||||||
|
}
|
||||||
if ((value & ~0x1fffff) && ((value & ~0x1fffff) != ~0x1fffff))
|
if ((value & ~0x1fffff) && ((value & ~0x1fffff) != ~0x1fffff))
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
_("conditional branch out of range"));
|
_("conditional branch out of range"));
|
||||||
@ -19109,7 +19196,57 @@ md_apply_fix (fixS * fixP,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_THUMB_PCREL_BLX:
|
case BFD_RELOC_THUMB_PCREL_BLX:
|
||||||
|
|
||||||
|
/* If there is a blx from a thumb state function to
|
||||||
|
another thumb function flip this to a bl and warn
|
||||||
|
about it. */
|
||||||
|
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& S_IS_DEFINED (fixP->fx_addsy)
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
||||||
|
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
|
||||||
|
&& THUMB_IS_FUNC (fixP->fx_addsy))
|
||||||
|
{
|
||||||
|
const char *name = S_GET_NAME (fixP->fx_addsy);
|
||||||
|
as_warn_where (fixP->fx_file, fixP->fx_line,
|
||||||
|
_("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
|
||||||
|
name);
|
||||||
|
newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
|
||||||
|
newval = newval | 0x1000;
|
||||||
|
md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
|
||||||
|
fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
|
||||||
|
fixP->fx_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
goto thumb_bl_common;
|
||||||
|
|
||||||
case BFD_RELOC_THUMB_PCREL_BRANCH23:
|
case BFD_RELOC_THUMB_PCREL_BRANCH23:
|
||||||
|
|
||||||
|
/* A bl from Thumb state ISA to an internal ARM state function
|
||||||
|
is converted to a blx. */
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& (S_GET_SEGMENT (fixP->fx_addsy) == seg)
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
||||||
|
&& S_IS_DEFINED (fixP->fx_addsy)
|
||||||
|
&& ARM_IS_FUNC (fixP->fx_addsy)
|
||||||
|
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
|
||||||
|
{
|
||||||
|
newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
|
||||||
|
newval = newval & ~0x1000;
|
||||||
|
md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
|
||||||
|
fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
|
||||||
|
fixP->fx_done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
thumb_bl_common:
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4 &&
|
||||||
|
fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
|
||||||
|
fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
|
if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
|
||||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||||
_("branch out of range"));
|
_("branch out of range"));
|
||||||
@ -19962,6 +20099,7 @@ arm_validate_fix (fixS * fixP)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
arm_force_relocation (struct fix * fixp)
|
arm_force_relocation (struct fix * fixp)
|
||||||
{
|
{
|
||||||
@ -19970,6 +20108,34 @@ arm_force_relocation (struct fix * fixp)
|
|||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* In case we have a call or a branch to a function in ARM ISA mode from
|
||||||
|
a thumb function or vice-versa force the relocation. These relocations
|
||||||
|
are cleared off for some cores that might have blx and simple transformations
|
||||||
|
are possible. */
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
switch (fixp->fx_r_type)
|
||||||
|
{
|
||||||
|
case BFD_RELOC_ARM_PCREL_JUMP:
|
||||||
|
case BFD_RELOC_ARM_PCREL_CALL:
|
||||||
|
case BFD_RELOC_THUMB_PCREL_BLX:
|
||||||
|
if (THUMB_IS_FUNC (fixp->fx_addsy))
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_ARM_PCREL_BLX:
|
||||||
|
case BFD_RELOC_THUMB_PCREL_BRANCH25:
|
||||||
|
case BFD_RELOC_THUMB_PCREL_BRANCH20:
|
||||||
|
case BFD_RELOC_THUMB_PCREL_BRANCH23:
|
||||||
|
if (ARM_IS_FUNC (fixp->fx_addsy))
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Resolve these relocations even if the symbol is extern or weak. */
|
/* Resolve these relocations even if the symbol is extern or weak. */
|
||||||
if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
|
if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
|
||||||
|| fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
|
|| fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
|
||||||
@ -21608,4 +21774,39 @@ arm_convert_symbolic_attribute (const char *name)
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Apply sym value for relocations only in the case that
|
||||||
|
they are for local symbols and you have the respective
|
||||||
|
architectural feature for blx and simple switches. */
|
||||||
|
int
|
||||||
|
arm_apply_sym_value (struct fix * fixP)
|
||||||
|
{
|
||||||
|
if (fixP->fx_addsy
|
||||||
|
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy))
|
||||||
|
{
|
||||||
|
switch (fixP->fx_r_type)
|
||||||
|
{
|
||||||
|
case BFD_RELOC_ARM_PCREL_BLX:
|
||||||
|
case BFD_RELOC_THUMB_PCREL_BRANCH23:
|
||||||
|
if (ARM_IS_FUNC (fixP->fx_addsy))
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BFD_RELOC_ARM_PCREL_CALL:
|
||||||
|
case BFD_RELOC_THUMB_PCREL_BLX:
|
||||||
|
if (THUMB_IS_FUNC (fixP->fx_addsy))
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* OBJ_ELF */
|
#endif /* OBJ_ELF */
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,15 +126,24 @@ bfd_boolean arm_is_eabi (void);
|
|||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
|
|
||||||
/* For ELF objects THUMB_IS_FUNC is inferred from
|
/* For ELF objects THUMB_IS_FUNC is inferred from
|
||||||
ARM_IS_TUMB and the function type. */
|
ARM_IS_THUMB and the function type. */
|
||||||
#define THUMB_IS_FUNC(s) \
|
#define THUMB_IS_FUNC(s) \
|
||||||
((arm_is_eabi () \
|
((arm_is_eabi () \
|
||||||
&& (ARM_IS_THUMB (s)) \
|
&& (ARM_IS_THUMB (s)) \
|
||||||
&& (symbol_get_bfdsym (s)->flags & BSF_FUNCTION)) \
|
&& (symbol_get_bfdsym (s)->flags & BSF_FUNCTION)) \
|
||||||
|| (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC))
|
|| (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC))
|
||||||
|
|
||||||
|
#define ARM_IS_FUNC(s) \
|
||||||
|
((arm_is_eabi () \
|
||||||
|
&& !(ARM_IS_THUMB (s)) \
|
||||||
|
/* && !(THUMB_FLAG_FUNC & ARM_GET_FLAG (s)) \ */ \
|
||||||
|
&& (symbol_get_bfdsym (s)->flags & BSF_FUNCTION)))
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define THUMB_IS_FUNC(s) (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC)
|
#define THUMB_IS_FUNC(s) (ARM_GET_FLAG (s) & THUMB_FLAG_FUNC)
|
||||||
|
#define ARM_IS_FUNC(s) (!THUMB_IS_FUNC (s) \
|
||||||
|
&& (symbol_get_bfdsym (s)->flags & BSF_FUNCTION))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ARM_SET_THUMB(s,t) ((t) ? ARM_SET_FLAG (s, ARM_FLAG_THUMB) : ARM_RESET_FLAG (s, ARM_FLAG_THUMB))
|
#define ARM_SET_THUMB(s,t) ((t) ? ARM_SET_FLAG (s, ARM_FLAG_THUMB) : ARM_RESET_FLAG (s, ARM_FLAG_THUMB))
|
||||||
@ -247,12 +256,17 @@ struct arm_segment_info_type
|
|||||||
|
|
||||||
# define EXTERN_FORCE_RELOC 1
|
# define EXTERN_FORCE_RELOC 1
|
||||||
# define tc_fix_adjustable(FIX) arm_fix_adjustable (FIX)
|
# define tc_fix_adjustable(FIX) arm_fix_adjustable (FIX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
/* Values passed to md_apply_fix don't include the symbol value. */
|
/* Values passed to md_apply_fix don't include the symbol value. */
|
||||||
# define MD_APPLY_SYM_VALUE(FIX) 0
|
# define MD_APPLY_SYM_VALUE(FIX) arm_apply_sym_value (FIX)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OBJ_COFF
|
#ifdef OBJ_COFF
|
||||||
# define TC_VALIDATE_FIX(FIX, SEGTYPE, LABEL) arm_validate_fix (FIX)
|
# define TC_VALIDATE_FIX(FIX, SEGTYPE, LABEL) arm_validate_fix (FIX)
|
||||||
|
/* Values passed to md_apply_fix don't include the symbol value. */
|
||||||
|
# define MD_APPLY_SYM_VALUE(FIX) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MD_PCREL_FROM_SECTION(F,S) md_pcrel_from_section(F,S)
|
#define MD_PCREL_FROM_SECTION(F,S) md_pcrel_from_section(F,S)
|
||||||
@ -290,4 +304,5 @@ void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
|
|||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
#define CONVERT_SYMBOLIC_ATTRIBUTE(name) arm_convert_symbolic_attribute (name)
|
#define CONVERT_SYMBOLIC_ATTRIBUTE(name) arm_convert_symbolic_attribute (name)
|
||||||
extern int arm_convert_symbolic_attribute (const char *);
|
extern int arm_convert_symbolic_attribute (const char *);
|
||||||
|
extern int arm_apply_sym_value (struct fix *);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
2009-05-05 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||||
|
|
||||||
|
* gas\arm\bl-local-v4t.d: New file.
|
||||||
|
* gas\arm\bl-local-v4t.s: New file.
|
||||||
|
* gas\arm\blx-local.s: Update for branches and calls to local
|
||||||
|
functions.
|
||||||
|
* gas\arm\blx-local.d: Likewise.
|
||||||
|
* gas\arm\blx-local.l: New file.
|
||||||
|
* gas\arm\blx-local-thumb.l: New file.
|
||||||
|
* gas\arm\blx-local-thumb.s: New file.
|
||||||
|
* gas\arm\blx-local-thumb.d: New file.
|
||||||
|
|
||||||
2009-05-01 Nathan Sidwell <nathan@codesourcery.com>
|
2009-05-01 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
Daniel Jacobowitz <dan@codesourcery.com>
|
Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
|
19
gas/testsuite/gas/arm/bl-local-v4t.d
Normal file
19
gas/testsuite/gas/arm/bl-local-v4t.d
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#name: bl local instructions for v4t.
|
||||||
|
#objdump: -drw --prefix-addresses --show-raw-insn
|
||||||
|
#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||||
|
#as:
|
||||||
|
# stderr: blx-local-thumb.l
|
||||||
|
|
||||||
|
.*: +file format .*arm.*
|
||||||
|
Disassembly of section .text:
|
||||||
|
0+00 <[^>]*> f7ff fffe bl 00+18 <[^>]*> 0: R_ARM_THM_CALL foo2
|
||||||
|
0+1c <[^>]*> d004 beq.n 00+28 <[^>]*>
|
||||||
|
0+1e <[^>]*> e003 b.n 00+28 <[^>]*>
|
||||||
|
0+20 <[^>]*> f000 f808 bl 00+34 <[^>]*>
|
||||||
|
0+24 <[^>]*> f000 f802 bl 00+2c <[^>]*>
|
||||||
|
0+28 <[^>]*> 46c0 nop \(mov r8, r8\)
|
||||||
|
0+2a <[^>]*> 46c0 nop \(mov r8, r8\)
|
||||||
|
0+2c <[^>]*> 46c0 nop \(mov r8, r8\)
|
||||||
|
...
|
||||||
|
0+30 <[^>]*> e1a00000 nop \(mov r0,r0\)
|
||||||
|
0+34 <[^>]*> e1a00000 nop \(mov r0,r0\)
|
25
gas/testsuite/gas/arm/bl-local-v4t.s
Normal file
25
gas/testsuite/gas/arm/bl-local-v4t.s
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.text
|
||||||
|
.arch armv4t
|
||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
one:
|
||||||
|
bl foo2 @ bl foo2 with reloc.
|
||||||
|
beq foo @ beq foo with reloc.
|
||||||
|
b foo @ branch foo with reloc.
|
||||||
|
bl fooundefarm
|
||||||
|
bl fooundefthumb
|
||||||
|
.thumb
|
||||||
|
.type foo, %function
|
||||||
|
.thumb_func
|
||||||
|
foo:
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
fooundefthumb:
|
||||||
|
nop
|
||||||
|
.type foo2, %function
|
||||||
|
.arm
|
||||||
|
.align 2
|
||||||
|
foo2:
|
||||||
|
nop
|
||||||
|
fooundefarm:
|
||||||
|
nop
|
2
gas/testsuite/gas/arm/blx-local-thumb.l
Normal file
2
gas/testsuite/gas/arm/blx-local-thumb.l
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[^;]*: Assembler messages:
|
||||||
|
[^;]*:6: Warning: blx to Thumb func 'foo' from Thumb ISA state changed to bl
|
@ -1,15 +1,29 @@
|
|||||||
#name: Local BLX instructions
|
#name: Local BLX instructions
|
||||||
#objdump: -dr --prefix-addresses --show-raw-insn
|
#objdump: -drw --prefix-addresses --show-raw-insn
|
||||||
#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
|
||||||
#as:
|
#as:
|
||||||
|
# stderr: blx-local.l
|
||||||
# Test assembler resolution of blx instructions.
|
# Test assembler resolution of blx and bl instructions in ARM mode.
|
||||||
|
|
||||||
.*: +file format .*arm.*
|
.*: +file format .*arm.*
|
||||||
|
|
||||||
Disassembly of section .text:
|
Disassembly of section .text:
|
||||||
|
0+00 <[^>]*> fa000006 blx 00000020 <foo>
|
||||||
0+00 <[^>]*> fa000000 blx 00+8 <foo>
|
0+04 <[^>]*> eb000007 bl 00000028 <foo2>
|
||||||
0+04 <[^>]*> fbffffff blx 00+a <foo2>
|
0+08 <[^>]*> fa000004 blx 00000020 <foo>
|
||||||
0+08 <[^>]*> 46c0 nop \(mov r8, r8\)
|
0+0c <[^>]*> eb000005 bl 00000028 <foo2>
|
||||||
0+0a <[^>]*> 46c0 nop \(mov r8, r8\)
|
0+10 <[^>]*> fa00000b blx 00000044 <fooundefarm>
|
||||||
|
0+14 <[^>]*> eb00000a bl 00000044 <fooundefarm>
|
||||||
|
0+18 <[^>]*> fa000001 blx 00000024 <fooundefthumb>
|
||||||
|
0+1c <[^>]*> eb000000 bl 00000024 <fooundefthumb>
|
||||||
|
0+20 <[^>]*> 46c0 nop \(mov r8, r8\)
|
||||||
|
0+22 <[^>]*> 46c0 nop \(mov r8, r8\)
|
||||||
|
0+24 <[^>]*> 46c0 nop \(mov r8, r8\)
|
||||||
|
0+26 <[^>]*> 46c0 nop \(mov r8, r8\)
|
||||||
|
0+28 <[^>]*> 0bfffffd bleq 00000024 <fooundefthumb>
|
||||||
|
0+2c <[^>]*> 0afffffc beq 00000024 <fooundefthumb>
|
||||||
|
0+30 <[^>]*> eafffffb b 00000024 <fooundefthumb>
|
||||||
|
0+34 <[^>]*> 0bfffffe bleq 00000020 <foo> 34: R_ARM_JUMP24 foo
|
||||||
|
0+58 <[^>]*> 0afffffe beq 00000020 <foo> 38: R_ARM_JUMP24 foo
|
||||||
|
0+5c <[^>]*> eafffffe b 00000020 <foo> 3c: R_ARM_JUMP24 foo
|
||||||
|
0+60 <[^>]*> e1a00000 nop \(mov r0,r0\)
|
||||||
|
0+64 <[^>]*> e1a00000 nop \(mov r0,r0\)
|
||||||
|
3
gas/testsuite/gas/arm/blx-local.l
Normal file
3
gas/testsuite/gas/arm/blx-local.l
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[^;]*: Assembler messages:
|
||||||
|
[^;]*:9: Warning: blx to 'foo2' an ARM ISA state function changed to bl
|
||||||
|
|
@ -1,16 +1,38 @@
|
|||||||
.text
|
# objdump: -fdrw --prefix-addresses --show-raw-insn
|
||||||
.arch armv5t
|
# not-target: *-*-*aout* *-*-pe
|
||||||
.arm
|
|
||||||
one:
|
|
||||||
blx foo
|
|
||||||
blx foo2
|
|
||||||
|
|
||||||
.thumb
|
.text
|
||||||
.type foo, %function
|
.arch armv5t
|
||||||
.thumb_func
|
.arm
|
||||||
|
one:
|
||||||
|
blx foo
|
||||||
|
blx foo2
|
||||||
|
bl foo
|
||||||
|
bl foo2
|
||||||
|
blx fooundefarm
|
||||||
|
bl fooundefarm
|
||||||
|
blx fooundefthumb
|
||||||
|
bl fooundefthumb
|
||||||
|
|
||||||
|
.thumb
|
||||||
|
.type foo, %function
|
||||||
|
.thumb_func
|
||||||
foo:
|
foo:
|
||||||
nop
|
nop
|
||||||
|
nop
|
||||||
|
fooundefthumb:
|
||||||
|
nop
|
||||||
|
|
||||||
|
.align 2
|
||||||
.type foo2, %function
|
.type foo2, %function
|
||||||
.thumb_func
|
.arm
|
||||||
foo2:
|
foo2:
|
||||||
nop
|
bleq fooundefthumb @no relocs
|
||||||
|
beq fooundefthumb @no relocs
|
||||||
|
b fooundefthumb @no relocs
|
||||||
|
bleq foo @ R_ARM_PCREL_JUMP
|
||||||
|
beq foo @ R_ARM_PCREL_JUMP
|
||||||
|
b foo @ R_ARM_PCREL_JUMP
|
||||||
|
nop
|
||||||
|
fooundefarm:
|
||||||
|
nop
|
||||||
|
Reference in New Issue
Block a user