Support -fdebug-prefix-map in llvm-mc. This is useful to omit the
authorPaul Robinson <paul.robinson@sony.com>
Tue, 10 Jul 2018 14:41:54 +0000 (14:41 +0000)
committerPaul Robinson <paul.robinson@sony.com>
Tue, 10 Jul 2018 14:41:54 +0000 (14:41 +0000)
debug compilation dir when compiling assembly files with -g.
Part of PR38050.

Patch by Siddhartha Bagaria!

Differential Revision: https://reviews.llvm.org/D48988

llvm-svn: 336680

llvm/include/llvm/MC/MCContext.h
llvm/include/llvm/MC/MCDwarf.h
llvm/lib/MC/MCContext.cpp
llvm/lib/MC/MCDwarf.cpp
llvm/lib/MC/MCObjectStreamer.cpp
llvm/test/MC/ELF/debug-prefix-map.s [new file with mode: 0644]
llvm/tools/llvm-mc/llvm-mc.cpp

index bb33879..6fa36d0 100644 (file)
@@ -137,6 +137,9 @@ namespace llvm {
     /// The compilation directory to use for DW_AT_comp_dir.
     SmallString<128> CompilationDir;
 
+    /// Prefix replacement map for source file information.
+    std::map<const std::string, const std::string> DebugPrefixMap;
+
     /// The main file name if passed in explicitly.
     std::string MainFileName;
 
@@ -490,6 +493,21 @@ namespace llvm {
     /// Set the compilation directory for DW_AT_comp_dir
     void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
 
+    /// Get the debug prefix map.
+    const std::map<const std::string, const std::string> &
+    getDebugPrefixMap() const {
+      return DebugPrefixMap;
+    }
+
+    /// Add an entry to the debug prefix map.
+    void addDebugPrefixMapEntry(const std::string &From, const std::string &To);
+
+    // Remaps the given path in-place as per the debug prefix map.
+    void RemapDebugPath(std::string *Path);
+
+    // Remaps the compilation dir as per the debug prefix map.
+    void RemapCompilationDir();
+
     /// Get the main file name for use in error messages and debug
     /// info. This can be set to ensure we've got the correct file name
     /// after preprocessing or for -save-temps.
index 785f42d..e091452 100644 (file)
@@ -301,6 +301,8 @@ public:
                                FileNumber));
   }
 
+  void RemapDwarfDirs(MCContext &Context);
+
   void setRootFile(StringRef Directory, StringRef FileName,
                    MD5::MD5Result *Checksum, Optional<StringRef> Source) {
     Header.CompilationDir = Directory;
index e4f90f4..b601ab2 100644 (file)
@@ -535,6 +535,26 @@ MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
   return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
 }
 
+void MCContext::addDebugPrefixMapEntry(const std::string &From,
+                                       const std::string &To) {
+  DebugPrefixMap.insert(std::make_pair(From, To));
+}
+
+void MCContext::RemapDebugPath(std::string *Path) {
+  for (const auto &Entry : DebugPrefixMap)
+    if (StringRef(*Path).startswith(Entry.first)) {
+      std::string RemappedPath =
+          (Twine(Entry.second) + Path->substr(Entry.first.size())).str();
+      Path->swap(RemappedPath);
+    }
+}
+
+void MCContext::RemapCompilationDir() {
+  std::string CompDir = CompilationDir.str();
+  RemapDebugPath(&CompDir);
+  CompilationDir = CompDir;
+}
+
 //===----------------------------------------------------------------------===//
 // Dwarf Management
 //===----------------------------------------------------------------------===//
index 37e1263..1d33d99 100644 (file)
@@ -250,8 +250,11 @@ void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS,
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
 
   // Handle the rest of the Compile Units.
-  for (const auto &CUIDTablePair : LineTables)
-    CUIDTablePair.second.EmitCU(MCOS, Params, LineStr);
+  for (const auto &CUIDTablePair : LineTables) {
+    auto &LineTable = context.getMCDwarfLineTable(CUIDTablePair.first);
+    LineTable.RemapDwarfDirs(MCOS->getContext());
+    LineTable.EmitCU(MCOS, Params, LineStr);
+  }
 
   if (LineStr)
     LineStr->emitSection(MCOS);
