diff options
| author | Rui Ueyama <ruiu@google.com> | 2014-11-25 19:01:01 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2014-11-25 19:01:01 +0000 |
| commit | 0d9a181d9d36523cadd6fb17d5465778541ea202 (patch) | |
| tree | 6a0dbb9cd61f823fcbf191ddee7d4c0c8a5cd689 | |
| parent | bda193edffea77f7262b041878d5a1d85c917700 (diff) | |
| download | bcm5719-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.h | 16 | ||||
| -rw-r--r-- | lld/lib/Driver/WinLinkDriver.cpp | 5 | ||||
| -rw-r--r-- | lld/lib/Driver/WinLinkOptions.td | 2 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/PECOFF/PDBPass.h | 41 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp | 19 | ||||
| -rw-r--r-- | lld/unittests/DriverTests/WinLinkDriverTest.cpp | 18 |
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()); |

