Skip to content

Commit

Permalink
[MCDwarf] Respect -fdebug-prefix-map= for generated assembly debug in…
Browse files Browse the repository at this point in the history
…fo (DWARF v5)

For generated assembly debug info, MCDwarfLineTableHeader::CompilationDir is an
unmapped path set in MCContext::setGenDwarfRootFile. Remap it.

A relative destination path of -fdebug-prefix-map= exposes a llvm-dwarfdump bug
which joins relative DW_AT_comp_dir and directories[0].

Fix #56609

Reviewed By: dblaikie

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

(cherry picked from commit f62e60f)
  • Loading branch information
MaskRay authored and tru committed Aug 16, 2022
1 parent e087912 commit e2da724
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 25 deletions.
3 changes: 3 additions & 0 deletions llvm/include/llvm/MC/MCContext.h
Expand Up @@ -698,6 +698,9 @@ class MCContext {
/// Add an entry to the debug prefix map.
void addDebugPrefixMapEntry(const std::string &From, const std::string &To);

/// Remap one path in-place as per the debug prefix map.
void remapDebugPath(SmallVectorImpl<char> &Path);

// Remaps all debug directory paths in-place as per the debug prefix map.
void RemapDebugPaths();

Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/MC/MCDwarf.h
Expand Up @@ -22,6 +22,7 @@
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/StringSaver.h"
#include <cassert>
#include <cstdint>
#include <string>
Expand All @@ -48,6 +49,8 @@ MCSymbol *emitListsTableHeaderStart(MCStreamer &S);

/// Manage the .debug_line_str section contents, if we use it.
class MCDwarfLineStr {
BumpPtrAllocator Alloc;
StringSaver Saver{Alloc};
MCSymbol *LineStrLabel = nullptr;
StringTableBuilder LineStrings{StringTableBuilder::DWARF};
bool UseRelocs = false;
Expand All @@ -57,6 +60,8 @@ class MCDwarfLineStr {
/// v5 line table).
explicit MCDwarfLineStr(MCContext &Ctx);

StringSaver &getSaver() { return Saver; }

/// Emit a reference to the string.
void emitRef(MCStreamer *MCOS, StringRef Path);

Expand Down
31 changes: 15 additions & 16 deletions llvm/lib/MC/MCContext.cpp
Expand Up @@ -855,30 +855,29 @@ void MCContext::addDebugPrefixMapEntry(const std::string &From,
DebugPrefixMap.insert(std::make_pair(From, To));
}

void MCContext::remapDebugPath(SmallVectorImpl<char> &Path) {
for (const auto &[From, To] : DebugPrefixMap)
if (llvm::sys::path::replace_path_prefix(Path, From, To))
break;
}

void MCContext::RemapDebugPaths() {
const auto &DebugPrefixMap = this->DebugPrefixMap;
if (DebugPrefixMap.empty())
return;

const auto RemapDebugPath = [&DebugPrefixMap](std::string &Path) {
SmallString<256> P(Path);
for (const auto &Entry : DebugPrefixMap) {
if (llvm::sys::path::replace_path_prefix(P, Entry.first, Entry.second)) {
Path = P.str().str();
break;
}
}
};

// Remap compilation directory.
std::string CompDir = std::string(CompilationDir.str());
RemapDebugPath(CompDir);
CompilationDir = CompDir;
remapDebugPath(CompilationDir);

// Remap MCDwarfDirs in all compilation units.
for (auto &CUIDTablePair : MCDwarfLineTablesCUMap)
for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs())
RemapDebugPath(Dir);
SmallString<256> P;
for (auto &CUIDTablePair : MCDwarfLineTablesCUMap) {
for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs()) {
P = Dir;
remapDebugPath(P);
Dir = std::string(P);
}
}
}

//===----------------------------------------------------------------------===//
Expand Down
12 changes: 9 additions & 3 deletions llvm/lib/MC/MCDwarf.cpp
Expand Up @@ -416,9 +416,15 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
: dwarf::DW_FORM_string);
MCOS->emitULEB128IntValue(MCDwarfDirs.size() + 1);
// Try not to emit an empty compilation directory.
const StringRef CompDir = CompilationDir.empty()
? MCOS->getContext().getCompilationDir()
: StringRef(CompilationDir);
SmallString<256> Dir;
StringRef CompDir = MCOS->getContext().getCompilationDir();
if (!CompilationDir.empty()) {
Dir = CompilationDir;
MCOS->getContext().remapDebugPath(Dir);
CompDir = Dir.str();
if (LineStr)
CompDir = LineStr->getSaver().save(CompDir);
}
if (LineStr) {
// Record path strings, emit references here.
LineStr->emitRef(MCOS, CompDir);
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/MC/ELF/debug-prefix-map.s
Expand Up @@ -31,19 +31,19 @@ f:
# MAP_V4: DW_AT_decl_file [DW_FORM_data4] ("src_root{{(/|\\)+}}src.s")
# MAP_V4-NOT: .foo

## FIXME DW_AT_decl_file and include_directories are not mapped
# MAP_V5: DW_AT_name [DW_FORM_string] ("src.s")
# MAP_V5: DW_AT_comp_dir [DW_FORM_string] ("src_root")
# MAP_V5: DW_AT_decl_file [DW_FORM_data4] ("{{.*}}.foo{{(/|\\)+}}src.s")
# MAP_V5: include_directories[ 0] = .debug_line_str[0x00000000] = "{{.*}}.foo"
## FIXME llvm-dwarfdump incorrectly joins include_directories[0] to DW_AT_comp_dir,
## so there are two src_root path components.
# MAP_V5: DW_AT_decl_file [DW_FORM_data4] ("src_root{{(/|\\)+}}src_root{{(/|\\)+}}src.s")
# MAP_V5: include_directories[ 0] = .debug_line_str[0x00000000] = "src_root"

# MAPABS_V4: DW_AT_name [DW_FORM_string] ("src.s")
# MAPABS_V4: DW_AT_comp_dir [DW_FORM_string] ("{{(/|\\)+}}src_root")
# MAPABS_V4: DW_AT_decl_file [DW_FORM_data4] ("{{(/|\\)+}}src_root{{(/|\\)+}}src.s")
# MAPABS_V4-NOT: .foo

## FIXME DW_AT_decl_file and include_directories are not mapped
# MAPABS_V5: DW_AT_name [DW_FORM_string] ("src.s")
# MAPABS_V5: DW_AT_comp_dir [DW_FORM_string] ("{{(/|\\)+}}src_root")
# MAPABS_V5: DW_AT_decl_file [DW_FORM_data4] ("{{.*}}.foo{{(/|\\)+}}src.s")
# MAPABS_V5: include_directories[ 0] = .debug_line_str[0x00000000] = "{{.*}}.foo"
# MAPABS_V5: DW_AT_decl_file [DW_FORM_data4] ("/src_root{{(/|\\)+}}src.s")
# MAPABS_V5: include_directories[ 0] = .debug_line_str[0x00000000] = "/src_root"

0 comments on commit e2da724

Please sign in to comment.