26 using namespace llvm::object;
28 #define DEBUG_TYPE "dyld"
44 dbgs() <<
"----- Contents of section " << S.
Name <<
" " << State <<
" -----";
47 dbgs() <<
"\n <section not emitted>\n";
51 const unsigned ColsPerRow = 16;
56 unsigned StartPadding = LoadAddr & (ColsPerRow - 1);
57 unsigned BytesRemaining = S.
Size;
61 LoadAddr & ~(uint64_t)(ColsPerRow - 1)) <<
":";
62 while (StartPadding--)
66 while (BytesRemaining > 0) {
67 if ((LoadAddr & (ColsPerRow - 1)) == 0)
68 dbgs() <<
"\n" <<
format(
"0x%016" PRIx64, LoadAddr) <<
":";
86 resolveExternalSymbols();
90 for (
int i = 0, e = Sections.size(); i != e; ++i) {
94 uint64_t Addr = Sections[i].LoadAddress;
95 DEBUG(
dbgs() <<
"Resolving relocations Section #" << i <<
"\t"
96 <<
format(
"%p", (uintptr_t)Addr) <<
"\n");
98 resolveRelocationList(Relocations[i], Addr);
100 Relocations.erase(i);
107 for (
unsigned i = 0, e = Sections.size(); i != e; ++i) {
108 if (Sections[i].
Address == LocalAddress) {
109 reassignSectionAddress(i, TargetAddress);
119 if (std::error_code EC = AddressOrErr.
getError())
122 return std::error_code();
125 std::pair<unsigned, unsigned>
131 unsigned SectionsAddedBeginIdx = Sections.size();
140 if (MemMgr.needsToReserveAllocationSpace()) {
141 uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
142 computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW);
143 MemMgr.reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
156 uint32_t
Flags =
I->getFlags();
160 CommonSymbols.push_back(*
I);
178 Check(SI->getContents(SectionData));
179 bool IsCode = SI->isText();
181 findOrEmitSection(Obj, *SI, IsCode, LocalSections);
182 DEBUG(
dbgs() <<
"\tType: " << SymType <<
" Name: " << Name
183 <<
" SID: " << SectionID <<
" Offset: "
184 <<
format(
"%p", (uintptr_t)SectOffset)
185 <<
" flags: " << Flags <<
"\n");
191 GlobalSymbolTable[
Name] =
198 emitCommonSymbols(Obj, CommonSymbols);
204 unsigned SectionID = 0;
208 if (RelocatedSection == SE)
214 if (I == E && !ProcessAllSections)
217 bool IsCode = RelocatedSection->isText();
219 findOrEmitSection(Obj, *RelocatedSection, IsCode, LocalSections);
220 DEBUG(
dbgs() <<
"\tSectionID: " << SectionID <<
"\n");
223 I = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs);
228 Checker->registerStubMap(Obj.
getFileName(), SectionID, Stubs);
232 finalizeLoad(Obj, LocalSections);
234 unsigned SectionsAddedEndIdx = Sections.size();
236 return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
244 uint64_t Alignment) {
245 uint64_t TotalSize = 0;
246 for (
size_t Idx = 0, Cnt = SectionSizes.size(); Idx < Cnt; Idx++) {
247 uint64_t AlignedSize =
248 (SectionSizes[Idx] + Alignment - 1) / Alignment * Alignment;
249 TotalSize += AlignedSize;
256 if (isa<object::ELFObjectFileBase>(Obj))
258 if (
auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj)) {
259 const coff_section *CoffSection = COFFObj->getCOFFSection(Section);
269 return HasContent && !IsDiscardable;
272 assert(isa<MachOObjectFile>(Obj));
278 if (isa<object::ELFObjectFileBase>(Obj))
281 if (
auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
282 return ((COFFObj->getCOFFSection(Section)->Characteristics &
290 assert(isa<MachOObjectFile>(Obj));
296 if (isa<object::ELFObjectFileBase>(Obj))
298 if (
auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
299 return COFFObj->getCOFFSection(Section)->Characteristics &
302 auto *MachO = cast<MachOObjectFile>(Obj);
303 unsigned SectionType = MachO->getSectionType(Section);
312 uint64_t &DataSizeRO,
313 uint64_t &DataSizeRW) {
315 std::vector<uint64_t> CodeSectionSizes;
316 std::vector<uint64_t> ROSectionSizes;
317 std::vector<uint64_t> RWSectionSizes;
318 uint64_t MaxAlignment =
sizeof(
void *);
331 uint64_t DataSize = Section.
getSize();
333 bool IsCode = Section.
isText();
336 unsigned Alignment = (
unsigned)Alignment64 & 0xffffffffL;
338 uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section);
346 if (Name ==
".eh_frame")
353 CodeSectionSizes.push_back(SectionSize);
354 }
else if (IsReadOnly) {
355 ROSectionSizes.push_back(SectionSize);
357 RWSectionSizes.push_back(SectionSize);
361 if (Alignment > MaxAlignment) {
362 MaxAlignment = Alignment;
368 uint64_t CommonSize = 0;
371 uint32_t
Flags =
I->getFlags();
374 uint64_t Size =
I->getCommonSize();
378 if (CommonSize != 0) {
379 RWSectionSizes.push_back(CommonSize);
395 unsigned StubSize = getMaxStubSize();
402 unsigned StubBufSize = 0;
406 if (!(RelSecI == Section))
411 StubBufSize += StubSize;
416 uint64_t DataSize = Section.
getSize();
420 unsigned Alignment = (
unsigned)Alignment64 & 0xffffffffL;
421 unsigned StubAlignment = getStubAlignment();
422 unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment);
423 if (StubAlignment > EndAlignment)
424 StubBufSize += StubAlignment - EndAlignment;
429 unsigned Size)
const {
431 if (IsTargetLittleEndian) {
434 Result = (Result << 8) | *Src--;
437 Result = (Result << 8) | *Src++;
443 unsigned Size)
const {
444 if (IsTargetLittleEndian) {
446 *Dst++ = Value & 0xFF;
452 *Dst-- = Value & 0xFF;
460 if (CommonSymbols.empty())
463 uint64_t CommonSize = 0;
466 DEBUG(
dbgs() <<
"Processing common symbols...\n");
468 for (
const auto &Sym : CommonSymbols) {
474 if (GlobalSymbolTable.count(Name) ||
475 Resolver.findSymbolInLogicalDylib(Name)) {
476 DEBUG(
dbgs() <<
"\tSkipping already emitted common symbol '" << Name
481 uint32_t
Align = Sym.getAlignment();
482 uint64_t Size = Sym.getCommonSize();
484 CommonSize += Align + Size;
485 SymbolsToAllocate.push_back(Sym);
489 unsigned SectionID = Sections.size();
490 uint8_t *Addr = MemMgr.allocateDataSection(CommonSize,
sizeof(
void *),
495 Sections.push_back(
SectionEntry(
"<common symbols>", Addr, CommonSize, 0));
496 memset(Addr, 0, CommonSize);
498 DEBUG(
dbgs() <<
"emitCommonSection SectionID: " << SectionID <<
" new addr: "
499 <<
format(
"%p", Addr) <<
" DataSize: " << CommonSize <<
"\n");
502 for (
auto &Sym : SymbolsToAllocate) {
503 uint32_t
Align = Sym.getAlignment();
504 uint64_t Size = Sym.getCommonSize();
512 Offset += AlignOffset;
514 uint32_t
Flags = Sym.getFlags();
520 DEBUG(
dbgs() <<
"Allocating common symbol " << Name <<
" address "
521 <<
format(
"%p", Addr) <<
"\n");
522 GlobalSymbolTable[
Name] =
535 unsigned Alignment = (
unsigned)Alignment64 & 0xffffffffL;
536 unsigned PaddingSize = 0;
537 unsigned StubBufSize = 0;
543 uint64_t DataSize = Section.
getSize();
546 StubBufSize = computeSectionStubBufSize(Obj, Section);
551 if (Name ==
".eh_frame")
555 unsigned SectionID = Sections.size();
557 const char *pData =
nullptr;
569 Allocate = DataSize + PaddingSize + StubBufSize;
572 Addr = IsCode ? MemMgr.allocateCodeSection(Allocate, Alignment, SectionID,
574 : MemMgr.allocateDataSection(Allocate, Alignment, SectionID,
580 if (IsZeroInit || IsVirtual)
581 memset(Addr, 0, DataSize);
583 memcpy(Addr, pData, DataSize);
586 if (PaddingSize != 0) {
587 memset(Addr + DataSize, 0, PaddingSize);
589 DataSize += PaddingSize;
592 DEBUG(
dbgs() <<
"emitSection SectionID: " << SectionID <<
" Name: " << Name
593 <<
" obj addr: " <<
format(
"%p", pData)
594 <<
" new addr: " <<
format(
"%p", Addr)
595 <<
" DataSize: " << DataSize <<
" StubBufSize: " << StubBufSize
596 <<
" Allocate: " << Allocate <<
"\n");
603 DEBUG(
dbgs() <<
"emitSection SectionID: " << SectionID <<
" Name: " << Name
604 <<
" obj addr: " <<
format(
"%p", data.
data()) <<
" new addr: 0"
605 <<
" DataSize: " << DataSize <<
" StubBufSize: " << StubBufSize
606 <<
" Allocate: " << Allocate <<
"\n");
609 Sections.push_back(
SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
612 Checker->registerSection(Obj.
getFileName(), SectionID);
622 unsigned SectionID = 0;
623 ObjSectionToIDMap::iterator i = LocalSections.find(Section);
624 if (i != LocalSections.end())
625 SectionID = i->second;
627 SectionID = emitSection(Obj, Section, IsCode);
628 LocalSections[
Section] = SectionID;
634 unsigned SectionID) {
635 Relocations[SectionID].push_back(RE);
644 if (Loc == GlobalSymbolTable.end()) {
645 ExternalSymbolRelocations[SymbolName].push_back(RE);
649 const auto &SymInfo = Loc->
second;
650 RECopy.
Addend += SymInfo.getOffset();
651 Relocations[SymInfo.getSectionID()].push_back(RECopy);
656 unsigned AbiVariant) {
662 writeBytesUnaligned(0xd2e00010, Addr, 4);
663 writeBytesUnaligned(0xf2c00010, Addr+4, 4);
664 writeBytesUnaligned(0xf2a00010, Addr+8, 4);
665 writeBytesUnaligned(0xf2800010, Addr+12, 4);
666 writeBytesUnaligned(0xd61f0200, Addr+16, 4);
672 writeBytesUnaligned(0xe51ff004, Addr, 4);
674 }
else if (IsMipsO32ABI) {
679 const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000;
680 const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0;
682 writeBytesUnaligned(LuiT9Instr, Addr, 4);
683 writeBytesUnaligned(AdduiT9Instr, Addr+4, 4);
684 writeBytesUnaligned(JrT9Instr, Addr+8, 4);
685 writeBytesUnaligned(NopInstr, Addr+12, 4);
691 writeInt32BE(Addr, 0x3D800000);
692 writeInt32BE(Addr+4, 0x618C0000);
693 writeInt32BE(Addr+8, 0x798C07C6);
694 writeInt32BE(Addr+12, 0x658C0000);
695 writeInt32BE(Addr+16, 0x618C0000);
696 if (AbiVariant == 2) {
699 writeInt32BE(Addr+20, 0xF8410018);
700 writeInt32BE(Addr+24, 0x7D8903A6);
701 writeInt32BE(Addr+28, 0x4E800420);
706 writeInt32BE(Addr+20, 0xF8410028);
707 writeInt32BE(Addr+24, 0xE96C0000);
708 writeInt32BE(Addr+28, 0xE84C0008);
709 writeInt32BE(Addr+32, 0x7D6903A6);
710 writeInt32BE(Addr+36, 0xE96C0010);
711 writeInt32BE(Addr+40, 0x4E800420);
715 writeInt16BE(Addr, 0xC418);
716 writeInt16BE(Addr+2, 0x0000);
717 writeInt16BE(Addr+4, 0x0004);
718 writeInt16BE(Addr+6, 0x07F1);
745 DEBUG(
dbgs() <<
"Reassigning address for section "
746 << SectionID <<
" (" << Sections[SectionID].
Name <<
"): "
747 <<
format(
"0x%016" PRIx64, Sections[SectionID].LoadAddress) <<
" -> "
748 <<
format(
"0x%016" PRIx64, Addr) <<
"\n");
749 Sections[SectionID].LoadAddress = Addr;
754 for (
unsigned i = 0, e = Relocs.
size(); i != e; ++i) {
757 if (Sections[RE.
SectionID].Address ==
nullptr)
759 resolveRelocation(RE, Value);
764 while (!ExternalSymbolRelocations.empty()) {
768 if (Name.
size() == 0) {
770 DEBUG(
dbgs() <<
"Resolving absolute relocations."
773 resolveRelocationList(Relocs, 0);
777 if (Loc == GlobalSymbolTable.end()) {
780 Addr = Resolver.findSymbol(Name.
data()).getAddress();
787 i = ExternalSymbolRelocations.find(Name);
791 const auto &SymInfo = Loc->
second;
792 Addr = getSectionLoadAddress(SymInfo.getSectionID()) +
799 "' which could not be resolved!");
803 if (Addr != UINT64_MAX) {
804 DEBUG(
dbgs() <<
"Resolving relocations Name: " << Name <<
"\t"
805 <<
format(
"0x%lx", Addr) <<
"\n");
809 resolveRelocationList(Relocs, Addr);
813 ExternalSymbolRelocations.erase(i);
822 for (
unsigned I = BeginIdx;
I != EndIdx; ++
I)
823 if (RTDyld.Sections[
I].Name == SectionName)
824 return RTDyld.Sections[
I].LoadAddress;
829 void RuntimeDyld::MemoryManager::anchor() {}
830 void RuntimeDyld::SymbolResolver::anchor() {}
834 : MemMgr(MemMgr), Resolver(Resolver) {
842 ProcessAllSections =
false;
848 static std::unique_ptr<RuntimeDyldCOFF>
852 std::unique_ptr<RuntimeDyldCOFF> Dyld =
854 Dyld->setProcessAllSections(ProcessAllSections);
855 Dyld->setRuntimeDyldChecker(Checker);
859 static std::unique_ptr<RuntimeDyldELF>
863 std::unique_ptr<RuntimeDyldELF> Dyld(
new RuntimeDyldELF(MM, Resolver));
864 Dyld->setProcessAllSections(ProcessAllSections);
865 Dyld->setRuntimeDyldChecker(Checker);
869 static std::unique_ptr<RuntimeDyldMachO>
872 bool ProcessAllSections,
874 std::unique_ptr<RuntimeDyldMachO> Dyld =
876 Dyld->setProcessAllSections(ProcessAllSections);
877 Dyld->setRuntimeDyldChecker(Checker);
881 std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
888 static_cast<Triple::ArchType>(Obj.
getArch()), MemMgr, Resolver,
889 ProcessAllSections, Checker);
892 static_cast<Triple::ArchType>(Obj.
getArch()), MemMgr, Resolver,
893 ProcessAllSections, Checker);
898 if (!Dyld->isCompatibleFile(Obj))
901 return Dyld->loadObject(Obj);
907 return Dyld->getSymbolLocalAddress(Name);
913 return Dyld->getSymbol(Name);
919 Dyld->reassignSectionAddress(SectionID, Addr);
924 Dyld->mapSectionAddress(LocalAddress, TargetAddress);
933 Dyld->registerEHFrames();
938 Dyld->deregisterEHFrames();
RelocationEntry - used to represent relocations internally in the dynamic linker. ...
std::error_code getError() const
size_t Size
Size - section size. Doesn't include the stubs.
void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const
Endian-aware write.
Represents either an error or a value T.
std::unique_ptr< LoadedObjectInfo > loadObject(const object::ObjectFile &O)
Add the referenced object file to the list of objects to be loaded and relocated. ...
void registerEHFrames()
Register any EH frame sections that have been loaded but not previously registered with the memory ma...
size_t size() const
size - Get the string size.
std::pair< unsigned, unsigned > loadObjectImpl(const object::ObjectFile &Obj)
std::string Name
Name - section name.
void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, uint64_t &DataSizeRO, uint64_t &DataSizeRW)
StringRef getErrorString()
void resolveExternalSymbols()
Resolve relocations to external symbols.
static bool isReadOnlyData(const SectionRef Section)
This class is the base class for all object file types.
uint8_t * Address
Address - address in the linker's memory where the section resides.
unsigned findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)
Find Section in LocalSections.
static std::error_code getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
static std::unique_ptr< RuntimeDyldCOFF > createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, RuntimeDyld::SymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker)
void deregisterEHFrames()
virtual unsigned getArch() const =0
SymbolInfo getSymbol(StringRef Name) const
Get the target address and flags for the named symbol.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
unsigned SectionID
SectionID - the section this relocation points to.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void resolveRelocationList(const RelocationList &Relocs, uint64_t Value)
Resolves relocations from Relocs list with address from Value.
static std::unique_ptr< RuntimeDyldELF > createRuntimeDyldELF(RuntimeDyld::MemoryManager &MM, RuntimeDyld::SymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker)
unsigned emitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode)
Emits section data from the object file to the MemoryManager.
This is a value type class that represents a single relocation in the list of relocations in the obje...
static bool isRequiredForExecution(const SectionRef Section)
std::map< RelocationValueRef, uintptr_t > StubMap
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
virtual void registerEHFrames()
support::ulittle32_t VirtualSize
static uint64_t computeAllocationSizeForSections(std::vector< uint64_t > &SectionSizes, uint64_t Alignment)
basic_symbol_iterator symbol_begin() const
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::error_code getName(StringRef &Result) const
virtual ~RuntimeDyldImpl()
void * getSymbolLocalAddress(StringRef Name) const
Get the address of our local copy of the symbol.
static std::unique_ptr< RuntimeDyldCOFF > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
uint64_t getAlignment() const
Get the alignment of this section as the actual value (not log 2).
Instances of this class acquire a given Mutex Lock when constructed and hold that lock until destruct...
support::ulittle32_t Characteristics
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
JITSymbolFlags
Flags for symbols in the JIT.
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
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.
void emitCommonSymbols(const ObjectFile &Obj, CommonSymbolList &CommonSymbols)
Given the common symbols discovered in the object file, emit a new section for them and update the sy...
static std::unique_ptr< RuntimeDyldMachO > create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, RuntimeDyld::SymbolResolver &Resolver)
Create a RuntimeDyldMachO instance for the given target architecture.
std::vector< SymbolRef > CommonSymbolList
support::ulittle32_t SizeOfRawData
uint64_t getAddress() const
StringRef getFileName() const
const ObjectFile * getObject() const
basic_symbol_iterator symbol_end() const
static void dumpSectionMemory(const SectionEntry &S, StringRef State)
unsigned computeSectionStubBufSize(const ObjectFile &Obj, const SectionRef &Section)
virtual section_iterator section_begin() const =0
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
static std::unique_ptr< RuntimeDyldMachO > createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, RuntimeDyld::SymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker)
uint64_t TargetAddress
Represents an address in the target process's address space.
uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)
Emits long jump instruction to Addr.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
uint64_t getSectionLoadAddress(StringRef Name) const
Obtain the Load Address of a section by Name.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Symbol info for RuntimeDyld.
void reassignSectionAddress(unsigned SectionID, uint64_t Addr)
std::error_code getContents(StringRef &Result) const
This is a value type class that represents a single symbol in the list of symbols in the object file...
static bool isZeroInit(const SectionRef Section)
virtual section_iterator section_end() const =0
std::map< SectionRef, unsigned > ObjSectionToIDMap
void resolveRelocations()
std::error_code Check(std::error_code Err)
uint64_t LoadAddress
LoadAddress - the address of the section in the target process's memory.
Information about a named symbol.
bool isLittleEndian() const
void resolveRelocations()
Resolve the relocations for all symbols we currently know about.
SectionEntry - represents a section emitted into memory by the dynamic linker.
virtual void deregisterEHFrames()
LLVM Value Representation.
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
void reassignSectionAddress(unsigned SectionID, uint64_t Addr)
StringRef - Represent a constant reference to a string, i.e.
S_ZEROFILL - Zero fill on demand section.
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
Map a section to its target address space value.
SectionType
These are the section type and attributes fields.
ErrorOr< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
This is a value type class that represents a single section in the list of sections in the object fil...
uint64_t getFlags() const