mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[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 llvm-svn: 312409
This commit is contained in:
parent
b4812cf126
commit
64af7a22c4
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/a.dwo
Normal file
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/a.dwo
Normal file
Binary file not shown.
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/b.dwo
Normal file
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/b.dwo
Normal file
Binary file not shown.
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/c.dwo
Normal file
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/c.dwo
Normal file
Binary file not shown.
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/d.dwo
Normal file
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/d.dwo
Normal file
Binary file not shown.
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/e.dwo
Normal file
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/e.dwo
Normal file
Binary file not shown.
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/libd.so
Executable file
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/libd.so
Executable file
Binary file not shown.
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/main
Executable file
BIN
test/tools/llvm-dwp/Inputs/dwos_list_from_exec/main
Executable file
Binary file not shown.
97
test/tools/llvm-dwp/X86/dwos_list_from_exec_simple.test
Normal file
97
test/tools/llvm-dwp/X86/dwos_list_from_exec_simple.test
Normal file
@ -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"
|
@ -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<std::string> InputFiles(Positional, OneOrMore,
|
||||
static list<std::string> InputFiles(Positional, ZeroOrMore,
|
||||
desc("<input files>"), cat(DwpCategory));
|
||||
|
||||
static list<std::string> ExecFilenames(
|
||||
"e", ZeroOrMore,
|
||||
desc("Specify the executable/library files to get the list of *.dwo from"),
|
||||
value_desc("filename"), cat(DwpCategory));
|
||||
|
||||
static opt<std::string> OutputFilename(Required, "o",
|
||||
desc("Specify the output file."),
|
||||
value_desc("filename"),
|
||||
@ -113,7 +120,7 @@ struct CompileUnitIdentifiers {
|
||||
};
|
||||
|
||||
static Expected<const char *>
|
||||
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<uint64_t, UnitIndexEntry> &PrevE,
|
||||
" and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
|
||||
}
|
||||
|
||||
static Expected<SmallVector<std::string, 16>>
|
||||
getDWOFilenames(StringRef ExecFilename) {
|
||||
auto ErrOrObj = object::ObjectFile::createObjectFile(ExecFilename);
|
||||
if (!ErrOrObj)
|
||||
return ErrOrObj.takeError();
|
||||
|
||||
const ObjectFile &Obj = *ErrOrObj.get().getBinary();
|
||||
std::unique_ptr<DWARFContext> DWARFCtx = DWARFContext::create(Obj);
|
||||
|
||||
SmallVector<std::string, 16> 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<std::string> 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<std::string> 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user