14 #define DEBUG_TYPE "dyld"
27 using namespace llvm::object;
33 void JITRegistrar::anchor() {}
34 void ObjectImage::anchor() {}
35 void ObjectImageCommon::anchor() {}
50 resolveExternalSymbols();
54 for (
int i = 0, e = Sections.size(); i != e; ++i) {
58 uint64_t Addr = Sections[i].LoadAddress;
59 DEBUG(
dbgs() <<
"Resolving relocations Section #" << i
60 <<
"\t" <<
format(
"%p", (uint8_t *)Addr)
62 resolveRelocationList(Relocations[i], Addr);
68 uint64_t TargetAddress) {
70 for (
unsigned i = 0, e = Sections.size(); i != e; ++i) {
71 if (Sections[i].Address == LocalAddress) {
72 reassignSectionAddress(i, TargetAddress);
104 uint64_t CommonSize = 0;
114 Check(i->getType(SymType));
115 Check(i->getName(Name));
118 Check(i->getFlags(flags));
120 bool isCommon = flags & SymbolRef::SF_Common;
124 Check(i->getAlignment(Align));
126 Check(i->getSize(Size));
127 CommonSize += Size +
Align;
137 Check(i->getFileOffset(FileOffset));
138 Check(i->getSection(si));
140 Check(si->getContents(SectionData));
141 Check(si->isText(IsCode));
142 const uint8_t* SymPtr = (
const uint8_t*)InputBuffer->
getBufferStart() +
143 (uintptr_t)FileOffset;
144 uintptr_t SectOffset = (uintptr_t)(SymPtr -
145 (
const uint8_t*)SectionData.
begin());
146 unsigned SectionID = findOrEmitSection(*obj, *si, IsCode, LocalSections);
147 LocalSymbols[Name.
data()] =
SymbolLoc(SectionID, SectOffset);
148 DEBUG(
dbgs() <<
"\tFileOffset: " <<
format(
"%p", (uintptr_t)FileOffset)
149 <<
" flags: " << flags
150 <<
" SID: " << SectionID
151 <<
" Offset: " <<
format(
"%p", SectOffset));
155 DEBUG(
dbgs() <<
"\tType: " << SymType <<
" Name: " << Name <<
"\n");
160 emitCommonSymbols(*obj, CommonSymbols, CommonSize, LocalSymbols);
167 bool isFirstRelocation =
true;
168 unsigned SectionID = 0;
173 e = si->end_relocations(); i != e; i.
increment(err)) {
177 if (isFirstRelocation) {
179 findOrEmitSection(*obj, *RelocatedSection,
true, LocalSections);
180 DEBUG(
dbgs() <<
"\tSectionID: " << SectionID <<
"\n");
181 isFirstRelocation =
false;
184 processRelocationRef(SectionID, *i, *obj, LocalSections, LocalSymbols,
190 finalizeLoad(LocalSections);
200 unsigned SectionID = Sections.size();
201 uint8_t *Addr = MemMgr->allocateDataSection(
202 TotalSize,
sizeof(
void*), SectionID,
StringRef(),
false);
207 memset(Addr, 0, TotalSize);
209 DEBUG(
dbgs() <<
"emitCommonSection SectionID: " << SectionID
210 <<
" new addr: " <<
format(
"%p", Addr)
211 <<
" DataSize: " << TotalSize
215 for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(),
216 itEnd = CommonSymbols.end(); it != itEnd; it++) {
217 uint64_t Size = it->second.first;
218 uint64_t
Align = it->second.second;
220 it->first.getName(Name);
225 Offset += AlignOffset;
226 DEBUG(
dbgs() <<
"Allocating common symbol " << Name <<
" address " <<
240 unsigned StubBufSize = 0,
241 StubSize = getMaxStubSize();
252 if (!(RelSecI == Section))
256 E = SI->end_relocations();
I != E;
I.increment(err),
Check(err)) {
257 StubBufSize += StubSize;
263 uint64_t Alignment64;
267 unsigned Alignment = (
unsigned)Alignment64 & 0xffffffffL;
273 unsigned PaddingSize = 0;
282 unsigned StubAlignment = getStubAlignment();
283 unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment);
284 if (StubAlignment > EndAlignment)
285 StubBufSize += StubAlignment - EndAlignment;
291 if (Name ==
".eh_frame")
295 unsigned SectionID = Sections.size();
297 const char *pData = 0;
302 Allocate = DataSize + PaddingSize + StubBufSize;
304 ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID, Name)
305 : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, Name,
315 if (IsZeroInit || IsVirtual)
316 memset(Addr, 0, DataSize);
318 memcpy(Addr, pData, DataSize);
321 if (PaddingSize != 0) {
322 memset(Addr + DataSize, 0, PaddingSize);
324 DataSize += PaddingSize;
327 DEBUG(
dbgs() <<
"emitSection SectionID: " << SectionID
329 <<
" obj addr: " <<
format(
"%p", pData)
330 <<
" new addr: " <<
format(
"%p", Addr)
331 <<
" DataSize: " << DataSize
332 <<
" StubBufSize: " << StubBufSize
333 <<
" Allocate: " << Allocate
343 DEBUG(
dbgs() <<
"emitSection SectionID: " << SectionID
347 <<
" DataSize: " << DataSize
348 <<
" StubBufSize: " << StubBufSize
349 <<
" Allocate: " << Allocate
353 Sections.push_back(
SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
362 unsigned SectionID = 0;
363 ObjSectionToIDMap::iterator i = LocalSections.find(Section);
364 if (i != LocalSections.end())
365 SectionID = i->second;
367 SectionID = emitSection(Obj, Section, IsCode);
368 LocalSections[
Section] = SectionID;
374 unsigned SectionID) {
375 Relocations[SectionID].push_back(RE);
384 GlobalSymbolTable.find(SymbolName);
385 if (Loc == GlobalSymbolTable.end()) {
386 ExternalSymbolRelocations[SymbolName].push_back(RE);
391 Relocations[Loc->
second.first].push_back(RECopy);
400 uint32_t *StubAddr = (uint32_t*)Addr;
403 *StubAddr = 0xd2e00010;
405 *StubAddr = 0xf2c00010;
407 *StubAddr = 0xf2a00010;
409 *StubAddr = 0xf2800010;
411 *StubAddr = 0xd61f0200;
417 uint32_t *StubAddr = (uint32_t*)Addr;
418 *StubAddr = 0xe51ff004;
419 return (uint8_t*)++StubAddr;
421 uint32_t *StubAddr = (uint32_t*)Addr;
426 const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000;
427 const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0;
429 *StubAddr = LuiT9Instr;
431 *StubAddr = AdduiT9Instr;
433 *StubAddr = JrT9Instr;
435 *StubAddr = NopInstr;
442 writeInt32BE(Addr, 0x3D800000);
443 writeInt32BE(Addr+4, 0x618C0000);
444 writeInt32BE(Addr+8, 0x798C07C6);
445 writeInt32BE(Addr+12, 0x658C0000);
446 writeInt32BE(Addr+16, 0x618C0000);
447 writeInt32BE(Addr+20, 0xF8410028);
448 writeInt32BE(Addr+24, 0xE96C0000);
449 writeInt32BE(Addr+28, 0xE84C0008);
450 writeInt32BE(Addr+32, 0x7D6903A6);
451 writeInt32BE(Addr+36, 0xE96C0010);
452 writeInt32BE(Addr+40, 0x4E800420);
456 writeInt16BE(Addr, 0xC418);
457 writeInt16BE(Addr+2, 0x0000);
458 writeInt16BE(Addr+4, 0x0004);
459 writeInt16BE(Addr+6, 0x07F1);
484 Sections[SectionID].LoadAddress = Addr;
489 for (
unsigned i = 0, e = Relocs.
size(); i != e; ++i) {
494 resolveRelocation(RE, Value);
499 while(!ExternalSymbolRelocations.empty()) {
503 if (Name.
size() == 0) {
505 DEBUG(
dbgs() <<
"Resolving absolute relocations." <<
"\n");
507 resolveRelocationList(Relocs, 0);
511 if (Loc == GlobalSymbolTable.end()) {
514 Addr = MemMgr->getSymbolAddress(Name.
data());
521 i = ExternalSymbolRelocations.find(Name);
526 Addr = getSectionLoadAddress(SymLoc.first) + SymLoc.second;
532 "' which could not be resolved!");
534 updateGOTEntries(Name, Addr);
535 DEBUG(
dbgs() <<
"Resolving relocations Name: " << Name
536 <<
"\t" <<
format(
"0x%lx", Addr)
541 resolveRelocationList(Relocs, Addr);
544 ExternalSymbolRelocations.erase(i);
600 if (!Dyld->isCompatibleFormat(InputBuffer))
604 return Dyld->loadObject(InputBuffer);
610 return Dyld->getSymbolAddress(Name);
616 return Dyld->getSymbolLoadAddress(Name);
620 Dyld->resolveRelocations();
625 Dyld->reassignSectionAddress(SectionID, Addr);
629 uint64_t TargetAddress) {
630 Dyld->mapSectionAddress(LocalAddress, TargetAddress);
634 return Dyld->getErrorString();
639 Dyld->registerEHFrames();
644 Dyld->deregisterEHFrames();
static bool Check(DecodeStatus &Out, DecodeStatus In)
unsigned findOrEmitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)
Find Section in LocalSections. If the secton is not found - emit it and store in LocalSections.
error_code isZeroInit(bool &Result) const
size_t size() const
size - Get the string size.
void emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols, uint64_t TotalSize, SymbolTableMap &SymbolTable)
Given the common symbols discovered in the object file, emit a new section for them and update the sy...
Mach-O dynlinked shared lib.
error_code getSize(uint64_t &Result) const
StringRef getErrorString()
void resolveExternalSymbols()
Resolve relocations to external symbols.
error_code isVirtual(bool &Result) const
ObjectImage * loadObject(ObjectBuffer *InputBuffer)
ELF Relocatable object file.
virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr)=0
void deregisterEHFrames()
uint8_t * createStubFunction(uint8_t *Addr)
Emits long jump instruction to Addr.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
error_code getAlignment(uint64_t &Result) const
Get the alignment of this section as the actual value (not log 2).
unsigned SectionID
SectionID - the section this relocation points to.
const char * getBufferStart() const
#define llvm_unreachable(msg)
void resolveRelocationList(const RelocationList &Relocs, uint64_t Value)
Resolves relocations from Relocs list with address from Value.
virtual section_iterator end_sections() const =0
virtual unsigned getArch() const =0
std::map< RelocationValueRef, uintptr_t > StubMap
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
virtual void registerEHFrames()
format_object1< T > format(const char *Fmt, const T &Val)
ELF dynamically linked shared lib.
const char * data() const
virtual object::symbol_iterator end_symbols() const =0
Windows compiled resource file (.rc)
virtual ~RuntimeDyldImpl()
virtual object::symbol_iterator begin_symbols() const =0
error_code getName(StringRef &Result) const
virtual ObjectImage * createObjectImage(ObjectBuffer *InputBuffer)
virtual section_iterator begin_sections() const =0
Guard a section of code with a Mutex.
std::pair< unsigned, uintptr_t > SymbolLoc
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)
Mach-O Preloaded Executable.
unsigned emitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode)
Emits section data from the object file to the MemoryManager.
std::pair< unsigned, unsigned > CommonSymbolInfo
virtual void updateSectionAddress(const object::SectionRef &Sec, uint64_t Addr)=0
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
content_iterator & increment(error_code &err)
error_code isReadOnlyData(bool &Result) const
uint64_t getSymbolLoadAddress(StringRef Name)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
virtual object::ObjectFile * getObjectFile() const =0
void reassignSectionAddress(unsigned SectionID, uint64_t Addr)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
ObjectImage * loadObject(ObjectBuffer *InputBuffer)
std::map< SectionRef, unsigned > ObjSectionToIDMap
void resolveRelocations()
std::map< SymbolRef, CommonSymbolInfo > CommonSymbolMap
Mach-O dSYM companion file.
error_code isRequiredForExecution(bool &Result) const
StringRef getBuffer() const
The Mach-O dynamic linker.
bool isLittleEndian() const
void resolveRelocations()
Resolve the relocations for all symbols we currently know about.
error_code getContents(StringRef &Result) const
virtual void deregisterEHFrames()
LLVM Value Representation.
void * getSymbolAddress(StringRef Name)
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
void reassignSectionAddress(unsigned SectionID, uint64_t Addr)
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
virtual object::section_iterator end_sections() const =0
virtual object::section_iterator begin_sections() const =0