summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h3
-rw-r--r--llvm/include/llvm/LTO/LTO.h4
-rw-r--r--llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp61
-rw-r--r--llvm/lib/LTO/LTO.cpp30
4 files changed, 69 insertions, 29 deletions
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index cc71fa3918a..f2519af383b 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -171,6 +171,9 @@ public:
const GlobalValue *GV) const override;
};
+void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
+ const Triple &TT, Mangler &Mangler);
+
} // end namespace llvm
#endif
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index 57b5e50e40d..5886ed99171 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -25,6 +25,7 @@
#include "llvm/LTO/Config.h"
#include "llvm/Linker/IRMover.h"
#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/thread.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/IPO/FunctionImport.h"
@@ -226,6 +227,9 @@ public:
symbol_iterator(SymTab.symbols().end(), SymTab, this));
}
+ /// Returns linker options specified in the input file.
+ Expected<std::string> getLinkerOpts();
+
/// Returns the path to the InputFile.
StringRef getName() const;
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index eb2a28f574a..6d45add71dc 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -919,6 +919,37 @@ static int getSelectionForCOFF(const GlobalValue *GV) {
return 0;
}
+void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
+ const Triple &TT, Mangler &Mangler) {
+ if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
+ return;
+
+ if (TT.isKnownWindowsMSVCEnvironment())
+ OS << " /EXPORT:";
+ else
+ OS << " -export:";
+
+ if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
+ std::string Flag;
+ raw_string_ostream FlagOS(Flag);
+ Mangler.getNameWithPrefix(FlagOS, GV, false);
+ FlagOS.flush();
+ if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
+ OS << Flag.substr(1);
+ else
+ OS << Flag;
+ } else {
+ Mangler.getNameWithPrefix(OS, GV, false);
+ }
+
+ if (!GV->getValueType()->isFunctionTy()) {
+ if (TT.isKnownWindowsMSVCEnvironment())
+ OS << ",DATA";
+ else
+ OS << ",data";
+ }
+}
+
MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
int Selection = 0;
@@ -1122,33 +1153,5 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
raw_ostream &OS, const GlobalValue *GV) const {
- if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
- return;
-
- const Triple &TT = getTargetTriple();
-
- if (TT.isKnownWindowsMSVCEnvironment())
- OS << " /EXPORT:";
- else
- OS << " -export:";
-
- if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
- std::string Flag;
- raw_string_ostream FlagOS(Flag);
- getMangler().getNameWithPrefix(FlagOS, GV, false);
- FlagOS.flush();
- if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
- OS << Flag.substr(1);
- else
- OS << Flag;
- } else {
- getMangler().getNameWithPrefix(OS, GV, false);
- }
-
- if (!GV->getValueType()->isFunctionTy()) {
- if (TT.isKnownWindowsMSVCEnvironment())
- OS << ",DATA";
- else
- OS << ",data";
- }
+ emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
}
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 51b7e7d13c7..db0253161b8 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -17,12 +17,16 @@
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/Analysis.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/LTO/LTOBackend.h"
#include "llvm/Linker/IRMover.h"
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
@@ -291,6 +295,32 @@ Expected<int> InputFile::Symbol::getComdatIndex() const {
return -1;
}
+Expected<std::string> InputFile::getLinkerOpts() {
+ std::string LinkerOpts;
+ raw_string_ostream LOS(LinkerOpts);
+ // Extract linker options from module metadata.
+ for (InputModule &Mod : Mods) {
+ std::unique_ptr<Module> &M = Mod.Mod;
+ if (auto E = M->materializeMetadata())
+ return std::move(E);
+ if (Metadata *Val = M->getModuleFlag("Linker Options")) {
+ MDNode *LinkerOptions = cast<MDNode>(Val);
+ for (const MDOperand &MDOptions : LinkerOptions->operands())
+ for (const MDOperand &MDOption : cast<MDNode>(MDOptions)->operands())
+ LOS << " " << cast<MDString>(MDOption)->getString();
+ }
+ }
+
+ // Synthesize export flags for symbols with dllexport storage.
+ const Triple TT(Mods[0].Mod->getTargetTriple());
+ Mangler M;
+ for (const ModuleSymbolTable::Symbol &Sym : SymTab.symbols())
+ if (auto *GV = Sym.dyn_cast<GlobalValue*>())
+ emitLinkerFlagsForGlobalCOFF(LOS, GV, TT, M);
+ LOS.flush();
+ return LinkerOpts;
+}
+
StringRef InputFile::getName() const {
return Mods[0].BM.getModuleIdentifier();
}
OpenPOWER on IntegriCloud