Index: llvm/lib/ExecutionEngine/Orc/Layer.cpp =================================================================== --- llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -77,6 +77,9 @@ // Otherwise we just need a normal linker mangling. auto MangledName = Mangle(G.getName()); SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); + if (G.getComdat() && + G.getComdat()->getSelectionKind() != Comdat::NoDeduplicate) + SymbolFlags[MangledName] |= JITSymbolFlags::Weak; SymbolToDefinition[MangledName] = &G; } Index: llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp =================================================================== --- llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -259,6 +259,48 @@ if (COFFSec.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT) I->second.setFlags(I->second.getFlags() | JITSymbolFlags::Weak); } + + // Handle any aliases. + for (auto &Sym : COFFObj->symbols()) { + uint32_t SymFlags = cantFail(Sym.getFlags()); + if (SymFlags & object::BasicSymbolRef::SF_Undefined) + continue; + auto Name = Sym.getName(); + if (!Name) + return Name.takeError(); + auto I = Resolved.find(*Name); + + // Skip already-resolved symbols, and symbols that we're not responsible + // for. + if (I != Resolved.end() || !R.getSymbols().count(ES.intern(*Name))) + continue; + + // Skip anything other than weak externals. + auto COFFSym = COFFObj->getCOFFSymbol(Sym); + if (!COFFSym.isWeakExternal()) + continue; + auto *WeakExternal = COFFSym.getAux(); + if (WeakExternal->Characteristics != + COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS) + continue; + + // We found an alias. Reuse the resolution of the alias target for the + // alias itself. + Expected TargetSymbol = + COFFObj->getSymbol(WeakExternal->TagIndex); + if (!TargetSymbol) + return TargetSymbol.takeError(); + Expected TargetName = + COFFObj->getSymbolName(*TargetSymbol); + if (!TargetName) + return TargetName.takeError(); + auto J = Resolved.find(*TargetName); + if (J == Resolved.end()) + return make_error("Could alias target " + *TargetName + + " not resolved", + inconvertibleErrorCode()); + Resolved[*Name] = J->second; + } } for (auto &KV : Resolved) { Index: llvm/test/ExecutionEngine/OrcLazy/Inputs/comdat-functions.ll =================================================================== --- /dev/null +++ llvm/test/ExecutionEngine/OrcLazy/Inputs/comdat-functions.ll @@ -0,0 +1,6 @@ +$baz = comdat any + +define i32 @baz() comdat { +entry: + ret i32 0 +} Index: llvm/test/ExecutionEngine/OrcLazy/comdat-functions.ll =================================================================== --- /dev/null +++ llvm/test/ExecutionEngine/OrcLazy/comdat-functions.ll @@ -0,0 +1,16 @@ +; REQUIRES: system-windows +; RUN: lli -jit-kind=orc-lazy -extra-module %p/Inputs/comdat-functions.ll %s +; Check if crashing comdat any functions are not causing duplicate symbol error. + +$baz = comdat any + +define i32 @baz() comdat { +entry: + ret i32 0 +} + +define i32 @main(i32 %argc, i8** %argv) { +entry: + %call = tail call i32 @baz() + ret i32 %call +}