@@ -394,13 +397,13 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
   if (LineStr) {
     // Record path strings, emit references here.
     LineStr->emitRef(MCOS, CompDir);
-    for (auto &Dir : MCDwarfDirs)
+    for (const auto &Dir : MCDwarfDirs)
       LineStr->emitRef(MCOS, Dir);
   } else {
     // The list of directory paths.  Compilation directory comes first.
     MCOS->EmitBytes(CompDir);
     MCOS->EmitBytes(StringRef("\0", 1));
-    for (auto &Dir : MCDwarfDirs) {
+    for (const auto &Dir : MCDwarfDirs) {
       MCOS->EmitBytes(Dir);                // The DirectoryName, and...
       MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
     }
@@ -631,6 +634,11 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
   return FileNumber;
 }
 
+void MCDwarfLineTable::RemapDwarfDirs(MCContext &Context) {
+  for (auto &Dir : Header.MCDwarfDirs)
+    Context.RemapDebugPath(&Dir);
+}
+
 /// Utility function to emit the encoding to a streamer.
 void MCDwarfLineAddr::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
                            int64_t LineDelta, uint64_t AddrDelta) {
index 432f4c2..8122af4 100644 (file)
@@ -661,6 +661,9 @@ void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
 }
 
 void MCObjectStreamer::FinishImpl() {
+  // Remap the compilation directory before emitting.
+  getContext().RemapCompilationDir();
+
   // If we are generating dwarf for assembly source files dump out the sections.
   if (getContext().getGenDwarfForAssembly())
     MCGenDwarfInfo::Emit(this);
diff --git a/llvm/test/MC/ELF/debug-prefix-map.s b/llvm/test/MC/ELF/debug-prefix-map.s
new file mode 100644 (file)
index 0000000..33c5b89
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: mkdir -p %t.foo
+// RUN: cp %s %t.foo/src.s
+// RUN: cd %t.foo
+
+// RUN: llvm-mc -triple=x86_64-linux-unknown -g src.s -filetype=obj -o out.o
+// RUN: llvm-dwarfdump -v -debug-info out.o | FileCheck --check-prefix=NO_MAP %s
+// RUN: llvm-mc -triple=x86_64-linux-unknown -g src.s -filetype=obj -o out.o -fdebug-prefix-map=%t.foo=src_root
+// RUN: llvm-dwarfdump -v -debug-info out.o | FileCheck --check-prefix=MAP --implicit-check-not ".foo" %s
+
+f:
+  nop
+
+// NO_MAP: DW_AT_comp_dir [DW_FORM_string] ("{{.*}}.foo")
+
+// MAP: DW_AT_name [DW_FORM_string] ("src.s")
+// MAP: DW_AT_comp_dir [DW_FORM_string] ("src_root")
+// MAP: DW_AT_decl_file [DW_FORM_data4] ("src_root/src.s")
index 9e69eee..f494d02 100644 (file)
@@ -152,6 +152,11 @@ static cl::opt<std::string>
 DebugCompilationDir("fdebug-compilation-dir",
                     cl::desc("Specifies the debug info's compilation dir"));
 
+static cl::list<std::string>
+DebugPrefixMap("fdebug-prefix-map",
+               cl::desc("Map file source paths in debug info"),
+               cl::value_desc("= separated key-value pairs"));
+
 static cl::opt<std::string>
 MainFileName("main-file-name",
              cl::desc("Specifies the name we should consider the input file"));
@@ -387,6 +392,10 @@ int main(int argc, char **argv) {
     if (!sys::fs::current_path(CWD))
       Ctx.setCompilationDir(CWD);
   }
+  for (const auto &Arg : DebugPrefixMap) {
+    const auto &KV = StringRef(Arg).split('=');
+    Ctx.addDebugPrefixMapEntry(KV.first, KV.second);
+  }
   if (!MainFileName.empty())
     Ctx.setMainFileName(MainFileName);
   if (GenDwarfForAssembly && DwarfVersion >= 5) {