diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 85a58a3677181..12e1ae6281127 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1340,7 +1340,7 @@ void LinkerDriver::maybeCreateECExportThunk(StringRef name, Symbol *&sym) { if (!sym) return; if (auto undef = dyn_cast(sym)) - def = undef->getWeakAlias(); + def = undef->getDefinedWeakAlias(); else def = dyn_cast(sym); if (!def) @@ -1376,7 +1376,7 @@ void LinkerDriver::createECExportThunks() { continue; Defined *targetSym; if (auto undef = dyn_cast(sym)) - targetSym = undef->getWeakAlias(); + targetSym = undef->getDefinedWeakAlias(); else targetSym = dyn_cast(sym); if (!targetSym) diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index 567c2b93776c9..89f2da02bdcf4 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -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 weakChain; for (Symbol *a = weakAlias; a; a = cast(a)->weakAlias) { - if (auto *d = dyn_cast(a)) - return d; + if (!isa(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; diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 9b21e09bf83a4..a898ebf05fd80 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -340,7 +340,10 @@ class Undefined : public Symbol { // 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(getWeakAlias()); + } // If this symbol is external weak, replace this object with aliased symbol. bool resolveWeakAlias(); diff --git a/lld/test/COFF/weak-lazy.s b/lld/test/COFF/weak-lazy.s new file mode 100644 index 0000000000000..2812ba7af8b5f --- /dev/null +++ b/lld/test/COFF/weak-lazy.s @@ -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