summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/test/Misc/cc1as-asm-debug.s3
-rw-r--r--clang/tools/driver/cc1as_main.cpp11
-rw-r--r--llvm/include/llvm/MC/MCContext.h4
-rw-r--r--llvm/include/llvm/MC/MCDwarf.h2
-rw-r--r--llvm/lib/MC/MCContext.cpp24
-rw-r--r--llvm/lib/MC/MCDwarf.cpp24
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp11
-rw-r--r--llvm/test/MC/ELF/debug-prefix-map.s2
-rw-r--r--llvm/tools/llvm-mc/llvm-mc.cpp14
9 files changed, 68 insertions, 27 deletions
diff --git a/clang/test/Misc/cc1as-asm-debug.s b/clang/test/Misc/cc1as-asm-debug.s
index cd36cad6206..a613fbfaeb4 100644
--- a/clang/test/Misc/cc1as-asm-debug.s
+++ b/clang/test/Misc/cc1as-asm-debug.s
@@ -8,4 +8,5 @@
// CHECK: {{\.}}section .debug_info
// CHECK: {{\.}}section .debug_info
// CHECK-NOT: {{\.}}section
-// CHECK: .ascii "comment.s"
+// Look for this as a relative path.
+// CHECK: .ascii "{{[^\\/].*}}comment.s"
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index 0a38e355c7a..a234ba3fc1b 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -336,7 +336,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
SourceMgr SrcMgr;
// Tell SrcMgr about this buffer, which is what the parser will pick up.
- SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());
+ unsigned BufferIndex = SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());
// Record the location of the include directories so that the lexer can find
// it later.
@@ -393,12 +393,21 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
if (!Opts.DebugCompilationDir.empty())
Ctx.setCompilationDir(Opts.DebugCompilationDir);
+ else {
+ // If no compilation dir is set, try to use the current directory.
+ SmallString<128> CWD;
+ if (!sys::fs::current_path(CWD))
+ Ctx.setCompilationDir(CWD);
+ }
if (!Opts.DebugPrefixMap.empty())
for (const auto &KV : Opts.DebugPrefixMap)
Ctx.addDebugPrefixMapEntry(KV.first, KV.second);
if (!Opts.MainFileName.empty())
Ctx.setMainFileName(StringRef(Opts.MainFileName));
Ctx.setDwarfVersion(Opts.DwarfVersion);
+ if (Opts.GenDwarfForAssembly)
+ Ctx.setGenDwarfRootFile(Opts.InputFile,
+ SrcMgr.getMemoryBuffer(BufferIndex)->getBuffer());
// Build up the feature string from the target feature list.
std::string FS;
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index b964965cf47..c87df5a82ce 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -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;
}
diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index 8eaa1523fe8..991ad525f89 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -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(); }
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index d7f95df726f..7cf4e1da5ac 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -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
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 2cab55f15bc..2b5bb610536 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -430,10 +430,14 @@ 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. 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,
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.
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index a66a4eb29af..4b487825935 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -845,9 +845,13 @@ bool AsmParser::enabledGenDwarfForAssembly() {
// 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 NoInitialTextSection, bool NoFinalize) {
eatToEndOfStatement();
}
- // Make sure we get proper DWARF even for empty files.
- (void)enabledGenDwarfForAssembly();
-
getTargetParser().onEndOfFile();
printPendingErrors();
diff --git a/llvm/test/MC/ELF/debug-prefix-map.s b/llvm/test/MC/ELF/debug-prefix-map.s
index 4d56b8816c6..9fe4c9bf176 100644
--- a/llvm/test/MC/ELF/debug-prefix-map.s
+++ b/llvm/test/MC/ELF/debug-prefix-map.s
@@ -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")
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index af19a64d37d..ec189c29786 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -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;
OpenPOWER on IntegriCloud