summaryrefslogtreecommitdiff
path: root/tools/llvm-dwp/llvm-dwp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-dwp/llvm-dwp.cpp')
-rw-r--r--tools/llvm-dwp/llvm-dwp.cpp72
1 files changed, 57 insertions, 15 deletions
diff --git a/tools/llvm-dwp/llvm-dwp.cpp b/tools/llvm-dwp/llvm-dwp.cpp
index 7a6922d8a3fc..dbbe61bf3b06 100644
--- a/tools/llvm-dwp/llvm-dwp.cpp
+++ b/tools/llvm-dwp/llvm-dwp.cpp
@@ -15,43 +15,43 @@
#include "DWPStringPool.h"
#include "llvm/ADT/MapVector.h"
#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/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.def"
#include "llvm/Object/Decompressor.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Compression.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#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"
-#include "llvm/Target/TargetMachine.h"
-#include <deque>
-#include <iostream>
-#include <memory>
using namespace llvm;
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 +113,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 +463,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();
@@ -642,7 +671,7 @@ int main(int argc, char **argv) {
MCObjectFileInfo MOFI;
MCContext MC(MAI.get(), MRI.get(), &MOFI);
- MOFI.InitMCObjectFileInfo(TheTriple, /*PIC*/ false, CodeModel::Default, MC);
+ MOFI.InitMCObjectFileInfo(TheTriple, /*PIC*/ false, MC);
MCTargetOptions Options;
auto MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, "", Options);
@@ -670,13 +699,26 @@ int main(int argc, char **argv) {
MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
std::unique_ptr<MCStreamer> MS(TheTarget->createMCObjectStreamer(
- TheTriple, MC, *MAB, OutFile, MCE, *MSTI, MCOptions.MCRelaxAll,
+ TheTriple, MC, std::unique_ptr<MCAsmBackend>(MAB), OutFile,
+ std::unique_ptr<MCCodeEmitter>(MCE), *MSTI, MCOptions.MCRelaxAll,
MCOptions.MCIncrementalLinkerCompatible,
/*DWARFMustBeAtTheEnd*/ false));
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;
}