virtual void NotifyObjectEmitted(const ObjectImage &obj) { uint64_t Addr; object::SymbolRef::Type SymbolType; #ifdef LLVM35 for (const object::SymbolRef &sym_iter : obj.symbols()) { sym_iter.getType(SymbolType); if (SymbolType != object::SymbolRef::ST_Function) continue; sym_iter.getAddress(Addr); ObjectInfo tmp = {obj.getObjectFile(), sym_iter, obj.getData().size()}; objectmap[Addr] = tmp; } #else error_code itererr; object::symbol_iterator sym_iter = obj.begin_symbols(); object::symbol_iterator sym_end = obj.end_symbols(); for (; sym_iter != sym_end; sym_iter.increment(itererr)) { sym_iter->getType(SymbolType); if (SymbolType != object::SymbolRef::ST_Function) continue; sym_iter->getAddress(Addr); ObjectInfo tmp = {obj.getObjectFile(), *sym_iter}; objectmap[Addr] = tmp; } #endif }
void RuntimeDyldMachO::finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) { unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; unsigned TextSID = RTDYLD_INVALID_SECTION_ID; unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; ObjSectionToIDMap::iterator i, e; for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) { const SectionRef &Section = i->first; StringRef Name; Section.getName(Name); if (Name == "__eh_frame") EHFrameSID = i->second; else if (Name == "__text") TextSID = i->second; else if (Name == "__gcc_except_tab") ExceptTabSID = i->second; else if (Name == "__jump_table") populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()), Section, i->second); else if (Name == "__pointers") populatePointersSection(cast<MachOObjectFile>(*ObjImg.getObjectFile()), Section, i->second); } UnregisteredEHFrameSections.push_back( EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID)); }
void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value, ObjectImage &ObjImg, const relocation_iterator &RI, unsigned OffsetToNextPC) { const MachOObjectFile &Obj = static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RI->getRawDataRefImpl()); bool IsPCRel = Obj.getAnyRelocationPCRel(RelInfo); if (IsPCRel) { uint64_t RelocAddr = 0; RI->getAddress(RelocAddr); Value.Addend += RelocAddr + OffsetToNextPC; } }
RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( ObjectImage &ObjImg, const relocation_iterator &RI, const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols) { const MachOObjectFile &Obj = static_cast<const MachOObjectFile &>(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RI->getRawDataRefImpl()); RelocationValueRef Value; bool IsExternal = Obj.getPlainRelocationExternal(RelInfo); if (IsExternal) { symbol_iterator Symbol = RI->getSymbol(); StringRef TargetName; Symbol->getName(TargetName); SymbolTableMap::const_iterator SI = Symbols.find(TargetName.data()); if (SI != Symbols.end()) { Value.SectionID = SI->second.first; Value.Addend = SI->second.second + RE.Addend; } else { SI = GlobalSymbolTable.find(TargetName.data()); if (SI != GlobalSymbolTable.end()) { Value.SectionID = SI->second.first; Value.Addend = SI->second.second + RE.Addend; } else { Value.SymbolName = TargetName.data(); Value.Addend = RE.Addend; } } } else { SectionRef Sec = Obj.getRelocationSection(RelInfo); bool IsCode = false; Sec.isText(IsCode); Value.SectionID = findOrEmitSection(ObjImg, Sec, IsCode, ObjSectionToID); uint64_t Addr; Sec.getAddress(Addr); Value.Addend = RE.Addend - Addr; } return Value; }
void RuntimeDyldMachO::processRelocationRef(unsigned SectionID, RelocationRef RelI, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) { const ObjectFile *OF = Obj.getObjectFile(); const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF); MachO::any_relocation_info RE= MachO->getRelocation(RelI.getRawDataRefImpl()); uint32_t RelType = MachO->getAnyRelocationType(RE); // FIXME: Properly handle scattered relocations. // For now, optimistically skip these: they can often be ignored, as // the static linker will already have applied the relocation, and it // only needs to be reapplied if symbols move relative to one another. // Note: This will fail horribly where the relocations *do* need to be // applied, but that was already the case. if (MachO->isRelocationScattered(RE)) return; RelocationValueRef Value; SectionEntry &Section = Sections[SectionID]; bool isExtern = MachO->getPlainRelocationExternal(RE); bool IsPCRel = MachO->getAnyRelocationPCRel(RE); unsigned Size = MachO->getAnyRelocationLength(RE); uint64_t Offset; RelI.getOffset(Offset); uint8_t *LocalAddress = Section.Address + Offset; unsigned NumBytes = 1 << Size; uint64_t Addend = 0; memcpy(&Addend, LocalAddress, NumBytes); if (isExtern) { // Obtain the symbol name which is referenced in the relocation symbol_iterator Symbol = RelI.getSymbol(); StringRef TargetName; Symbol->getName(TargetName); // First search for the symbol in the local symbol table SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); if (lsi != Symbols.end()) { Value.SectionID = lsi->second.first; Value.Addend = lsi->second.second + Addend; } else { // Search for the symbol in the global symbol table SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data()); if (gsi != GlobalSymbolTable.end()) { Value.SectionID = gsi->second.first; Value.Addend = gsi->second.second + Addend; } else { Value.SymbolName = TargetName.data(); Value.Addend = Addend; } } } else { SectionRef Sec = MachO->getRelocationSection(RE); bool IsCode = false; Sec.isText(IsCode); Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID); uint64_t Addr; Sec.getAddress(Addr); Value.Addend = Addend - Addr; if (IsPCRel) Value.Addend += Offset + NumBytes; } if (Arch == Triple::x86_64 && (RelType == MachO::X86_64_RELOC_GOT || RelType == MachO::X86_64_RELOC_GOT_LOAD)) { assert(IsPCRel); assert(Size == 2); StubMap::const_iterator i = Stubs.find(Value); uint8_t *Addr; if (i != Stubs.end()) { Addr = Section.Address + i->second; } else { Stubs[Value] = Section.StubOffset; uint8_t *GOTEntry = Section.Address + Section.StubOffset; RelocationEntry RE(SectionID, Section.StubOffset, MachO::X86_64_RELOC_UNSIGNED, 0, false, 3); if (Value.SymbolName) addRelocationForSymbol(RE, Value.SymbolName); else addRelocationForSection(RE, Value.SectionID); Section.StubOffset += 8; Addr = GOTEntry; } resolveRelocation(Section, Offset, (uint64_t)Addr, MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true, 2); } else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) { // This is an ARM branch relocation, need to use a stub function. // Look up for existing stub. StubMap::const_iterator i = Stubs.find(Value); if (i != Stubs.end()) resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second, RelType, 0, IsPCRel, Size); else { // Create a new stub function. Stubs[Value] = Section.StubOffset; uint8_t *StubTargetAddr = createStubFunction(Section.Address + Section.StubOffset); RelocationEntry RE(SectionID, StubTargetAddr - Section.Address, MachO::GENERIC_RELOC_VANILLA, Value.Addend); if (Value.SymbolName) addRelocationForSymbol(RE, Value.SymbolName); else addRelocationForSection(RE, Value.SectionID); resolveRelocation(Section, Offset, (uint64_t)Section.Address + Section.StubOffset, RelType, 0, IsPCRel, Size); Section.StubOffset += getMaxStubSize(); } } else { RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, IsPCRel, Size); if (Value.SymbolName) addRelocationForSymbol(RE, Value.SymbolName); else addRelocationForSection(RE, Value.SectionID); } }
virtual void NotifyObjectEmitted(const ObjectImage &obj) #endif { int8_t gc_state = jl_gc_safe_enter(); uv_rwlock_wrlock(&threadsafe); jl_gc_safe_leave(gc_state); #ifdef LLVM36 object::section_iterator Section = obj.section_begin(); object::section_iterator EndSection = obj.section_end(); #else object::section_iterator Section = obj.begin_sections(); object::section_iterator EndSection = obj.end_sections(); #endif #if defined(_OS_WINDOWS_) uint64_t SectionAddrCheck = 0; // assert that all of the Sections are at the same location uint8_t *UnwindData = NULL; #if defined(_CPU_X86_64_) uint8_t *catchjmp = NULL; for (const object::SymbolRef &sym_iter : obj.symbols()) { StringRef sName; #ifdef LLVM37 sName = sym_iter.getName().get(); #else sym_iter.getName(sName); #endif uint8_t **pAddr = NULL; if (sName.equals("__UnwindData")) { pAddr = &UnwindData; } else if (sName.equals("__catchjmp")) { pAddr = &catchjmp; } if (pAddr) { uint64_t Addr, SectionAddr; #if defined(LLVM38) Addr = sym_iter.getAddress().get(); Section = sym_iter.getSection().get(); assert(Section != EndSection && Section->isText()); SectionAddr = L.getSectionLoadAddress(*Section); #elif defined(LLVM37) Addr = sym_iter.getAddress().get(); sym_iter.getSection(Section); assert(Section != EndSection && Section->isText()); Section->getName(sName); SectionAddr = L.getSectionLoadAddress(sName); #elif defined(LLVM36) sym_iter.getAddress(Addr); sym_iter.getSection(Section); assert(Section != EndSection && Section->isText()); Section->getName(sName); SectionAddr = L.getSectionLoadAddress(sName); #else // LLVM35 sym_iter.getAddress(Addr); sym_iter.getSection(Section); assert(Section != EndSection); assert(!Section->isText(isText) && isText); Section->getAddress(SectionAddr); #endif #ifdef LLVM36 Addr += SectionAddr; #endif *pAddr = (uint8_t*)Addr; if (SectionAddrCheck) assert(SectionAddrCheck == SectionAddr); else SectionAddrCheck = SectionAddr; } } assert(catchjmp); assert(UnwindData); assert(SectionAddrCheck); catchjmp[0] = 0x48; catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [&_seh_exception_handle] *(uint64_t*)(&catchjmp[2]) = (uint64_t)&_seh_exception_handler; catchjmp[10] = 0xff; catchjmp[11] = 0xe0; // jmp RAX UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER UnwindData[1] = 4; // size of prolog (bytes) UnwindData[2] = 2; // count of unwind codes (slots) UnwindData[3] = 0x05; // frame register (rbp) = rsp UnwindData[4] = 4; // second instruction UnwindData[5] = 0x03; // mov RBP, RSP UnwindData[6] = 1; // first instruction UnwindData[7] = 0x50; // push RBP *(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - (uint8_t*)SectionAddrCheck); // relative location of catchjmp #endif // defined(_OS_X86_64_) #endif // defined(_OS_WINDOWS_) #ifdef LLVM37 auto symbols = object::computeSymbolSizes(obj); for(const auto &sym_size : symbols) { const object::SymbolRef &sym_iter = sym_size.first; object::SymbolRef::Type SymbolType = sym_iter.getType(); if (SymbolType != object::SymbolRef::ST_Function) continue; uint64_t Size = sym_size.second; uint64_t Addr = sym_iter.getAddress().get(); #ifdef LLVM38 Section = sym_iter.getSection().get(); #else sym_iter.getSection(Section); #endif if (Section == EndSection) continue; if (!Section->isText()) continue; #ifdef LLVM38 uint64_t SectionAddr = L.getSectionLoadAddress(*Section); #else StringRef secName; Section->getName(secName); uint64_t SectionAddr = L.getSectionLoadAddress(secName); #endif Addr += SectionAddr; StringRef sName = sym_iter.getName().get(); #if defined(_OS_WINDOWS_) uint64_t SectionSize = Section->getSize(); if (SectionAddrCheck) assert(SectionAddrCheck == SectionAddr); else SectionAddrCheck = SectionAddr; create_PRUNTIME_FUNCTION( (uint8_t*)(intptr_t)Addr, (size_t)Size, sName, (uint8_t*)(intptr_t)SectionAddr, (size_t)SectionSize, UnwindData); #endif StringMap<jl_lambda_info_t*>::iterator linfo_it = linfo_in_flight.find(sName); jl_lambda_info_t *linfo = NULL; if (linfo_it != linfo_in_flight.end()) { linfo = linfo_it->second; linfo_in_flight.erase(linfo_it); } ObjectInfo tmp = {&debugObj, (size_t)Size, L.clone().release(), linfo}; objectmap[Addr] = tmp; } #else // pre-LLVM37 uint64_t Addr; uint64_t Size; object::SymbolRef::Type SymbolType; StringRef sName; #ifdef LLVM36 uint64_t SectionAddr = 0; #else bool isText; #ifdef _OS_WINDOWS_ uint64_t SectionAddr = 0; #endif #endif #if defined(LLVM35) for (const object::SymbolRef &sym_iter : obj.symbols()) { sym_iter.getType(SymbolType); if (SymbolType != object::SymbolRef::ST_Function) continue; sym_iter.getSize(Size); sym_iter.getAddress(Addr); sym_iter.getSection(Section); if (Section == EndSection) continue; #if defined(LLVM36) if (!Section->isText()) continue; Section->getName(sName); SectionAddr = L.getSectionLoadAddress(sName); Addr += SectionAddr; #else if (Section->isText(isText) || !isText) continue; #endif sym_iter.getName(sName); #ifdef _OS_DARWIN_ # if !defined(LLVM36) Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName, true); if (!Addr && sName[0] == '_') { Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName.substr(1), true); } if (!Addr) continue; # endif #elif defined(_OS_WINDOWS_) uint64_t SectionSize = 0; # if defined(LLVM36) SectionSize = Section->getSize(); # else Section->getAddress(SectionAddr); Section->getSize(SectionSize); # endif if (SectionAddrCheck) assert(SectionAddrCheck == SectionAddr); else SectionAddrCheck = SectionAddr; create_PRUNTIME_FUNCTION( (uint8_t*)(intptr_t)Addr, (size_t)Size, sName, (uint8_t*)(intptr_t)SectionAddr, (size_t)SectionSize, UnwindData); #endif StringMap<jl_lambda_info_t*>::iterator linfo_it = linfo_in_flight.find(sName); jl_lambda_info_t *linfo = NULL; if (linfo_it != linfo_in_flight.end()) { linfo = linfo_it->second; linfo_in_flight.erase(linfo_it); } const object::ObjectFile *objfile = #ifdef LLVM36 &obj; #else obj.getObjectFile(); #endif ObjectInfo tmp = {objfile, (size_t)Size, #ifdef LLVM37 L.clone().release(), #elif defined(LLVM36) (size_t)SectionAddr, #endif #ifdef _OS_DARWIN_ strndup(sName.data(), sName.size()), #endif linfo }; objectmap[Addr] = tmp; } #else //LLVM34 error_code itererr; object::symbol_iterator sym_iter = obj.begin_symbols(); object::symbol_iterator sym_end = obj.end_symbols(); for (; sym_iter != sym_end; sym_iter.increment(itererr)) { sym_iter->getType(SymbolType); if (SymbolType != object::SymbolRef::ST_Function) continue; sym_iter->getAddress(Addr); sym_iter->getSize(Size); ObjectInfo tmp = {obj.getObjectFile(), (size_t)Size}; objectmap[Addr] = tmp; } #endif #endif uv_rwlock_wrunlock(&threadsafe); }
virtual void NotifyObjectEmitted(const ObjectImage &obj) #endif { uint64_t Addr; uint64_t Size; object::SymbolRef::Type SymbolType; #ifdef LLVM36 object::section_iterator Section = obj.section_begin(); object::section_iterator EndSection = obj.section_end(); uint64_t SectionAddr = 0; StringRef sName; #else object::section_iterator Section = obj.begin_sections(); object::section_iterator EndSection = obj.end_sections(); bool isText; #ifndef _OS_LINUX_ StringRef sName; #endif #endif #ifndef LLVM36 uint64_t SectionAddr = 0; #endif uint64_t SectionSize = 0; uint64_t SectionAddrCheck = 0; // assert that all of the Sections are at the same location #if defined(_OS_WINDOWS_) #if defined(_CPU_X86_64_) uint8_t *UnwindData = NULL; uint8_t *catchjmp = NULL; for (const object::SymbolRef &sym_iter : obj.symbols()) { # ifdef LLVM37 sName = sym_iter.getName().get(); # else sym_iter.getName(sName); # endif if (sName.equals("__UnwindData")) { # ifdef LLVM37 Addr = sym_iter.getAddress().get(); # else sym_iter.getAddress(Addr); # endif sym_iter.getSection(Section); # ifdef LLVM36 assert(Section->isText()); Section->getName(sName); SectionAddr = L.getSectionLoadAddress(sName); Addr += SectionAddr; # else if (Section->isText(isText) || !isText) assert(0 && "!isText"); Section->getAddress(SectionAddr); # endif UnwindData = (uint8_t*)Addr; if (SectionAddrCheck) assert(SectionAddrCheck == SectionAddr); else SectionAddrCheck = SectionAddr; } if (sName.equals("__catchjmp")) { # ifdef LLVM37 Addr = sym_iter.getAddress().get(); # else sym_iter.getAddress(Addr); # endif sym_iter.getSection(Section); # ifdef LLVM36 assert(Section->isText()); Section->getName(sName); SectionAddr = L.getSectionLoadAddress(sName); Addr += SectionAddr; # else if (Section->isText(isText) || !isText) assert(0 && "!isText"); Section->getAddress(SectionAddr); # endif catchjmp = (uint8_t*)Addr; if (SectionAddrCheck) assert(SectionAddrCheck == SectionAddr); else SectionAddrCheck = SectionAddr; } } assert(catchjmp); assert(UnwindData); catchjmp[0] = 0x48; catchjmp[1] = 0xb8; // mov RAX, QWORD PTR [&_seh_exception_handle] *(uint64_t*)(&catchjmp[2]) = (uint64_t)&_seh_exception_handler; catchjmp[10] = 0xff; catchjmp[11] = 0xe0; // jmp RAX UnwindData[0] = 0x09; // version info, UNW_FLAG_EHANDLER UnwindData[1] = 4; // size of prolog (bytes) UnwindData[2] = 2; // count of unwind codes (slots) UnwindData[3] = 0x05; // frame register (rbp) = rsp UnwindData[4] = 4; // second instruction UnwindData[5] = 0x03; // mov RBP, RSP UnwindData[6] = 1; // first instruction UnwindData[7] = 0x50; // push RBP *(DWORD*)&UnwindData[8] = (DWORD)(catchjmp - (uint8_t*)SectionAddr); // relative location of catchjmp #else // defined(_OS_X86_64_) uint8_t *UnwindData = NULL; #endif // defined(_OS_X86_64_) #endif // defined(_OS_WINDOWS_) #ifdef LLVM35 for (const object::SymbolRef &sym_iter : obj.symbols()) { # ifdef LLVM37 SymbolType = sym_iter.getType(); # else sym_iter.getType(SymbolType); # endif if (SymbolType != object::SymbolRef::ST_Function) continue; # ifdef LLVM37 Addr = sym_iter.getAddress().get(); # else sym_iter.getAddress(Addr); # endif sym_iter.getSection(Section); if (Section == EndSection) continue; #if defined(LLVM36) if (!Section->isText()) continue; Section->getName(sName); SectionAddr = L.getSectionLoadAddress(sName); Addr += SectionAddr; #else if (Section->isText(isText) || !isText) continue; #endif #if defined(LLVM36) SectionSize = Section->getSize(); #else Section->getAddress(SectionAddr); Section->getSize(SectionSize); #endif #ifdef _OS_DARWIN_ # if defined(LLVM37) Size = Section->getSize(); sName = sym_iter.getName().get(); # else sym_iter.getName(sName); # endif # if defined(LLVM36) if (sName[0] == '_') { sName = sName.substr(1); } # else Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName, true); if (!Addr && sName[0] == '_') { sName = sName.substr(1); Addr = ((MCJIT*)jl_ExecutionEngine)->getSymbolAddress(sName, true); } if (!Addr) continue; # endif #elif defined(_OS_WINDOWS_) # if defined(LLVM37) assert(obj.isELF()); Size = ((llvm::object::ELFSymbolRef)sym_iter).getSize(); sName = sym_iter.getName().get(); # else sym_iter.getSize(Size); sym_iter.getName(sName); # endif # ifdef _CPU_X86_ if (sName[0] == '_') sName = sName.substr(1); # endif if (SectionAddrCheck) assert(SectionAddrCheck == SectionAddr); else SectionAddrCheck = SectionAddr; create_PRUNTIME_FUNCTION( (uint8_t*)(intptr_t)Addr, (size_t)Size, sName, (uint8_t*)(intptr_t)SectionAddr, (size_t)SectionSize, UnwindData); #endif const object::ObjectFile *objfile = #ifdef LLVM36 &obj; #else obj.getObjectFile(); #endif ObjectInfo tmp = {objfile, SectionSize #ifdef LLVM37 ,L.clone().release() #elif defined(LLVM36) ,(size_t)SectionAddr #endif #ifdef _OS_DARWIN_ ,strndup(sName.data(), sName.size()) #endif }; objectmap[Addr] = tmp; } #else //LLVM34 error_code itererr; object::symbol_iterator sym_iter = obj.begin_symbols(); object::symbol_iterator sym_end = obj.end_symbols(); for (; sym_iter != sym_end; sym_iter.increment(itererr)) { sym_iter->getType(SymbolType); if (SymbolType != object::SymbolRef::ST_Function) continue; sym_iter->getAddress(Addr); sym_iter->getSize(Size); ObjectInfo tmp = {obj.getObjectFile(), (size_t)Size}; objectmap[Addr] = tmp; } #endif }
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode) { unsigned StubBufSize = 0, StubSize = getMaxStubSize(); error_code err; const ObjectFile *ObjFile = Obj.getObjectFile(); // FIXME: this is an inefficient way to handle this. We should computed the // necessary section allocation size in loadObject by walking all the sections // once. if (StubSize > 0) { for (section_iterator SI = ObjFile->begin_sections(), SE = ObjFile->end_sections(); SI != SE; SI.increment(err), Check(err)) { section_iterator RelSecI = SI->getRelocatedSection(); if (!(RelSecI == Section)) continue; for (relocation_iterator I = SI->begin_relocations(), E = SI->end_relocations(); I != E; I.increment(err), Check(err)) { StubBufSize += StubSize; } } } StringRef data; uint64_t Alignment64; Check(Section.getContents(data)); Check(Section.getAlignment(Alignment64)); unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; bool IsRequired; bool IsVirtual; bool IsZeroInit; bool IsReadOnly; uint64_t DataSize; StringRef Name; Check(Section.isRequiredForExecution(IsRequired)); Check(Section.isVirtual(IsVirtual)); Check(Section.isZeroInit(IsZeroInit)); Check(Section.isReadOnlyData(IsReadOnly)); Check(Section.getSize(DataSize)); Check(Section.getName(Name)); if (StubSize > 0) { unsigned StubAlignment = getStubAlignment(); unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment); if (StubAlignment > EndAlignment) StubBufSize += StubAlignment - EndAlignment; } unsigned Allocate; unsigned SectionID = Sections.size(); uint8_t *Addr; const char *pData = 0; // Some sections, such as debug info, don't need to be loaded for execution. // Leave those where they are. if (IsRequired) { Allocate = DataSize + StubBufSize; Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID) : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, IsReadOnly); if (!Addr) report_fatal_error("Unable to allocate section memory!"); // Virtual sections have no data in the object image, so leave pData = 0 if (!IsVirtual) pData = data.data(); // Zero-initialize or copy the data from the image if (IsZeroInit || IsVirtual) memset(Addr, 0, DataSize); else memcpy(Addr, pData, DataSize); DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); Obj.updateSectionAddress(Section, (uint64_t)Addr); } else { // Even if we didn't load the section, we need to record an entry for it // to handle later processing (and by 'handle' I mean don't do anything // with these sections). Allocate = 0; Addr = 0; DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); } Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); return SectionID; }