[llvm] r355226 - [DWARF] Make -g with empty assembler source work better.

Paul Robinson via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 1 12:58:04 PST 2019


Author: probinson
Date: Fri Mar  1 12:58:04 2019
New Revision: 355226

URL: http://llvm.org/viewvc/llvm-project?rev=355226&view=rev
Log:
[DWARF] Make -g with empty assembler source work better.

This was sometimes causing clang or llvm-mc to crash, and in other
cases could emit a bogus DWARF line-table header. I did an interim
patch in r352541; this patch should be a cleaner and more complete
fix, and retains the test.

Addresses PR40538.

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

Modified:
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCDwarf.h
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCDwarf.cpp
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/test/MC/ELF/debug-prefix-map.s
    llvm/trunk/tools/llvm-mc/llvm-mc.cpp

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=355226&r1=355225&r2=355226&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Fri Mar  1 12:58:04 2019
@@ -594,6 +594,10 @@ namespace llvm {
       GenDwarfFileNumber = FileNumber;
     }
 
+    /// Specifies information about the "root file" for assembler clients
+    /// (e.g., llvm-mc). Assumes compilation dir etc. have been set up.
+    void setGenDwarfRootFile(StringRef FileName, StringRef Buffer);
+
     const SetVector<MCSection *> &getGenDwarfSectionSyms() {
       return SectionsForRanges;
     }

Modified: llvm/trunk/include/llvm/MC/MCDwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=355226&r1=355225&r2=355226&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCDwarf.h (original)
+++ llvm/trunk/include/llvm/MC/MCDwarf.h Fri Mar  1 12:58:04 2019
@@ -320,6 +320,8 @@ public:
 
   bool hasRootFile() const { return !Header.RootFile.Name.empty(); }
 
+  const MCDwarfFile &getRootFile() const { return Header.RootFile; }
+
   // Report whether MD5 usage has been consistent (all-or-none).
   bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
 

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=355226&r1=355225&r2=355226&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Fri Mar  1 12:58:04 2019
@@ -37,6 +37,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/raw_ostream.h"
@@ -565,6 +566,29 @@ void MCContext::RemapDebugPaths() {
 // Dwarf Management
 //===----------------------------------------------------------------------===//
 
+void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
+  // MCDwarf needs the root file as well as the compilation directory.
+  // If we find a '.file 0' directive that will supersede these values.
+  MD5::MD5Result *Cksum = nullptr;
+  if (getDwarfVersion() >= 5) {
+    MD5 Hash;
+    Cksum = (MD5::MD5Result *)allocate(sizeof(MD5::MD5Result), 1);
+    Hash.update(Buffer);
+    Hash.final(*Cksum);
+  }
+  // Canonicalize the root filename. It cannot be empty, and should not
+  // repeat the compilation dir.
+  StringRef FileName =
+      !getMainFileName().empty() ? StringRef(getMainFileName()) : InputFileName;
+  if (FileName.empty() || FileName == "-")
+    FileName = "<stdin>";
+  if (FileName.consume_front(getCompilationDir()))
+    FileName.consume_front(llvm::sys::path::get_separator());
+  assert(!FileName.empty());
+  setMCLineTableRootFile(
+      /*CUID=*/0, getCompilationDir(), FileName, Cksum, None);
+}
+
 /// getDwarfFile - takes a file name and number to place in the dwarf file and
 /// directory tables.  If the file number has already been allocated it is an
 /// error and zero is returned and the client reports the error, else the

Modified: llvm/trunk/lib/MC/MCDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=355226&r1=355225&r2=355226&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDwarf.cpp (original)
+++ llvm/trunk/lib/MC/MCDwarf.cpp Fri Mar  1 12:58:04 2019
@@ -430,10 +430,14 @@ void MCDwarfLineTableHeader::emitV5FileD
                                       : dwarf::DW_FORM_string);
   }
   // Then the counted list of files. The root file is file #0, then emit the
-  // files as provide by .file directives.  To accommodate assembler source
-  // written for DWARF v4 but trying to emit v5, if we didn't see a root file
-  // explicitly, replicate file #1.
-  MCOS->EmitULEB128IntValue(MCDwarfFiles.size());
+  // files as provide by .file directives.
+  // MCDwarfFiles has an unused element [0] so use size() not size()+1.
+  // But sometimes MCDwarfFiles is empty, in which case we still emit one file.
+  MCOS->EmitULEB128IntValue(MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size());
+  // To accommodate assembler source written for DWARF v4 but trying to emit
+  // v5: If we didn't see a root file explicitly, replicate file #1.
+  assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) &&
+         "No root file and no .file directives");
   emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
                      HasAllMD5, HasSource, LineStr);
   for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
