From 263130d589e9f7b58bde8abe2b83b34fcc41fd22 Mon Sep 17 00:00:00 2001 From: Paul Robinson Date: Tue, 12 Jun 2018 16:09:03 +0000 Subject: [PATCH] [DWARFv5] llvm-mc -dwarf-version does not imply -g. Don't provide the assembler source as the "root file" unless the user asked to have debug info for the assembler source (with -g). If the source doesn't provide an explicit ".file 0" then (a) use the compilation directory as directory #0, and (b) use the file #1 info for file #0 also. Differential Revision: https://reviews.llvm.org/D48055 llvm-svn: 334512 --- include/llvm/MC/MCDwarf.h | 4 ++-- lib/MC/MCDwarf.cpp | 21 ++++++++++++++------- test/MC/ELF/debug-file-options.s | 16 +++++++--------- test/MC/ELF/debug-md5.s | 9 ++++----- test/MC/ELF/debug-source.s | 18 ++++++++---------- test/MC/ELF/dwarf-file0.s | 2 +- tools/llvm-mc/llvm-mc.cpp | 2 +- 7 files changed, 37 insertions(+), 35 deletions(-) diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 3b0d3db9760..432cb4b7a41 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -234,8 +234,8 @@ struct MCDwarfLineTableHeader { private: void emitV2FileDirTables(MCStreamer *MCOS) const; - void emitV5FileDirTables(MCStreamer *MCOS, - Optional &LineStr) const; + void emitV5FileDirTables(MCStreamer *MCOS, Optional &LineStr, + StringRef CtxCompilationDir) const; }; class MCDwarfDwoLineTable { diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 57823e419f7..9dbe211cd8e 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -378,7 +378,8 @@ static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, } void MCDwarfLineTableHeader::emitV5FileDirTables( - MCStreamer *MCOS, Optional &LineStr) const { + MCStreamer *MCOS, Optional &LineStr, + StringRef CtxCompilationDir) const { // The directory format, which is just a list of the directory paths. In a // non-split object, these are references to .debug_line_str; in a split // object, they are inline strings. @@ -387,14 +388,17 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp : dwarf::DW_FORM_string); MCOS->EmitULEB128IntValue(MCDwarfDirs.size() + 1); + // Try not to emit an empty compilation directory. + const StringRef &CompDir = + CompilationDir.empty() ? CtxCompilationDir : CompilationDir; if (LineStr) { // Record path strings, emit references here. - LineStr->emitRef(MCOS, CompilationDir); + LineStr->emitRef(MCOS, CompDir); for (auto &Dir : MCDwarfDirs) LineStr->emitRef(MCOS, Dir); } else { - // The list of directory paths. CompilationDir comes first. - MCOS->EmitBytes(CompilationDir); + // The list of directory paths. Compilation directory comes first. + MCOS->EmitBytes(CompDir); MCOS->EmitBytes(StringRef("\0", 1)); for (auto &Dir : MCDwarfDirs) { MCOS->EmitBytes(Dir); // The DirectoryName, and... @@ -426,9 +430,12 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( : 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. + // 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()); - emitOneV5FileEntry(MCOS, RootFile, HasMD5, HasSource, LineStr); + emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile, + HasMD5, HasSource, LineStr); for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasMD5, HasSource, LineStr); } @@ -501,7 +508,7 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, // Put out the directory and file tables. The formats vary depending on // the version. if (LineTableVersion >= 5) - emitV5FileDirTables(MCOS, LineStr); + emitV5FileDirTables(MCOS, LineStr, context.getCompilationDir()); else emitV2FileDirTables(MCOS); diff --git a/test/MC/ELF/debug-file-options.s b/test/MC/ELF/debug-file-options.s index dd1bdcf71f0..01bb58b01f2 100644 --- a/test/MC/ELF/debug-file-options.s +++ b/test/MC/ELF/debug-file-options.s @@ -16,15 +16,15 @@ # CHECK: include_directories[ 2] = .debug_line_str[0x[[DIR2:[0-9a-f]+]]] = "dir2" # CHECK-NOT: include_directories # CHECK: file_names[ 0]: -# CHECK-NEXT: name: .debug_line_str[0x[[FILE0:[0-9a-f]+]]] = "{{.+}}" -# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: name: .debug_line_str[0x[[FILE0:[0-9a-f]+]]] = "foo" +# CHECK-NEXT: dir_index: 1 # CHECK-NEXT: md5_checksum: -# CHECK-NEXT: source: .debug_line_str[0x[[FILE0SRC:[0-9a-f]+]]] = "" +# CHECK-NEXT: source: .debug_line_str[0x[[FILE0SRC:[0-9a-f]+]]] = "void foo() {}" # CHECK: file_names[ 1]: -# CHECK-NEXT: name: .debug_line_str[0x[[FILE1:[0-9a-f]+]]] = "foo" +# CHECK-NEXT: name: .debug_line_str[0x[[FILE0]]] = "foo" # CHECK-NEXT: dir_index: 1 # CHECK-NEXT: md5_checksum: ee87e05688663173cd6043a3a15bba6e -# CHECK-NEXT: source: .debug_line_str[0x[[FILE1SRC:[0-9a-f]+]]] = "void foo() {}" +# CHECK-NEXT: source: .debug_line_str[0x[[FILE0SRC]]] = "void foo() {}" # CHECK: file_names[ 2]: # CHECK-NEXT: name: .debug_line_str[0x[[FILE2:[0-9a-f]+]]] = "bar" # CHECK-NEXT: dir_index: 2 @@ -35,9 +35,7 @@ # CHECK-NEXT: 0x[[DIR0]]: "{{.+}}" # CHECK-NEXT: 0x[[DIR1]]: "dir1" # CHECK-NEXT: 0x[[DIR2]]: "dir2" -# CHECK-NEXT: 0x[[FILE0]]: "{{.+}}" -# CHECK-NEXT: 0x[[FILE0SRC]]: "" -# CHECK-NEXT: 0x[[FILE1]]: "foo" -# CHECK-NEXT: 0x[[FILE1SRC]]: "void foo() {}" +# CHECK-NEXT: 0x[[FILE0]]: "foo" +# CHECK-NEXT: 0x[[FILE0SRC]]: "void foo() {}" # CHECK-NEXT: 0x[[FILE2]]: "bar" # CHECK-NEXT: 0x[[FILE2SRC]]: "void bar() {}" diff --git a/test/MC/ELF/debug-md5.s b/test/MC/ELF/debug-md5.s index a9aaa2b961a..f5442f47154 100644 --- a/test/MC/ELF/debug-md5.s +++ b/test/MC/ELF/debug-md5.s @@ -14,10 +14,10 @@ # CHECK: include_directories[ 2] = .debug_line_str[0x[[DIR2:[0-9a-f]+]]] = "dir2" # CHECK-NOT: include_directories # CHECK: file_names[ 0]: -# CHECK-NEXT: name: .debug_line_str[0x[[FILE0:[0-9a-f]+]]] = "{{.+}}" -# CHECK-NEXT: dir_index: 0 +# CHECK-NEXT: name: .debug_line_str[0x[[FILE0:[0-9a-f]+]]] = "foo" +# CHECK-NEXT: dir_index: 1 # CHECK: file_names[ 1]: -# CHECK-NEXT: name: .debug_line_str[0x[[FILE1:[0-9a-f]+]]] = "foo" +# CHECK-NEXT: name: .debug_line_str[0x[[FILE0]]] = "foo" # CHECK-NEXT: dir_index: 1 # CHECK-NEXT: md5_checksum: 00112233445566778899aabbccddeeff # CHECK: file_names[ 2]: @@ -29,6 +29,5 @@ # CHECK-NEXT: 0x[[DIR0]]: "/tmp" # CHECK-NEXT: 0x[[DIR1]]: "dir1" # CHECK-NEXT: 0x[[DIR2]]: "dir2" -# CHECK-NEXT: 0x[[FILE0]]: "{{.+}}" -# CHECK-NEXT: 0x[[FILE1]]: "foo" +# CHECK-NEXT: 0x[[FILE0]]: "foo" # CHECK-NEXT: 0x[[FILE2]]: "bar" diff --git a/test/MC/ELF/debug-source.s b/test/MC/ELF/debug-source.s index 1cf39c7a9d2..9642e8fb69a 100644 --- a/test/MC/ELF/debug-source.s +++ b/test/MC/ELF/debug-source.s @@ -14,13 +14,13 @@ # CHECK: include_directories[ 2] = .debug_line_str[0x[[DIR2:[0-9a-f]+]]] = "dir2" # CHECK-NOT: include_directories # CHECK: file_names[ 0]: -# CHECK-NEXT: name: .debug_line_str[0x[[FILE0:[0-9a-f]+]]] = "{{.+}}" -# CHECK-NEXT: dir_index: 0 -# CHECK-NEXT: source: .debug_line_str[0x[[FILE0SRC:[0-9a-f]+]]] = "" -# CHECK: file_names[ 1]: -# CHECK-NEXT: name: .debug_line_str[0x[[FILE1:[0-9a-f]+]]] = "foo" +# CHECK-NEXT: name: .debug_line_str[0x[[FILE0:[0-9a-f]+]]] = "foo" # CHECK-NEXT: dir_index: 1 -# CHECK-NEXT: source: .debug_line_str[0x[[FILE1SRC:[0-9a-f]+]]] = "void foo() {}" +# CHECK-NEXT: source: .debug_line_str[0x[[FILE0SRC:[0-9a-f]+]]] = "void foo() {}" +# CHECK: file_names[ 1]: +# CHECK-NEXT: name: .debug_line_str[0x[[FILE0]]] = "foo" +# CHECK-NEXT: dir_index: 1 +# CHECK-NEXT: source: .debug_line_str[0x[[FILE0SRC]]] = "void foo() {}" # CHECK: file_names[ 2]: # CHECK-NEXT: name: .debug_line_str[0x[[FILE2:[0-9a-f]+]]] = "bar" # CHECK-NEXT: dir_index: 2 @@ -30,9 +30,7 @@ # CHECK-NEXT: 0x[[DIR0]]: "{{.+}}" # CHECK-NEXT: 0x[[DIR1]]: "dir1" # CHECK-NEXT: 0x[[DIR2]]: "dir2" -# CHECK-NEXT: 0x[[FILE0]]: "{{.+}}" -# CHECK-NEXT: 0x[[FILE0SRC]]: "" -# CHECK-NEXT: 0x[[FILE1]]: "foo" -# CHECK-NEXT: 0x[[FILE1SRC]]: "void foo() {}" +# CHECK-NEXT: 0x[[FILE0]]: "foo" +# CHECK-NEXT: 0x[[FILE0SRC]]: "void foo() {}" # CHECK-NEXT: 0x[[FILE2]]: "bar" # CHECK-NEXT: 0x[[FILE2SRC]]: "void bar()\n{\n}" diff --git a/test/MC/ELF/dwarf-file0.s b/test/MC/ELF/dwarf-file0.s index 707f113bc9a..49e120894e4 100644 --- a/test/MC/ELF/dwarf-file0.s +++ b/test/MC/ELF/dwarf-file0.s @@ -6,7 +6,7 @@ .file 0 "root.cpp" .file 1 "header.h" .file 2 "root.cpp" -# CHECK-5: include_directories[ 0] = "" +# CHECK-5: include_directories[ 0] = "{{.+}}" # CHECK-4-NOT: include_directories # CHECK-4-NOT: file_names[ 0] # CHECK-5: file_names[ 0]: diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 7b83c5e3e05..9e69eee32ad 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -389,7 +389,7 @@ int main(int argc, char **argv) { } if (!MainFileName.empty()) Ctx.setMainFileName(MainFileName); - if (DwarfVersion >= 5) { + 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;