[lld] r222773 - [PECOFF] Create an empty PDB file if debug option is enabled.

Rui Ueyama ruiu at google.com
Tue Nov 25 11:01:01 PST 2014


Author: ruiu
Date: Tue Nov 25 13:01:01 2014
New Revision: 222773

URL: http://llvm.org/viewvc/llvm-project?rev=222773&view=rev
Log:
[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.

Added:
    lld/trunk/lib/ReaderWriter/PECOFF/PDBPass.h
Modified:
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/Driver/WinLinkOptions.td
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=222773&r1=222772&r2=222773&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Tue Nov 25 13:01:01 2014
@@ -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;
 

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=222773&r1=222772&r2=222773&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Nov 25 13:01:01 2014
@@ -1180,6 +1180,7 @@ bool WinLinkDriver::parse(int argc, cons
       // 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, cons
       inputFiles.push_back(ctx.allocate(inputArg->getValue()));
       break;
 
+    case OPT_pdb:
+      ctx.setPDBFilePath(inputArg->getValue());
+      break;
+
     case OPT_lldmoduledeffile:
       ctx.setModuleDefinitionFile(inputArg->getValue());
       break;

Modified: lld/trunk/lib/Driver/WinLinkOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkOptions.td?rev=222773&r1=222772&r2=222773&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkOptions.td (original)
+++ lld/trunk/lib/Driver/WinLinkOptions.td Tue Nov 25 13:01:01 2014
@@ -39,6 +39,7 @@ def stub    : P<"stub", "Specify DOS stu
 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">;

Added: lld/trunk/lib/ReaderWriter/PECOFF/PDBPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PDBPass.h?rev=222773&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PDBPass.h (added)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PDBPass.h Tue Nov 25 13:01:01 2014
@@ -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

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=222773&r1=222772&r2=222773&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Tue Nov 25 13:01:01 2014
@@ -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(
   _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())));

Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=222773&r1=222772&r2=222773&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Tue Nov 25 13:01:01 2014
@@ -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());





More information about the llvm-commits mailing list