summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp186
1 files changed, 119 insertions, 67 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index c0047d0cde6a..cc6729d21320 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -65,7 +65,7 @@ template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
- typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
+ typedef typename ELFT::uint addr_type;
DyldELFObject(ELFObjectFile<ELFT> &&Obj);
@@ -148,8 +148,8 @@ template <typename ELFT>
static Expected<std::unique_ptr<DyldELFObject<ELFT>>>
createRTDyldELFObject(MemoryBufferRef Buffer, const ObjectFile &SourceObject,
const LoadedELFObjectInfo &L) {
- typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
- typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
+ typedef typename ELFT::Shdr Elf_Shdr;
+ typedef typename ELFT::uint addr_type;
Expected<std::unique_ptr<DyldELFObject<ELFT>>> ObjOrErr =
DyldELFObject<ELFT>::create(Buffer);
@@ -273,8 +273,8 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
case ELF::R_X86_64_64: {
support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
Value + Addend;
- DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
case ELF::R_X86_64_32:
@@ -286,8 +286,8 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
TruncatedAddr;
- DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
case ELF::R_X86_64_PC8: {
@@ -312,6 +312,22 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
int64_t RealOffset = Value + Addend - FinalAddress;
support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
RealOffset;
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", RealOffset) << " at "
+ << format("%p\n", FinalAddress));
+ break;
+ }
+ case ELF::R_X86_64_GOTOFF64: {
+ // Compute Value - GOTBase.
+ uint64_t GOTBase = 0;
+ for (const auto &Section : Sections) {
+ if (Section.getName() == ".got") {
+ GOTBase = Section.getLoadAddressWithOffset(0);
+ break;
+ }
+ }
+ assert(GOTBase != 0 && "missing GOT");
+ int64_t GOTOffset = Value - GOTBase + Addend;
+ support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) = GOTOffset;
break;
}
}
@@ -326,6 +342,9 @@ void RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section,
Value + Addend;
break;
}
+ // Handle R_386_PLT32 like R_386_PC32 since it should be able to
+ // reach any 32 bit address.
+ case ELF::R_386_PLT32:
case ELF::R_386_PC32: {
uint32_t FinalAddress =
Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
@@ -351,12 +370,12 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
// Data should use target endian. Code should always use little endian.
bool isBE = Arch == Triple::aarch64_be;
- DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
- << format("%llx", Section.getAddressWithOffset(Offset))
- << " FinalAddress: 0x" << format("%llx", FinalAddress)
- << " Value: 0x" << format("%llx", Value) << " Type: 0x"
- << format("%x", Type) << " Addend: 0x" << format("%llx", Addend)
- << "\n");
+ LLVM_DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
+ << format("%llx", Section.getAddressWithOffset(Offset))
+ << " FinalAddress: 0x" << format("%llx", FinalAddress)
+ << " Value: 0x" << format("%llx", Value) << " Type: 0x"
+ << format("%x", Type) << " Addend: 0x"
+ << format("%llx", Addend) << "\n");
switch (Type) {
default:
@@ -471,11 +490,12 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
Value += Addend;
- DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: "
- << Section.getAddressWithOffset(Offset)
- << " FinalAddress: " << format("%p", FinalAddress) << " Value: "
- << format("%x", Value) << " Type: " << format("%x", Type)
- << " Addend: " << format("%x", Addend) << "\n");
+ LLVM_DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: "
+ << Section.getAddressWithOffset(Offset)
+ << " FinalAddress: " << format("%p", FinalAddress)
+ << " Value: " << format("%x", Value)
+ << " Type: " << format("%x", Type)
+ << " Addend: " << format("%x", Addend) << "\n");
switch (Type) {
default:
@@ -526,10 +546,11 @@ void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
IsMipsN64ABI = false;
return;
}
- unsigned AbiVariant;
- Obj.getPlatformFlags(AbiVariant);
- IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
- IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2;
+ if (auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
+ unsigned AbiVariant = E->getPlatformFlags();
+ IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
+ IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2;
+ }
IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips");
}
@@ -718,9 +739,11 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
break;
case ELF::R_PPC64_ADDR16_HI:
+ case ELF::R_PPC64_ADDR16_HIGH:
writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
break;
case ELF::R_PPC64_ADDR16_HA:
+ case ELF::R_PPC64_ADDR16_HIGHA:
writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
break;
case ELF::R_PPC64_ADDR16_HIGHER:
@@ -767,8 +790,9 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
if (SignExtend64<26>(delta) != delta)
llvm_unreachable("Relocation R_PPC64_REL24 overflow");
- // Generates a 'bl <address>' instruction
- writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
+ // We preserve bits other than LI field, i.e. PO and AA/LK fields.
+ uint32_t Inst = readBytesUnaligned(LocalAddress, 4);
+ writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
} break;
case ELF::R_PPC64_REL32: {
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
@@ -855,16 +879,16 @@ void RuntimeDyldELF::resolveBPFRelocation(const SectionEntry &Section,
break;
case ELF::R_BPF_64_64: {
write(isBE, Section.getAddressWithOffset(Offset), Value + Addend);
- DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
case ELF::R_BPF_64_32: {
Value += Addend;
assert(Value <= UINT32_MAX);
write(isBE, Section.getAddressWithOffset(Offset), static_cast<uint32_t>(Value));
- DEBUG(dbgs() << "Writing " << format("%p", Value) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", Value) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
}
@@ -1021,7 +1045,7 @@ void RuntimeDyldELF::resolveAArch64Branch(unsigned SectionID,
relocation_iterator RelI,
StubMap &Stubs) {
- DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
SectionEntry &Section = Sections[SectionID];
uint64_t Offset = RelI->getOffset();
@@ -1032,10 +1056,10 @@ void RuntimeDyldELF::resolveAArch64Branch(unsigned SectionID,
resolveRelocation(Section, Offset,
(uint64_t)Section.getAddressWithOffset(i->second),
RelType, 0);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else if (!resolveAArch64ShortBranch(SectionID, RelI, Value)) {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()));
@@ -1092,8 +1116,8 @@ RuntimeDyldELF::processRelocationRef(
else
return TargetNameOrErr.takeError();
}
- DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
- << " TargetName: " << TargetName << "\n");
+ LLVM_DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
+ << " TargetName: " << TargetName << "\n");
RelocationValueRef Value;
// First search for the symbol in the local symbol table
SymbolRef::Type SymType = SymbolRef::ST_Unknown;
@@ -1134,7 +1158,7 @@ RuntimeDyldELF::processRelocationRef(
section_iterator si = *SectionOrErr;
if (si == Obj.section_end())
llvm_unreachable("Symbol section not found, bad object file format!");
- DEBUG(dbgs() << "\t\tThis is section symbol\n");
+ LLVM_DEBUG(dbgs() << "\t\tThis is section symbol\n");
bool isCode = si->isText();
if (auto SectionIDOrErr = findOrEmitSection(Obj, (*si), isCode,
ObjSectionToID))
@@ -1166,8 +1190,8 @@ RuntimeDyldELF::processRelocationRef(
uint64_t Offset = RelI->getOffset();
- DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
- << "\n");
+ LLVM_DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
+ << "\n");
if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be)) {
if (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26) {
resolveAArch64Branch(SectionID, Value, RelI, Stubs);
@@ -1189,7 +1213,7 @@ RuntimeDyldELF::processRelocationRef(
if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
RelType == ELF::R_ARM_JUMP24) {
// This is an ARM branch relocation, need to use a stub function.
- DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");
+ LLVM_DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");
SectionEntry &Section = Sections[SectionID];
// Look for an existing stub.
@@ -1199,10 +1223,10 @@ RuntimeDyldELF::processRelocationRef(
Section, Offset,
reinterpret_cast<uint64_t>(Section.getAddressWithOffset(i->second)),
RelType, 0);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()));
@@ -1237,7 +1261,7 @@ RuntimeDyldELF::processRelocationRef(
uint32_t Opcode = readBytesUnaligned(Placeholder, 4);
if (RelType == ELF::R_MIPS_26) {
// This is an Mips branch relocation, need to use a stub function.
- DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
SectionEntry &Section = Sections[SectionID];
// Extract the addend from the instruction.
@@ -1252,14 +1276,13 @@ RuntimeDyldELF::processRelocationRef(
if (i != Stubs.end()) {
RelocationEntry RE(SectionID, Offset, RelType, i->second);
addRelocationForSection(RE, SectionID);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
- unsigned AbiVariant;
- O.getPlatformFlags(AbiVariant);
+ unsigned AbiVariant = Obj.getPlatformFlags();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
@@ -1340,7 +1363,7 @@ RuntimeDyldELF::processRelocationRef(
addRelocationForSection(RE, Value.SectionID);
} else if (RelType == ELF::R_MIPS_26) {
// This is an Mips branch relocation, need to use a stub function.
- DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
SectionEntry &Section = Sections[SectionID];
// Look up for existing stub.
@@ -1348,14 +1371,13 @@ RuntimeDyldELF::processRelocationRef(
if (i != Stubs.end()) {
RelocationEntry RE(SectionID, Offset, RelType, i->second);
addRelocationForSection(RE, SectionID);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
- unsigned AbiVariant;
- O.getPlatformFlags(AbiVariant);
+ unsigned AbiVariant = Obj.getPlatformFlags();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
@@ -1412,8 +1434,7 @@ RuntimeDyldELF::processRelocationRef(
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
if (RelType == ELF::R_PPC64_REL24) {
// Determine ABI variant in use for this object.
- unsigned AbiVariant;
- Obj.getPlatformFlags(AbiVariant);
+ unsigned AbiVariant = Obj.getPlatformFlags();
AbiVariant &= ELF::EF_PPC64_ABI;
// A PPC branch relocation will need a stub function if the target is
// an external symbol (either Value.SymbolName is set, or SymType is
@@ -1422,7 +1443,8 @@ RuntimeDyldELF::processRelocationRef(
SectionEntry &Section = Sections[SectionID];
uint8_t *Target = Section.getAddressWithOffset(Offset);
bool RangeOverflow = false;
- if (!Value.SymbolName && SymType != SymbolRef::ST_Unknown) {
+ bool IsExtern = Value.SymbolName || SymType == SymbolRef::ST_Unknown;
+ if (!IsExtern) {
if (AbiVariant != 2) {
// In the ELFv1 ABI, a function call may point to the .opd entry,
// so the final symbol value is calculated based on the relocation
@@ -1432,21 +1454,24 @@ RuntimeDyldELF::processRelocationRef(
} else {
// In the ELFv2 ABI, a function symbol may provide a local entry
// point, which must be used for direct calls.
- uint8_t SymOther = Symbol->getOther();
- Value.Addend += ELF::decodePPC64LocalEntryOffset(SymOther);
+ if (Value.SectionID == SectionID){
+ uint8_t SymOther = Symbol->getOther();
+ Value.Addend += ELF::decodePPC64LocalEntryOffset(SymOther);
+ }
}
uint8_t *RelocTarget =
Sections[Value.SectionID].getAddressWithOffset(Value.Addend);
int64_t delta = static_cast<int64_t>(Target - RelocTarget);
// If it is within 26-bits branch range, just set the branch target
- if (SignExtend64<26>(delta) == delta) {
+ if (SignExtend64<26>(delta) != delta) {
+ RangeOverflow = true;
+ } else if ((AbiVariant != 2) ||
+ (AbiVariant == 2 && Value.SectionID == SectionID)) {
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
addRelocationForSection(RE, Value.SectionID);
- } else {
- RangeOverflow = true;
}
}
- if (Value.SymbolName || SymType == SymbolRef::ST_Unknown ||
+ if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID) ||
RangeOverflow) {
// It is an external symbol (either Value.SymbolName is set, or
// SymType is SymbolRef::ST_Unknown) or out of range.
@@ -1457,10 +1482,10 @@ RuntimeDyldELF::processRelocationRef(
reinterpret_cast<uint64_t>(
Section.getAddressWithOffset(i->second)),
RelType, 0);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()),
@@ -1503,10 +1528,10 @@ RuntimeDyldELF::processRelocationRef(
RelType, 0);
Section.advanceStubOffset(getMaxStubSize());
}
- if (Value.SymbolName || SymType == SymbolRef::ST_Unknown) {
+ if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID)) {
// Restore the TOC for external calls
if (AbiVariant == 2)
- writeInt32BE(Target + 4, 0xE8410018); // ld r2,28(r1)
+ writeInt32BE(Target + 4, 0xE8410018); // ld r2,24(r1)
else
writeInt32BE(Target + 4, 0xE8410028); // ld r2,40(r1)
}
@@ -1577,7 +1602,7 @@ RuntimeDyldELF::processRelocationRef(
// parts of the stub separately. However, as things stand, we allocate
// a stub for every relocation, so using a GOT in JIT code should be
// no less space efficient than using an explicit constant pool.
- DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation.");
SectionEntry &Section = Sections[SectionID];
// Look for an existing stub.
@@ -1585,10 +1610,10 @@ RuntimeDyldELF::processRelocationRef(
uintptr_t StubAddress;
if (i != Stubs.end()) {
StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
uintptr_t BaseAddress = uintptr_t(Section.getAddress());
uintptr_t StubAlignment = getStubAlignment();
@@ -1639,10 +1664,10 @@ RuntimeDyldELF::processRelocationRef(
uintptr_t StubAddress;
if (i != Stubs.end()) {
StubAddress = uintptr_t(Section.getAddress()) + i->second;
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function (equivalent to a PLT entry).
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
uintptr_t BaseAddress = uintptr_t(Section.getAddress());
uintptr_t StubAlignment = getStubAlignment();
@@ -1691,6 +1716,29 @@ RuntimeDyldELF::processRelocationRef(
addRelocationForSymbol(RE, Value.SymbolName);
else
addRelocationForSection(RE, Value.SectionID);
+ } else if (RelType == ELF::R_X86_64_GOT64) {
+ // Fill in a 64-bit GOT offset.
+ uint64_t GOTOffset = allocateGOTEntries(1);
+ resolveRelocation(Sections[SectionID], Offset, GOTOffset,
+ ELF::R_X86_64_64, 0);
+
+ // Fill in the value of the symbol we're targeting into the GOT
+ RelocationEntry RE =
+ computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_64);
+ if (Value.SymbolName)
+ addRelocationForSymbol(RE, Value.SymbolName);
+ else
+ addRelocationForSection(RE, Value.SectionID);
+ } else if (RelType == ELF::R_X86_64_GOTPC64) {
+ // Materialize the address of the base of the GOT relative to the PC.
+ // This doesn't create a GOT entry, but it does mean we need a GOT
+ // section.
+ (void)allocateGOTEntries(0);
+ resolveGOTOffsetRelocation(SectionID, Offset, Addend, ELF::R_X86_64_PC64);
+ } else if (RelType == ELF::R_X86_64_GOTOFF64) {
+ // GOTOFF relocations ultimately require a section difference relocation.
+ (void)allocateGOTEntries(0);
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
} else if (RelType == ELF::R_X86_64_PC32) {
Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
processSimpleRelocation(SectionID, Offset, RelType, Value);
@@ -1862,6 +1910,7 @@ bool RuntimeDyldELF::relocationNeedsGot(const RelocationRef &R) const {
if (Arch == Triple::x86_64)
return RelTy == ELF::R_X86_64_GOTPCREL ||
RelTy == ELF::R_X86_64_GOTPCRELX ||
+ RelTy == ELF::R_X86_64_GOT64 ||
RelTy == ELF::R_X86_64_REX_GOTPCRELX;
return false;
}
@@ -1878,6 +1927,9 @@ bool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const {
case ELF::R_X86_64_GOTPCREL:
case ELF::R_X86_64_GOTPCRELX:
case ELF::R_X86_64_REX_GOTPCRELX:
+ case ELF::R_X86_64_GOTPC64:
+ case ELF::R_X86_64_GOT64:
+ case ELF::R_X86_64_GOTOFF64:
case ELF::R_X86_64_PC32:
case ELF::R_X86_64_PC64:
case ELF::R_X86_64_64: