mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-01 03:33:42 +00:00
[RuntimeDyld] Make LoadedObjectInfo::getLoadedSectionAddress take a SectionRef
rather than a string section name. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243456 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eb9ef2d368
commit
ce8287db09
@ -145,12 +145,12 @@ public:
|
||||
|
||||
/// 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.
|
||||
///
|
||||
@ -162,7 +162,8 @@ public:
|
||||
/// 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;
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,10 @@
|
||||
#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 {
|
||||
@ -59,26 +61,27 @@ public:
|
||||
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));
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define LLVM_OBJECT_SYMBOLICFILE_H
|
||||
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
@ -29,6 +30,12 @@ union DataRefImpl {
|
||||
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.
|
||||
|
@ -556,10 +556,11 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
|
||||
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.
|
||||
@ -623,7 +624,6 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
|
||||
TypesDWOSections[Section].Data = data;
|
||||
}
|
||||
|
||||
section_iterator RelocatedSection = Section.getRelocatedSection();
|
||||
if (RelocatedSection == Obj.section_end())
|
||||
continue;
|
||||
|
||||
@ -634,7 +634,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
|
||||
// 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(
|
||||
@ -704,7 +704,10 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
|
||||
// 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();
|
||||
}
|
||||
|
@ -122,14 +122,10 @@ static std::error_code getOffset(const SymbolRef &Sym, SectionRef Sec,
|
||||
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();
|
||||
@ -231,9 +227,10 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
||||
// 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.
|
||||
@ -818,10 +815,19 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
// 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;
|
||||
}
|
||||
|
@ -27,9 +27,8 @@ namespace {
|
||||
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 {
|
||||
@ -55,10 +54,7 @@ llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch,
|
||||
|
||||
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) {
|
||||
|
@ -107,9 +107,8 @@ void DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef,
|
||||
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;
|
||||
@ -118,6 +117,7 @@ public:
|
||||
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;
|
||||
@ -127,6 +127,7 @@ createRTDyldELFObject(MemoryBufferRef Buffer,
|
||||
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);
|
||||
@ -135,12 +136,13 @@ createRTDyldELFObject(MemoryBufferRef Buffer,
|
||||
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;
|
||||
@ -158,16 +160,20 @@ OwningBinary<ObjectFile> createELFDebugObject(const ObjectFile &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");
|
||||
|
||||
@ -215,10 +221,7 @@ void RuntimeDyldELF::deregisterEHFrames() {
|
||||
|
||||
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,
|
||||
|
@ -378,7 +378,7 @@ protected:
|
||||
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,
|
||||
|
@ -29,9 +29,9 @@ namespace {
|
||||
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 {
|
||||
@ -334,10 +334,7 @@ RuntimeDyldMachO::create(Triple::ArchType Arch,
|
||||
|
||||
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
|
||||
|
@ -277,6 +277,7 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
|
||||
if (UseDebugObj) {
|
||||
DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
|
||||
SymbolObj = DebugObj.getBinary();
|
||||
LoadedObjInfo.release();
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,7 +309,7 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
|
||||
StringRef SecName;
|
||||
Sec->getName(SecName);
|
||||
uint64_t SectionLoadAddress =
|
||||
LoadedObjInfo->getSectionLoadAddress(SecName);
|
||||
LoadedObjInfo->getSectionLoadAddress(*Sec);
|
||||
if (SectionLoadAddress != 0)
|
||||
Addr += SectionLoadAddress - Sec->getAddress();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user