diff --git a/llvm/test/tools/llvm-dwp/X86/dwos_list_from_exec_remap.test b/llvm/test/tools/llvm-dwp/X86/dwos_list_from_exec_remap.test new file mode 100644 index 0000000000000..437d635b54e31 --- /dev/null +++ b/llvm/test/tools/llvm-dwp/X86/dwos_list_from_exec_remap.test @@ -0,0 +1,129 @@ +// Test remapping old DWO paths in the executables and libraries to new paths. + +RUN: rm -rf %t +RUN: mkdir %t +RUN: cd %t + +RUN: cp %p/../Inputs/dwos_list_from_exec/main main +RUN: cp %p/../Inputs/dwos_list_from_exec/libd.so libd.so + +// Test remapping full DWO paths (/) to absolute paths +RUN: touch remapping_path_to_absolute.txt +RUN: echo "./a.dwo %p/../Inputs/dwos_list_from_exec/a.dwo" >> remapping_path_to_absolute.txt +RUN: echo "./b.dwo %p/../Inputs/dwos_list_from_exec/b.dwo" >> remapping_path_to_absolute.txt +RUN: echo "./d.dwo %p/../Inputs/dwos_list_from_exec/d.dwo" >> remapping_path_to_absolute.txt +RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \ +RUN: -e main -e libd.so --exec-dwo-path-remapping-file=remapping_path_to_absolute.txt -o - | llvm-dwarfdump -v - | FileCheck %s + +// Test remapping full DWO paths (/) to relative paths +RUN: mkdir foo && cp %p/../Inputs/dwos_list_from_exec/a.dwo foo/a.dwo +RUN: mkdir bar && cp %p/../Inputs/dwos_list_from_exec/b.dwo bar/b.dwo +RUN: mkdir qux && cp %p/../Inputs/dwos_list_from_exec/d.dwo qux/d.dwo +RUN: touch remapping_path_to_relative.txt +RUN: echo "./a.dwo foo/a.dwo" >> remapping_path_to_relative.txt +RUN: echo "./b.dwo bar/b.dwo" >> remapping_path_to_relative.txt +RUN: echo "./d.dwo qux/d.dwo" >> remapping_path_to_relative.txt +RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \ +RUN: -e main -e libd.so --exec-dwo-path-remapping-file=remapping_path_to_relative.txt -o - | llvm-dwarfdump -v - | FileCheck %s + +// Test remapping DWO name () to relative paths +RUN: touch remapping_name_to_relative.txt +RUN: echo "a.dwo foo/a.dwo" >> remapping_name_to_relative.txt +RUN: echo "b.dwo bar/b.dwo" >> remapping_name_to_relative.txt +RUN: echo "d.dwo qux/d.dwo" >> remapping_name_to_relative.txt +RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \ +RUN: -e main -e libd.so --exec-dwo-path-remapping-file=remapping_name_to_relative.txt -o - | llvm-dwarfdump -v - | FileCheck %s + +// Test remapping with multiple files +RUN: touch remapping_main.txt +RUN: echo "./a.dwo %p/../Inputs/dwos_list_from_exec/a.dwo" >> remapping_main.txt +RUN: echo "./b.dwo %p/../Inputs/dwos_list_from_exec/b.dwo" >> remapping_main.txt +RUN: echo "./d.dwo %p/../Inputs/dwos_list_from_exec/d.dwo" > remapping_libd.txt +RUN: llvm-dwp %p/../Inputs/dwos_list_from_exec/c.dwo %p/../Inputs/dwos_list_from_exec/e.dwo \ +RUN: -e main -e libd.so \ +RUN: --exec-dwo-path-remapping-file=remapping_main.txt \ +RUN: --exec-dwo-path-remapping-file=remapping_libd.txt \ +RUN: -o - | llvm-dwarfdump -v - | FileCheck %s + +Build commands for the test binaries: + +clang++ -Xclang -fdebug-compilation-dir -Xclang "./" -g -O0 -gsplit-dwarf a.cpp b.cpp -o main +clang++ -g -O0 -gsplit-dwarf -c c.cpp -o c.o +clang++ -Xclang -fdebug-compilation-dir -Xclang "./" -g -O0 -gsplit-dwarf -fPIC -shared d.cpp -o libd.so +clang++ -g -O0 -gsplit-dwarf -c e.cpp -o e.o + +sources: +a.cpp: + void a() {} + +b.cpp: + void b() {} + int main() { + return 0; + } + +c.cpp: + void c() {} + +d.cpp: + void d() {} + +e.cpp: + void e() {} + +CHECK-LABEL: .debug_abbrev.dwo contents: + +CHECK-LABEL: Abbrev table for offset: +CHECK: DW_TAG_compile_unit +CHECK: DW_TAG_subprogram + +CHECK-LABEL: Abbrev table for offset: +CHECK: DW_TAG_compile_unit +CHECK: DW_TAG_subprogram + +CHECK-LABEL: Abbrev table for offset: +CHECK: DW_TAG_compile_unit +CHECK: DW_TAG_subprogram + +CHECK-LABEL: Abbrev table for offset: +CHECK: DW_TAG_compile_unit +CHECK: DW_TAG_subprogram + +CHECK-LABEL: Abbrev table for offset: +CHECK: DW_TAG_compile_unit +CHECK: DW_TAG_subprogram + +CHECK: .debug_info.dwo contents: +CHECK: [[AOFF:0x[0-9a-f]*]]: + +CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004 +CHECK: DW_TAG_compile_unit +CHECK: DW_AT_name {{.*}} "c.cpp" +CHECK: DW_TAG_subprogram +CHECK: DW_AT_name {{.*}} "c" + +CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004 +CHECK: DW_TAG_compile_unit +CHECK: DW_AT_name {{.*}} "e.cpp" +CHECK: DW_TAG_subprogram +CHECK: DW_AT_name {{.*}} "e" + +CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004 +CHECK: DW_TAG_compile_unit +CHECK: DW_AT_name {{.*}} "a.cpp" +CHECK: DW_TAG_subprogram +CHECK: DW_AT_name {{.*}} "a" + +CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004 +CHECK: DW_TAG_compile_unit +CHECK: DW_AT_name {{.*}} "b.cpp" +CHECK: DW_TAG_subprogram +CHECK: DW_AT_name {{.*}} "b" +CHECK: DW_TAG_subprogram +CHECK: DW_AT_name {{.*}} "main" + +CHECK-LABEL: Compile Unit: length = {{.*}}, version = 0x0004 +CHECK: DW_TAG_compile_unit +CHECK: DW_AT_name {{.*}} "d.cpp" +CHECK: DW_TAG_subprogram +CHECK: DW_AT_name {{.*}} "d" diff --git a/llvm/tools/llvm-dwp/Opts.td b/llvm/tools/llvm-dwp/Opts.td index 46593bc40ebae..ecc1c25814c50 100644 --- a/llvm/tools/llvm-dwp/Opts.td +++ b/llvm/tools/llvm-dwp/Opts.td @@ -16,3 +16,5 @@ def continueOnCuIndexOverflow_EQ : Joined<["-", "--"], "continue-on-cu-index-ove "\t\ttruncated but valid DWP file, discarding any DWO files that would not fit within \n" "\t\tthe 32 bit/4GB limits of the format.">, Values<"continue,soft-stop">; +def execDwoPathRemappingFile : Joined<["--"], "exec-dwo-path-remapping-file=">, MetaVarName<"">, + HelpText<"Use the old and new paths described in to map old dwo paths in executables/libraries to the new paths.">; diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp index 61ba82d0634ac..c5761017aa27d 100644 --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -10,6 +10,7 @@ // package files). // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringMap.h" #include "llvm/DWP/DWP.h" #include "llvm/DWP/DWPError.h" #include "llvm/DWP/DWPStringPool.h" @@ -75,7 +76,8 @@ static std::string OutputFilename; static std::string ContinueOption; static Expected> -getDWOFilenames(StringRef ExecFilename) { +getDWOFilenames(StringRef ExecFilename, + const StringMap &DWOPathMap) { auto ErrOrObj = object::ObjectFile::createObjectFile(ExecFilename); if (!ErrOrObj) return ErrOrObj.takeError(); @@ -95,11 +97,17 @@ getDWOFilenames(StringRef ExecFilename) { if (!DWOCompDir.empty()) { SmallString<16> DWOPath(DWOName); sys::fs::make_absolute(DWOCompDir, DWOPath); + if (auto I = DWOPathMap.find(DWOPath); I != DWOPathMap.end()) + DWOPath = I->getValue(); + if (auto I = DWOPathMap.find(DWOName); I != DWOPathMap.end()) + DWOName = I->getValue(); if (!sys::fs::exists(DWOPath) && sys::fs::exists(DWOName)) DWOPaths.push_back(std::move(DWOName)); else DWOPaths.emplace_back(DWOPath.data(), DWOPath.size()); } else { + if (auto I = DWOPathMap.find(DWOName); I != DWOPathMap.end()) + DWOName = I->getValue(); DWOPaths.push_back(std::move(DWOName)); } } @@ -120,6 +128,33 @@ static Expected readTargetTriple(StringRef FileName) { return ErrOrObj->getBinary()->makeTriple(); } +static Error addPathsToRemapFromFile(StringMap &DWOPathMap, + BumpPtrAllocator &Alloc, + StringRef Filename) { + StringSaver Saver(Alloc); + SmallVector Lines; + auto BufOrErr = MemoryBuffer::getFile(Filename); + if (!BufOrErr) + return createFileError(Filename, BufOrErr.getError()); + + BufOrErr.get()->getBuffer().split(Lines, '\n'); + for (size_t LineNo = 0, NumLines = Lines.size(); LineNo < NumLines; + ++LineNo) { + StringRef TrimmedLine = Lines[LineNo].split('#').first.trim(); + if (TrimmedLine.empty()) + continue; + + std::pair Pair = Saver.save(TrimmedLine).split(' '); + StringRef NewName = Pair.second.trim(); + if (NewName.empty()) + return createStringError(errc::invalid_argument, + "%s:%zu: missing new DWO path", + Filename.str().c_str(), LineNo + 1); + DWOPathMap.insert({Pair.first, NewName}); + } + return Error::success(); +} + int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) { DwpOptTable Tbl; llvm::BumpPtrAllocator A; @@ -173,8 +208,16 @@ int llvm_dwp_main(int argc, char **argv, const llvm::ToolContext &) { llvm::InitializeAllTargets(); llvm::InitializeAllAsmPrinters(); + llvm::StringMap DWOPathMap; + for (auto *Arg : Args.filtered(OPT_execDwoPathRemappingFile)) { + if (Error E = addPathsToRemapFromFile(DWOPathMap, A, Arg->getValue())) { + logAllUnhandledErrors(std::move(E), WithColor::error()); + return 1; + } + } + for (const auto &ExecFilename : ExecFilenames) { - auto DWOs = getDWOFilenames(ExecFilename); + auto DWOs = getDWOFilenames(ExecFilename, DWOPathMap); if (!DWOs) { logAllUnhandledErrors( handleErrors(DWOs.takeError(),