mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:26:45 +00:00
[LLD][COFF] Fix handling of weak aliases referencing lazy symbols (#112243)
The assumption that a symbol is either `Defined` or `Undefined` is not always true for some cases. For example, `mangleMaybe` may create a weak alias to a lazy archive symbol.
This commit is contained in:
parent
34cdd67c85
commit
ba898dba48
@ -1340,7 +1340,7 @@ void LinkerDriver::maybeCreateECExportThunk(StringRef name, Symbol *&sym) {
|
||||
if (!sym)
|
||||
return;
|
||||
if (auto undef = dyn_cast<Undefined>(sym))
|
||||
def = undef->getWeakAlias();
|
||||
def = undef->getDefinedWeakAlias();
|
||||
else
|
||||
def = dyn_cast<Defined>(sym);
|
||||
if (!def)
|
||||
@ -1376,7 +1376,7 @@ void LinkerDriver::createECExportThunks() {
|
||||
continue;
|
||||
Defined *targetSym;
|
||||
if (auto undef = dyn_cast<Undefined>(sym))
|
||||
targetSym = undef->getWeakAlias();
|
||||
targetSym = undef->getDefinedWeakAlias();
|
||||
else
|
||||
targetSym = dyn_cast<Defined>(sym);
|
||||
if (!targetSym)
|
||||
|
@ -112,12 +112,12 @@ DefinedImportThunk::DefinedImportThunk(COFFLinkerContext &ctx, StringRef name,
|
||||
ImportThunkChunk *chunk)
|
||||
: Defined(DefinedImportThunkKind, name), wrappedSym(s), data(chunk) {}
|
||||
|
||||
Defined *Undefined::getWeakAlias() {
|
||||
Symbol *Undefined::getWeakAlias() {
|
||||
// A weak alias may be a weak alias to another symbol, so check recursively.
|
||||
DenseSet<Symbol *> weakChain;
|
||||
for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias) {
|
||||
if (auto *d = dyn_cast<Defined>(a))
|
||||
return d;
|
||||
if (!isa<Undefined>(a))
|
||||
return a;
|
||||
if (!weakChain.insert(a).second)
|
||||
break; // We have a cycle.
|
||||
}
|
||||
@ -125,7 +125,7 @@ Defined *Undefined::getWeakAlias() {
|
||||
}
|
||||
|
||||
bool Undefined::resolveWeakAlias() {
|
||||
Defined *d = getWeakAlias();
|
||||
Defined *d = getDefinedWeakAlias();
|
||||
if (!d)
|
||||
return false;
|
||||
|
||||
|
@ -340,7 +340,10 @@ public:
|
||||
// If this symbol is external weak, try to resolve it to a defined
|
||||
// symbol by searching the chain of fallback symbols. Returns the symbol if
|
||||
// successful, otherwise returns null.
|
||||
Defined *getWeakAlias();
|
||||
Symbol *getWeakAlias();
|
||||
Defined *getDefinedWeakAlias() {
|
||||
return dyn_cast_or_null<Defined>(getWeakAlias());
|
||||
}
|
||||
|
||||
// If this symbol is external weak, replace this object with aliased symbol.
|
||||
bool resolveWeakAlias();
|
||||
|
18
lld/test/COFF/weak-lazy.s
Normal file
18
lld/test/COFF/weak-lazy.s
Normal file
@ -0,0 +1,18 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=i686-windows %s -o %t.obj
|
||||
# RUN: llvm-lib -machine:x86 -out:%t-func.lib %t.obj
|
||||
|
||||
# -export:func creates a weak alias to a lazy symbol. Make sure we can handle that when processing -export:func2=func.
|
||||
# RUN: lld-link -dll -noentry -machine:x86 -out:%t.dll %t-func.lib -export:func -export:func2=func
|
||||
|
||||
.text
|
||||
.def @feat.00;
|
||||
.scl 3;
|
||||
.type 0;
|
||||
.endef
|
||||
.globl @feat.00
|
||||
.set @feat.00, 1
|
||||
.globl _func@0
|
||||
_func@0:
|
||||
retl
|
Loading…
x
Reference in New Issue
Block a user