forked from OSchip/llvm-project
[RuntimeDyld] Track symbol visibility in RuntimeDyld.
RuntimeDyld symbol info previously consisted of just a Section/Offset pair. This patch replaces that pair type with a SymbolInfo class that also tracks symbol visibility. A new method, RuntimeDyld::getExportedSymbolLoadAddress, is introduced which only returns a non-zero result for exported symbols. For non-exported or non-existant symbols this method will return zero. The RuntimeDyld::getSymbolAddress method retains its current behavior, returning non-zero results for all symbols regardless of visibility. No in-tree clients of RuntimeDyld are changed. The newly introduced functionality will be used by the Orc APIs. No test case: Since this patch doesn't modify the behavior for any in-tree clients we don't have a good tool to test this with yet. Once Orc is in we can use it to write regression tests that test these changes. llvm-svn: 226341
This commit is contained in:
parent
cb0d13fc23
commit
6bfd398022
|
@ -81,10 +81,14 @@ public:
|
|||
/// and resolve relocatons based on where they put it).
|
||||
void *getSymbolAddress(StringRef Name) const;
|
||||
|
||||
/// Get the address of the target copy of the symbol. This is the address
|
||||
/// used for relocation.
|
||||
/// Get the address of the target copy of the symbol (works for both exported
|
||||
/// and non-exported symbols). This is the address used for relocation.
|
||||
uint64_t getSymbolLoadAddress(StringRef Name) const;
|
||||
|
||||
/// Get the address of the target copy of the symbol (works for exported
|
||||
/// symbols only). This is the address used for relocation.
|
||||
uint64_t getExportedSymbolLoadAddress(StringRef Name) const;
|
||||
|
||||
/// Resolve the relocations for all symbols we currently know about.
|
||||
void resolveRelocations();
|
||||
|
||||
|
|
|
@ -200,9 +200,14 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
|||
bool IsCode = SI->isText();
|
||||
unsigned SectionID =
|
||||
findOrEmitSection(Obj, *SI, IsCode, LocalSections);
|
||||
DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset)
|
||||
<< " flags: " << Flags << " SID: " << SectionID);
|
||||
GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
|
||||
DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
|
||||
<< " SID: " << SectionID << " Offset: "
|
||||
<< format("%p", (uintptr_t)SectOffset)
|
||||
<< " flags: " << Flags << "\n");
|
||||
SymbolInfo::Visibility Vis =
|
||||
(Flags & SymbolRef::SF_Exported) ?
|
||||
SymbolInfo::Default : SymbolInfo::Hidden;
|
||||
GlobalSymbolTable[Name] = {SectionID, SectOffset, Vis};
|
||||
}
|
||||
}
|
||||
DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
|
||||
|
@ -444,7 +449,7 @@ void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst,
|
|||
void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
|
||||
const CommonSymbolMap &CommonSymbols,
|
||||
uint64_t TotalSize,
|
||||
SymbolTableMap &SymbolTable) {
|
||||
RTDyldSymbolTable &SymbolTable) {
|
||||
// Allocate memory for the section
|
||||
unsigned SectionID = Sections.size();
|
||||
uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void *),
|
||||
|
@ -473,7 +478,11 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
|
|||
DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
|
||||
<< format("%p\n", Addr));
|
||||
}
|
||||
SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset);
|
||||
uint32_t Flags = it->first.getFlags();
|
||||
SymbolInfo::Visibility Vis =
|
||||
(Flags & SymbolRef::SF_Exported) ?
|
||||
SymbolInfo::Default : SymbolInfo::Hidden;
|
||||
SymbolTable[Name.data()] = {SectionID, Offset, Vis};
|
||||
Offset += Size;
|
||||
Addr += Size;
|
||||
}
|
||||
|
@ -589,14 +598,15 @@ void RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE,
|
|||
// Relocation by symbol. If the symbol is found in the global symbol table,
|
||||
// create an appropriate section relocation. Otherwise, add it to
|
||||
// ExternalSymbolRelocations.
|
||||
SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(SymbolName);
|
||||
RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(SymbolName);
|
||||
if (Loc == GlobalSymbolTable.end()) {
|
||||
ExternalSymbolRelocations[SymbolName].push_back(RE);
|
||||
} else {
|
||||
// Copy the RE since we want to modify its addend.
|
||||
RelocationEntry RECopy = RE;
|
||||
RECopy.Addend += Loc->second.second;
|
||||
Relocations[Loc->second.first].push_back(RECopy);
|
||||
const auto &SymInfo = Loc->second;
|
||||
RECopy.Addend += SymInfo.getOffset();
|
||||
Relocations[SymInfo.getSectionID()].push_back(RECopy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -721,7 +731,7 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
|
|||
resolveRelocationList(Relocs, 0);
|
||||
} else {
|
||||
uint64_t Addr = 0;
|
||||
SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name);
|
||||
RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(Name);
|
||||
if (Loc == GlobalSymbolTable.end()) {
|
||||
// This is an external symbol, try to get its address from
|
||||
// MemoryManager.
|
||||
|
@ -736,8 +746,9 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
|
|||
} else {
|
||||
// We found the symbol in our global table. It was probably in a
|
||||
// Module that we loaded previously.
|
||||
SymbolLoc SymLoc = Loc->second;
|
||||
Addr = getSectionLoadAddress(SymLoc.first) + SymLoc.second;
|
||||
const auto &SymInfo = Loc->second;
|
||||
Addr = getSectionLoadAddress(SymInfo.getSectionID()) +
|
||||
SymInfo.getOffset();
|
||||
}
|
||||
|
||||
// FIXME: Implement error handling that doesn't kill the host program!
|
||||
|
@ -834,6 +845,12 @@ uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) const {
|
|||
return Dyld->getSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
uint64_t RuntimeDyld::getExportedSymbolLoadAddress(StringRef Name) const {
|
||||
if (!Dyld)
|
||||
return 0;
|
||||
return Dyld->getExportedSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
|
||||
|
||||
void RuntimeDyld::reassignSectionAddress(unsigned SectionID, uint64_t Addr) {
|
||||
|
|
|
@ -850,14 +850,16 @@ std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
|
|||
|
||||
StringRef
|
||||
RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
|
||||
RuntimeDyldImpl::SymbolTableMap::const_iterator pos =
|
||||
RTDyldSymbolTable::const_iterator pos =
|
||||
getRTDyld().GlobalSymbolTable.find(Name);
|
||||
if (pos == getRTDyld().GlobalSymbolTable.end())
|
||||
return StringRef();
|
||||
RuntimeDyldImpl::SymbolLoc Loc = pos->second;
|
||||
uint8_t *SectionAddr = getRTDyld().getSectionAddress(Loc.first);
|
||||
return StringRef(reinterpret_cast<const char *>(SectionAddr) + Loc.second,
|
||||
getRTDyld().Sections[Loc.first].Size - Loc.second);
|
||||
const auto &SymInfo = pos->second;
|
||||
uint8_t *SectionAddr = getRTDyld().getSectionAddress(SymInfo.getSectionID());
|
||||
return StringRef(reinterpret_cast<const char *>(SectionAddr) +
|
||||
SymInfo.getOffset(),
|
||||
getRTDyld().Sections[SymInfo.getSectionID()].Size -
|
||||
SymInfo.getOffset());
|
||||
}
|
||||
|
||||
void RuntimeDyldCheckerImpl::registerSection(
|
||||
|
@ -887,9 +889,10 @@ void RuntimeDyldCheckerImpl::registerStubMap(
|
|||
// If this is a (Section, Offset) pair, do a reverse lookup in the
|
||||
// global symbol table to find the name.
|
||||
for (auto &GSTEntry : getRTDyld().GlobalSymbolTable) {
|
||||
if (GSTEntry.second.first == StubMapEntry.first.SectionID &&
|
||||
GSTEntry.second.second ==
|
||||
static_cast<uint64_t>(StubMapEntry.first.Offset)) {
|
||||
const auto &SymInfo = GSTEntry.second;
|
||||
if (SymInfo.getSectionID() == StubMapEntry.first.SectionID &&
|
||||
SymInfo.getOffset() ==
|
||||
static_cast<uint64_t>(StubMapEntry.first.Offset)) {
|
||||
SymbolName = GSTEntry.first();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -920,15 +920,16 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
|
|||
SymbolRef::Type SymType = SymbolRef::ST_Unknown;
|
||||
|
||||
// Search for the symbol in the global symbol table
|
||||
SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end();
|
||||
RTDyldSymbolTable::const_iterator gsi = GlobalSymbolTable.end();
|
||||
if (Symbol != Obj.symbol_end()) {
|
||||
gsi = GlobalSymbolTable.find(TargetName.data());
|
||||
Symbol->getType(SymType);
|
||||
}
|
||||
if (gsi != GlobalSymbolTable.end()) {
|
||||
Value.SectionID = gsi->second.first;
|
||||
Value.Offset = gsi->second.second;
|
||||
Value.Addend = gsi->second.second + Addend;
|
||||
const auto &SymInfo = gsi->second;
|
||||
Value.SectionID = SymInfo.getSectionID();
|
||||
Value.Offset = SymInfo.getOffset();
|
||||
Value.Addend = SymInfo.getOffset() + Addend;
|
||||
} else {
|
||||
switch (SymType) {
|
||||
case SymbolRef::ST_Debug: {
|
||||
|
|
|
@ -156,6 +156,28 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// @brief Symbol info for RuntimeDyld.
|
||||
class SymbolInfo {
|
||||
public:
|
||||
typedef enum { Hidden = 0, Default = 1 } Visibility;
|
||||
|
||||
SymbolInfo() : Offset(0), SectionID(0), Vis(Hidden) {}
|
||||
|
||||
SymbolInfo(unsigned SectionID, uint64_t Offset, Visibility Vis)
|
||||
: Offset(Offset), SectionID(SectionID), Vis(Vis) {}
|
||||
|
||||
unsigned getSectionID() const { return SectionID; }
|
||||
uint64_t getOffset() const { return Offset; }
|
||||
Visibility getVisibility() const { return Vis; }
|
||||
|
||||
private:
|
||||
uint64_t Offset;
|
||||
unsigned SectionID : 31;
|
||||
Visibility Vis : 1;
|
||||
};
|
||||
|
||||
typedef StringMap<SymbolInfo> RTDyldSymbolTable;
|
||||
|
||||
class RuntimeDyldImpl {
|
||||
friend class RuntimeDyld::LoadedObjectInfo;
|
||||
friend class RuntimeDyldCheckerImpl;
|
||||
|
@ -178,11 +200,8 @@ protected:
|
|||
// references it.
|
||||
typedef std::map<SectionRef, unsigned> ObjSectionToIDMap;
|
||||
|
||||
// A global symbol table for symbols from all loaded modules. Maps the
|
||||
// symbol name to a (SectionID, offset in section) pair.
|
||||
typedef std::pair<unsigned, uintptr_t> SymbolLoc;
|
||||
typedef StringMap<SymbolLoc> SymbolTableMap;
|
||||
SymbolTableMap GlobalSymbolTable;
|
||||
// A global symbol table for symbols from all loaded modules.
|
||||
RTDyldSymbolTable GlobalSymbolTable;
|
||||
|
||||
// Pair representing the size and alignment requirement for a common symbol.
|
||||
typedef std::pair<unsigned, unsigned> CommonSymbolInfo;
|
||||
|
@ -289,7 +308,7 @@ protected:
|
|||
/// symbol table.
|
||||
void emitCommonSymbols(const ObjectFile &Obj,
|
||||
const CommonSymbolMap &CommonSymbols,
|
||||
uint64_t TotalSize, SymbolTableMap &SymbolTable);
|
||||
uint64_t TotalSize, RTDyldSymbolTable &SymbolTable);
|
||||
|
||||
/// \brief Emits section data from the object file to the MemoryManager.
|
||||
/// \param IsCode if it's true then allocateCodeSection() will be
|
||||
|
@ -374,21 +393,31 @@ public:
|
|||
uint8_t* getSymbolAddress(StringRef Name) const {
|
||||
// FIXME: Just look up as a function for now. Overly simple of course.
|
||||
// Work in progress.
|
||||
SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
if (pos == GlobalSymbolTable.end())
|
||||
return nullptr;
|
||||
SymbolLoc Loc = pos->second;
|
||||
return getSectionAddress(Loc.first) + Loc.second;
|
||||
const auto &SymInfo = pos->second;
|
||||
return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
uint64_t getSymbolLoadAddress(StringRef Name) const {
|
||||
// FIXME: Just look up as a function for now. Overly simple of course.
|
||||
// Work in progress.
|
||||
SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
if (pos == GlobalSymbolTable.end())
|
||||
return 0;
|
||||
SymbolLoc Loc = pos->second;
|
||||
return getSectionLoadAddress(Loc.first) + Loc.second;
|
||||
const auto &SymInfo = pos->second;
|
||||
return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
uint64_t getExportedSymbolLoadAddress(StringRef Name) const {
|
||||
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
|
||||
if (pos == GlobalSymbolTable.end())
|
||||
return 0;
|
||||
const auto &SymInfo = pos->second;
|
||||
if (SymInfo.getVisibility() == SymbolInfo::Hidden)
|
||||
return 0;
|
||||
return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
|
||||
}
|
||||
|
||||
void resolveRelocations();
|
||||
|
|
|
@ -64,11 +64,12 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
|
|||
symbol_iterator Symbol = RI->getSymbol();
|
||||
StringRef TargetName;
|
||||
Symbol->getName(TargetName);
|
||||
SymbolTableMap::const_iterator SI =
|
||||
RTDyldSymbolTable::const_iterator SI =
|
||||
GlobalSymbolTable.find(TargetName.data());
|
||||
if (SI != GlobalSymbolTable.end()) {
|
||||
Value.SectionID = SI->second.first;
|
||||
Value.Offset = SI->second.second + RE.Addend;
|
||||
const auto &SymInfo = SI->second;
|
||||
Value.SectionID = SymInfo.getSectionID();
|
||||
Value.Offset = SymInfo.getOffset() + RE.Addend;
|
||||
} else {
|
||||
Value.SymbolName = TargetName.data();
|
||||
Value.Offset = RE.Addend;
|
||||
|
|
Loading…
Reference in New Issue