From: Alexander Shaposhnikov Date: Sat, 2 Sep 2017 08:19:01 +0000 (+0000) Subject: [llvm-dwp] Implement -e option X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dce71c7425d1d90a63024a03f8b763d0a8394932;p=llvm [llvm-dwp] Implement -e option The binutils utility dwp has an option "-e" https://gcc.gnu.org/wiki/DebugFissionDWP to specify an executable/library to get the list of *.dwo files from it. This option is particularly useful when someone runs the tool manually outside of a build system. This diff adds an implementation of "-e" to llvm-dwp. Test plan: make check-all Differential revision: https://reviews.llvm.org/D37371 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312409 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/a.dwo b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/a.dwo new file mode 100644 index 00000000000..b6c77343564 Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/a.dwo differ diff --git a/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/b.dwo b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/b.dwo new file mode 100644 index 00000000000..d9084945838 Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/b.dwo differ diff --git a/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/c.dwo b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/c.dwo new file mode 100644 index 00000000000..60779693c89 Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/c.dwo differ diff --git a/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/d.dwo b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/d.dwo new file mode 100644 index 00000000000..42401022c2e Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/d.dwo differ diff --git a/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/e.dwo b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/e.dwo new file mode 100644 index 00000000000..edca66e3af1 Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/e.dwo differ diff --git a/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/libd.so b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/libd.so new file mode 100755 index 00000000000..56a30cf3caf Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/libd.so differ diff --git a/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/main b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/main new file mode 100755 index 00000000000..a56edf63415 Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/dwos_list_from_exec/main differ diff --git a/test/tools/llvm-dwp/X86/dwos_list_from_exec_simple.test b/test/tools/llvm-dwp/X86/dwos_list_from_exec_simple.test new file mode 100644 index 00000000000..4bbc2fb7b62 --- /dev/null +++ b/test/tools/llvm-dwp/X86/dwos_list_from_exec_simple.test @@ -0,0 +1,97 @@ +REQUIRES: shell + +RUN: rm -rf %t +RUN: mkdir %t +RUN: cd %t +RUN: cp %p/../Inputs/dwos_list_from_exec/a.dwo a.dwo +RUN: cp %p/../Inputs/dwos_list_from_exec/b.dwo b.dwo +RUN: cp %p/../Inputs/dwos_list_from_exec/c.dwo c.dwo +RUN: cp %p/../Inputs/dwos_list_from_exec/d.dwo d.dwo +RUN: cp %p/../Inputs/dwos_list_from_exec/e.dwo e.dwo +RUN: cp %p/../Inputs/dwos_list_from_exec/main main +RUN: cp %p/../Inputs/dwos_list_from_exec/libd.so libd.so +RUN: llvm-dwp c.dwo e.dwo -e main -e libd.so -o pkg.dwp +RUN: llvm-dwarfdump pkg.dwp | 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/tools/llvm-dwp/llvm-dwp.cpp b/tools/llvm-dwp/llvm-dwp.cpp index 2297db6097e..aab3f88d257 100644 --- a/tools/llvm-dwp/llvm-dwp.cpp +++ b/tools/llvm-dwp/llvm-dwp.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSet.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include "llvm/MC/MCAsmInfo.h" @@ -36,6 +37,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Options.h" +#include "llvm/Support/Path.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" @@ -49,9 +51,14 @@ using namespace llvm::object; using namespace cl; OptionCategory DwpCategory("Specific Options"); -static list InputFiles(Positional, OneOrMore, +static list InputFiles(Positional, ZeroOrMore, desc(""), cat(DwpCategory)); +static list ExecFilenames( + "e", ZeroOrMore, + desc("Specify the executable/library files to get the list of *.dwo from"), + value_desc("filename"), cat(DwpCategory)); + static opt OutputFilename(Required, "o", desc("Specify the output file."), value_desc("filename"), @@ -113,7 +120,7 @@ struct CompileUnitIdentifiers { }; static Expected -getIndexedString(dwarf::Form Form, DataExtractor InfoData, +getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint32_t &InfoOffset, StringRef StrOffsets, StringRef Str) { if (Form == dwarf::DW_FORM_string) return InfoData.getCStr(&InfoOffset); @@ -463,6 +470,35 @@ buildDuplicateError(const std::pair &PrevE, " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName)); } +static Expected> +getDWOFilenames(StringRef ExecFilename) { + auto ErrOrObj = object::ObjectFile::createObjectFile(ExecFilename); + if (!ErrOrObj) + return ErrOrObj.takeError(); + + const ObjectFile &Obj = *ErrOrObj.get().getBinary(); + std::unique_ptr DWARFCtx = DWARFContext::create(Obj); + + SmallVector DWOPaths; + for (const auto &CU : DWARFCtx->compile_units()) { + const DWARFDie &Die = CU->getUnitDIE(); + std::string DWOName = dwarf::toString( + Die.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), ""); + if (DWOName.empty()) + continue; + std::string DWOCompDir = + dwarf::toString(Die.find(dwarf::DW_AT_comp_dir), ""); + if (!DWOCompDir.empty()) { + SmallString<16> DWOPath; + sys::path::append(DWOPath, DWOCompDir, DWOName); + DWOPaths.emplace_back(DWOPath.data(), DWOPath.size()); + } else { + DWOPaths.push_back(std::move(DWOName)); + } + } + return std::move(DWOPaths); +} + static Error write(MCStreamer &Out, ArrayRef Inputs) { const auto &MCOFI = *Out.getContext().getObjectFileInfo(); MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); @@ -676,7 +712,19 @@ int main(int argc, char **argv) { if (!MS) return error("no object streamer for target " + TripleName, Context); - if (auto Err = write(*MS, InputFiles)) { + std::vector DWOFilenames = InputFiles; + for (const auto &ExecFilename : ExecFilenames) { + auto DWOs = getDWOFilenames(ExecFilename); + if (!DWOs) { + logAllUnhandledErrors(DWOs.takeError(), errs(), "error: "); + return 1; + } + DWOFilenames.insert(DWOFilenames.end(), + std::make_move_iterator(DWOs->begin()), + std::make_move_iterator(DWOs->end())); + } + + if (auto Err = write(*MS, DWOFilenames)) { logAllUnhandledErrors(std::move(Err), errs(), "error: "); return 1; }