17
17
#include " llvm/ADT/STLExtras.h"
18
18
#include " llvm/ADT/StringSet.h"
19
19
#include " llvm/CodeGen/AsmPrinter.h"
20
+ #include " llvm/DebugInfo/DWARF/DWARFContext.h"
20
21
#include " llvm/DebugInfo/DWARF/DWARFFormValue.h"
21
22
#include " llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
22
23
#include " llvm/MC/MCAsmInfo.h"
36
37
#include " llvm/Support/MathExtras.h"
37
38
#include " llvm/Support/MemoryBuffer.h"
38
39
#include " llvm/Support/Options.h"
40
+ #include " llvm/Support/Path.h"
39
41
#include " llvm/Support/TargetRegistry.h"
40
42
#include " llvm/Support/TargetSelect.h"
41
43
#include " llvm/Support/raw_ostream.h"
@@ -49,9 +51,14 @@ using namespace llvm::object;
49
51
using namespace cl ;
50
52
51
53
OptionCategory DwpCategory (" Specific Options" );
52
- static list<std::string> InputFiles (Positional, OneOrMore ,
54
+ static list<std::string> InputFiles (Positional, ZeroOrMore ,
53
55
desc (" <input files>" ), cat(DwpCategory));
54
56
57
+ static list<std::string> ExecFilenames (
58
+ " e" , ZeroOrMore,
59
+ desc (" Specify the executable/library files to get the list of *.dwo from" ),
60
+ value_desc(" filename" ), cat(DwpCategory));
61
+
55
62
static opt<std::string> OutputFilename (Required, " o" ,
56
63
desc (" Specify the output file." ),
57
64
value_desc(" filename" ),
@@ -113,7 +120,7 @@ struct CompileUnitIdentifiers {
113
120
};
114
121
115
122
static Expected<const char *>
116
- getIndexedString (dwarf::Form Form, DataExtractor InfoData,
123
+ getIndexedString (dwarf::Form Form, DataExtractor InfoData,
117
124
uint32_t &InfoOffset, StringRef StrOffsets, StringRef Str) {
118
125
if (Form == dwarf::DW_FORM_string)
119
126
return InfoData.getCStr (&InfoOffset);
@@ -463,6 +470,35 @@ buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
463
470
" and " + buildDWODescription (ID.Name , DWPName, ID.DWOName ));
464
471
}
465
472
473
+ static Expected<SmallVector<std::string, 16 >>
474
+ getDWOFilenames (StringRef ExecFilename) {
475
+ auto ErrOrObj = object::ObjectFile::createObjectFile (ExecFilename);
476
+ if (!ErrOrObj)
477
+ return ErrOrObj.takeError ();
478
+
479
+ const ObjectFile &Obj = *ErrOrObj.get ().getBinary ();
480
+ std::unique_ptr<DWARFContext> DWARFCtx = DWARFContext::create (Obj);
481
+
482
+ SmallVector<std::string, 16 > DWOPaths;
483
+ for (const auto &CU : DWARFCtx->compile_units ()) {
484
+ const DWARFDie &Die = CU->getUnitDIE ();
485
+ std::string DWOName = dwarf::toString (
486
+ Die.find ({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), " " );
487
+ if (DWOName.empty ())
488
+ continue ;
489
+ std::string DWOCompDir =
490
+ dwarf::toString (Die.find (dwarf::DW_AT_comp_dir), " " );
491
+ if (!DWOCompDir.empty ()) {
492
+ SmallString<16 > DWOPath;
493
+ sys::path::append (DWOPath, DWOCompDir, DWOName);
494
+ DWOPaths.emplace_back (DWOPath.data (), DWOPath.size ());
495
+ } else {
496
+ DWOPaths.push_back (std::move (DWOName));
497
+ }
498
+ }
499
+ return std::move (DWOPaths);
500
+ }
501
+
466
502
static Error write (MCStreamer &Out, ArrayRef<std::string> Inputs) {
467
503
const auto &MCOFI = *Out.getContext ().getObjectFileInfo ();
468
504
MCSection *const StrSection = MCOFI.getDwarfStrDWOSection ();
@@ -676,7 +712,19 @@ int main(int argc, char **argv) {
676
712
if (!MS)
677
713
return error (" no object streamer for target " + TripleName, Context);
678
714
679
- if (auto Err = write (*MS, InputFiles)) {
715
+ std::vector<std::string> DWOFilenames = InputFiles;
716
+ for (const auto &ExecFilename : ExecFilenames) {
717
+ auto DWOs = getDWOFilenames (ExecFilename);
718
+ if (!DWOs) {
719
+ logAllUnhandledErrors (DWOs.takeError (), errs (), " error: " );
720
+ return 1 ;
721
+ }
722
+ DWOFilenames.insert (DWOFilenames.end (),
723
+ std::make_move_iterator (DWOs->begin ()),
724
+ std::make_move_iterator (DWOs->end ()));
725
+ }
726
+
727
+ if (auto Err = write (*MS, DWOFilenames)) {
680
728
logAllUnhandledErrors (std::move (Err), errs (), " error: " );
681
729
return 1 ;
682
730
}
0 commit comments