summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine/RuntimeDyld
diff options
context:
space:
mode:
authorKeno Fischer <kfischer@college.harvard.edu>2015-01-27 20:02:31 +0000
committerKeno Fischer <kfischer@college.harvard.edu>2015-01-27 20:02:31 +0000
commit88cc26811bdbd8055dd2cd84c89009c22adf4875 (patch)
treeac42a5aed96d2c6da4b86030211ed3d6c46dfe5c /llvm/lib/ExecutionEngine/RuntimeDyld
parent5f92a08fc051d921f75af0cab01ce6a5b255b9c4 (diff)
downloadbcm5719-llvm-88cc26811bdbd8055dd2cd84c89009c22adf4875.tar.gz
bcm5719-llvm-88cc26811bdbd8055dd2cd84c89009c22adf4875.zip
[ExecutionEngine] Add weak symbol support to RuntimeDyld
Support weak symbols by first looking up if there is an externally visible symbol we can find, and only if that fails using the one in the object file we're loading. Reviewed By: lhames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D6950 llvm-svn: 227228
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld')
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp28
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp1
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h3
3 files changed, 31 insertions, 1 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index fb53ba96055..81b8eb2238f 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -168,6 +168,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
uint32_t Flags = I->getFlags();
bool IsCommon = Flags & SymbolRef::SF_Common;
+ bool IsWeak = Flags & SymbolRef::SF_Weak;
if (IsCommon)
CommonSymbols.push_back(*I);
else {
@@ -188,6 +189,11 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
continue;
StringRef SectionData;
Check(SI->getContents(SectionData));
+ // TODO: It make make sense to delay emitting the section for weak
+ // symbols until they are actually required, but that's not possible
+ // currently, because we only know whether we will need the symbol
+ // in resolveRelocations, which happens after we have already finalized
+ // the Load.
bool IsCode = SI->isText();
unsigned SectionID =
findOrEmitSection(Obj, *SI, IsCode, LocalSections);
@@ -198,7 +204,11 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
SymbolInfo::Visibility Vis =
(Flags & SymbolRef::SF_Exported) ?
SymbolInfo::Default : SymbolInfo::Hidden;
- GlobalSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
+ if (!IsWeak) {
+ GlobalSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
+ } else {
+ WeakSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
+ }
}
}
}
@@ -768,6 +778,21 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
SymInfo.getOffset();
}
+ // If we didn't find the symbol yet, and it is present in the weak symbol
+ // table, the definition from this object file needs to be used, so emit
+ // it now
+ if (!Addr) {
+ RTDyldSymbolTable::const_iterator Loc = WeakSymbolTable.find(Name);
+ if (Loc != WeakSymbolTable.end()) {
+ SymbolInfo SymInfo = Loc->second;
+ Addr = getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
+ // Since the weak symbol is now, materialized, add it to the
+ // GlobalSymbolTable. If somebody later asks the ExecutionEngine
+ // for the address of this symbol that's where it'll look
+ GlobalSymbolTable[Name] = SymInfo;
+ }
+ }
+
// FIXME: Implement error handling that doesn't kill the host program!
if (!Addr)
report_fatal_error("Program used external function '" + Name +
@@ -784,6 +809,7 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
ExternalSymbolRelocations.erase(i);
}
+ WeakSymbolTable.clear();
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 0f3ca0f2f39..a01b063831a 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -947,6 +947,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
break;
}
case SymbolRef::ST_Data:
+ case SymbolRef::ST_Function:
case SymbolRef::ST_Unknown: {
Value.SymbolName = TargetName.data();
Value.Addend = Addend;
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index f37a9a768a2..69d6cf53034 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -203,6 +203,9 @@ protected:
// A global symbol table for symbols from all loaded modules.
RTDyldSymbolTable GlobalSymbolTable;
+ // Like the global symbol table but for weak symbols
+ RTDyldSymbolTable WeakSymbolTable;
+
// Keep a map of common symbols to their info pairs
typedef std::vector<SymbolRef> CommonSymbolList;
OpenPOWER on IntegriCloud