mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 15:19:33 +00:00
[RuntimeDyld][MachO] Properly handle thumb to thumb calls within a section.
Previously thumb bits were only checked for external relocations (thumb to arm code and vice-versa). This patch adds detection for thumb callees in the same section asthe (also thumb) caller. The MachO/Thumb test case is updated to cover this, and redundant checks (handled by the MachO/ARM test) are removed. llvm-svn: 331838
This commit is contained in:
parent
f5611cc773
commit
cc9d8f83c8
@ -47,6 +47,18 @@ public:
|
||||
return Addr;
|
||||
}
|
||||
|
||||
bool isAddrTargetThumb(unsigned SectionID, uint64_t Offset) {
|
||||
auto TargetObjAddr = Sections[SectionID].getObjAddress() + Offset;
|
||||
for (auto &KV : GlobalSymbolTable) {
|
||||
auto &Entry = KV.second;
|
||||
auto SymbolObjAddr =
|
||||
Sections[Entry.getSectionID()].getObjAddress() + Entry.getOffset();
|
||||
if (TargetObjAddr == SymbolObjAddr)
|
||||
return (Entry.getFlags().getTargetFlags() & ARMJITSymbolFlags::Thumb);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Expected<int64_t> decodeAddend(const RelocationEntry &RE) const {
|
||||
const SectionEntry &Section = Sections[RE.SectionID];
|
||||
uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
|
||||
@ -161,12 +173,18 @@ public:
|
||||
// the value as being a thumb stub: we don't want to mix it up with an ARM
|
||||
// stub targeting the same function.
|
||||
if (RE.RelType == MachO::ARM_THUMB_RELOC_BR22)
|
||||
Value.IsStubThumb = TargetIsLocalThumbFunc;
|
||||
Value.IsStubThumb = true;
|
||||
|
||||
if (RE.IsPCRel)
|
||||
makeValueAddendPCRel(Value, RelI,
|
||||
(RE.RelType == MachO::ARM_THUMB_RELOC_BR22) ? 4 : 8);
|
||||
|
||||
// If this is a non-external branch target check whether Value points to a
|
||||
// thumb func.
|
||||
if (!Value.SymbolName && (RelType == MachO::ARM_RELOC_BR24 ||
|
||||
RelType == MachO::ARM_THUMB_RELOC_BR22))
|
||||
RE.IsTargetThumbFunc = isAddrTargetThumb(Value.SectionID, Value.Offset);
|
||||
|
||||
if (RE.RelType == MachO::ARM_RELOC_BR24 ||
|
||||
RE.RelType == MachO::ARM_THUMB_RELOC_BR22)
|
||||
processBranchRelocation(RE, Value, Stubs);
|
||||
|
@ -5,48 +5,57 @@
|
||||
.section __TEXT,__text,regular,pure_instructions
|
||||
.syntax unified
|
||||
|
||||
# Add 'aaa' to the common symbols to make sure 'baz' isn't at the start of the
|
||||
# section. This ensures that we test VANILLA relocation addends correctly.
|
||||
.comm aaa, 4, 2
|
||||
.comm baz, 4, 2
|
||||
|
||||
|
||||
.globl bar
|
||||
.globl thumb_caller_thumb_callee
|
||||
.p2align 1
|
||||
.code 16 @ @bar
|
||||
.thumb_func bar
|
||||
|
||||
bar:
|
||||
# Check lower 16-bits of section difference relocation
|
||||
# rtdyld-check: decode_operand(insn1, 1) = (foo-(nextPC+8))[15:0]
|
||||
insn1:
|
||||
movw r0, :lower16:(foo-(nextPC+8))
|
||||
# Check upper 16-bits of section difference relocation
|
||||
# rtdyld-check: decode_operand(insn2, 2) = (foo-(nextPC+8))[31:16]
|
||||
insn2:
|
||||
movt r0, :upper16:(foo-(nextPC+8))
|
||||
nextPC:
|
||||
.code 16
|
||||
.thumb_func thumb_caller_thumb_callee
|
||||
thumb_caller_thumb_callee:
|
||||
nop
|
||||
|
||||
# Check stub generation for external symbols by referencing a common symbol, 'baz'.
|
||||
# Check both the content of the stub, and the reference to the stub.
|
||||
# Stub should contain '0xf000f8df' (ldr.w pc, [pc]), followed by the target.
|
||||
#
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, baz)) = 0xf000f8df
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, baz) + 4) = baz
|
||||
#
|
||||
# rtdyld-check: decode_operand(insn3, 0) = stub_addr(MachO_Thumb.o, __text, baz) - (insn3 + 4)
|
||||
insn3:
|
||||
bl baz
|
||||
.globl arm_caller_thumb_callee
|
||||
.p2align 1
|
||||
.code 16
|
||||
.thumb_func arm_caller_thumb_callee
|
||||
arm_caller_thumb_callee:
|
||||
nop
|
||||
|
||||
# Check stub generation for internal symbols by referencing 'bar'.
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, bar) + 4) = bar & 0xfffffffffffffffe
|
||||
insn4:
|
||||
bl bar
|
||||
.globl thumb_caller_arm_callee
|
||||
.p2align 1
|
||||
.code 32
|
||||
thumb_caller_arm_callee:
|
||||
nop
|
||||
|
||||
.section __DATA,__data
|
||||
.align 2
|
||||
foo:
|
||||
.long 0
|
||||
.globl thumb_caller
|
||||
.p2align 1
|
||||
.code 16
|
||||
.thumb_func thumb_caller
|
||||
thumb_caller:
|
||||
nop
|
||||
|
||||
# Check that stubs for thumb callers use thumb code (not arm), and that thumb
|
||||
# callees have the low bit set on their addresses.
|
||||
#
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_thumb_callee)) = 0xf000f8df
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_thumb_callee) + 4) = (thumb_caller_thumb_callee | 0x1)
|
||||
bl thumb_caller_thumb_callee
|
||||
|
||||
# Check that arm callees do not have the low bit set on their addresses.
|
||||
#
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_arm_callee)) = 0xf000f8df
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, thumb_caller_arm_callee) + 4) = thumb_caller_arm_callee
|
||||
bl thumb_caller_arm_callee
|
||||
|
||||
.globl arm_caller
|
||||
.p2align 2
|
||||
.code 32
|
||||
arm_caller:
|
||||
nop
|
||||
|
||||
# Check that stubs for arm callers use arm code (not thumb), and that thumb
|
||||
# callees have the low bit set on their addresses.
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, arm_caller_thumb_callee)) = 0xe51ff004
|
||||
# rtdyld-check: *{4}(stub_addr(MachO_Thumb.o, __text, arm_caller_thumb_callee) + 4) = (arm_caller_thumb_callee | 0x1)
|
||||
bl arm_caller_thumb_callee
|
||||
nop
|
||||
|
||||
.subsections_via_symbols
|
||||
|
Loading…
Reference in New Issue
Block a user