Symbol(Addressable &Base, orc::ExecutorAddrDiff Offset, StringRef Name,
orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive,
bool IsCallable)
- : Name(Name), Base(&Base), Offset(Offset), Size(Size) {
+ : Name(Name), Base(&Base), Offset(Offset), WeakRef(0), Size(Size) {
assert(Offset <= MaxOffset && "Offset out of range");
setLinkage(L);
setScope(S);
static Symbol &constructExternal(BumpPtrAllocator &Allocator,
Addressable &Base, StringRef Name,
- orc::ExecutorAddrDiff Size, Linkage L) {
+ orc::ExecutorAddrDiff Size, Linkage L,
+ bool WeaklyReferenced) {
assert(!Base.isDefined() &&
"Cannot create external symbol from defined block");
assert(!Name.empty() && "External symbol name cannot be empty");
auto *Sym = Allocator.Allocate<Symbol>();
new (Sym) Symbol(Base, 0, Name, Size, L, Scope::Default, false, false);
+ Sym->setWeaklyReferenced(WeaklyReferenced);
return *Sym;
}
this->S = static_cast<uint8_t>(S);
}
+ /// Returns true if this is a weakly referenced external symbol.
+ /// This method may only be called on external symbols.
+ bool isWeaklyReferenced() const {
+ assert(isExternal() && "isWeaklyReferenced called on non-external");
+ return WeakRef;
+ }
+
+ /// Set the WeaklyReferenced value for this symbol.
+ /// This method may only be called on external symbols.
+ void setWeaklyReferenced(bool WeakRef) {
+ assert(isExternal() && "setWeaklyReferenced called on non-external");
+ this->WeakRef = WeakRef;
+ }
+
private:
void makeExternal(Addressable &A) {
assert(!A.isDefined() && !A.isAbsolute() &&
// FIXME: A char* or SymbolStringPtr may pack better.
StringRef Name;
Addressable *Base = nullptr;
- uint64_t Offset : 59;
+ uint64_t Offset : 58;
uint64_t L : 1;
uint64_t S : 2;
uint64_t IsLive : 1;
uint64_t IsCallable : 1;
+ uint64_t WeakRef : 1;
size_t Size = 0;
};
/// Add an external symbol.
/// Some formats (e.g. ELF) allow Symbols to have sizes. For Symbols whose
/// size is not known, you should substitute '0'.
- /// For external symbols Linkage determines whether the symbol must be
- /// present during lookup: Externals with strong linkage must be found or
- /// an error will be emitted. Externals with weak linkage are permitted to
- /// be undefined, in which case they are assigned a value of 0.
+ /// The IsWeaklyReferenced argument determines whether the symbol must be
+ /// present during lookup: Externals that are strongly referenced must be
+ /// found or an error will be emitted. Externals that are weakly referenced
+ /// are permitted to be undefined, in which case they are assigned an address
+ /// of 0.
Symbol &addExternalSymbol(StringRef Name, orc::ExecutorAddrDiff Size,
- Linkage L) {
+ bool IsWeaklyReferenced) {
assert(llvm::count_if(ExternalSymbols,
[&](const Symbol *Sym) {
return Sym->getName() == Name;
"Duplicate external symbol");
auto &Sym = Symbol::constructExternal(
Allocator, createAddressable(orc::ExecutorAddr(), false), Name, Size,
- L);
+ Linkage::Strong, IsWeaklyReferenced);
ExternalSymbols.insert(&Sym);
return Sym;
}
case COFF_OPT_incl: {
auto DataCopy = G->allocateString(S);
StringRef StrCopy(DataCopy.data(), DataCopy.size());
- ExternalSymbols[StrCopy] =
- &G->addExternalSymbol(StrCopy, 0, Linkage::Strong);
+ ExternalSymbols[StrCopy] = &G->addExternalSymbol(StrCopy, 0, false);
ExternalSymbols[StrCopy]->setLive(true);
break;
}
object::COFFSymbolRef Symbol, const object::coff_section *Section) {
if (!ExternalSymbols.count(SymbolName))
ExternalSymbols[SymbolName] =
- &G->addExternalSymbol(SymbolName, Symbol.getValue(), Linkage::Strong);
+ &G->addExternalSymbol(SymbolName, Symbol.getValue(), false);
LLVM_DEBUG({
dbgs() << " " << SymIndex
continue;
}
- // Map Visibility and Binding to Scope and Linkage:
- Linkage L;
- Scope S;
-
- if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
- std::tie(L, S) = *LSOrErr;
- else
- return LSOrErr.takeError();
-
if (Sym.isDefined() &&
(Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
Sym.getType() == ELF::STT_OBJECT ||
Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
+
+ // Map Visibility and Binding to Scope and Linkage:
+ Linkage L;
+ Scope S;
+ if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
+ std::tie(L, S) = *LSOrErr;
+ else
+ return LSOrErr.takeError();
+
// Handle extended tables.
unsigned Shndx = Sym.st_shndx;
if (Shndx == ELF::SHN_XINDEX) {
<< ": Creating external graph symbol for ELF symbol \"" << *Name
<< "\"\n";
});
- auto &GSym = G->addExternalSymbol(*Name, Sym.st_size, L);
+
+ if (Sym.getBinding() != ELF::STB_GLOBAL &&
+ Sym.getBinding() != ELF::STB_WEAK)
+ return make_error<StringError>(
+ "Invalid symbol binding " +
+ Twine(static_cast<int>(Sym.getBinding())) +
+ " for external symbol " + *Name,
+ inconvertibleErrorCode());
+
+ if (Sym.getVisibility() != ELF::STV_DEFAULT)
+ return make_error<StringError>(
+ "Invalid symbol visibility " +
+ Twine(static_cast<int>(Sym.getVisibility())) +
+ " for external symbol " + *Name,
+ inconvertibleErrorCode());
+
+ // If L is Linkage::Weak that means this is a weakly referenced symbol.
+ auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
+ Sym.getBinding() == ELF::STB_WEAK);
setGraphSymbol(SymIndex, GSym);
} else {
LLVM_DEBUG({
Symbol &getTLSDescResolver(LinkGraph &G) {
if (!TLSDescResolver)
- TLSDescResolver =
- &G.addExternalSymbol("__tlsdesc_resolver", 8, Linkage::Strong);
+ TLSDescResolver = &G.addExternalSymbol("__tlsdesc_resolver", 8, false);
return *TLSDescResolver;
}
assert(Sym->getName() != StringRef() && Sym->getName() != "" &&
"Externals must be named");
SymbolLookupFlags LookupFlags =
- Sym->getLinkage() == Linkage::Weak
- ? SymbolLookupFlags::WeaklyReferencedSymbol
- : SymbolLookupFlags::RequiredSymbol;
+ Sym->isWeaklyReferenced() ? SymbolLookupFlags::WeaklyReferencedSymbol
+ : SymbolLookupFlags::RequiredSymbol;
UnresolvedExternals[Sym->getName()] = LookupFlags;
}
return UnresolvedExternals;
Sym->getAddressable().setAddress(
orc::ExecutorAddr(ResultI->second.getAddress()));
else
- assert(Sym->getLinkage() == Linkage::Weak &&
+ assert(Sym->isWeaklyReferenced() &&
"Failed to resolve non-weak reference");
}
"index " +
Twine(KV.first));
NSym.GraphSymbol = &G->addExternalSymbol(
- *NSym.Name, 0,
- NSym.Desc & MachO::N_WEAK_REF ? Linkage::Weak : Linkage::Strong);
+ *NSym.Name, 0, (NSym.Desc & MachO::N_WEAK_REF) != 0);
}
break;
case MachO::N_ABS: