Index: include/llvm/MC/MCContext.h =================================================================== --- include/llvm/MC/MCContext.h +++ include/llvm/MC/MCContext.h @@ -137,6 +137,9 @@ /// The compilation directory to use for DW_AT_comp_dir. SmallString<128> CompilationDir; + /// Prefix replacement map for source file information. + std::map DebugPrefixMap; + /// The main file name if passed in explicitly. std::string MainFileName; @@ -490,6 +493,14 @@ /// Set the compilation directory for DW_AT_comp_dir void setCompilationDir(StringRef S) { CompilationDir = S.str(); } + /// Get the debug prefix map. + const std::map& getDebugPrefixMap() const { + return DebugPrefixMap; + } + + /// Set the compilation directory for DW_AT_comp_dir + void addDebugPrefixMapEntry(const std::string& From, const std::string& To); + /// 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: lib/MC/MCContext.cpp =================================================================== --- lib/MC/MCContext.cpp +++ lib/MC/MCContext.cpp @@ -535,6 +535,10 @@ return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI); } +void MCContext::addDebugPrefixMapEntry(const std::string& From, const std::string& To) { + DebugPrefixMap.insert(std::make_pair(From, To)); +} + //===----------------------------------------------------------------------===// // Dwarf Management //===----------------------------------------------------------------------===// Index: lib/MC/MCDwarf.cpp =================================================================== --- lib/MC/MCDwarf.cpp +++ lib/MC/MCDwarf.cpp @@ -307,6 +307,13 @@ OS.EmitValue(ABS, Size); } +static std::string remapDebugPath(MCStreamer *MCOS, StringRef Path) { + for (const auto &Entry : MCOS->getContext().getDebugPrefixMap()) + if (Path.startswith(Entry.first)) + return (Twine(Entry.second) + Path.substr(Entry.first.size())).str(); + return Path; +} + void MCDwarfLineStr::emitSection(MCStreamer *MCOS) { // Switch to the .debug_line_str section. MCOS->SwitchSection( @@ -332,8 +339,9 @@ void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const { // First the directory table. for (auto &Dir : MCDwarfDirs) { - MCOS->EmitBytes(Dir); // The DirectoryName, and... - MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + const std::string RemappedDir = remapDebugPath(MCOS, Dir); + MCOS->EmitBytes(RemappedDir); // The DirectoryName, and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. } MCOS->EmitIntValue(0, 1); // Terminate the directory list. @@ -391,17 +399,21 @@ // Try not to emit an empty compilation directory. const StringRef CompDir = CompilationDir.empty() ? CtxCompilationDir : StringRef(CompilationDir); + const std::string RemappedCompDir = remapDebugPath(MCOS, CompDir); if (LineStr) { // Record path strings, emit references here. - LineStr->emitRef(MCOS, CompDir); - for (auto &Dir : MCDwarfDirs) - LineStr->emitRef(MCOS, Dir); + LineStr->emitRef(MCOS, RemappedCompDir); + for (auto &Dir : MCDwarfDirs) { + const std::string RemappedDir = remapDebugPath(MCOS, Dir); + LineStr->emitRef(MCOS, RemappedDir); + } } else { // The list of directory paths. Compilation directory comes first. - MCOS->EmitBytes(CompDir); + MCOS->EmitBytes(RemappedCompDir); MCOS->EmitBytes(StringRef("\0", 1)); for (auto &Dir : MCDwarfDirs) { - MCOS->EmitBytes(Dir); // The DirectoryName, and... + const std::string RemappedDir = remapDebugPath(MCOS, Dir); + MCOS->EmitBytes(RemappedDir); // The DirectoryName, and... MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. } } @@ -955,7 +967,8 @@ // and file table entries. const SmallVectorImpl &MCDwarfDirs = context.getMCDwarfDirs(); if (MCDwarfDirs.size() > 0) { - MCOS->EmitBytes(MCDwarfDirs[0]); + const std::string RemappedDir = remapDebugPath(MCOS, MCDwarfDirs[0]); + MCOS->EmitBytes(RemappedDir); MCOS->EmitBytes(sys::path::get_separator()); } const SmallVectorImpl &MCDwarfFiles = @@ -965,7 +978,8 @@ // AT_comp_dir, the working directory the assembly was done in. if (!context.getCompilationDir().empty()) { - MCOS->EmitBytes(context.getCompilationDir()); + const std::string RemappedCompDir = remapDebugPath(MCOS, context.getCompilationDir()); + MCOS->EmitBytes(RemappedCompDir); MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. }