#ifndef NDEBUG
static void dumpSectionMemory(const SectionEntry &S, StringRef State) {
- dbgs() << "----- Contents of section " << S.Name << " " << State << " -----";
+ dbgs() << "----- Contents of section " << S.getName() << " " << State
+ << " -----";
- if (S.Address == nullptr) {
+ if (S.getAddress() == nullptr) {
dbgs() << "\n <section not emitted>\n";
return;
}
const unsigned ColsPerRow = 16;
- uint8_t *DataAddr = S.Address;
- uint64_t LoadAddr = S.LoadAddress;
+ uint8_t *DataAddr = S.getAddress();
+ uint64_t LoadAddr = S.getLoadAddress();
unsigned StartPadding = LoadAddr & (ColsPerRow - 1);
- unsigned BytesRemaining = S.Size;
+ unsigned BytesRemaining = S.getSize();
if (StartPadding) {
dbgs() << "\n" << format("0x%016" PRIx64,
void RuntimeDyldImpl::resolveRelocations() {
MutexGuard locked(lock);
+ // Print out the sections prior to relocation.
+ DEBUG(
+ for (int i = 0, e = Sections.size(); i != e; ++i)
+ dumpSectionMemory(Sections[i], "before relocations");
+ );
+
// First, resolve relocations associated with external symbols.
resolveExternalSymbols();
- // Just iterate over the sections we have and resolve all the relocations
- // in them. Gross overkill, but it gets the job done.
- for (int i = 0, e = Sections.size(); i != e; ++i) {
+ // Iterate over all outstanding relocations
+ for (auto it = Relocations.begin(), e = Relocations.end(); it != e; ++it) {
// The Section here (Sections[i]) refers to the section in which the
// symbol for the relocation is located. The SectionID in the relocation
// entry provides the section to which the relocation will be applied.
- uint64_t Addr = Sections[i].LoadAddress;
- DEBUG(dbgs() << "Resolving relocations Section #" << i << "\t"
+ int Idx = it->getFirst();
+ uint64_t Addr = Sections[Idx].getLoadAddress();
+ DEBUG(dbgs() << "Resolving relocations Section #" << Idx << "\t"
<< format("%p", (uintptr_t)Addr) << "\n");
- DEBUG(dumpSectionMemory(Sections[i], "before relocations"));
- resolveRelocationList(Relocations[i], Addr);
- DEBUG(dumpSectionMemory(Sections[i], "after relocations"));
- Relocations.erase(i);
+ resolveRelocationList(it->getSecond(), Addr);
}
+ Relocations.clear();
+
+ // Print out sections after relocation.
+ DEBUG(
+ for (int i = 0, e = Sections.size(); i != e; ++i)
+ dumpSectionMemory(Sections[i], "after relocations");
+ );
+
}
void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress,
uint64_t TargetAddress) {
MutexGuard locked(lock);
for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
- if (Sections[i].Address == LocalAddress) {
+ if (Sections[i].getAddress() == LocalAddress) {
reassignSectionAddress(i, TargetAddress);
return;
}
++I) {
uint32_t Flags = I->getFlags();
- bool IsCommon = Flags & SymbolRef::SF_Common;
- if (IsCommon)
+ if (Flags & SymbolRef::SF_Common)
CommonSymbols.push_back(*I);
else {
object::SymbolRef::Type SymType = I->getType();
- if (SymType == object::SymbolRef::ST_Function ||
- SymType == object::SymbolRef::ST_Data ||
- SymType == object::SymbolRef::ST_Unknown) {
-
- ErrorOr<StringRef> NameOrErr = I->getName();
- Check(NameOrErr.getError());
- StringRef Name = *NameOrErr;
- section_iterator SI = Obj.section_end();
- Check(I->getSection(SI));
+ // Get symbol name.
+ ErrorOr<StringRef> NameOrErr = I->getName();
+ Check(NameOrErr.getError());
+ StringRef Name = *NameOrErr;
+
+ // Compute JIT symbol flags.
+ JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
+ if (Flags & SymbolRef::SF_Weak)
+ RTDyldSymFlags |= JITSymbolFlags::Weak;
+ if (Flags & SymbolRef::SF_Exported)
+ RTDyldSymFlags |= JITSymbolFlags::Exported;
+
+ if (Flags & SymbolRef::SF_Absolute &&
+ SymType != object::SymbolRef::ST_File) {
+ auto Addr = I->getAddress();
+ Check(Addr.getError());
+ uint64_t SectOffset = *Addr;
+ unsigned SectionID = AbsoluteSymbolSection;
+
+ DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name
+ << " SID: " << SectionID << " Offset: "
+ << format("%p", (uintptr_t)SectOffset)
+ << " flags: " << Flags << "\n");
+ GlobalSymbolTable[Name] =
+ SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags);
+ } else if (SymType == object::SymbolRef::ST_Function ||
+ SymType == object::SymbolRef::ST_Data ||
+ SymType == object::SymbolRef::ST_Unknown ||
+ SymType == object::SymbolRef::ST_Other) {
+
+ ErrorOr<section_iterator> SIOrErr = I->getSection();
+ Check(SIOrErr.getError());
+ section_iterator SI = *SIOrErr;
if (SI == Obj.section_end())
continue;
+ // Get symbol offset.
uint64_t SectOffset;
Check(getOffset(*I, *SI, SectOffset));
- StringRef SectionData;
- Check(SI->getContents(SectionData));
bool IsCode = SI->isText();
- unsigned SectionID =
- findOrEmitSection(Obj, *SI, IsCode, LocalSections);
+ unsigned SectionID = findOrEmitSection(Obj, *SI, IsCode, LocalSections);
+
DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
<< " SID: " << SectionID << " Offset: "
<< format("%p", (uintptr_t)SectOffset)
<< " flags: " << Flags << "\n");
- JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
- if (Flags & SymbolRef::SF_Weak)
- RTDyldSymFlags |= JITSymbolFlags::Weak;
- if (Flags & SymbolRef::SF_Exported)
- RTDyldSymFlags |= JITSymbolFlags::Exported;
GlobalSymbolTable[Name] =
SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags);
}
Offset += Size;
Addr += Size;
}
+
+ if (Checker)
+ Checker->registerSection(Obj.getFileName(), SectionID);
}
unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
uint8_t *Addr;
const char *pData = nullptr;
- // In either case, set the location of the unrelocated section in memory,
- // since we still process relocations for it even if we're not applying them.
- Check(Section.getContents(data));
- // Virtual sections have no data in the object image, so leave pData = 0
- if (!IsVirtual)
+ // If this section contains any bits (i.e. isn't a virtual or bss section),
+ // grab a reference to them.
+ if (!IsVirtual && !IsZeroInit) {
+ // In either case, set the location of the unrelocated section in memory,
+ // since we still process relocations for it even if we're not applying them.
+ Check(Section.getContents(data));
pData = data.data();
+ }
+
+ // Code section alignment needs to be at least as high as stub alignment or
+ // padding calculations may by incorrect when the section is remapped to a
+ // higher alignment.
+ if (IsCode)
+ Alignment = std::max(Alignment, getStubAlignment());
// Some sections, such as debug info, don't need to be loaded for execution.
// Leave those where they are.
// Addr is a uint64_t because we can't assume the pointer width
// of the target is the same as that of the host. Just use a generic
// "big enough" type.
- DEBUG(dbgs() << "Reassigning address for section "
- << SectionID << " (" << Sections[SectionID].Name << "): "
- << format("0x%016" PRIx64, Sections[SectionID].LoadAddress) << " -> "
- << format("0x%016" PRIx64, Addr) << "\n");
- Sections[SectionID].LoadAddress = Addr;
+ DEBUG(dbgs() << "Reassigning address for section " << SectionID << " ("
+ << Sections[SectionID].getName() << "): "
+ << format("0x%016" PRIx64, Sections[SectionID].getLoadAddress())
+ << " -> " << format("0x%016" PRIx64, Addr) << "\n");
+ Sections[SectionID].setLoadAddress(Addr);
}
void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
const RelocationEntry &RE = Relocs[i];
// Ignore relocations for sections that were not loaded
- if (Sections[RE.SectionID].Address == nullptr)
+ if (Sections[RE.SectionID].getAddress() == nullptr)
continue;
resolveRelocation(RE, Value);
}
uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress(
const object::SectionRef &Sec) const {
-// llvm::dbgs() << "Searching for " << Sec.getRawDataRefImpl() << " in:\n";
-// for (auto E : ObjSecToIDMap)
-// llvm::dbgs() << "Added: " << E.first.getRawDataRefImpl() << " -> " << E.second << "\n";
-
auto I = ObjSecToIDMap.find(Sec);
- if (I != ObjSecToIDMap.end()) {
-// llvm::dbgs() << "Found ID " << I->second << " for Sec: " << Sec.getRawDataRefImpl() << ", LoadAddress = " << RTDyld.Sections[I->second].LoadAddress << "\n";
- return RTDyld.Sections[I->second].LoadAddress;
- } else {
-// llvm::dbgs() << "Not found.\n";
- }
+ if (I != ObjSecToIDMap.end())
+ return RTDyld.Sections[I->second].getLoadAddress();
return 0;
}