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].LoadAddress;
+ 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,
llvm_unreachable("Attempting to remap address of unknown section!");
}
-static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) {
+static std::error_code getOffset(const SymbolRef &Sym, SectionRef Sec,
+ uint64_t &Result) {
ErrorOr<uint64_t> AddressOrErr = Sym.getAddress();
if (std::error_code EC = AddressOrErr.getError())
return EC;
- uint64_t Address = *AddressOrErr;
-
- if (Address == UnknownAddress) {
- Result = UnknownAddress;
- return std::error_code();
- }
-
- const ObjectFile *Obj = Sym.getObject();
- section_iterator SecI(Obj->section_begin());
- if (std::error_code EC = Sym.getSection(SecI))
- return EC;
-
- if (SecI == Obj->section_end()) {
- Result = UnknownAddress;
- return std::error_code();
- }
-
- uint64_t SectionAddress = SecI->getAddress();
- Result = Address - SectionAddress;
+ Result = *AddressOrErr - Sec.getAddress();
return std::error_code();
}
-std::pair<unsigned, unsigned>
+RuntimeDyldImpl::ObjSectionToIDMap
RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
MutexGuard locked(lock);
- // Grab the first Section ID. We'll use this later to construct the underlying
- // range for the returned LoadedObjectInfo.
- unsigned SectionsAddedBeginIdx = Sections.size();
-
// Save information about our target
Arch = (Triple::ArchType)Obj.getArch();
IsTargetLittleEndian = Obj.isLittleEndian();
ErrorOr<StringRef> NameOrErr = I->getName();
Check(NameOrErr.getError());
StringRef Name = *NameOrErr;
- uint64_t SectOffset;
- Check(getOffset(*I, SectOffset));
- section_iterator SI = Obj.section_end();
- Check(I->getSection(SI));
+ ErrorOr<section_iterator> SIOrErr = I->getSection();
+ Check(SIOrErr.getError());
+ section_iterator SI = *SIOrErr;
if (SI == Obj.section_end())
continue;
- StringRef SectionData;
- Check(SI->getContents(SectionData));
+ uint64_t SectOffset;
+ Check(getOffset(*I, *SI, SectOffset));
bool IsCode = SI->isText();
unsigned SectionID =
findOrEmitSection(Obj, *SI, IsCode, LocalSections);
// Give the subclasses a chance to tie-up any loose ends.
finalizeLoad(Obj, LocalSections);
- unsigned SectionsAddedEndIdx = Sections.size();
+// for (auto E : LocalSections)
+// llvm::dbgs() << "Added: " << E.first.getRawDataRefImpl() << " -> " << E.second << "\n";
- return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx);
+ return LocalSections;
}
// A helper method for computeTotalAllocSize.
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.
// RuntimeDyld class implementation
uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress(
- StringRef SectionName) const {
- for (unsigned I = BeginIdx; I != EndIdx; ++I)
- if (RTDyld.Sections[I].Name == SectionName)
- return RTDyld.Sections[I].LoadAddress;
+ 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";
+ }
return 0;
}