diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/IR/Mangler.cpp | 10 |
3 files changed, 45 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 2a20c64e82c..87d91377dc9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1434,6 +1434,7 @@ bool AsmPrinter::doFinalization(Module &M) { // Emit /EXPORT: flags for each exported global as necessary. const auto &TLOF = getObjFileLowering(); std::string Flags; + for (const GlobalValue &GV : M.global_values()) { raw_string_ostream OS(Flags); TLOF.emitLinkerFlagsForGlobal(OS, &GV); @@ -1444,6 +1445,35 @@ bool AsmPrinter::doFinalization(Module &M) { } Flags.clear(); } + + // Emit /INCLUDE: flags for each used global as necessary. + if (const auto *LU = M.getNamedGlobal("llvm.used")) { + assert(LU->hasInitializer() && + "expected llvm.used to have an initializer"); + assert(isa<ArrayType>(LU->getValueType()) && + "expected llvm.used to be an array type"); + if (const auto *A = cast<ConstantArray>(LU->getInitializer())) { + for (const Value *Op : A->operands()) { + const auto *GV = + cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases()); + // Global symbols with internal linkage are not visible to the linker, + // and thus would cause an error when the linker tried to preserve the + // symbol due to the `/include:` directive. + if (GV->hasInternalLinkage()) + continue; + + raw_string_ostream OS(Flags); + TLOF.emitLinkerFlagsForUsed(OS, GV); + OS.flush(); + + if (!Flags.empty()) { + OutStreamer->SwitchSection(TLOF.getDrectveSection()); + OutStreamer->EmitBytes(Flags); + } + Flags.clear(); + } + } + } } // Allow the target to emit any magic that it wants at the end of the file, diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index bdc4bc0302b..0e90df901fd 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1250,6 +1250,11 @@ void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); } +void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed( + raw_ostream &OS, const GlobalValue *GV) const { + emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler()); +} + //===----------------------------------------------------------------------===// // Wasm //===----------------------------------------------------------------------===// diff --git a/llvm/lib/IR/Mangler.cpp b/llvm/lib/IR/Mangler.cpp index 03723bfd2dd..7adcc59f571 100644 --- a/llvm/lib/IR/Mangler.cpp +++ b/llvm/lib/IR/Mangler.cpp @@ -204,3 +204,13 @@ void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV, OS << ",data"; } } + +void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV, + const Triple &T, Mangler &M) { + if (!T.isKnownWindowsMSVCEnvironment()) + return; + + OS << " /INCLUDE:"; + M.getNameWithPrefix(OS, GV, false); +} + |