2010-03-22 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_relocate_functions::abs8, Arm_relocate_functions::abs16): Use correct check for overflow specified in the ARM ELF specs. (Arm_relocate_functions): thumb_branch_common. Handle bit 1 of branch target of a BLX instruction specially. (Reloc_stub::stub_type_for_reloc): Ditto. (Relocate::relocate): Use symbolic names instead of numeric relocation codes to report error. (Target_arm::do_relox): Reduce default stub-group size for Cortex-A8 workaround. * testsuite/Makefile.am (check_DATA): add thumb_blx_in_range.stdout, thumb_blx_out_of_range.stdout, thumb2_blx_in_range.stdout and thumb2_blx_out_of_range.stdout (thumb_bl_out_of_range, thumb_bl_out_of_range.o, thumb2_bl_out_of_range, thumb2_bl_out_of_range.o): Fix dependenices. (thumb_blx_in_range.stdout, thumb_blx_in_range, thumb_blx_in_range.o, thumb_blx_out_of_range.stdout, thumb_blx_out_of_range, thumb_blx_out_of_range.o, thumb2_blx_in_range.stdout, thumb2_blx_in_range, thumb2_blx_in_range.o, thumb2_blx_out_of_range.stdout, thumb2_blx_out_of_range, thumb2_blx_out_of_range.o): New rules. (MOSTLYCLEANFILES): Add thumb_blx_in_range, thumb_blx_out_of_range, thumb2_blx_in_range and thumb2_blx_out_of_range. * testsuite/Makefile.in: Regenerate. * arm_branch_in_range.sh: Add tests for THUMB BLX. * testsuite/thumb_blx_in_range.s: New file. * testsuite/thumb_blx_out_of_range.s: New file.
This commit is contained in:
parent
f9b58c5ba6
commit
a2c7281b72
@ -1,3 +1,33 @@
|
||||
2010-03-22 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* arm.cc (Arm_relocate_functions::abs8,
|
||||
Arm_relocate_functions::abs16): Use correct check for overflow
|
||||
specified in the ARM ELF specs.
|
||||
(Arm_relocate_functions): thumb_branch_common. Handle bit 1 of branch
|
||||
target of a BLX instruction specially.
|
||||
(Reloc_stub::stub_type_for_reloc): Ditto.
|
||||
(Relocate::relocate): Use symbolic names instead of numeric relocation
|
||||
codes to report error.
|
||||
(Target_arm::do_relox): Reduce default stub-group size for Cortex-A8
|
||||
workaround.
|
||||
* testsuite/Makefile.am (check_DATA): add thumb_blx_in_range.stdout,
|
||||
thumb_blx_out_of_range.stdout, thumb2_blx_in_range.stdout and
|
||||
thumb2_blx_out_of_range.stdout
|
||||
(thumb_bl_out_of_range, thumb_bl_out_of_range.o,
|
||||
thumb2_bl_out_of_range, thumb2_bl_out_of_range.o): Fix dependenices.
|
||||
(thumb_blx_in_range.stdout, thumb_blx_in_range, thumb_blx_in_range.o,
|
||||
thumb_blx_out_of_range.stdout, thumb_blx_out_of_range,
|
||||
thumb_blx_out_of_range.o, thumb2_blx_in_range.stdout,
|
||||
thumb2_blx_in_range, thumb2_blx_in_range.o,
|
||||
thumb2_blx_out_of_range.stdout, thumb2_blx_out_of_range,
|
||||
thumb2_blx_out_of_range.o): New rules.
|
||||
(MOSTLYCLEANFILES): Add thumb_blx_in_range, thumb_blx_out_of_range,
|
||||
thumb2_blx_in_range and thumb2_blx_out_of_range.
|
||||
* testsuite/Makefile.in: Regenerate.
|
||||
* arm_branch_in_range.sh: Add tests for THUMB BLX.
|
||||
* testsuite/thumb_blx_in_range.s: New file.
|
||||
* testsuite/thumb_blx_out_of_range.s: New file.
|
||||
|
||||
2010-03-22 Rafael Espindola <espindola@google.com>
|
||||
|
||||
* archive.cc (Should_include): Move to archive.h.
|
||||
|
58
gold/arm.cc
58
gold/arm.cc
@ -2985,7 +2985,10 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
|
||||
Reltype x = psymval->value(object, addend);
|
||||
val = utils::bit_select(val, x, 0xffU);
|
||||
elfcpp::Swap<8, big_endian>::writeval(wv, val);
|
||||
return (utils::has_signed_unsigned_overflow<8>(x)
|
||||
|
||||
// R_ARM_ABS8 permits signed or unsigned results.
|
||||
int signed_x = static_cast<int32_t>(x);
|
||||
return ((signed_x < -128 || signed_x > 255)
|
||||
? This::STATUS_OVERFLOW
|
||||
: This::STATUS_OKAY);
|
||||
}
|
||||
@ -3004,7 +3007,10 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian>
|
||||
Reltype x = psymval->value(object, addend);
|
||||
val = utils::bit_select(val, x << 6, 0x7e0U);
|
||||
elfcpp::Swap<16, big_endian>::writeval(wv, val);
|
||||
return (utils::has_overflow<5>(x)
|
||||
|
||||
// R_ARM_ABS16 permits signed or unsigned results.
|
||||
int signed_x = static_cast<int32_t>(x);
|
||||
return ((signed_x < -32768 || signed_x > 65535)
|
||||
? This::STATUS_OVERFLOW
|
||||
: This::STATUS_OKAY);
|
||||
}
|
||||
@ -3831,11 +3837,16 @@ Arm_relocate_functions<big_endian>::thumb_branch_common(
|
||||
|
||||
int32_t addend = This::thumb32_branch_offset(upper_insn, lower_insn);
|
||||
Arm_address branch_target = psymval->value(object, addend);
|
||||
|
||||
// For BLX, bit 1 of target address comes from bit 1 of base address.
|
||||
bool may_use_blx = arm_target->may_use_blx();
|
||||
if (thumb_bit == 0 && may_use_blx)
|
||||
branch_target = utils::bit_select(branch_target, address, 0x2);
|
||||
|
||||
int32_t branch_offset = branch_target - address;
|
||||
|
||||
// We need a stub if the branch offset is too large or if we need
|
||||
// to switch mode.
|
||||
bool may_use_blx = arm_target->may_use_blx();
|
||||
bool thumb2 = arm_target->using_thumb2();
|
||||
if ((!thumb2 && utils::has_overflow<23>(branch_offset))
|
||||
|| (thumb2 && utils::has_overflow<25>(branch_offset))
|
||||
@ -3861,6 +3872,8 @@ Arm_relocate_functions<big_endian>::thumb_branch_common(
|
||||
gold_assert(stub != NULL);
|
||||
thumb_bit = stub->stub_template()->entry_in_thumb_mode() ? 1 : 0;
|
||||
branch_target = stub_table->address() + stub->offset() + addend;
|
||||
if (thumb_bit == 0 && may_use_blx)
|
||||
branch_target = utils::bit_select(branch_target, address, 0x2);
|
||||
branch_offset = branch_target - address;
|
||||
}
|
||||
}
|
||||
@ -3881,12 +3894,12 @@ Arm_relocate_functions<big_endian>::thumb_branch_common(
|
||||
lower_insn |= 0x1000U;
|
||||
}
|
||||
|
||||
// For a BLX instruction, make sure that the relocation is rounded up
|
||||
// to a word boundary. This follows the semantics of the instruction
|
||||
// which specifies that bit 1 of the target address will come from bit
|
||||
// 1 of the base address.
|
||||
if ((lower_insn & 0x5000U) == 0x4000U)
|
||||
// For a BLX instruction, make sure that the relocation is rounded up
|
||||
// to a word boundary. This follows the semantics of the instruction
|
||||
// which specifies that bit 1 of the target address will come from bit
|
||||
// 1 of the base address.
|
||||
branch_offset = (branch_offset + 2) & ~3;
|
||||
gold_assert((branch_offset & 3) == 0);
|
||||
|
||||
// Put BRANCH_OFFSET back into the insn. Assumes two's complement.
|
||||
// We use the Thumb-2 encoding, which is safe even if dealing with
|
||||
@ -3897,6 +3910,8 @@ Arm_relocate_functions<big_endian>::thumb_branch_common(
|
||||
elfcpp::Swap<16, big_endian>::writeval(wv, upper_insn);
|
||||
elfcpp::Swap<16, big_endian>::writeval(wv + 1, lower_insn);
|
||||
|
||||
gold_assert(!utils::has_overflow<25>(branch_offset));
|
||||
|
||||
return ((thumb2
|
||||
? utils::has_overflow<25>(branch_offset)
|
||||
: utils::has_overflow<23>(branch_offset))
|
||||
@ -4225,10 +4240,15 @@ Reloc_stub::stub_type_for_reloc(
|
||||
thumb_only = little_endian_target->using_thumb_only();
|
||||
}
|
||||
|
||||
int64_t branch_offset = (int64_t)destination - location;
|
||||
|
||||
int64_t branch_offset;
|
||||
if (r_type == elfcpp::R_ARM_THM_CALL || r_type == elfcpp::R_ARM_THM_JUMP24)
|
||||
{
|
||||
// For THUMB BLX instruction, bit 1 of target comes from bit 1 of the
|
||||
// base address (instruction address + 4).
|
||||
if ((r_type == elfcpp::R_ARM_THM_CALL) && may_use_blx && !target_is_thumb)
|
||||
destination = utils::bit_select(destination, location, 0x2);
|
||||
branch_offset = static_cast<int64_t>(destination) - location;
|
||||
|
||||
// Handle cases where:
|
||||
// - this call goes too far (different Thumb/Thumb2 max
|
||||
// distance)
|
||||
@ -4309,6 +4329,7 @@ Reloc_stub::stub_type_for_reloc(
|
||||
|| r_type == elfcpp::R_ARM_JUMP24
|
||||
|| r_type == elfcpp::R_ARM_PLT32)
|
||||
{
|
||||
branch_offset = static_cast<int64_t>(destination) - location;
|
||||
if (target_is_thumb)
|
||||
{
|
||||
// Arm to thumb.
|
||||
@ -8562,16 +8583,16 @@ Target_arm<big_endian>::Relocate::relocate(
|
||||
break;
|
||||
case Arm_relocate_functions::STATUS_OVERFLOW:
|
||||
gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
|
||||
_("relocation overflow in relocation %u"),
|
||||
r_type);
|
||||
_("relocation overflow in %s"),
|
||||
reloc_property->name().c_str());
|
||||
break;
|
||||
case Arm_relocate_functions::STATUS_BAD_RELOC:
|
||||
gold_error_at_location(
|
||||
relinfo,
|
||||
relnum,
|
||||
rel.get_r_offset(),
|
||||
_("unexpected opcode while processing relocation %u"),
|
||||
r_type);
|
||||
_("unexpected opcode while processing relocation %s"),
|
||||
reloc_property->name().c_str());
|
||||
break;
|
||||
default:
|
||||
gold_unreachable();
|
||||
@ -10297,13 +10318,18 @@ Target_arm<big_endian>::do_relax(
|
||||
// Default value.
|
||||
// Thumb branch range is +-4MB has to be used as the default
|
||||
// maximum size (a given section can contain both ARM and Thumb
|
||||
// code, so the worst case has to be taken into account).
|
||||
// code, so the worst case has to be taken into account). If we are
|
||||
// fixing cortex-a8 errata, the branch range has to be even smaller,
|
||||
// since wide conditional branch has a range of +-1MB only.
|
||||
//
|
||||
// This value is 24K less than that, which allows for 2025
|
||||
// 12-byte stubs. If we exceed that, then we will fail to link.
|
||||
// The user will have to relink with an explicit group size
|
||||
// option.
|
||||
stub_group_size = 4170000;
|
||||
if (this->fix_cortex_a8_)
|
||||
stub_group_size = 1024276;
|
||||
else
|
||||
stub_group_size = 4170000;
|
||||
}
|
||||
|
||||
group_sections(layout, stub_group_size, stubs_always_after_branch);
|
||||
|
@ -1488,7 +1488,9 @@ MOSTLYCLEANFILES += arm_abs_global
|
||||
check_SCRIPTS += arm_branch_in_range.sh
|
||||
check_DATA += arm_bl_in_range.stdout arm_bl_out_of_range.stdout \
|
||||
thumb_bl_in_range.stdout thumb_bl_out_of_range.stdout \
|
||||
thumb2_bl_in_range.stdout thumb2_bl_out_of_range.stdout
|
||||
thumb2_bl_in_range.stdout thumb2_bl_out_of_range.stdout \
|
||||
thumb_blx_in_range.stdout thumb_blx_out_of_range.stdout \
|
||||
thumb2_blx_in_range.stdout thumb2_blx_out_of_range.stdout
|
||||
|
||||
arm_bl_in_range.stdout: arm_bl_in_range
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
@ -1520,10 +1522,10 @@ thumb_bl_in_range.o: thumb_bl_in_range.s
|
||||
thumb_bl_out_of_range.stdout: thumb_bl_out_of_range
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
thumb_bl_out_of_range: thumb_bl_in_range.o ../ld-new
|
||||
thumb_bl_out_of_range: thumb_bl_out_of_range.o ../ld-new
|
||||
../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $<
|
||||
|
||||
thumb_bl_out_of_range.o: thumb_bl_in_range.s
|
||||
thumb_bl_out_of_range.o: thumb_bl_out_of_range.s
|
||||
$(TEST_AS) -o $@ -march=armv5te $<
|
||||
|
||||
thumb2_bl_in_range.stdout: thumb2_bl_in_range
|
||||
@ -1538,14 +1540,52 @@ thumb2_bl_in_range.o: thumb_bl_in_range.s
|
||||
thumb2_bl_out_of_range.stdout: thumb2_bl_out_of_range
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
thumb2_bl_out_of_range: thumb2_bl_in_range.o ../ld-new
|
||||
thumb2_bl_out_of_range: thumb2_bl_out_of_range.o ../ld-new
|
||||
../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $<
|
||||
|
||||
thumb2_bl_out_of_range.o: thumb_bl_in_range.s
|
||||
thumb2_bl_out_of_range.o: thumb_bl_out_of_range.s
|
||||
$(TEST_AS) -o $@ -march=armv7-a $<
|
||||
|
||||
thumb_blx_in_range.stdout: thumb_blx_in_range
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
thumb_blx_in_range: thumb_blx_in_range.o ../ld-new
|
||||
../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $<
|
||||
|
||||
thumb_blx_in_range.o: thumb_blx_in_range.s
|
||||
$(TEST_AS) -o $@ -march=armv5te $<
|
||||
|
||||
thumb_blx_out_of_range.stdout: thumb_blx_out_of_range
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
thumb_blx_out_of_range: thumb_blx_out_of_range.o ../ld-new
|
||||
../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $<
|
||||
|
||||
thumb_blx_out_of_range.o: thumb_blx_out_of_range.s
|
||||
$(TEST_AS) -o $@ -march=armv5te $<
|
||||
|
||||
thumb2_blx_in_range.stdout: thumb2_blx_in_range
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
thumb2_blx_in_range: thumb2_blx_in_range.o ../ld-new
|
||||
../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $<
|
||||
|
||||
thumb2_blx_in_range.o: thumb_blx_in_range.s
|
||||
$(TEST_AS) -o $@ -march=armv7-a $<
|
||||
|
||||
thumb2_blx_out_of_range.stdout: thumb2_blx_out_of_range
|
||||
$(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
thumb2_blx_out_of_range: thumb2_blx_out_of_range.o ../ld-new
|
||||
../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $<
|
||||
|
||||
thumb2_blx_out_of_range.o: thumb_blx_out_of_range.s
|
||||
$(TEST_AS) -o $@ -march=armv7-a $<
|
||||
|
||||
MOSTLYCLEANFILES += arm_bl_in_range arm_bl_out_of_range thumb_bl_in_range \
|
||||
thumb_bl_out_of_range thumb2_bl_in_range thumb2_bl_out_of_range
|
||||
thumb_bl_out_of_range thumb2_bl_in_range thumb2_bl_out_of_range \
|
||||
thumb_blx_in_range thumb_blx_out_of_range thumb2_blx_in_range \
|
||||
thumb2_blx_out_of_range
|
||||
|
||||
check_SCRIPTS += arm_fix_v4bx.sh
|
||||
check_DATA += arm_fix_v4bx.stdout arm_fix_v4bx_interworking.stdout \
|
||||
|
@ -338,6 +338,10 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb_bl_out_of_range.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_in_range.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_out_of_range.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb_blx_in_range.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb_blx_out_of_range.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_blx_in_range.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_blx_out_of_range.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ arm_fix_v4bx.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ arm_fix_v4bx_interworking.stdout \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ arm_no_fix_v4bx.stdout
|
||||
@ -346,7 +350,11 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb_bl_in_range \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb_bl_out_of_range \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_in_range \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_out_of_range arm_fix_v4bx \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_bl_out_of_range \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb_blx_in_range \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb_blx_out_of_range \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_blx_in_range \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ thumb2_blx_out_of_range arm_fix_v4bx \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ arm_fix_v4bx_interworking \
|
||||
@DEFAULT_TARGET_ARM_TRUE@ arm_no_fix_v4bx
|
||||
subdir = testsuite
|
||||
@ -3288,10 +3296,10 @@ uninstall-am:
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range.stdout: thumb_bl_out_of_range
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range: thumb_bl_in_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range: thumb_bl_out_of_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range.o: thumb_bl_in_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_bl_out_of_range.o: thumb_bl_out_of_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv5te $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_in_range.stdout: thumb2_bl_in_range
|
||||
@ -3306,10 +3314,46 @@ uninstall-am:
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range.stdout: thumb2_bl_out_of_range
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range: thumb2_bl_in_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range: thumb2_bl_out_of_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range.o: thumb_bl_in_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_bl_out_of_range.o: thumb_bl_out_of_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv7-a $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_blx_in_range.stdout: thumb_blx_in_range
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_blx_in_range: thumb_blx_in_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_blx_in_range.o: thumb_blx_in_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv5te $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_blx_out_of_range.stdout: thumb_blx_out_of_range
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_blx_out_of_range: thumb_blx_out_of_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb_branch_range.t -o $@ $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb_blx_out_of_range.o: thumb_blx_out_of_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv5te $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_blx_in_range.stdout: thumb2_blx_in_range
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_blx_in_range: thumb2_blx_in_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_blx_in_range.o: thumb_blx_in_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv7-a $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_blx_out_of_range.stdout: thumb2_blx_out_of_range
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_OBJDUMP) -D $< > $@
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_blx_out_of_range: thumb2_blx_out_of_range.o ../ld-new
|
||||
@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -T $(srcdir)/thumb2_branch_range.t -o $@ $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@thumb2_blx_out_of_range.o: thumb_blx_out_of_range.s
|
||||
@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -o $@ -march=armv7-a $<
|
||||
|
||||
@DEFAULT_TARGET_ARM_TRUE@arm_fix_v4bx.stdout: arm_fix_v4bx
|
||||
|
@ -53,5 +53,12 @@ check thumb2_bl_in_range.stdout \
|
||||
" 2000004: f400 d000 bl 1000008 <_backward_target>"
|
||||
check thumb2_bl_in_range.stdout \
|
||||
" 2000008: f3ff d7ff bl 300000a <_forward_target>"
|
||||
|
||||
check thumb_blx_in_range.stdout \
|
||||
" 800006: f400 e800 blx 400008 <_backward_target>"
|
||||
check thumb_blx_in_range.stdout \
|
||||
" 80000c: f3ff effe blx c0000c <_forward_target>"
|
||||
check thumb2_blx_in_range.stdout \
|
||||
" 2000006: f400 c000 blx 1000008 <_backward_target>"
|
||||
check thumb2_blx_in_range.stdout \
|
||||
" 200000c: f3ff c7fe blx 300000c <_forward_target>"
|
||||
exit 0
|
||||
|
64
gold/testsuite/thumb_blx_in_range.s
Normal file
64
gold/testsuite/thumb_blx_in_range.s
Normal file
@ -0,0 +1,64 @@
|
||||
# thumb_blx_in_range.s
|
||||
#
|
||||
# Test THUMB/THUMB-2 blx instructions just within the branch range limits.
|
||||
# Because bit 1 of the branch target comes from the branch instruction
|
||||
# address, the branch range from PC (branch instruction address + 4) is
|
||||
# acutally -((1<<22) + 2) to ((1<<22) - 4) for THUMB and -((1<<24) + 2) to
|
||||
# ((1<<24) - 4) from THUMB2.
|
||||
|
||||
.syntax unified
|
||||
.section .text.pre,"x"
|
||||
|
||||
# Add padding so that target is just in branch range.
|
||||
.space 8
|
||||
|
||||
.align 2
|
||||
.global _backward_target
|
||||
.code 32
|
||||
.type _backword_target, %function
|
||||
_backward_target:
|
||||
bx lr
|
||||
.size _backward_target, .-_backward_target
|
||||
|
||||
.text
|
||||
|
||||
# Define _start so that linker does not complain.
|
||||
.global _start
|
||||
.code 32
|
||||
.align 2
|
||||
.type _start, %function
|
||||
_start:
|
||||
bx lr
|
||||
.size _start, .-_start
|
||||
|
||||
.global _backward_test
|
||||
.code 16
|
||||
.thumb_func
|
||||
.type _backward_test, %function
|
||||
_backward_test:
|
||||
nop.n
|
||||
blx _backward_target
|
||||
.size _backward_test, .-_backward_test
|
||||
|
||||
.align 2
|
||||
.global _forward_test
|
||||
.code 16
|
||||
.thumb_func
|
||||
.type _forward_test, %function
|
||||
_forward_test:
|
||||
blx _forward_target
|
||||
.size _forward_test, .-_forward_test
|
||||
.code 32
|
||||
|
||||
.section .text.post,"x"
|
||||
|
||||
# Add padding so that target is just in branch range.
|
||||
.space 12
|
||||
|
||||
.align 2
|
||||
.global _forward_target
|
||||
.code 32
|
||||
.type _forward_target, %function
|
||||
_forward_target:
|
||||
bx lr
|
||||
.size _forward_target, .-_forward_target
|
61
gold/testsuite/thumb_blx_out_of_range.s
Normal file
61
gold/testsuite/thumb_blx_out_of_range.s
Normal file
@ -0,0 +1,61 @@
|
||||
# thumb_blx_out_of_range.s
|
||||
# Test THUMB/THUMB-2 blx instructions just out of the branch range limits.
|
||||
.syntax unified
|
||||
|
||||
.section .text.pre,"x"
|
||||
|
||||
# Add padding so that target is just output of branch range.
|
||||
.space 6
|
||||
|
||||
.global _forward_target
|
||||
.global _backward_target
|
||||
.type _backword_target, %function
|
||||
_backward_target:
|
||||
bx lr
|
||||
.size _backward_target, .-_backward_target
|
||||
|
||||
.text
|
||||
|
||||
# Define _start so that linker does not complain.
|
||||
.align 2
|
||||
.global _start
|
||||
.code 32
|
||||
.type _start, %function
|
||||
_start:
|
||||
bx lr
|
||||
.size _start, .-_start
|
||||
|
||||
.global _backward_test
|
||||
.code 16
|
||||
.thumb_func
|
||||
.type _backward_test, %function
|
||||
_backward_test:
|
||||
bl _backward_target
|
||||
.size _backward_test, .-_backward_test
|
||||
|
||||
.align 2
|
||||
.global _forward_test
|
||||
.code 16
|
||||
.thumb_func
|
||||
.type _forward_test, %function
|
||||
_forward_test:
|
||||
# Bit 1 of the BLX target comes from bit 1 of branch base address,
|
||||
# which is BLX instruction's address + 4. We intentionally put this
|
||||
# forward BLX at an address n*4 + 2 so that the branch offset is
|
||||
# bumped up by 2.
|
||||
nop.n
|
||||
bl _forward_target
|
||||
.size _forward_test, .-_forward_test
|
||||
.code 32
|
||||
|
||||
.section .text.post,"x"
|
||||
|
||||
# Add padding so that target is just out of branch range.
|
||||
.space 12
|
||||
.align 2
|
||||
.code 32
|
||||
.global _forward_target
|
||||
.type _forward_target, %function
|
||||
_forward_target:
|
||||
bx lr
|
||||
.size _forward_target, .-_forward_target
|
Loading…
Reference in New Issue
Block a user