@@ -1006,9 +1010,15 @@ static void EmitGenDwarfInfo(MCStreamer
     MCOS->EmitBytes(MCDwarfDirs[0]);
     MCOS->EmitBytes(sys::path::get_separator());
   }
-  const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
-    MCOS->getContext().getMCDwarfFiles();
-  MCOS->EmitBytes(MCDwarfFiles[1].Name);
+  const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles();
+  // MCDwarfFiles might be empty if we have an empty source file.
+  // If it's not empty, [0] is unused and [1] is the first actual file.
+  assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);
+  const MCDwarfFile &RootFile =
+      MCDwarfFiles.empty()
+          ? context.getMCDwarfLineTable(/*CUID=*/0).getRootFile()
+          : MCDwarfFiles[1];
+  MCOS->EmitBytes(RootFile.Name);
   MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
 
   // AT_comp_dir, the working directory the assembly was done in.

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=355226&r1=355225&r2=355226&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Fri Mar  1 12:58:04 2019
@@ -845,9 +845,13 @@ bool AsmParser::enabledGenDwarfForAssemb
   // If we haven't encountered any .file directives (which would imply that
   // the assembler source was produced with debug info already) then emit one
   // describing the assembler source file itself.
-  if (getContext().getGenDwarfFileNumber() == 0)
+  if (getContext().getGenDwarfFileNumber() == 0) {
+    const MCDwarfFile &RootFile =
+        getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
     getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
-        0, StringRef(), getContext().getMainFileName()));
+        /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name,
+        RootFile.Checksum, RootFile.Source));
+  }
   return true;
 }
 
@@ -900,9 +904,6 @@ bool AsmParser::Run(bool NoInitialTextSe
       eatToEndOfStatement();
   }
 
-  // Make sure we get proper DWARF even for empty files.
-  (void)enabledGenDwarfForAssembly();
-
   getTargetParser().onEndOfFile();
   printPendingErrors();
 

Modified: llvm/trunk/test/MC/ELF/debug-prefix-map.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/debug-prefix-map.s?rev=355226&r1=355225&r2=355226&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/debug-prefix-map.s (original)
+++ llvm/trunk/test/MC/ELF/debug-prefix-map.s Fri Mar  1 12:58:04 2019
@@ -20,6 +20,6 @@ f:
 // MAP: DW_AT_comp_dir [DW_FORM_string] ("src_root")
 // MAP: DW_AT_decl_file [DW_FORM_data4] ("src_root{{(/|\\)+}}src.s")
 
-// MAP_ABS: DW_AT_name [DW_FORM_string] ("{{(/|\\)+}}src_root{{(/|\\)+}}src.s")
+// MAP_ABS: DW_AT_name [DW_FORM_string] ("src.s")
 // MAP_ABS: DW_AT_comp_dir [DW_FORM_string] ("{{(/|\\)+}}src_root")
 // MAP_ABS: DW_AT_decl_file [DW_FORM_data4] ("{{(/|\\)+}}src_root{{(/|\\)+}}src.s")

Modified: llvm/trunk/tools/llvm-mc/llvm-mc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/llvm-mc.cpp?rev=355226&r1=355225&r2=355226&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mc/llvm-mc.cpp (original)
+++ llvm/trunk/tools/llvm-mc/llvm-mc.cpp Fri Mar  1 12:58:04 2019
@@ -401,18 +401,8 @@ int main(int argc, char **argv) {
   }
   if (!MainFileName.empty())
     Ctx.setMainFileName(MainFileName);
-  if (GenDwarfForAssembly && DwarfVersion >= 5) {
-    // DWARF v5 needs the root file as well as the compilation directory.
-    // If we find a '.file 0' directive that will supersede these values.
-    MD5 Hash;
-    MD5::MD5Result *Cksum =
-        (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1);
-    Hash.update(Buffer->getBuffer());
-    Hash.final(*Cksum);
-    Ctx.setMCLineTableRootFile(
-        /*CUID=*/0, Ctx.getCompilationDir(),
-        !MainFileName.empty() ? MainFileName : InputFilename, Cksum, None);
-  }
+  if (GenDwarfForAssembly)
+    Ctx.setGenDwarfRootFile(InputFilename, Buffer->getBuffer());
 
   // Package up features to be passed to target/subtarget
   std::string FeaturesStr;




More information about the llvm-commits mailing list