summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-11-25 19:01:01 +0000
committerRui Ueyama <ruiu@google.com>2014-11-25 19:01:01 +0000
commit0d9a181d9d36523cadd6fb17d5465778541ea202 (patch)
tree6a0dbb9cd61f823fcbf191ddee7d4c0c8a5cd689
parentbda193edffea77f7262b041878d5a1d85c917700 (diff)
downloadbcm5719-llvm-0d9a181d9d36523cadd6fb17d5465778541ea202.tar.gz
bcm5719-llvm-0d9a181d9d36523cadd6fb17d5465778541ea202.zip
[PECOFF] Create an empty PDB file if debug option is enabled.
There are many build files in the wild that depend on the fact that link.exe produces a PDB file if /DEBUG option is given. They fail if the file is not created. This patch is to make LLD create an empty (dummy) file to satisfy such build targets. This doesn't do anything other than "touching" the file. If a target depends on the content of the PDB file, this workaround is no help, of course. Otherwise this patch should help build some stuff. llvm-svn: 222773
-rw-r--r--lld/include/lld/ReaderWriter/PECOFFLinkingContext.h16
-rw-r--r--lld/lib/Driver/WinLinkDriver.cpp5
-rw-r--r--lld/lib/Driver/WinLinkOptions.td2
-rw-r--r--lld/lib/ReaderWriter/PECOFF/PDBPass.h41
-rw-r--r--lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp19
-rw-r--r--lld/unittests/DriverTests/WinLinkDriverTest.cpp18
6 files changed, 90 insertions, 11 deletions
diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
index f521161a593..967b750727f 100644
--- a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
@@ -47,8 +47,8 @@ public:
_createManifest(true), _embedManifest(false), _manifestId(1),
_manifestUAC(true), _manifestLevel("'asInvoker'"),
_manifestUiAccess("'false'"), _isDll(false), _highEntropyVA(true),
- _requireSEH(false), _noSEH(false), _implib(""),
- _dosStub(llvm::makeArrayRef(DEFAULT_DOS_STUB)) {
+ _requireSEH(false), _noSEH(false), _implib(""), _debug(false),
+ _pdbFilePath(""), _dosStub(llvm::makeArrayRef(DEFAULT_DOS_STUB)) {
setDeadStripping(true);
}
@@ -231,6 +231,12 @@ public:
void setOutputImportLibraryPath(const std::string &val) { _implib = val; }
std::string getOutputImportLibraryPath() const;
+ void setDebug(bool val) { _debug = val; }
+ bool getDebug() { return _debug; }
+
+ void setPDBFilePath(StringRef str) { _pdbFilePath = str; }
+ std::string getPDBFilePath() const;
+
void addDelayLoadDLL(StringRef dll) {
_delayLoadDLLs.insert(dll.lower());
}
@@ -390,6 +396,12 @@ private:
// /IMPLIB command line option.
std::string _implib;
+ // True if /DEBUG is given.
+ bool _debug;
+
+ // PDB file output path. NB: this is dummy -- LLD just creates the empty file.
+ std::string _pdbFilePath;
+
// /DELAYLOAD option.
std::set<std::string> _delayLoadDLLs;
diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp
index a5c125fd24a..dc6cc79a9dc 100644
--- a/lld/lib/Driver/WinLinkDriver.cpp
+++ b/lld/lib/Driver/WinLinkDriver.cpp
@@ -1180,6 +1180,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
// any effect.
// TODO: This should disable dead stripping. Currently we can't do that
// because removal of associative sections depends on dead stripping.
+ ctx.setDebug(true);
break;
case OPT_verbose:
@@ -1267,6 +1268,10 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
inputFiles.push_back(ctx.allocate(inputArg->getValue()));
break;
+ case OPT_pdb:
+ ctx.setPDBFilePath(inputArg->getValue());
+ break;
+
case OPT_lldmoduledeffile:
ctx.setModuleDefinitionFile(inputArg->getValue());
break;
diff --git a/lld/lib/Driver/WinLinkOptions.td b/lld/lib/Driver/WinLinkOptions.td
index 7d82e3f664e..4a3b0d00103 100644
--- a/lld/lib/Driver/WinLinkOptions.td
+++ b/lld/lib/Driver/WinLinkOptions.td
@@ -39,6 +39,7 @@ def stub : P<"stub", "Specify DOS stub file">;
def opt : P<"opt", "Control optimizations">;
def implib : P<"implib", "Import library name">;
def delayload : P<"delayload", "Delay loaded DLL name">;
+def pdb : P<"pdb", "PDB file path">;
def manifest : F<"manifest">;
def manifest_colon : P<"manifest", "Create manifest file">;
@@ -110,7 +111,6 @@ def delay : QF<"delay">;
def errorreport : QF<"errorreport">;
def idlout : QF<"idlout">;
def ignore : QF<"ignore">;
-def pdb : QF<"pdb">;
def pdbaltpath : QF<"pdbaltpath">;
def tlbid : QF<"tlbid">;
def tlbout : QF<"tlbout">;
diff --git a/lld/lib/ReaderWriter/PECOFF/PDBPass.h b/lld/lib/ReaderWriter/PECOFF/PDBPass.h
new file mode 100644
index 00000000000..92199c9a952
--- /dev/null
+++ b/lld/lib/ReaderWriter/PECOFF/PDBPass.h
@@ -0,0 +1,41 @@
+//===- lib/ReaderWriter/PECOFF/PDBPass.h ----------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_PE_COFF_PDB_PASS_H
+#define LLD_READER_WRITER_PE_COFF_PDB_PASS_H
+
+#include "lld/Core/Pass.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace lld {
+namespace pecoff {
+
+class PDBPass : public lld::Pass {
+public:
+ PDBPass(PECOFFLinkingContext &ctx) : _ctx(ctx) {}
+
+ void perform(std::unique_ptr<MutableFile> &file) override {
+ if (_ctx.getDebug())
+ touch(_ctx.getPDBFilePath());
+ }
+
+private:
+ void touch(StringRef path) {
+ int fd;
+ if (llvm::sys::fs::openFileForWrite(path, fd, llvm::sys::fs::F_Append))
+ llvm::report_fatal_error("failed to create a PDB file");
+ }
+
+ PECOFFLinkingContext &_ctx;
+};
+
+} // namespace pecoff
+} // namespace lld
+
+#endif
diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
index 1e5962eaced..b8f8e39cdcd 100644
--- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
@@ -14,6 +14,7 @@
#include "InferSubsystemPass.h"
#include "LinkerGeneratedSymbolFile.h"
#include "LoadConfigPass.h"
+#include "PDBPass.h"
#include "lld/Core/PassManager.h"
#include "lld/Core/Simple.h"
#include "lld/Passes/LayoutPass.h"
@@ -274,15 +275,27 @@ void PECOFFLinkingContext::addDllExport(ExportDesc &desc) {
_dllExports.push_back(desc);
}
+static std::string replaceExtension(StringRef path, StringRef ext) {
+ SmallString<128> ss = path;
+ llvm::sys::path::replace_extension(ss, ext);
+ return ss.str();
+}
+
std::string PECOFFLinkingContext::getOutputImportLibraryPath() const {
if (!_implib.empty())
return _implib;
- SmallString<128> path = outputPath();
- llvm::sys::path::replace_extension(path, ".lib");
- return path.str();
+ return replaceExtension(outputPath(), ".lib");
+}
+
+std::string PECOFFLinkingContext::getPDBFilePath() const {
+ assert(_debug);
+ if (!_pdbFilePath.empty())
+ return _pdbFilePath;
+ return replaceExtension(outputPath(), ".pdb");
}
void PECOFFLinkingContext::addPasses(PassManager &pm) {
+ pm.add(std::unique_ptr<Pass>(new pecoff::PDBPass(*this)));
pm.add(std::unique_ptr<Pass>(new pecoff::EdataPass(*this)));
pm.add(std::unique_ptr<Pass>(new pecoff::IdataPass(*this)));
pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
diff --git a/lld/unittests/DriverTests/WinLinkDriverTest.cpp b/lld/unittests/DriverTests/WinLinkDriverTest.cpp
index 8b95a984943..26f0afa9186 100644
--- a/lld/unittests/DriverTests/WinLinkDriverTest.cpp
+++ b/lld/unittests/DriverTests/WinLinkDriverTest.cpp
@@ -546,8 +546,16 @@ TEST_F(WinLinkParserTest, SwapRunFromNet) {
}
TEST_F(WinLinkParserTest, Debug) {
- EXPECT_TRUE(parse("link.exe", "/debug", "a.out", nullptr));
+ EXPECT_TRUE(parse("link.exe", "/debug", "a.obj", nullptr));
EXPECT_TRUE(_context.deadStrip());
+ EXPECT_TRUE(_context.getDebug());
+ EXPECT_EQ("a.pdb", _context.getPDBFilePath());
+}
+
+TEST_F(WinLinkParserTest, PDB) {
+ EXPECT_TRUE(parse("link.exe", "/debug", "/pdb:foo.pdb", "a.obj", nullptr));
+ EXPECT_TRUE(_context.getDebug());
+ EXPECT_EQ("foo.pdb", _context.getPDBFilePath());
}
TEST_F(WinLinkParserTest, Fixed) {
@@ -690,10 +698,10 @@ TEST_F(WinLinkParserTest, Ignore) {
// compatibility with link.exe.
EXPECT_TRUE(parse("link.exe", "/nologo", "/errorreport:prompt",
"/incremental", "/incremental:no", "/delay:unload",
- "/disallowlib:foo", "/pdb:foo",
- "/pdbaltpath:bar", "/verbose", "/verbose:icf", "/wx",
- "/wx:no", "/tlbid:1", "/tlbout:foo", "/idlout:foo",
- "/ignore:4000", "/ignoreidl", "/implib:foo", "/safeseh",
+ "/disallowlib:foo", "/pdbaltpath:bar", "/verbose",
+ "/verbose:icf", "/wx", "/wx:no", "/tlbid:1",
+ "/tlbout:foo", "/idlout:foo", "/ignore:4000",
+ "/ignoreidl", "/implib:foo", "/safeseh",
"/safeseh:no", "/functionpadmin", "a.obj", nullptr));
EXPECT_EQ("", errorMessage());
EXPECT_EQ(3, inputFileCount());
OpenPOWER on IntegriCloud