COFF: handle /debugtype option
authorSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 8 Aug 2016 22:02:44 +0000 (22:02 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Mon, 8 Aug 2016 22:02:44 +0000 (22:02 +0000)
Add the support infrastructure for the /debugtype option which takes a comma
delimited list of debug info to generate. The defaults are based on other
options potentially (/driver or /profile). This sets up the infrastructure to
allow us to emit RSDS records to get "build id" equivalents on COFF (similar to
binutils).

llvm-svn: 278056

lld/COFF/Config.h
lld/COFF/Driver.cpp
lld/COFF/Options.td

index a5472e9..2bb6a98 100644 (file)
@@ -61,6 +61,13 @@ struct Export {
   }
 };
 
+enum class DebugType {
+  None  = 0x0,
+  CV    = 0x1,  /// CodeView
+  PData = 0x2,  /// Procedure Data
+  Fixup = 0x4,  /// Relocation Table
+};
+
 // Global configuration.
 struct Configuration {
   enum ManifestKind { SideBySide, Embed, No };
@@ -78,6 +85,7 @@ struct Configuration {
   bool Force = false;
   bool Debug = false;
   bool WriteSymtab = true;
+  unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
 
   // Symbols in this set are considered as live by the garbage collector.
   std::set<Undefined *> GCRoot;
index 9395568..ffd6936 100644 (file)
@@ -16,6 +16,7 @@
 #include "Writer.h"
 #include "lld/Driver/Driver.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/LibDriver/LibDriver.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -282,6 +283,28 @@ static std::string createResponseFile(const llvm::opt::InputArgList &Args,
   return Data.str();
 }
 
+static unsigned getDefaultDebugType(const llvm::opt::InputArgList &Args) {
+  unsigned DebugTypes = static_cast<unsigned>(DebugType::CV);
+  if (Args.hasArg(OPT_driver))
+    DebugTypes |= static_cast<unsigned>(DebugType::PData);
+  if (Args.hasArg(OPT_profile))
+    DebugTypes |= static_cast<unsigned>(DebugType::Fixup);
+  return DebugTypes;
+}
+
+static unsigned parseDebugType(StringRef Arg) {
+  llvm::SmallVector<StringRef, 3> Types;
+  Arg.split(Types, ',', /*KeepEmpty=*/false);
+
+  unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
+  for (StringRef Type : Types)
+    DebugTypes |= StringSwitch<unsigned>(Type.lower())
+                      .Case("cv", static_cast<unsigned>(DebugType::CV))
+                      .Case("pdata", static_cast<unsigned>(DebugType::PData))
+                      .Case("fixup", static_cast<unsigned>(DebugType::Fixup));
+  return DebugTypes;
+}
+
 void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
   // If the first command line argument is "/lib", link.exe acts like lib.exe.
   // We call our own implementation of lib.exe that understands bitcode files.
@@ -341,8 +364,13 @@ void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
     Config->Force = true;
 
   // Handle /debug
-  if (Args.hasArg(OPT_debug))
+  if (Args.hasArg(OPT_debug)) {
     Config->Debug = true;
+    Config->DebugTypes =
+        Args.hasArg(OPT_debugtype)
+            ? parseDebugType(Args.getLastArg(OPT_debugtype)->getValue())
+            : getDefaultDebugType(Args);
+  }
 
   // Handle /noentry
   if (Args.hasArg(OPT_noentry)) {
index 28c498b..3866993 100644 (file)
@@ -62,7 +62,9 @@ def deffile : Joined<["/", "-"], "def:">,
     HelpText<"Use module-definition file">;
 
 def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;
+def debugtype : P<"debugtype", "Debug Info Options">;
 def dll : F<"dll">, HelpText<"Create a DLL">;
+def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
 def nodefaultlib_all : F<"nodefaultlib">;
 def noentry : F<"noentry">;
 def profile : F<"profile">;