/// Obtain the Load Address of a section by Name.
///
- /// Calculate the address of the section identified by the passed in Name.
+ /// Calculate the address of the given section.
/// The section need not be present in the local address space. The addresses
- /// need to be consistent with the addresses used to query the DIContext and
+ /// needs to be consistent with the addresses used to query the DIContext and
/// the output of this function should be deterministic, i.e. repeated calls with
- /// the same Name should give the same address.
- virtual uint64_t getSectionLoadAddress(StringRef Name) const = 0;
+ /// the same Sec should give the same address.
+ virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const = 0;
/// If conveniently available, return the content of the given Section.
///
/// local (unrelocated) object file and applied on the fly. Note that this method
/// is used purely for optimzation purposes in the common case of JITting in the
/// local address space, so returning false should always be correct.
- virtual bool getLoadedSectionContents(StringRef Name, StringRef &Data) const {
+ virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
+ StringRef &Data) const {
return false;
}
#include "JITSymbolFlags.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Memory.h"
#include "llvm/DebugInfo/DIContext.h"
+#include <map>
#include <memory>
namespace llvm {
class LoadedObjectInfo : public llvm::LoadedObjectInfo {
friend class RuntimeDyldImpl;
public:
- LoadedObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
- unsigned EndIdx)
- : RTDyld(RTDyld), BeginIdx(BeginIdx), EndIdx(EndIdx) { }
+ typedef std::map<object::SectionRef, unsigned> ObjSectionToIDMap;
+
+ LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
+ : RTDyld(RTDyld), ObjSecToIDMap(ObjSecToIDMap) { }
virtual object::OwningBinary<object::ObjectFile>
getObjectForDebug(const object::ObjectFile &Obj) const = 0;
- uint64_t getSectionLoadAddress(StringRef Name) const;
+ uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const;
protected:
virtual void anchor();
RuntimeDyldImpl &RTDyld;
- unsigned BeginIdx, EndIdx;
+ ObjSectionToIDMap ObjSecToIDMap;
};
template <typename Derived> struct LoadedObjectInfoHelper : LoadedObjectInfo {
- LoadedObjectInfoHelper(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
- unsigned EndIdx)
- : LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {}
+ LoadedObjectInfoHelper(RuntimeDyldImpl &RTDyld,
+ LoadedObjectInfo::ObjSectionToIDMap ObjSecToIDMap)
+ : LoadedObjectInfo(RTDyld, std::move(ObjSecToIDMap)) {}
std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
}
#define LLVM_OBJECT_SYMBOLICFILE_H
#include "llvm/Object/Binary.h"
+#include "llvm/Support/Format.h"
namespace llvm {
namespace object {
DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
};
+template <typename OStream>
+OStream& operator<<(OStream &OS, const DataRefImpl &D) {
+ OS << "(" << format("0x%x8", D.p) << " (" << format("0x%x8", D.d.a) << ", " << format("0x%x8", D.d.b) << "))";
+ return OS;
+}
+
inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
// Check bitwise identical. This is the only legal way to compare a union w/o
// knowing which member is in use.
continue;
StringRef data;
+ section_iterator RelocatedSection = Section.getRelocatedSection();
// Try to obtain an already relocated version of this section.
// Else use the unrelocated section from the object file. We'll have to
// apply relocations ourselves later.
- if (!L || !L->getLoadedSectionContents(name,data))
+ if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
Section.getContents(data);
name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
TypesDWOSections[Section].Data = data;
}
- section_iterator RelocatedSection = Section.getRelocatedSection();
if (RelocatedSection == Obj.section_end())
continue;
// If the section we're relocating was relocated already by the JIT,
// then we used the relocated version above, so we do not need to process
// relocations for it now.
- if (L && L->getLoadedSectionContents(RelSecName,RelSecData))
+ if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
continue;
RelSecName = RelSecName.substr(
// we need to perform the same computation.
StringRef SecName;
RSec->getName(SecName);
- SectionLoadAddress = L->getSectionLoadAddress(SecName);
+// llvm::dbgs() << "Name: '" << SecName
+// << "', RSec: " << RSec->getRawDataRefImpl()
+// << ", Section: " << Section.getRawDataRefImpl() << "\n";
+ SectionLoadAddress = L->getSectionLoadAddress(*RSec);
if (SectionLoadAddress != 0)
SymAddr += SectionLoadAddress - RSec->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();
// 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.
// 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;
}
class LoadedCOFFObjectInfo
: public RuntimeDyld::LoadedObjectInfoHelper<LoadedCOFFObjectInfo> {
public:
- LoadedCOFFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
- unsigned EndIdx)
- : LoadedObjectInfoHelper(RTDyld, BeginIdx, EndIdx) {}
+ LoadedCOFFObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
+ : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
OwningBinary<ObjectFile>
getObjectForDebug(const ObjectFile &Obj) const override {
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
RuntimeDyldCOFF::loadObject(const object::ObjectFile &O) {
- unsigned SectionStartIdx, SectionEndIdx;
- std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O);
- return llvm::make_unique<LoadedCOFFObjectInfo>(*this, SectionStartIdx,
- SectionEndIdx);
+ return llvm::make_unique<LoadedCOFFObjectInfo>(*this, loadObjectImpl(O));
}
uint64_t RuntimeDyldCOFF::getSymbolOffset(const SymbolRef &Sym) {
class LoadedELFObjectInfo
: public RuntimeDyld::LoadedObjectInfoHelper<LoadedELFObjectInfo> {
public:
- LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
- unsigned EndIdx)
- : LoadedObjectInfoHelper(RTDyld, BeginIdx, EndIdx) {}
+ LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
+ : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
OwningBinary<ObjectFile>
getObjectForDebug(const ObjectFile &Obj) const override;
template <typename ELFT>
std::unique_ptr<DyldELFObject<ELFT>>
createRTDyldELFObject(MemoryBufferRef Buffer,
+ const ObjectFile &SourceObject,
const LoadedELFObjectInfo &L,
std::error_code &ec) {
typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
llvm::make_unique<DyldELFObject<ELFT>>(Buffer, ec);
// Iterate over all sections in the object.
+ auto SI = SourceObject.section_begin();
for (const auto &Sec : Obj->sections()) {
StringRef SectionName;
Sec.getName(SectionName);
Elf_Shdr *shdr = const_cast<Elf_Shdr *>(
reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
- if (uint64_t SecLoadAddr = L.getSectionLoadAddress(SectionName)) {
+ if (uint64_t SecLoadAddr = L.getSectionLoadAddress(*SI)) {
// This assumes that the address passed in matches the target address
// bitness. The template-based type cast handles everything else.
shdr->sh_addr = static_cast<addr_type>(SecLoadAddr);
}
}
+ ++SI;
}
return Obj;
std::unique_ptr<ObjectFile> DebugObj;
if (Obj.getBytesInAddress() == 4 && Obj.isLittleEndian()) {
typedef ELFType<support::little, false> ELF32LE;
- DebugObj = createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), L, ec);
+ DebugObj = createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), Obj, L,
+ ec);
} else if (Obj.getBytesInAddress() == 4 && !Obj.isLittleEndian()) {
typedef ELFType<support::big, false> ELF32BE;
- DebugObj = createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), L, ec);
+ DebugObj = createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), Obj, L,
+ ec);
} else if (Obj.getBytesInAddress() == 8 && !Obj.isLittleEndian()) {
typedef ELFType<support::big, true> ELF64BE;
- DebugObj = createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), L, ec);
+ DebugObj = createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), Obj, L,
+ ec);
} else if (Obj.getBytesInAddress() == 8 && Obj.isLittleEndian()) {
typedef ELFType<support::little, true> ELF64LE;
- DebugObj = createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), L, ec);
+ DebugObj = createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), Obj, L,
+ ec);
} else
llvm_unreachable("Unexpected ELF format");
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
RuntimeDyldELF::loadObject(const object::ObjectFile &O) {
- unsigned SectionStartIdx, SectionEndIdx;
- std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O);
- return llvm::make_unique<LoadedELFObjectInfo>(*this, SectionStartIdx,
- SectionEndIdx);
+ return llvm::make_unique<LoadedELFObjectInfo>(*this, loadObjectImpl(O));
}
void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
const SectionRef &Section);
// \brief Implementation of the generic part of the loadObject algorithm.
- std::pair<unsigned, unsigned> loadObjectImpl(const object::ObjectFile &Obj);
+ ObjSectionToIDMap loadObjectImpl(const object::ObjectFile &Obj);
public:
RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr,
class LoadedMachOObjectInfo
: public RuntimeDyld::LoadedObjectInfoHelper<LoadedMachOObjectInfo> {
public:
- LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
- unsigned EndIdx)
- : LoadedObjectInfoHelper(RTDyld, BeginIdx, EndIdx) {}
+ LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld,
+ ObjSectionToIDMap ObjSecToIDMap)
+ : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
OwningBinary<ObjectFile>
getObjectForDebug(const ObjectFile &Obj) const override {
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
RuntimeDyldMachO::loadObject(const object::ObjectFile &O) {
- unsigned SectionStartIdx, SectionEndIdx;
- std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O);
- return llvm::make_unique<LoadedMachOObjectInfo>(*this, SectionStartIdx,
- SectionEndIdx);
+ return llvm::make_unique<LoadedMachOObjectInfo>(*this, loadObjectImpl(O));
}
} // end namespace llvm
if (UseDebugObj) {
DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
SymbolObj = DebugObj.getBinary();
+ LoadedObjInfo.release();
}
}
StringRef SecName;
Sec->getName(SecName);
uint64_t SectionLoadAddress =
- LoadedObjInfo->getSectionLoadAddress(SecName);
+ LoadedObjInfo->getSectionLoadAddress(*Sec);
if (SectionLoadAddress != 0)
Addr += SectionLoadAddress - Sec->getAddress();
}