1 //===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF
12 //===----------------------------------------------------------------------===//
14 #include "DWPStringPool.h"
15 #include "llvm/ADT/MapVector.h"
16 #include "llvm/ADT/Optional.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
19 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
20 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
21 #include "llvm/MC/MCAsmBackend.h"
22 #include "llvm/MC/MCAsmInfo.h"
23 #include "llvm/MC/MCCodeEmitter.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCObjectFileInfo.h"
27 #include "llvm/MC/MCObjectWriter.h"
28 #include "llvm/MC/MCRegisterInfo.h"
29 #include "llvm/MC/MCStreamer.h"
30 #include "llvm/MC/MCTargetOptionsCommandFlags.inc"
31 #include "llvm/Object/Decompressor.h"
32 #include "llvm/Object/ObjectFile.h"
33 #include "llvm/Support/DataExtractor.h"
34 #include "llvm/Support/Error.h"
35 #include "llvm/Support/FileSystem.h"
36 #include "llvm/Support/InitLLVM.h"
37 #include "llvm/Support/MathExtras.h"
38 #include "llvm/Support/MemoryBuffer.h"
39 #include "llvm/Support/Path.h"
40 #include "llvm/Support/TargetRegistry.h"
41 #include "llvm/Support/TargetSelect.h"
42 #include "llvm/Support/ToolOutputFile.h"
43 #include "llvm/Support/WithColor.h"
44 #include "llvm/Support/raw_ostream.h"
47 using namespace llvm::object
;
49 cl::OptionCategory
DwpCategory("Specific Options");
50 static cl::list
<std::string
> InputFiles(cl::Positional
, cl::ZeroOrMore
,
51 cl::desc("<input files>"),
52 cl::cat(DwpCategory
));
54 static cl::list
<std::string
> ExecFilenames(
56 cl::desc("Specify the executable/library files to get the list of *.dwo from"),
57 cl::value_desc("filename"), cl::cat(DwpCategory
));
59 static cl::opt
<std::string
> OutputFilename(cl::Required
, "o",
60 cl::desc("Specify the output file."),
61 cl::value_desc("filename"),
62 cl::cat(DwpCategory
));
64 static void writeStringsAndOffsets(MCStreamer
&Out
, DWPStringPool
&Strings
,
65 MCSection
*StrOffsetSection
,
66 StringRef CurStrSection
,
67 StringRef CurStrOffsetSection
) {
68 // Could possibly produce an error or warning if one of these was non-null but
69 // the other was null.
70 if (CurStrSection
.empty() || CurStrOffsetSection
.empty())
73 DenseMap
<uint64_t, uint32_t> OffsetRemapping
;
75 DataExtractor
Data(CurStrSection
, true, 0);
76 uint64_t LocalOffset
= 0;
77 uint64_t PrevOffset
= 0;
78 while (const char *s
= Data
.getCStr(&LocalOffset
)) {
79 OffsetRemapping
[PrevOffset
] =
80 Strings
.getOffset(s
, LocalOffset
- PrevOffset
);
81 PrevOffset
= LocalOffset
;
84 Data
= DataExtractor(CurStrOffsetSection
, true, 0);
86 Out
.SwitchSection(StrOffsetSection
);
89 uint64_t Size
= CurStrOffsetSection
.size();
90 while (Offset
< Size
) {
91 auto OldOffset
= Data
.getU32(&Offset
);
92 auto NewOffset
= OffsetRemapping
[OldOffset
];
93 Out
.EmitIntValue(NewOffset
, 4);
97 static uint64_t getCUAbbrev(StringRef Abbrev
, uint64_t AbbrCode
) {
100 DataExtractor
AbbrevData(Abbrev
, true, 0);
101 while ((CurCode
= AbbrevData
.getULEB128(&Offset
)) != AbbrCode
) {
103 AbbrevData
.getULEB128(&Offset
);
105 AbbrevData
.getU8(&Offset
);
107 while (AbbrevData
.getULEB128(&Offset
) | AbbrevData
.getULEB128(&Offset
))
113 struct CompileUnitIdentifiers
{
114 uint64_t Signature
= 0;
115 const char *Name
= "";
116 const char *DWOName
= "";
119 static Expected
<const char *>
120 getIndexedString(dwarf::Form Form
, DataExtractor InfoData
,
121 uint64_t &InfoOffset
, StringRef StrOffsets
, StringRef Str
) {
122 if (Form
== dwarf::DW_FORM_string
)
123 return InfoData
.getCStr(&InfoOffset
);
124 if (Form
!= dwarf::DW_FORM_GNU_str_index
)
125 return make_error
<DWPError
>(
126 "string field encoded without DW_FORM_string or DW_FORM_GNU_str_index");
127 auto StrIndex
= InfoData
.getULEB128(&InfoOffset
);
128 DataExtractor
StrOffsetsData(StrOffsets
, true, 0);
129 uint64_t StrOffsetsOffset
= 4 * StrIndex
;
130 uint64_t StrOffset
= StrOffsetsData
.getU32(&StrOffsetsOffset
);
131 DataExtractor
StrData(Str
, true, 0);
132 return StrData
.getCStr(&StrOffset
);
135 static Expected
<CompileUnitIdentifiers
> getCUIdentifiers(StringRef Abbrev
,
137 StringRef StrOffsets
,
140 DataExtractor
InfoData(Info
, true, 0);
141 dwarf::DwarfFormat Format
= dwarf::DwarfFormat::DWARF32
;
142 uint64_t Length
= InfoData
.getU32(&Offset
);
143 // If the length is 0xffffffff, then this indictes that this is a DWARF 64
144 // stream and the length is actually encoded into a 64 bit value that follows.
145 if (Length
== 0xffffffffU
) {
146 Format
= dwarf::DwarfFormat::DWARF64
;
147 Length
= InfoData
.getU64(&Offset
);
149 uint16_t Version
= InfoData
.getU16(&Offset
);
150 InfoData
.getU32(&Offset
); // Abbrev offset (should be zero)
151 uint8_t AddrSize
= InfoData
.getU8(&Offset
);
153 uint32_t AbbrCode
= InfoData
.getULEB128(&Offset
);
155 DataExtractor
AbbrevData(Abbrev
, true, 0);
156 uint64_t AbbrevOffset
= getCUAbbrev(Abbrev
, AbbrCode
);
157 auto Tag
= static_cast<dwarf::Tag
>(AbbrevData
.getULEB128(&AbbrevOffset
));
158 if (Tag
!= dwarf::DW_TAG_compile_unit
)
159 return make_error
<DWPError
>("top level DIE is not a compile unit");
161 AbbrevData
.getU8(&AbbrevOffset
);
164 CompileUnitIdentifiers ID
;
165 Optional
<uint64_t> Signature
= None
;
166 while ((Name
= AbbrevData
.getULEB128(&AbbrevOffset
)) |
167 (Form
= static_cast<dwarf::Form
>(AbbrevData
.getULEB128(&AbbrevOffset
))) &&
168 (Name
!= 0 || Form
!= 0)) {
170 case dwarf::DW_AT_name
: {
171 Expected
<const char *> EName
=
172 getIndexedString(Form
, InfoData
, Offset
, StrOffsets
, Str
);
174 return EName
.takeError();
178 case dwarf::DW_AT_GNU_dwo_name
: {
179 Expected
<const char *> EName
=
180 getIndexedString(Form
, InfoData
, Offset
, StrOffsets
, Str
);
182 return EName
.takeError();
186 case dwarf::DW_AT_GNU_dwo_id
:
187 Signature
= InfoData
.getU64(&Offset
);
190 DWARFFormValue::skipValue(Form
, InfoData
, &Offset
,
191 dwarf::FormParams({Version
, AddrSize
, Format
}));
195 return make_error
<DWPError
>("compile unit missing dwo_id");
196 ID
.Signature
= *Signature
;
200 struct UnitIndexEntry
{
201 DWARFUnitIndex::Entry::SectionContribution Contributions
[8];
207 static StringRef
getSubsection(StringRef Section
,
208 const DWARFUnitIndex::Entry
&Entry
,
209 DWARFSectionKind Kind
) {
210 const auto *Off
= Entry
.getOffset(Kind
);
213 return Section
.substr(Off
->Offset
, Off
->Length
);
216 static void addAllTypesFromDWP(
217 MCStreamer
&Out
, MapVector
<uint64_t, UnitIndexEntry
> &TypeIndexEntries
,
218 const DWARFUnitIndex
&TUIndex
, MCSection
*OutputTypes
, StringRef Types
,
219 const UnitIndexEntry
&TUEntry
, uint32_t &TypesOffset
) {
220 Out
.SwitchSection(OutputTypes
);
221 for (const DWARFUnitIndex::Entry
&E
: TUIndex
.getRows()) {
222 auto *I
= E
.getOffsets();
225 auto P
= TypeIndexEntries
.insert(std::make_pair(E
.getSignature(), TUEntry
));
228 auto &Entry
= P
.first
->second
;
229 // Zero out the debug_info contribution
230 Entry
.Contributions
[0] = {};
231 for (auto Kind
: TUIndex
.getColumnKinds()) {
232 auto &C
= Entry
.Contributions
[Kind
- DW_SECT_INFO
];
233 C
.Offset
+= I
->Offset
;
234 C
.Length
= I
->Length
;
237 auto &C
= Entry
.Contributions
[DW_SECT_TYPES
- DW_SECT_INFO
];
238 Out
.EmitBytes(Types
.substr(
239 C
.Offset
- TUEntry
.Contributions
[DW_SECT_TYPES
- DW_SECT_INFO
].Offset
,
241 C
.Offset
= TypesOffset
;
242 TypesOffset
+= C
.Length
;
246 static void addAllTypes(MCStreamer
&Out
,
247 MapVector
<uint64_t, UnitIndexEntry
> &TypeIndexEntries
,
248 MCSection
*OutputTypes
,
249 const std::vector
<StringRef
> &TypesSections
,
250 const UnitIndexEntry
&CUEntry
, uint32_t &TypesOffset
) {
251 for (StringRef Types
: TypesSections
) {
252 Out
.SwitchSection(OutputTypes
);
254 DataExtractor
Data(Types
, true, 0);
255 while (Data
.isValidOffset(Offset
)) {
256 UnitIndexEntry Entry
= CUEntry
;
257 // Zero out the debug_info contribution
258 Entry
.Contributions
[0] = {};
259 auto &C
= Entry
.Contributions
[DW_SECT_TYPES
- DW_SECT_INFO
];
260 C
.Offset
= TypesOffset
;
261 auto PrevOffset
= Offset
;
262 // Length of the unit, including the 4 byte length field.
263 C
.Length
= Data
.getU32(&Offset
) + 4;
265 Data
.getU16(&Offset
); // Version
266 Data
.getU32(&Offset
); // Abbrev offset
267 Data
.getU8(&Offset
); // Address size
268 auto Signature
= Data
.getU64(&Offset
);
269 Offset
= PrevOffset
+ C
.Length
;
271 auto P
= TypeIndexEntries
.insert(std::make_pair(Signature
, Entry
));
275 Out
.EmitBytes(Types
.substr(PrevOffset
, C
.Length
));
276 TypesOffset
+= C
.Length
;
282 writeIndexTable(MCStreamer
&Out
, ArrayRef
<unsigned> ContributionOffsets
,
283 const MapVector
<uint64_t, UnitIndexEntry
> &IndexEntries
,
284 uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field
) {
285 for (const auto &E
: IndexEntries
)
286 for (size_t i
= 0; i
!= array_lengthof(E
.second
.Contributions
); ++i
)
287 if (ContributionOffsets
[i
])
288 Out
.EmitIntValue(E
.second
.Contributions
[i
].*Field
, 4);
292 writeIndex(MCStreamer
&Out
, MCSection
*Section
,
293 ArrayRef
<unsigned> ContributionOffsets
,
294 const MapVector
<uint64_t, UnitIndexEntry
> &IndexEntries
) {
295 if (IndexEntries
.empty())
298 unsigned Columns
= 0;
299 for (auto &C
: ContributionOffsets
)
303 std::vector
<unsigned> Buckets(NextPowerOf2(3 * IndexEntries
.size() / 2));
304 uint64_t Mask
= Buckets
.size() - 1;
306 for (const auto &P
: IndexEntries
) {
309 auto HP
= ((S
>> 32) & Mask
) | 1;
311 assert(S
!= IndexEntries
.begin()[Buckets
[H
] - 1].first
&&
319 Out
.SwitchSection(Section
);
320 Out
.EmitIntValue(2, 4); // Version
321 Out
.EmitIntValue(Columns
, 4); // Columns
322 Out
.EmitIntValue(IndexEntries
.size(), 4); // Num Units
323 Out
.EmitIntValue(Buckets
.size(), 4); // Num Buckets
325 // Write the signatures.
326 for (const auto &I
: Buckets
)
327 Out
.EmitIntValue(I
? IndexEntries
.begin()[I
- 1].first
: 0, 8);
329 // Write the indexes.
330 for (const auto &I
: Buckets
)
331 Out
.EmitIntValue(I
, 4);
333 // Write the column headers (which sections will appear in the table)
334 for (size_t i
= 0; i
!= ContributionOffsets
.size(); ++i
)
335 if (ContributionOffsets
[i
])
336 Out
.EmitIntValue(i
+ DW_SECT_INFO
, 4);
338 // Write the offsets.
339 writeIndexTable(Out
, ContributionOffsets
, IndexEntries
,
340 &DWARFUnitIndex::Entry::SectionContribution::Offset
);
342 // Write the lengths.
343 writeIndexTable(Out
, ContributionOffsets
, IndexEntries
,
344 &DWARFUnitIndex::Entry::SectionContribution::Length
);
347 std::string
buildDWODescription(StringRef Name
, StringRef DWPName
, StringRef DWOName
) {
348 std::string Text
= "\'";
351 if (!DWPName
.empty()) {
353 if (!DWOName
.empty()) {
365 static Error
createError(StringRef Name
, Error E
) {
366 return make_error
<DWPError
>(
367 ("failure while decompressing compressed section: '" + Name
+ "', " +
368 llvm::toString(std::move(E
)))
373 handleCompressedSection(std::deque
<SmallString
<32>> &UncompressedSections
,
374 StringRef
&Name
, StringRef
&Contents
) {
375 if (!Decompressor::isGnuStyle(Name
))
376 return Error::success();
378 Expected
<Decompressor
> Dec
=
379 Decompressor::create(Name
, Contents
, false /*IsLE*/, false /*Is64Bit*/);
381 return createError(Name
, Dec
.takeError());
383 UncompressedSections
.emplace_back();
384 if (Error E
= Dec
->resizeAndDecompress(UncompressedSections
.back()))
385 return createError(Name
, std::move(E
));
387 Name
= Name
.substr(2); // Drop ".z"
388 Contents
= UncompressedSections
.back();
389 return Error::success();
392 static Error
handleSection(
393 const StringMap
<std::pair
<MCSection
*, DWARFSectionKind
>> &KnownSections
,
394 const MCSection
*StrSection
, const MCSection
*StrOffsetSection
,
395 const MCSection
*TypesSection
, const MCSection
*CUIndexSection
,
396 const MCSection
*TUIndexSection
, const SectionRef
&Section
, MCStreamer
&Out
,
397 std::deque
<SmallString
<32>> &UncompressedSections
,
398 uint32_t (&ContributionOffsets
)[8], UnitIndexEntry
&CurEntry
,
399 StringRef
&CurStrSection
, StringRef
&CurStrOffsetSection
,
400 std::vector
<StringRef
> &CurTypesSection
, StringRef
&InfoSection
,
401 StringRef
&AbbrevSection
, StringRef
&CurCUIndexSection
,
402 StringRef
&CurTUIndexSection
) {
404 return Error::success();
406 if (Section
.isVirtual())
407 return Error::success();
409 Expected
<StringRef
> NameOrErr
= Section
.getName();
411 return NameOrErr
.takeError();
412 StringRef Name
= *NameOrErr
;
414 Expected
<StringRef
> ContentsOrErr
= Section
.getContents();
416 return ContentsOrErr
.takeError();
417 StringRef Contents
= *ContentsOrErr
;
419 if (auto Err
= handleCompressedSection(UncompressedSections
, Name
, Contents
))
422 Name
= Name
.substr(Name
.find_first_not_of("._"));
424 auto SectionPair
= KnownSections
.find(Name
);
425 if (SectionPair
== KnownSections
.end())
426 return Error::success();
428 if (DWARFSectionKind Kind
= SectionPair
->second
.second
) {
429 auto Index
= Kind
- DW_SECT_INFO
;
430 if (Kind
!= DW_SECT_TYPES
) {
431 CurEntry
.Contributions
[Index
].Offset
= ContributionOffsets
[Index
];
432 ContributionOffsets
[Index
] +=
433 (CurEntry
.Contributions
[Index
].Length
= Contents
.size());
438 InfoSection
= Contents
;
441 AbbrevSection
= Contents
;
448 MCSection
*OutSection
= SectionPair
->second
.first
;
449 if (OutSection
== StrOffsetSection
)
450 CurStrOffsetSection
= Contents
;
451 else if (OutSection
== StrSection
)
452 CurStrSection
= Contents
;
453 else if (OutSection
== TypesSection
)
454 CurTypesSection
.push_back(Contents
);
455 else if (OutSection
== CUIndexSection
)
456 CurCUIndexSection
= Contents
;
457 else if (OutSection
== TUIndexSection
)
458 CurTUIndexSection
= Contents
;
460 Out
.SwitchSection(OutSection
);
461 Out
.EmitBytes(Contents
);
463 return Error::success();
467 buildDuplicateError(const std::pair
<uint64_t, UnitIndexEntry
> &PrevE
,
468 const CompileUnitIdentifiers
&ID
, StringRef DWPName
) {
469 return make_error
<DWPError
>(
470 std::string("Duplicate DWO ID (") + utohexstr(PrevE
.first
) + ") in " +
471 buildDWODescription(PrevE
.second
.Name
, PrevE
.second
.DWPName
,
472 PrevE
.second
.DWOName
) +
473 " and " + buildDWODescription(ID
.Name
, DWPName
, ID
.DWOName
));
476 static Expected
<SmallVector
<std::string
, 16>>
477 getDWOFilenames(StringRef ExecFilename
) {
478 auto ErrOrObj
= object::ObjectFile::createObjectFile(ExecFilename
);
480 return ErrOrObj
.takeError();
482 const ObjectFile
&Obj
= *ErrOrObj
.get().getBinary();
483 std::unique_ptr
<DWARFContext
> DWARFCtx
= DWARFContext::create(Obj
);
485 SmallVector
<std::string
, 16> DWOPaths
;
486 for (const auto &CU
: DWARFCtx
->compile_units()) {
487 const DWARFDie
&Die
= CU
->getUnitDIE();
488 std::string DWOName
= dwarf::toString(
489 Die
.find({dwarf::DW_AT_dwo_name
, dwarf::DW_AT_GNU_dwo_name
}), "");
492 std::string DWOCompDir
=
493 dwarf::toString(Die
.find(dwarf::DW_AT_comp_dir
), "");
494 if (!DWOCompDir
.empty()) {
495 SmallString
<16> DWOPath
;
496 sys::path::append(DWOPath
, DWOCompDir
, DWOName
);
497 DWOPaths
.emplace_back(DWOPath
.data(), DWOPath
.size());
499 DWOPaths
.push_back(std::move(DWOName
));
502 return std::move(DWOPaths
);
505 static Error
write(MCStreamer
&Out
, ArrayRef
<std::string
> Inputs
) {
506 const auto &MCOFI
= *Out
.getContext().getObjectFileInfo();
507 MCSection
*const StrSection
= MCOFI
.getDwarfStrDWOSection();
508 MCSection
*const StrOffsetSection
= MCOFI
.getDwarfStrOffDWOSection();
509 MCSection
*const TypesSection
= MCOFI
.getDwarfTypesDWOSection();
510 MCSection
*const CUIndexSection
= MCOFI
.getDwarfCUIndexSection();
511 MCSection
*const TUIndexSection
= MCOFI
.getDwarfTUIndexSection();
512 const StringMap
<std::pair
<MCSection
*, DWARFSectionKind
>> KnownSections
= {
513 {"debug_info.dwo", {MCOFI
.getDwarfInfoDWOSection(), DW_SECT_INFO
}},
514 {"debug_types.dwo", {MCOFI
.getDwarfTypesDWOSection(), DW_SECT_TYPES
}},
515 {"debug_str_offsets.dwo", {StrOffsetSection
, DW_SECT_STR_OFFSETS
}},
516 {"debug_str.dwo", {StrSection
, static_cast<DWARFSectionKind
>(0)}},
517 {"debug_loc.dwo", {MCOFI
.getDwarfLocDWOSection(), DW_SECT_LOC
}},
518 {"debug_line.dwo", {MCOFI
.getDwarfLineDWOSection(), DW_SECT_LINE
}},
519 {"debug_abbrev.dwo", {MCOFI
.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV
}},
520 {"debug_cu_index", {CUIndexSection
, static_cast<DWARFSectionKind
>(0)}},
521 {"debug_tu_index", {TUIndexSection
, static_cast<DWARFSectionKind
>(0)}}};
523 MapVector
<uint64_t, UnitIndexEntry
> IndexEntries
;
524 MapVector
<uint64_t, UnitIndexEntry
> TypeIndexEntries
;
526 uint32_t ContributionOffsets
[8] = {};
528 DWPStringPool
Strings(Out
, StrSection
);
530 SmallVector
<OwningBinary
<object::ObjectFile
>, 128> Objects
;
531 Objects
.reserve(Inputs
.size());
533 std::deque
<SmallString
<32>> UncompressedSections
;
535 for (const auto &Input
: Inputs
) {
536 auto ErrOrObj
= object::ObjectFile::createObjectFile(Input
);
538 return ErrOrObj
.takeError();
540 auto &Obj
= *ErrOrObj
->getBinary();
541 Objects
.push_back(std::move(*ErrOrObj
));
543 UnitIndexEntry CurEntry
= {};
545 StringRef CurStrSection
;
546 StringRef CurStrOffsetSection
;
547 std::vector
<StringRef
> CurTypesSection
;
548 StringRef InfoSection
;
549 StringRef AbbrevSection
;
550 StringRef CurCUIndexSection
;
551 StringRef CurTUIndexSection
;
553 for (const auto &Section
: Obj
.sections())
554 if (auto Err
= handleSection(
555 KnownSections
, StrSection
, StrOffsetSection
, TypesSection
,
556 CUIndexSection
, TUIndexSection
, Section
, Out
,
557 UncompressedSections
, ContributionOffsets
, CurEntry
,
558 CurStrSection
, CurStrOffsetSection
, CurTypesSection
, InfoSection
,
559 AbbrevSection
, CurCUIndexSection
, CurTUIndexSection
))
562 if (InfoSection
.empty())
565 writeStringsAndOffsets(Out
, Strings
, StrOffsetSection
, CurStrSection
,
566 CurStrOffsetSection
);
568 if (CurCUIndexSection
.empty()) {
569 Expected
<CompileUnitIdentifiers
> EID
= getCUIdentifiers(
570 AbbrevSection
, InfoSection
, CurStrOffsetSection
, CurStrSection
);
572 return createFileError(Input
, EID
.takeError());
573 const auto &ID
= *EID
;
574 auto P
= IndexEntries
.insert(std::make_pair(ID
.Signature
, CurEntry
));
576 return buildDuplicateError(*P
.first
, ID
, "");
577 P
.first
->second
.Name
= ID
.Name
;
578 P
.first
->second
.DWOName
= ID
.DWOName
;
579 addAllTypes(Out
, TypeIndexEntries
, TypesSection
, CurTypesSection
,
580 CurEntry
, ContributionOffsets
[DW_SECT_TYPES
- DW_SECT_INFO
]);
584 DWARFUnitIndex
CUIndex(DW_SECT_INFO
);
585 DataExtractor
CUIndexData(CurCUIndexSection
, Obj
.isLittleEndian(), 0);
586 if (!CUIndex
.parse(CUIndexData
))
587 return make_error
<DWPError
>("Failed to parse cu_index");
589 for (const DWARFUnitIndex::Entry
&E
: CUIndex
.getRows()) {
590 auto *I
= E
.getOffsets();
593 auto P
= IndexEntries
.insert(std::make_pair(E
.getSignature(), CurEntry
));
594 Expected
<CompileUnitIdentifiers
> EID
= getCUIdentifiers(
595 getSubsection(AbbrevSection
, E
, DW_SECT_ABBREV
),
596 getSubsection(InfoSection
, E
, DW_SECT_INFO
),
597 getSubsection(CurStrOffsetSection
, E
, DW_SECT_STR_OFFSETS
),
600 return createFileError(Input
, EID
.takeError());
601 const auto &ID
= *EID
;
603 return buildDuplicateError(*P
.first
, ID
, Input
);
604 auto &NewEntry
= P
.first
->second
;
605 NewEntry
.Name
= ID
.Name
;
606 NewEntry
.DWOName
= ID
.DWOName
;
607 NewEntry
.DWPName
= Input
;
608 for (auto Kind
: CUIndex
.getColumnKinds()) {
609 auto &C
= NewEntry
.Contributions
[Kind
- DW_SECT_INFO
];
610 C
.Offset
+= I
->Offset
;
611 C
.Length
= I
->Length
;
616 if (!CurTypesSection
.empty()) {
617 if (CurTypesSection
.size() != 1)
618 return make_error
<DWPError
>("multiple type unit sections in .dwp file");
619 DWARFUnitIndex
TUIndex(DW_SECT_TYPES
);
620 DataExtractor
TUIndexData(CurTUIndexSection
, Obj
.isLittleEndian(), 0);
621 if (!TUIndex
.parse(TUIndexData
))
622 return make_error
<DWPError
>("Failed to parse tu_index");
623 addAllTypesFromDWP(Out
, TypeIndexEntries
, TUIndex
, TypesSection
,
624 CurTypesSection
.front(), CurEntry
,
625 ContributionOffsets
[DW_SECT_TYPES
- DW_SECT_INFO
]);
629 // Lie about there being no info contributions so the TU index only includes
630 // the type unit contribution
631 ContributionOffsets
[0] = 0;
632 writeIndex(Out
, MCOFI
.getDwarfTUIndexSection(), ContributionOffsets
,
635 // Lie about the type contribution
636 ContributionOffsets
[DW_SECT_TYPES
- DW_SECT_INFO
] = 0;
637 // Unlie about the info contribution
638 ContributionOffsets
[0] = 1;
640 writeIndex(Out
, MCOFI
.getDwarfCUIndexSection(), ContributionOffsets
,
643 return Error::success();
646 static int error(const Twine
&Error
, const Twine
&Context
) {
647 errs() << Twine("while processing ") + Context
+ ":\n";
648 errs() << Twine("error: ") + Error
+ "\n";
652 int main(int argc
, char **argv
) {
653 InitLLVM
X(argc
, argv
);
655 cl::ParseCommandLineOptions(argc
, argv
, "merge split dwarf (.dwo) files\n");
657 llvm::InitializeAllTargetInfos();
658 llvm::InitializeAllTargetMCs();
659 llvm::InitializeAllTargets();
660 llvm::InitializeAllAsmPrinters();
662 std::string ErrorStr
;
663 StringRef Context
= "dwarf streamer init";
665 Triple
TheTriple("x86_64-linux-gnu");
668 const Target
*TheTarget
=
669 TargetRegistry::lookupTarget("", TheTriple
, ErrorStr
);
671 return error(ErrorStr
, Context
);
672 std::string TripleName
= TheTriple
.getTriple();
674 // Create all the MC Objects.
675 std::unique_ptr
<MCRegisterInfo
> MRI(TheTarget
->createMCRegInfo(TripleName
));
677 return error(Twine("no register info for target ") + TripleName
, Context
);
679 std::unique_ptr
<MCAsmInfo
> MAI(TheTarget
->createMCAsmInfo(*MRI
, TripleName
));
681 return error("no asm info for target " + TripleName
, Context
);
683 MCObjectFileInfo MOFI
;
684 MCContext
MC(MAI
.get(), MRI
.get(), &MOFI
);
685 MOFI
.InitMCObjectFileInfo(TheTriple
, /*PIC*/ false, MC
);
687 std::unique_ptr
<MCSubtargetInfo
> MSTI(
688 TheTarget
->createMCSubtargetInfo(TripleName
, "", ""));
690 return error("no subtarget info for target " + TripleName
, Context
);
692 MCTargetOptions Options
;
693 auto MAB
= TheTarget
->createMCAsmBackend(*MSTI
, *MRI
, Options
);
695 return error("no asm backend for target " + TripleName
, Context
);
697 std::unique_ptr
<MCInstrInfo
> MII(TheTarget
->createMCInstrInfo());
699 return error("no instr info info for target " + TripleName
, Context
);
701 MCCodeEmitter
*MCE
= TheTarget
->createMCCodeEmitter(*MII
, *MRI
, MC
);
703 return error("no code emitter for target " + TripleName
, Context
);
705 // Create the output file.
707 ToolOutputFile
OutFile(OutputFilename
, EC
, sys::fs::OF_None
);
708 Optional
<buffer_ostream
> BOS
;
709 raw_pwrite_stream
*OS
;
711 return error(Twine(OutputFilename
) + ": " + EC
.message(), Context
);
712 if (OutFile
.os().supportsSeeking()) {
715 BOS
.emplace(OutFile
.os());
716 OS
= BOS
.getPointer();
719 MCTargetOptions MCOptions
= InitMCTargetOptionsFromFlags();
720 std::unique_ptr
<MCStreamer
> MS(TheTarget
->createMCObjectStreamer(
721 TheTriple
, MC
, std::unique_ptr
<MCAsmBackend
>(MAB
),
722 MAB
->createObjectWriter(*OS
), std::unique_ptr
<MCCodeEmitter
>(MCE
), *MSTI
,
723 MCOptions
.MCRelaxAll
, MCOptions
.MCIncrementalLinkerCompatible
,
724 /*DWARFMustBeAtTheEnd*/ false));
726 return error("no object streamer for target " + TripleName
, Context
);
728 std::vector
<std::string
> DWOFilenames
= InputFiles
;
729 for (const auto &ExecFilename
: ExecFilenames
) {
730 auto DWOs
= getDWOFilenames(ExecFilename
);
732 logAllUnhandledErrors(DWOs
.takeError(), WithColor::error());
735 DWOFilenames
.insert(DWOFilenames
.end(),
736 std::make_move_iterator(DWOs
->begin()),
737 std::make_move_iterator(DWOs
->end()));
740 if (auto Err
= write(*MS
, DWOFilenames
)) {
741 logAllUnhandledErrors(std::move(Err
), WithColor::error());