void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value,
ObjectImage &ObjImg,
- const relocation_iterator &RI) {
+ const relocation_iterator &RI,
+ unsigned OffsetToNextPC) {
const MachOObjectFile &Obj =
static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile());
MachO::any_relocation_info RelInfo =
if (IsPCRel) {
uint64_t RelocAddr = 0;
RI->getAddress(RelocAddr);
- unsigned RelocSize = Obj.getAnyRelocationLength(RelInfo);
- Value.Addend += RelocAddr + (1ULL << RelocSize);
+ Value.Addend += RelocAddr + OffsetToNextPC;
}
}
class RuntimeDyldMachOARM
: public RuntimeDyldMachOCRTPBase<RuntimeDyldMachOARM> {
+private:
+ typedef RuntimeDyldMachOCRTPBase<RuntimeDyldMachOARM> ParentT;
+
public:
RuntimeDyldMachOARM(RTDyldMemoryManager *MM) : RuntimeDyldMachOCRTPBase(MM) {}
unsigned getStubAlignment() override { return 4; }
+ int64_t decodeAddend(uint8_t *LocalAddress, unsigned NumBytes,
+ MachO::RelocationInfoType RelType) const {
+ switch (RelType) {
+ default:
+ return ParentT::decodeAddend(LocalAddress, NumBytes, RelType);
+ case MachO::ARM_RELOC_BR24: {
+ uint32_t Temp;
+ memcpy(&Temp, LocalAddress, 4);
+ Temp &= 0x00ffffff; // Mask out the opcode.
+ // Now we've got the shifted immediate, shift by 2, sign extend and ret.
+ return SignExtend32<26>(Temp << 2);
+ }
+ }
+ }
+
relocation_iterator
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID,
RelocationValueRef Value(
getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols));
- bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
- if (!IsExtern && RE.IsPCRel)
- makeValueAddendPCRel(Value, ObjImg, RelI);
+ if (RE.IsPCRel)
+ makeValueAddendPCRel(Value, ObjImg, RelI, 8);
if ((RE.RelType & 0xf) == MachO::ARM_RELOC_BR24)
processBranchRelocation(RE, Value, Stubs);
uint8_t *StubTargetAddr =
createStubFunction(Section.Address + Section.StubOffset);
RelocationEntry StubRE(RE.SectionID, StubTargetAddr - Section.Address,
- MachO::GENERIC_RELOC_VANILLA, Value.Addend);
+ MachO::GENERIC_RELOC_VANILLA, Value.Addend, false,
+ 2);
if (Value.SymbolName)
addRelocationForSymbol(StubRE, Value.SymbolName);
else
Addr = Section.Address + Section.StubOffset;
Section.StubOffset += getMaxStubSize();
}
- RelocationEntry TargetRE(Value.SectionID, RE.Offset, RE.RelType, 0,
+ RelocationEntry TargetRE(RE.SectionID, RE.Offset, RE.RelType, 0,
RE.IsPCRel, RE.Size);
resolveRelocation(TargetRE, (uint64_t)Addr);
}
-# RUN: llvm-mc -triple=armv7s-apple-ios7.0.0 -relocation-model=pic -filetype=obj -o %t.o %s
-# RUN: llvm-rtdyld -triple=armv7s-apple-ios7.0.0 -verify -check=%s %t.o
-# RUN: rm %t.o
+# RUN: llvm-mc -triple=armv7s-apple-ios7.0.0 -relocation-model=pic -filetype=obj -o %T/foo.o %s
+# RUN: llvm-rtdyld -triple=armv7s-apple-ios7.0.0 -verify -check=%s %/T/foo.o
.syntax unified
.section __TEXT,__text,regular,pure_instructions
movt r0, :upper16:(foo-(nextPC+8))
nextPC:
add r0, pc, r0
+
+# Check stub generation by referencing a common symbol, 'baz'. Check both the
+# Content of the stub, and the reference to the stub.
+# Stub should contain '0xe51ff004' (ldr pc, [pc, #-4]), followed by the target.
+#
+# rtdyld-check: *{4}(stub_addr(foo.o, __text, baz)) = 0xe51ff004
+# rtdyld-check: *{4}(stub_addr(foo.o, __text, baz) + 4) = baz
+#
+# rtdyld-check: decode_operand(insn3, 0) = stub_addr(foo.o, __text, baz) - (insn3 + 8)
+insn3:
+ bl baz
bx lr
.globl foo
foo:
bx lr
+ .comm baz, 4, 2
+
.subsections_via_symbols