[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:
Lang Hames 2015-01-16 23:13:56 +00:00
parent cb0d13fc23
commit 6bfd398022
6 changed files with 95 additions and 40 deletions

View File

@ -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();

View File

@ -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) {

View File

@ -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;
}

View File

@ -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: {

View File

@ -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();

View File

@ -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;