30 using namespace llvm::object;
31 using namespace llvm::support::endian;
33 #define DEBUG_TYPE "dyld"
38 or32le(L, (Imm & 0xFFF) << 10);
41 template <
class T>
static void write(
bool isBE,
void *
P,
T V) {
42 isBE ? write<T, support::big>(
P, V) : write<T, support::little>(P, V);
47 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
48 uint64_t
Mask = (0x3 << 29) | (0x1FFFFC << 3);
54 static uint64_t
getBits(uint64_t Val,
int Start,
int End) {
55 uint64_t
Mask = ((uint64_t)1 << (End + 1 - Start)) - 1;
56 return (Val >> Start) &
Mask;
61 template <
class ELFT>
class DyldELFObject :
public ELFObjectFile<ELFT> {
96 DyldELFObject<ELFT>::DyldELFObject(
MemoryBufferRef Wrapper, std::error_code &EC)
98 this->isDyldELFObject =
true;
101 template <
class ELFT>
102 void DyldELFObject<ELFT>::updateSectionAddress(
const SectionRef &Sec,
106 const_cast<Elf_Shdr *
>(
reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
110 shdr->sh_addr =
static_cast<addr_type
>(Addr);
113 template <
class ELFT>
114 void DyldELFObject<ELFT>::updateSymbolAddress(
const SymbolRef &SymRef,
117 Elf_Sym *sym =
const_cast<Elf_Sym *
>(
122 sym->st_value =
static_cast<addr_type
>(Addr);
125 class LoadedELFObjectInfo final
128 LoadedELFObjectInfo(
RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
129 : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
135 template <
typename ELFT>
136 std::unique_ptr<DyldELFObject<ELFT>>
139 const LoadedELFObjectInfo &
L,
140 std::error_code &ec) {
144 std::unique_ptr<DyldELFObject<ELFT>> Obj =
145 llvm::make_unique<DyldELFObject<ELFT>>(Buffer, ec);
149 for (
const auto &Sec : Obj->sections()) {
152 if (SectionName !=
"") {
154 Elf_Shdr *shdr =
const_cast<Elf_Shdr *
>(
155 reinterpret_cast<const Elf_Shdr *
>(ShdrRef.
p));
157 if (uint64_t SecLoadAddr = L.getSectionLoadAddress(*SI)) {
160 shdr->sh_addr =
static_cast<addr_type
>(SecLoadAddr);
170 const LoadedELFObjectInfo &L) {
173 std::unique_ptr<MemoryBuffer> Buffer =
178 std::unique_ptr<ObjectFile> DebugObj;
181 DebugObj = createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), Obj,
L,
185 DebugObj = createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), Obj,
L,
189 DebugObj = createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), Obj,
L,
193 DebugObj = createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), Obj,
L,
198 assert(!ec &&
"Could not construct copy ELF object file");
204 LoadedELFObjectInfo::getObjectForDebug(
const ObjectFile &Obj)
const {
205 return createELFDebugObject(Obj, *
this);
214 :
RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {}
218 for (
int i = 0, e = UnregisteredEHFrameSections.
size();
i != e; ++
i) {
219 SID EHFrameSID = UnregisteredEHFrameSections[
i];
220 uint8_t *EHFrameAddr =
Sections[EHFrameSID].getAddress();
221 uint64_t EHFrameLoadAddr =
Sections[EHFrameSID].getLoadAddress();
222 size_t EHFrameSize =
Sections[EHFrameSID].getSize();
224 RegisteredEHFrameSections.
push_back(EHFrameSID);
226 UnregisteredEHFrameSections.
clear();
230 for (
int i = 0, e = RegisteredEHFrameSections.
size();
i != e; ++
i) {
231 SID EHFrameSID = RegisteredEHFrameSections[
i];
232 uint8_t *EHFrameAddr =
Sections[EHFrameSID].getAddress();
233 uint64_t EHFrameLoadAddr =
Sections[EHFrameSID].getLoadAddress();
234 size_t EHFrameSize =
Sections[EHFrameSID].getSize();
237 RegisteredEHFrameSections.
clear();
240 std::unique_ptr<RuntimeDyldELF>
246 return make_unique<RuntimeDyldELF>(MemMgr, Resolver);
251 return make_unique<RuntimeDyldELFMips>(MemMgr, Resolver);
255 std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
258 return llvm::make_unique<LoadedELFObjectInfo>(*
this, *ObjSectionToIDOrErr);
270 uint64_t SymOffset) {
275 case ELF::R_X86_64_64: {
282 case ELF::R_X86_64_32:
283 case ELF::R_X86_64_32S: {
285 assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) ||
286 (Type == ELF::R_X86_64_32S &&
287 ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN)));
288 uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
295 case ELF::R_X86_64_PC8: {
297 int64_t RealOffset = Value + Addend - FinalAddress;
299 int8_t TruncOffset = (RealOffset & 0xFF);
303 case ELF::R_X86_64_PC32: {
305 int64_t RealOffset = Value + Addend - FinalAddress;
307 int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
312 case ELF::R_X86_64_PC64: {
314 int64_t RealOffset = Value + Addend - FinalAddress;
322 void RuntimeDyldELF::resolveX86Relocation(
const SectionEntry &Section,
326 case ELF::R_386_32: {
331 case ELF::R_386_PC32: {
334 uint32_t RealOffset = Value + Addend - FinalAddress;
347 void RuntimeDyldELF::resolveAArch64Relocation(
const SectionEntry &Section,
348 uint64_t Offset, uint64_t Value,
356 DEBUG(
dbgs() <<
"resolveAArch64Relocation, LocalAddress: 0x"
358 <<
" FinalAddress: 0x" <<
format(
"%llx", FinalAddress)
359 <<
" Value: 0x" <<
format(
"%llx", Value) <<
" Type: 0x"
360 <<
format(
"%x", Type) <<
" Addend: 0x" <<
format(
"%llx", Addend)
367 case ELF::R_AARCH64_ABS64:
368 write(isBE, TargetPtr, Value + Addend);
370 case ELF::R_AARCH64_PREL32: {
371 uint64_t Result = Value + Addend - FinalAddress;
372 assert(static_cast<int64_t>(Result) >= INT32_MIN &&
373 static_cast<int64_t>(Result) <= UINT32_MAX);
374 write(isBE, TargetPtr, static_cast<uint32_t>(Result & 0xffffffffU));
377 case ELF::R_AARCH64_PREL64:
378 write(isBE, TargetPtr, Value + Addend - FinalAddress);
380 case ELF::R_AARCH64_CALL26:
381 case ELF::R_AARCH64_JUMP26: {
384 uint64_t BranchImm = Value + Addend - FinalAddress;
387 assert(isInt<28>(BranchImm));
388 or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2);
391 case ELF::R_AARCH64_MOVW_UABS_G3:
392 or32le(TargetPtr, ((Value + Addend) & 0xFFFF000000000000) >> 43);
394 case ELF::R_AARCH64_MOVW_UABS_G2_NC:
395 or32le(TargetPtr, ((Value + Addend) & 0xFFFF00000000) >> 27);
397 case ELF::R_AARCH64_MOVW_UABS_G1_NC:
398 or32le(TargetPtr, ((Value + Addend) & 0xFFFF0000) >> 11);
400 case ELF::R_AARCH64_MOVW_UABS_G0_NC:
401 or32le(TargetPtr, ((Value + Addend) & 0xFFFF) << 5);
403 case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
406 ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
409 assert(isInt<33>(Result) &&
"overflow check failed for relocation");
416 case ELF::R_AARCH64_ADD_ABS_LO12_NC:
422 case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
428 case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
437 void RuntimeDyldELF::resolveARMRelocation(
const SectionEntry &Section,
446 DEBUG(
dbgs() <<
"resolveARMRelocation, LocalAddress: "
448 <<
" FinalAddress: " <<
format(
"%p", FinalAddress) <<
" Value: "
449 <<
format(
"%x", Value) <<
" Type: " <<
format(
"%x", Type)
450 <<
" Addend: " <<
format(
"%x", Addend) <<
"\n");
456 case ELF::R_ARM_NONE:
459 case ELF::R_ARM_PREL31:
462 ((Value - FinalAddress) & ~0x80000000);
464 case ELF::R_ARM_TARGET1:
465 case ELF::R_ARM_ABS32:
470 case ELF::R_ARM_MOVW_ABS_NC:
471 case ELF::R_ARM_MOVT_ABS:
472 if (Type == ELF::R_ARM_MOVW_ABS_NC)
473 Value = Value & 0xFFFF;
474 else if (Type == ELF::R_ARM_MOVT_ABS)
475 Value = (Value >> 16) & 0xFFFF;
478 (((Value >> 12) & 0xF) << 16);
481 case ELF::R_ARM_PC24:
482 case ELF::R_ARM_CALL:
483 case ELF::R_ARM_JUMP24:
484 int32_t RelValue =
static_cast<int32_t
>(Value - FinalAddress - 8);
485 RelValue = (RelValue & 0x03FFFFFC) >> 2;
493 void RuntimeDyldELF::setMipsABI(
const ObjectFile &Obj) {
510 ObjSectionToIDMap &LocalSections,
522 for (
auto &Section: Obj.
sections()) {
524 if (
auto EC = Section.
getName(SectionName))
527 if (SectionName ==
".got"
528 || SectionName ==
".toc"
529 || SectionName ==
".tocbss"
530 || SectionName ==
".plt") {
531 if (
auto SectionIDOrErr =
535 return SectionIDOrErr.takeError();
550 ObjSectionToIDMap &LocalSections,
561 if (
auto EC = RelSecI->getName(RelSectionName))
564 if (RelSectionName !=
".opd")
568 e = si->relocation_end();
572 uint64_t TypeFunc =
i->getType();
573 if (TypeFunc != ELF::R_PPC64_ADDR64) {
578 uint64_t TargetSymbolOffset =
i->getOffset();
581 if (
auto AddendOrErr =
i->getAddend())
582 Addend = *AddendOrErr;
591 uint64_t TypeTOC = i->getType();
592 if (TypeTOC != ELF::R_PPC64_TOC)
598 if (Rel.
Addend != (int64_t)TargetSymbolOffset)
602 if (
auto TSIOrErr = TargetSymbol->
getSection())
605 return TSIOrErr.takeError();
608 bool IsCode = TSI->isText();
613 return SectionIDOrErr.takeError();
626 static inline uint16_t
applyPPClo(uint64_t value) {
return value & 0xffff; }
629 return (value >> 16) & 0xffff;
633 return ((value + 0x8000) >> 16) & 0xffff;
637 return (value >> 32) & 0xffff;
641 return ((value + 0x8000) >> 32) & 0xffff;
645 return (value >> 48) & 0xffff;
649 return ((value + 0x8000) >> 48) & 0xffff;
652 void RuntimeDyldELF::resolvePPC32Relocation(
const SectionEntry &Section,
653 uint64_t Offset, uint64_t Value,
660 case ELF::R_PPC_ADDR16_LO:
663 case ELF::R_PPC_ADDR16_HI:
666 case ELF::R_PPC_ADDR16_HA:
672 void RuntimeDyldELF::resolvePPC64Relocation(
const SectionEntry &Section,
673 uint64_t Offset, uint64_t Value,
680 case ELF::R_PPC64_ADDR16:
683 case ELF::R_PPC64_ADDR16_DS:
686 case ELF::R_PPC64_ADDR16_LO:
689 case ELF::R_PPC64_ADDR16_LO_DS:
692 case ELF::R_PPC64_ADDR16_HI:
695 case ELF::R_PPC64_ADDR16_HA:
698 case ELF::R_PPC64_ADDR16_HIGHER:
701 case ELF::R_PPC64_ADDR16_HIGHERA:
704 case ELF::R_PPC64_ADDR16_HIGHEST:
707 case ELF::R_PPC64_ADDR16_HIGHESTA:
710 case ELF::R_PPC64_ADDR14: {
711 assert(((Value + Addend) & 3) == 0);
713 uint8_t aalk = *(LocalAddress + 3);
714 writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc));
716 case ELF::R_PPC64_REL16_LO: {
718 uint64_t Delta = Value - FinalAddress + Addend;
721 case ELF::R_PPC64_REL16_HI: {
723 uint64_t Delta = Value - FinalAddress + Addend;
726 case ELF::R_PPC64_REL16_HA: {
728 uint64_t Delta = Value - FinalAddress + Addend;
731 case ELF::R_PPC64_ADDR32: {
732 int32_t Result =
static_cast<int32_t
>(Value + Addend);
733 if (SignExtend32<32>(Result) != Result)
737 case ELF::R_PPC64_REL24: {
739 int32_t delta =
static_cast<int32_t
>(Value - FinalAddress + Addend);
740 if (SignExtend32<26>(delta) != delta)
743 writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
745 case ELF::R_PPC64_REL32: {
747 int32_t delta =
static_cast<int32_t
>(Value - FinalAddress + Addend);
748 if (SignExtend32<32>(delta) != delta)
752 case ELF::R_PPC64_REL64: {
754 uint64_t Delta = Value - FinalAddress + Addend;
757 case ELF::R_PPC64_ADDR64:
763 void RuntimeDyldELF::resolveSystemZRelocation(
const SectionEntry &Section,
764 uint64_t Offset, uint64_t Value,
771 case ELF::R_390_PC16DBL:
772 case ELF::R_390_PLT16DBL: {
774 assert(int16_t(Delta / 2) * 2 == Delta &&
"R_390_PC16DBL overflow");
778 case ELF::R_390_PC32DBL:
779 case ELF::R_390_PLT32DBL: {
781 assert(int32_t(Delta / 2) * 2 == Delta &&
"R_390_PC32DBL overflow");
785 case ELF::R_390_PC32: {
787 assert(int32_t(Delta) == Delta &&
"R_390_PC32 overflow");
794 case ELF::R_390_PC64: {
829 void RuntimeDyldELF::resolveRelocation(
const SectionEntry &Section,
830 uint64_t Offset, uint64_t Value,
832 uint64_t SymOffset, SID SectionID) {
835 resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);
838 resolveX86Relocation(Section, Offset, (
uint32_t)(Value & 0xffffffffL), Type,
843 resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
849 resolveARMRelocation(Section, Offset, (
uint32_t)(Value & 0xffffffffL), Type,
853 resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
857 resolvePPC64Relocation(Section, Offset, Value, Type, Addend);
860 resolveSystemZRelocation(Section, Offset, Value, Type, Addend);
867 void *RuntimeDyldELF::computePlaceholderAddress(
unsigned SectionID, uint64_t Offset)
const {
871 void RuntimeDyldELF::processSimpleRelocation(
unsigned SectionID, uint64_t Offset,
unsigned RelType,
RelocationValueRef Value) {
880 bool IsLocal)
const {
882 case ELF::R_MICROMIPS_GOT16:
884 return ELF::R_MICROMIPS_LO16;
886 case ELF::R_MICROMIPS_HI16:
887 return ELF::R_MICROMIPS_LO16;
888 case ELF::R_MIPS_GOT16:
890 return ELF::R_MIPS_LO16;
892 case ELF::R_MIPS_HI16:
893 return ELF::R_MIPS_LO16;
894 case ELF::R_MIPS_PCHI16:
895 return ELF::R_MIPS_PCLO16;
899 return ELF::R_MIPS_NONE;
911 bool RuntimeDyldELF::resolveAArch64ShortBranch(
922 const auto &SymInfo = Loc->second;
924 uint64_t(
Sections[SymInfo.getSectionID()].getLoadAddressWithOffset(
925 SymInfo.getOffset()));
929 uint64_t Offset = RelI->getOffset();
930 uint64_t SourceAddress =
Sections[SectionID].getLoadAddressWithOffset(Offset);
935 if (!isInt<28>(Address + Value.
Addend - SourceAddress))
938 resolveRelocation(
Sections[SectionID], Offset, Address, RelI->getType(),
948 const auto &Obj = cast<ELFObjectFileBase>(O);
949 uint64_t RelType = RelI->getType();
951 int64_t Addend = AddendOrErr ? *AddendOrErr : 0;
957 if (
auto TargetNameOrErr = Symbol->
getName())
958 TargetName = *TargetNameOrErr;
960 return TargetNameOrErr.takeError();
962 DEBUG(
dbgs() <<
"\t\tRelType: " << RelType <<
" Addend: " << Addend
963 <<
" TargetName: " << TargetName <<
"\n");
980 SymType = *SymTypeOrErr;
983 const auto &SymInfo = gsi->
second;
984 Value.
SectionID = SymInfo.getSectionID();
985 Value.
Offset = SymInfo.getOffset();
986 Value.
Addend = SymInfo.getOffset() + Addend;
1004 DEBUG(
dbgs() <<
"\t\tThis is section symbol\n");
1005 bool isCode = si->isText();
1010 return SectionIDOrErr.takeError();
1034 uint64_t Offset = RelI->getOffset();
1036 DEBUG(
dbgs() <<
"\t\tSectionID: " << SectionID <<
" Offset: " << Offset
1039 (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26)) {
1041 DEBUG(
dbgs() <<
"\t\tThis is an AArch64 branch relocation.");
1045 StubMap::const_iterator i = Stubs.find(Value);
1046 if (i != Stubs.end()) {
1047 resolveRelocation(Section, Offset,
1050 DEBUG(
dbgs() <<
" Stub function found\n");
1051 }
else if (!resolveAArch64ShortBranch(SectionID, RelI, Value)) {
1053 DEBUG(
dbgs() <<
" Create a new stub function\n");
1060 ELF::R_AARCH64_MOVW_UABS_G3, Value.
Addend);
1063 ELF::R_AARCH64_MOVW_UABS_G2_NC, Value.
Addend);
1066 ELF::R_AARCH64_MOVW_UABS_G1_NC, Value.
Addend);
1069 ELF::R_AARCH64_MOVW_UABS_G0_NC, Value.
Addend);
1082 resolveRelocation(Section, Offset,
1089 if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
1090 RelType == ELF::R_ARM_JUMP24) {
1092 DEBUG(
dbgs() <<
"\t\tThis is an ARM branch relocation.\n");
1096 StubMap::const_iterator i = Stubs.find(Value);
1097 if (i != Stubs.end()) {
1102 DEBUG(
dbgs() <<
" Stub function found\n");
1105 DEBUG(
dbgs() <<
" Create a new stub function\n");
1110 ELF::R_ARM_ABS32, Value.
Addend);
1116 resolveRelocation(Section, Offset, reinterpret_cast<uint64_t>(
1124 reinterpret_cast<uint32_t*
>(computePlaceholderAddress(SectionID, Offset));
1125 if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
1126 RelType == ELF::R_ARM_ABS32) {
1127 Value.
Addend += *Placeholder;
1128 }
else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
1130 Value.
Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
1132 processSimpleRelocation(SectionID, Offset, RelType, Value);
1135 uint8_t *Placeholder =
reinterpret_cast<uint8_t *
>(
1136 computePlaceholderAddress(SectionID, Offset));
1138 if (RelType == ELF::R_MIPS_26) {
1140 DEBUG(
dbgs() <<
"\t\tThis is a Mips branch relocation.");
1146 uint32_t Addend = (Opcode & 0x03ffffff) << 2;
1151 StubMap::const_iterator i = Stubs.find(Value);
1152 if (i != Stubs.end()) {
1155 DEBUG(
dbgs() <<
" Stub function found\n");
1158 DEBUG(
dbgs() <<
" Create a new stub function\n");
1161 unsigned AbiVariant;
1169 ELF::R_MIPS_HI16, Value.
Addend);
1172 ELF::R_MIPS_LO16, Value.
Addend);
1187 }
else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
1188 int64_t Addend = (Opcode & 0x0000ffff) << 16;
1190 PendingRelocs.push_back(std::make_pair(Value, RE));
1191 }
else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
1192 int64_t Addend = Value.
Addend + SignExtend32<16>(Opcode & 0x0000ffff);
1193 for (
auto I = PendingRelocs.begin();
I != PendingRelocs.end();) {
1196 if (MatchingValue == Value &&
1197 RelType == getMatchingLoRelocation(Reloc.
RelType) &&
1204 I = PendingRelocs.erase(
I);
1214 if (RelType == ELF::R_MIPS_32)
1216 else if (RelType == ELF::R_MIPS_PC16)
1217 Value.
Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
1218 else if (RelType == ELF::R_MIPS_PC19_S2)
1219 Value.
Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
1220 else if (RelType == ELF::R_MIPS_PC21_S2)
1221 Value.
Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
1222 else if (RelType == ELF::R_MIPS_PC26_S2)
1223 Value.
Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
1224 processSimpleRelocation(SectionID, Offset, RelType, Value);
1229 if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
1230 || r_type == ELF::R_MIPS_GOT_DISP) {
1232 if (i != GOTSymbolOffsets.
end())
1235 RE.
SymOffset = allocateGOTEntries(SectionID, 1);
1236 GOTSymbolOffsets[TargetName] = RE.
SymOffset;
1244 if (RelType == ELF::R_PPC64_REL24) {
1246 unsigned AbiVariant;
1254 bool RangeOverflow =
false;
1256 if (AbiVariant != 2) {
1260 if (
auto Err = findOPDEntrySection(Obj, ObjSectionToID, Value))
1261 return std::move(Err);
1265 uint8_t SymOther =
Symbol->getOther();
1268 uint8_t *RelocTarget =
1270 int32_t delta =
static_cast<int32_t
>(Target - RelocTarget);
1272 if (SignExtend32<26>(delta) == delta) {
1275 addRelocationForSymbol(RE, Value.
SymbolName);
1277 addRelocationForSection(RE, Value.
SectionID);
1279 RangeOverflow =
true;
1285 StubMap::const_iterator i = Stubs.find(Value);
1286 if (i != Stubs.end()) {
1288 resolveRelocation(Section, Offset,
1289 reinterpret_cast<uint64_t>(
1292 DEBUG(
dbgs() <<
" Stub function found\n");
1295 DEBUG(
dbgs() <<
" Create a new stub function\n");
1297 uint8_t *StubTargetAddr = createStubFunction(
1301 ELF::R_PPC64_ADDR64, Value.
Addend);
1307 uint64_t StubRelocOffset = StubTargetAddr - Section.
getAddress();
1308 if (!IsTargetLittleEndian)
1309 StubRelocOffset += 2;
1312 ELF::R_PPC64_ADDR16_HIGHEST, Value.
Addend);
1314 ELF::R_PPC64_ADDR16_HIGHER, Value.
Addend);
1316 ELF::R_PPC64_ADDR16_HI, Value.
Addend);
1318 ELF::R_PPC64_ADDR16_LO, Value.
Addend);
1321 addRelocationForSymbol(REhst, Value.
SymbolName);
1322 addRelocationForSymbol(REhr, Value.
SymbolName);
1323 addRelocationForSymbol(REh, Value.
SymbolName);
1324 addRelocationForSymbol(REl, Value.
SymbolName);
1326 addRelocationForSection(REhst, Value.
SectionID);
1327 addRelocationForSection(REhr, Value.
SectionID);
1328 addRelocationForSection(REh, Value.
SectionID);
1329 addRelocationForSection(REl, Value.
SectionID);
1332 resolveRelocation(Section, Offset, reinterpret_cast<uint64_t>(
1340 if (AbiVariant == 2)
1341 writeInt32BE(Target + 4, 0xE8410018);
1343 writeInt32BE(Target + 4, 0xE8410028);
1346 }
else if (RelType == ELF::R_PPC64_TOC16 ||
1347 RelType == ELF::R_PPC64_TOC16_DS ||
1348 RelType == ELF::R_PPC64_TOC16_LO ||
1349 RelType == ELF::R_PPC64_TOC16_LO_DS ||
1350 RelType == ELF::R_PPC64_TOC16_HI ||
1351 RelType == ELF::R_PPC64_TOC16_HA) {
1363 case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16;
break;
1364 case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS;
break;
1365 case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO;
break;
1366 case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS;
break;
1367 case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI;
break;
1368 case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA;
break;
1373 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
1374 return std::move(Err);
1378 resolveRelocation(Sections[SectionID], Offset, Value.
Addend, RelType, 0);
1384 if (RelType == ELF::R_PPC64_TOC) {
1385 RelType = ELF::R_PPC64_ADDR64;
1386 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
1387 return std::move(Err);
1388 }
else if (TargetName ==
".TOC.") {
1389 if (
auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
1390 return std::move(Err);
1397 addRelocationForSymbol(RE, Value.
SymbolName);
1399 addRelocationForSection(RE, Value.
SectionID);
1402 (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
1412 DEBUG(
dbgs() <<
"\t\tThis is a SystemZ indirect relocation.");
1416 StubMap::const_iterator i = Stubs.find(Value);
1417 uintptr_t StubAddress;
1418 if (i != Stubs.end()) {
1420 DEBUG(
dbgs() <<
" Stub function found\n");
1423 DEBUG(
dbgs() <<
" Create a new stub function\n");
1425 uintptr_t BaseAddress = uintptr_t(Section.
getAddress());
1426 uintptr_t StubAlignment = getStubAlignment();
1428 (BaseAddress + Section.
getStubOffset() + StubAlignment - 1) &
1430 unsigned StubOffset = StubAddress - BaseAddress;
1432 Stubs[Value] = StubOffset;
1433 createStubFunction((uint8_t *)StubAddress);
1437 addRelocationForSymbol(RE, Value.
SymbolName);
1439 addRelocationForSection(RE, Value.
SectionID);
1443 if (RelType == ELF::R_390_GOTENT)
1444 resolveRelocation(Section, Offset, StubAddress + 8, ELF::R_390_PC32DBL,
1447 resolveRelocation(Section, Offset, StubAddress, RelType, Addend);
1449 if (RelType == ELF::R_X86_64_PLT32) {
1470 StubMap::const_iterator i = Stubs.find(Value);
1471 uintptr_t StubAddress;
1472 if (i != Stubs.end()) {
1473 StubAddress = uintptr_t(Section.
getAddress()) + i->second;
1474 DEBUG(
dbgs() <<
" Stub function found\n");
1477 DEBUG(
dbgs() <<
" Create a new stub function\n");
1479 uintptr_t BaseAddress = uintptr_t(Section.
getAddress());
1480 uintptr_t StubAlignment = getStubAlignment();
1482 (BaseAddress + Section.
getStubOffset() + StubAlignment - 1) &
1484 unsigned StubOffset = StubAddress - BaseAddress;
1485 Stubs[Value] = StubOffset;
1486 createStubFunction((uint8_t *)StubAddress);
1492 uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
1495 resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4);
1498 addRelocationForSymbol(
1499 computeGOTOffsetRE(SectionID, GOTOffset, 0, ELF::R_X86_64_64),
1504 resolveRelocation(Section, Offset, StubAddress, ELF::R_X86_64_PC32,
1509 addRelocationForSection(RE, Value.
SectionID);
1511 }
else if (RelType == ELF::R_X86_64_GOTPCREL ||
1512 RelType == ELF::R_X86_64_GOTPCRELX ||
1513 RelType == ELF::R_X86_64_REX_GOTPCRELX) {
1514 uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
1515 resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend);
1520 addRelocationForSymbol(RE, Value.
SymbolName);
1522 addRelocationForSection(RE, Value.
SectionID);
1523 }
else if (RelType == ELF::R_X86_64_PC32) {
1525 processSimpleRelocation(SectionID, Offset, RelType, Value);
1526 }
else if (RelType == ELF::R_X86_64_PC64) {
1528 processSimpleRelocation(SectionID, Offset, RelType, Value);
1530 processSimpleRelocation(SectionID, Offset, RelType, Value);
1536 processSimpleRelocation(SectionID, Offset, RelType, Value);
1541 size_t RuntimeDyldELF::getGOTEntrySize() {
1552 Result =
sizeof(uint64_t);
1566 Result =
sizeof(uint64_t);
1576 uint64_t RuntimeDyldELF::allocateGOTEntries(
unsigned SectionID,
unsigned no)
1579 if (GOTSectionID == 0) {
1586 CurrentGOTIndex += no;
1590 void RuntimeDyldELF::resolveGOTOffsetRelocation(
unsigned SectionID, uint64_t Offset, uint64_t GOTOffset)
1593 RelocationEntry GOTRE(SectionID, Offset, ELF::R_X86_64_PC32, GOTOffset);
1597 RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(
unsigned SectionID, uint64_t GOTOffset, uint64_t SymbolOffset,
1607 if (!PendingRelocs.empty())
1608 return make_error<RuntimeDyldError>(
"Can't find matching LO16 reloc");
1611 if (GOTSectionID != 0) {
1615 GOTSectionID,
".got",
false);
1617 return make_error<RuntimeDyldError>(
"Unable to allocate memory for GOT!");
1627 memset(Addr, 0, TotalSize);
1633 if (SI->relocation_begin() != SI->relocation_end()) {
1635 ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
1636 assert (i != SectionMap.end());
1640 GOTSymbolOffsets.
clear();
1645 ObjSectionToIDMap::iterator
i, e;
1646 for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++
i) {
1650 if (Name ==
".eh_frame") {
1651 UnregisteredEHFrameSections.
push_back(i->second);
1657 CurrentGOTIndex = 0;
1666 bool RuntimeDyldELF::relocationNeedsStub(
const RelocationRef &R)
const {
1675 case ELF::R_X86_64_GOTPCREL:
1676 case ELF::R_X86_64_GOTPCRELX:
1677 case ELF::R_X86_64_REX_GOTPCRELX:
1678 case ELF::R_X86_64_PC32:
1679 case ELF::R_X86_64_PC64:
1680 case ELF::R_X86_64_64:
RelocationEntry - used to represent relocations internally in the dynamic linker. ...
void push_back(const T &Elt)
Represents either an error or a value T.
static void or32AArch64Imm(void *L, uint64_t Imm)
Expected< StringRef > getName() const
DataRefImpl getRawDataRefImpl() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void writeInt16BE(uint8_t *Addr, uint16_t Value)
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner)
Log all errors (if any) in E to OS.
RuntimeDyld::MemoryManager & MemMgr
uint8_t * getAddress() const
iterator find(StringRef Key)
constexpr bool isInt< 8 >(int64_t x)
This class is the base class for all object file types.
RuntimeDyldCheckerImpl * Checker
static uint16_t applyPPChigher(uint64_t value)
void write32le(void *P, uint32_t V)
static uint16_t applyPPChighesta(uint64_t value)
Error takeError()
Take ownership of the stored error.
DataRefImpl getRawDataRefImpl() const
static uint16_t applyPPChighera(uint64_t value)
ELFType< support::little, true > ELF64LE
static std::unique_ptr< RuntimeDyldELF > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)
ELFType< support::big, false > ELF32BE
static int64_t decodePPC64LocalEntryOffset(unsigned Other)
unsigned SectionID
SectionID - the section this relocation points to.
This is a value type class that represents a single relocation in the list of relocations in the obje...
StringRef getData() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr, size_t Size)=0
std::unique_ptr< RuntimeDyld::LoadedObjectInfo > loadObject(const object::ObjectFile &O) override
std::map< RelocationValueRef, uintptr_t > StubMap
Tagged union holding either a T or a Error.
std::error_code getName(StringRef &Result) const
Function Alias Analysis false
Expected< SymbolRef::Type > getType() const
uint64_t getLoadAddressWithOffset(unsigned OffsetBytes) const
Return the load address of this section with an offset.
Expected< relocation_iterator > processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) override
Parses one or more object file relocations (some object files use relocation pairs) and stores it to ...
static uint16_t applyPPChi(uint64_t value)
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type cast(const Y &Val)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
uint8_t * getAddressWithOffset(unsigned OffsetBytes) const
Return the address of this section with an offset.
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
ELFType< support::little, false > ELF32LE
The instances of the Type class are immutable: once they are created, they are never changed...
void registerEHFrames() override
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
static uint64_t getBits(uint64_t Val, int Start, int End)
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
static StringRef getArchTypePrefix(ArchType Kind)
getArchTypePrefix - Get the "prefix" canonical name for the Kind architecture.
~RuntimeDyldELF() override
static const unsigned End
ELFType< support::big, true > ELF64BE
static uint16_t applyPPClo(uint64_t value)
uintptr_t getStubOffset() const
virtual basic_symbol_iterator symbol_end() const =0
virtual std::error_code getPlatformFlags(unsigned &Result) const
Returns platform-specific object flags, if any.
void writeInt32BE(uint8_t *Addr, uint32_t Value)
Expected< unsigned > findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)
Find Section in LocalSections.
section_iterator_range sections() const
bool isCompatibleFile(const object::ObjectFile &Obj) const override
DenseMap< SID, SID > SectionToGOTMap
static void write(bool isBE, void *P, T V)
virtual uint8_t * allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly)=0
Allocate a memory block of (at least) the given size suitable for data.
StringRef getFileName() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static uint16_t applyPPChighest(uint64_t value)
static ErrorSuccess success()
Create a success value.
constexpr bool isInt< 32 >(int64_t x)
void deregisterEHFrames() override
virtual object::OwningBinary< object::ObjectFile > getObjectForDebug(const object::ObjectFile &Obj) const =0
Error finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) override
virtual section_iterator section_begin() const =0
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
uint32_t RelType
RelType - relocation type.
ErrorOr< int64_t > getAddend() const
LLVM_NODISCARD bool isa(const Y &Val)
static void or32le(void *P, int32_t V)
uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)
Emits long jump instruction to Addr.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Target - Wrapper for Target specific information.
This is a value type class that represents a single symbol in the list of symbols in the object file...
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
uint64_t Offset
Offset - offset into the section.
virtual section_iterator section_end() const =0
std::map< SectionRef, unsigned > ObjSectionToIDMap
void writeInt64BE(uint8_t *Addr, uint64_t Value)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
uint32_t read32le(const void *P)
bool isLittleEndian() const
SectionEntry - represents a section emitted into memory by the dynamic linker.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver)
A raw_ostream that writes to an std::string.
LLVM Value Representation.
RTDyldSymbolTable GlobalSymbolTable
Lightweight error class with error context and mandatory checking.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static void write32AArch64Addr(void *L, uint64_t Imm)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
void advanceStubOffset(unsigned StubSize)
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
StringRef - Represent a constant reference to a string, i.e.
virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size)=0
Register the EH frames with the runtime so that c++ exceptions work.
Expected< ObjSectionToIDMap > loadObjectImpl(const object::ObjectFile &Obj)
StringRef getName() const
static uint16_t applyPPCha(uint64_t value)
virtual StringRef getFileFormatName() const =0
This is a value type class that represents a single section in the list of sections in the object fil...