1 //===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF
13 //===----------------------------------------------------------------------===//
15 #include "DWPStringPool.h"
16 #include "llvm/ADT/MapVector.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/raw_ostream.h"
45 using namespace llvm::object
;
47 cl::OptionCategory
DwpCategory("Specific Options");
48 static cl::list
<std::string
> InputFiles(cl::Positional
, cl::ZeroOrMore
,
49 cl::desc("<input files>"),
50 cl::cat(DwpCategory
));
52 static cl::list
<std::string
> ExecFilenames(
54 cl::desc("Specify the executable/library files to get the list of *.dwo from"),
55 cl::value_desc("filename"), cl::cat(DwpCategory
));
57 static cl::opt
<std::string
> OutputFilename(cl::Required
, "o",
58 cl::desc("Specify the output file."),
59 cl::value_desc("filename"),
60 cl::cat(DwpCategory
));
62 static void writeStringsAndOffsets(MCStreamer
&Out
, DWPStringPool
&Strings
,
63 MCSection
*StrOffsetSection
,
64 StringRef CurStrSection
,
65 StringRef CurStrOffsetSection
) {
66 // Could possibly produce an error or warning if one of these was non-null but
67 // the other was null.
68 if (CurStrSection
.empty() || CurStrOffsetSection
.empty())
71 DenseMap
<uint32_t, uint32_t> OffsetRemapping
;
73 DataExtractor
Data(CurStrSection
, true, 0);
74 uint32_t LocalOffset
= 0;
75 uint32_t PrevOffset
= 0;
76 while (const char *s
= Data
.getCStr(&LocalOffset
)) {
77 OffsetRemapping
[PrevOffset
] =
78 Strings
.getOffset(s
, LocalOffset
- PrevOffset
);
79 PrevOffset
= LocalOffset
;
82 Data
= DataExtractor(CurStrOffsetSection
, true, 0);
84 Out
.SwitchSection(StrOffsetSection
);
87 uint64_t Size
= CurStrOffsetSection
.size();
88 while (Offset
< Size
) {
89 auto OldOffset
= Data
.getU32(&Offset
);
90 auto NewOffset
= OffsetRemapping
[OldOffset
];
91 Out
.EmitIntValue(NewOffset
, 4);
95 static uint32_t getCUAbbrev(StringRef Abbrev
, uint64_t AbbrCode
) {
98 DataExtractor
AbbrevData(Abbrev
, true, 0);
99 while ((CurCode
= AbbrevData
.getULEB128(&Offset
)) != AbbrCode
) {
101 AbbrevData
.getULEB128(&Offset
);
103 AbbrevData
.getU8(&Offset
);
105 while (AbbrevData
.getULEB128(&Offset
) | AbbrevData
.getULEB128(&Offset
))
111 struct CompileUnitIdentifiers
{
112 uint64_t Signature
= 0;
113 const char *Name
= "";
114 const char *DWOName
= "";
117 static Expected
<const char *>
118 getIndexedString(dwarf::Form Form
, DataExtractor InfoData
,
119 uint32_t &InfoOffset
, StringRef StrOffsets
, StringRef Str
) {
120 if (Form
== dwarf::DW_FORM_string
)
121 return InfoData
.getCStr(&InfoOffset
);
122 if (Form
!= dwarf::DW_FORM_GNU_str_index
)
123 return make_error
<DWPError
>(
124 "string field encoded without DW_FORM_string or DW_FORM_GNU_str_index");
125 auto StrIndex
= InfoData
.getULEB128(&InfoOffset
);
126 DataExtractor
StrOffsetsData(StrOffsets
, true, 0);
127 uint32_t StrOffsetsOffset
= 4 * StrIndex
;
128 uint32_t StrOffset
= StrOffsetsData
.getU32(&StrOffsetsOffset
);
129 DataExtractor
StrData(Str
, true, 0);
130 return StrData
.getCStr(&StrOffset
);
133 static Expected
<CompileUnitIdentifiers
> getCUIdentifiers(StringRef Abbrev
,
135 StringRef StrOffsets
,
138 DataExtractor
InfoData(Info
, true, 0);
139 dwarf::DwarfFormat Format
= dwarf::DwarfFormat::DWARF32
;
140 uint64_t Length
= InfoData
.getU32(&Offset
);
141 // If the length is 0xffffffff, then this indictes that this is a DWARF 64
142 // stream and the length is actually encoded into a 64 bit value that follows.
143 if (Length
== 0xffffffffU
) {
144 Format
= dwarf::DwarfFormat::DWARF64
;
145 Length
= InfoData
.getU64(&Offset
);
147 uint16_t Version
= InfoData
.getU16(&Offset
);
148 InfoData
.getU32(&Offset
); // Abbrev offset (should be zero)
149 uint8_t AddrSize
= InfoData
.getU8(&Offset
);
151 uint32_t AbbrCode
= InfoData
.getULEB128(&Offset
);
153 DataExtractor
AbbrevData(Abbrev
, true, 0);
154 uint32_t AbbrevOffset
= getCUAbbrev(Abbrev
, AbbrCode
);
155 auto Tag
= static_cast<dwarf::Tag
>(AbbrevData
.getULEB128(&AbbrevOffset
));
156 if (Tag
!= dwarf::DW_TAG_compile_unit
)
157 return make_error
<DWPError
>("top level DIE is not a compile unit");
159 AbbrevData
.getU8(&AbbrevOffset
);
162 CompileUnitIdentifiers ID
;
163 while ((Name
= AbbrevData
.getULEB128(&AbbrevOffset
)) |
164 (Form
= static_cast<dwarf::Form
>(AbbrevData
.getULEB128(&AbbrevOffset
))) &&
165 (Name
!= 0 || Form
!= 0)) {
167 case dwarf::DW_AT_name
: {
168 Expected
<const char *> EName
=
169 getIndexedString(Form
, InfoData
, Offset
, StrOffsets
, Str
);
171 return EName
.takeError();
175 case dwarf::DW_AT_GNU_dwo_name
: {
176 Expected
<const char *> EName
=
177 getIndexedString(Form
, InfoData
, Offset
, StrOffsets
, Str
);
179 return EName
.takeError();
183 case dwarf::DW_AT_GNU_dwo_id
:
184 ID
.Signature
= InfoData
.getU64(&Offset
);
187 DWARFFormValue::skipValue(Form
, InfoData
, &Offset
,
188 dwarf::FormParams({Version
, AddrSize
, Format
}));
194 struct UnitIndexEntry
{
195 DWARFUnitIndex::Entry::SectionContribution Contributions
[8];
201 static StringRef
getSubsection(StringRef Section
,
202 const DWARFUnitIndex::Entry
&Entry
,
203 DWARFSectionKind Kind
) {
204 const auto *Off
= Entry
.getOffset(Kind
);
207 return Section
.substr(Off
->Offset
, Off
->Length
);
210 static void addAllTypesFromDWP(
211 MCStreamer
&Out
, MapVector
<uint64_t, UnitIndexEntry
> &TypeIndexEntries
,
212 const DWARFUnitIndex
&TUIndex
, MCSection
*OutputTypes
, StringRef Types
,
213 const UnitIndexEntry
&TUEntry
, uint32_t &TypesOffset
) {
214 Out
.SwitchSection(OutputTypes
);
215 for (const DWARFUnitIndex::Entry
&E
: TUIndex
.getRows()) {
216 auto *I
= E
.getOffsets();
219 auto P
= TypeIndexEntries
.insert(std::make_pair(E
.getSignature(), TUEntry
));
222 auto &Entry
= P
.first
->second
;
223 // Zero out the debug_info contribution
224 Entry
.Contributions
[0] = {};
225 for (auto Kind
: TUIndex
.getColumnKinds()) {
226 auto &C
= Entry
.Contributions
[Kind
- DW_SECT_INFO
];
227 C
.Offset
+= I
->Offset
;
228 C
.Length
= I
->Length
;
231 auto &C
= Entry
.Contributions
[DW_SECT_TYPES
- DW_SECT_INFO
];
232 Out
.EmitBytes(Types
.substr(
233 C
.Offset
- TUEntry
.Contributions
[DW_SECT_TYPES
- DW_SECT_INFO
].Offset
,
235 C
.Offset
= TypesOffset
;
236 TypesOffset
+= C
.Length
;
240 static void addAllTypes(MCStreamer
&Out
,
241 MapVector
<uint64_t, UnitIndexEntry
> &TypeIndexEntries
,
242 MCSection
*OutputTypes
,
243 const std::vector
<StringRef
> &TypesSections
,
244 const UnitIndexEntry
&CUEntry
, uint32_t &TypesOffset
) {
245 for (StringRef Types
: TypesSections
) {
246 Out
.SwitchSection(OutputTypes
);
248 DataExtractor
Data(Types
, true, 0);
249 while (Data
.isValidOffset(Offset
)) {
250 UnitIndexEntry Entry
= CUEntry
;
251 // Zero out the debug_info contribution
252 Entry
.Contributions
[0] = {};
253 auto &C
= Entry
.Contributions
[DW_SECT_TYPES
- DW_SECT_INFO
];
254 C
.Offset
= TypesOffset
;
255 auto PrevOffset
= Offset
;
256 // Length of the unit, including the 4 byte length field.
257 C
.Length
= Data
.getU32(&Offset
) + 4;
259 Data
.getU16(&Offset
); // Version
260 Data
.getU32(&Offset
); // Abbrev offset
261 Data
.getU8(&Offset
); // Address size
262 auto Signature
= Data
.getU64(&Offset
);
263 Offset
= PrevOffset
+ C
.Length
;
265 auto P
= TypeIndexEntries
.insert(std::make_pair(Signature
, Entry
));
269 Out
.EmitBytes(Types
.substr(PrevOffset
, C
.Length
));
270 TypesOffset
+= C
.Length
;
276 writeIndexTable(MCStreamer
&Out
, ArrayRef
<unsigned> ContributionOffsets
,
277 const MapVector
<uint64_t, UnitIndexEntry
> &IndexEntries
,
278 uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field
) {
279 for (const auto &E
: IndexEntries
)
280 for (size_t i
= 0; i
!= array_lengthof(E
.second
.Contributions
); ++i
)
281 if (ContributionOffsets
[i
])
282 Out
.EmitIntValue(E
.second
.Contributions
[i
].*Field
, 4);
286 writeIndex(MCStreamer
&Out
, MCSection
*Section
,
287 ArrayRef
<unsigned> ContributionOffsets
,
288 const MapVector
<uint64_t, UnitIndexEntry
> &IndexEntries
) {
289 if (IndexEntries
.empty())
292 unsigned Columns
= 0;
293 for (auto &C
: ContributionOffsets
)
297 std::vector
<unsigned> Buckets(NextPowerOf2(3 * IndexEntries
.size() / 2));
298 uint64_t Mask
= Buckets
.size() - 1;
300 for (const auto &P
: IndexEntries
) {
303 auto HP
= ((S
>> 32) & Mask
) | 1;
305 assert(S
!= IndexEntries
.begin()[Buckets
[H
] - 1].first
&&
313 Out
.SwitchSection(Section
);
314 Out
.EmitIntValue(2, 4); // Version
315 Out
.EmitIntValue(Columns
, 4); // Columns
316 Out
.EmitIntValue(IndexEntries
.size(), 4); // Num Units
317 Out
.EmitIntValue(Buckets
.size(), 4); // Num Buckets
319 // Write the signatures.
320 for (const auto &I
: Buckets
)
321 Out
.EmitIntValue(I
? IndexEntries
.begin()[I
- 1].first
: 0, 8);
323 // Write the indexes.
324 for (const auto &I
: Buckets
)
325 Out
.EmitIntValue(I
, 4);
327 // Write the column headers (which sections will appear in the table)
328 for (size_t i
= 0; i
!= ContributionOffsets
.size(); ++i
)
329 if (ContributionOffsets
[i
])
330 Out
.EmitIntValue(i
+ DW_SECT_INFO
, 4);
332 // Write the offsets.
333 writeIndexTable(Out
, ContributionOffsets
, IndexEntries
,
334 &DWARFUnitIndex::Entry::SectionContribution::Offset
);
336 // Write the lengths.
337 writeIndexTable(Out
, ContributionOffsets
, IndexEntries
,
338 &DWARFUnitIndex::Entry::SectionContribution::Length
);
341 std::string
buildDWODescription(StringRef Name
, StringRef DWPName
, StringRef DWOName
) {
342 std::string Text
= "\'";
345 if (!DWPName
.empty()) {
347 if (!DWOName
.empty()) {
359 static Error
createError(StringRef Name
, Error E
) {
360 return make_error
<DWPError
>(
361 ("failure while decompressing compressed section: '" + Name
+ "', " +
362 llvm::toString(std::move(E
)))
367 handleCompressedSection(std::deque
<SmallString
<32>> &UncompressedSections
,
368 StringRef
&Name
, StringRef
&Contents
) {
369 if (!Decompressor::isGnuStyle(Name
))
370 return Error::success();
372 Expected
<Decompressor
> Dec
=
373 Decompressor::create(Name
, Contents
, false /*IsLE*/, false /*Is64Bit*/);
375 return createError(Name
, Dec
.takeError());
377 UncompressedSections
.emplace_back();
378 if (Error E
= Dec
->resizeAndDecompress(UncompressedSections
.back()))
379 return createError(Name
, std::move(E
));
381 Name
= Name
.substr(2); // Drop ".z"
382 Contents
= UncompressedSections
.back();
383 return Error::success();
386 static Error
handleSection(
387 const StringMap
<std::pair
<MCSection
*, DWARFSectionKind
>> &KnownSections
,
388 const MCSection
*StrSection
, const MCSection
*StrOffsetSection
,
389 const MCSection
*TypesSection
, const MCSection
*CUIndexSection
,
390 const MCSection
*TUIndexSection
, const SectionRef
&Section
, MCStreamer
&Out
,
391 std::deque
<SmallString
<32>> &UncompressedSections
,
392 uint32_t (&ContributionOffsets
)[8], UnitIndexEntry
&CurEntry
,
393 StringRef
&CurStrSection
, StringRef
&CurStrOffsetSection
,
394 std::vector
<StringRef
> &CurTypesSection
, StringRef
&InfoSection
,
395 StringRef
&AbbrevSection
, StringRef
&CurCUIndexSection
,
396 StringRef
&CurTUIndexSection
) {
398 return Error::success();
400 if (Section
.isVirtual())
401 return Error::success();
404 if (std::error_code Err
= Section
.getName(Name
))
405 return errorCodeToError(Err
);
408 if (auto Err
= Section
.getContents(Contents
))
409 return errorCodeToError(Err
);
411 if (auto Err
= handleCompressedSection(UncompressedSections
, Name
, Contents
))
414 Name
= Name
.substr(Name
.find_first_not_of("._"));
416 auto SectionPair
= KnownSections
.find(Name
);
417 if (SectionPair
== KnownSections
.end())
418 return Error::success();
420 if (DWARFSectionKind Kind
= SectionPair
->second
.second
) {
421 auto Index
= Kind
- DW_SECT_INFO
;
422 if (Kind
!= DW_SECT_TYPES
) {
423 CurEntry
.Contributions
[Index
].Offset
= ContributionOffsets
[Index
];
424 ContributionOffsets
[Index
] +=
425 (CurEntry
.Contributions
[Index
].Length
= Contents
.size());
430 InfoSection
= Contents
;
433 AbbrevSection
= Contents
;
440 MCSection
*OutSection
= SectionPair
->second
.first
;
441 if (OutSection
== StrOffsetSection
)
442 CurStrOffsetSection
= Contents
;
443 else if (OutSection
== StrSection
)
444 CurStrSection
= Contents
;
445 else if (OutSection
== TypesSection
)
446 CurTypesSection
.push_back(Contents
);
447 else if (OutSection
== CUIndexSection
)
448 CurCUIndexSection
= Contents
;
449 else if (OutSection
== TUIndexSection
)
450 CurTUIndexSection
= Contents
;
452 Out
.SwitchSection(OutSection
);
453 Out
.EmitBytes(Contents
);
455 return Error::success();
459 buildDuplicateError(const std::pair
<uint64_t, UnitIndexEntry
> &PrevE
,
460 const CompileUnitIdentifiers
&ID
, StringRef DWPName
) {
461 return make_error
<DWPError
>(
462 std::string("Duplicate DWO ID (") + utohexstr(PrevE
.first
) + ") in " +
463 buildDWODescription(PrevE
.second
.Name
, PrevE
.second
.DWPName
,
464 PrevE
.second
.DWOName
) +
465 " and " + buildDWODescription(ID
.Name
, DWPName
, ID
.DWOName
));
468 static Expected
<SmallVector
<std::string
, 16>>
469 getDWOFilenames(StringRef ExecFilename
) {
470 auto ErrOrObj
= object::ObjectFile::createObjectFile(ExecFilename
);
472 return ErrOrObj
.takeError();
474 const ObjectFile
&Obj
= *ErrOrObj
.get().getBinary();
475 std::unique_ptr
<DWARFContext
> DWARFCtx
= DWARFContext::create(Obj
);
477 SmallVector
<std::string
, 16> DWOPaths
;
478 for (const auto &CU
: DWARFCtx
->compile_units()) {
479 const DWARFDie
&Die
= CU
->getUnitDIE();
480 std::string DWOName
= dwarf::toString(
481 Die
.find({dwarf::DW_AT_dwo_name
, dwarf::DW_AT_GNU_dwo_name
}), "");
484 std::string DWOCompDir
=
485 dwarf::toString(Die
.find(dwarf::DW_AT_comp_dir
), "");
486 if (!DWOCompDir
.empty()) {
487 SmallString
<16> DWOPath
;
488 sys::path::append(DWOPath
, DWOCompDir
, DWOName
);
489 DWOPaths
.emplace_back(DWOPath
.data(), DWOPath
.size());
491 DWOPaths
.push_back(std::move(DWOName
));
494 return std::move(DWOPaths
);
497 static Error
write(MCStreamer
&Out
, ArrayRef
<std::string
> Inputs
) {
498 const auto &MCOFI
= *Out
.getContext().getObjectFileInfo();
499 MCSection
*const StrSection
= MCOFI
.getDwarfStrDWOSection();
500 MCSection
*const StrOffsetSection
= MCOFI
.getDwarfStrOffDWOSection();
501 MCSection
*const TypesSection
= MCOFI
.getDwarfTypesDWOSection();
502 MCSection
*const CUIndexSection
= MCOFI
.getDwarfCUIndexSection();
503 MCSection
*const TUIndexSection
= MCOFI
.getDwarfTUIndexSection();
504 const StringMap
<std::pair
<MCSection
*, DWARFSectionKind
>> KnownSections
= {
505 {"debug_info.dwo", {MCOFI
.getDwarfInfoDWOSection(), DW_SECT_INFO
}},
506 {"debug_types.dwo", {MCOFI
.getDwarfTypesDWOSection(), DW_SECT_TYPES
}},
507 {"debug_str_offsets.dwo", {StrOffsetSection
, DW_SECT_STR_OFFSETS
}},
508 {"debug_str.dwo", {StrSection
, static_cast<DWARFSectionKind
>(0)}},
509 {"debug_loc.dwo", {MCOFI
.getDwarfLocDWOSection(), DW_SECT_LOC
}},
510 {"debug_line.dwo", {MCOFI
.getDwarfLineDWOSection(), DW_SECT_LINE
}},
511 {"debug_abbrev.dwo", {MCOFI
.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV
}},
512 {"debug_cu_index", {CUIndexSection
, static_cast<DWARFSectionKind
>(0)}},
513 {"debug_tu_index", {TUIndexSection
, static_cast<DWARFSectionKind
>(0)}}};
515 MapVector
<uint64_t, UnitIndexEntry
> IndexEntries
;
516 MapVector
<uint64_t, UnitIndexEntry
> TypeIndexEntries
;
518 uint32_t ContributionOffsets
[8] = {};
520 DWPStringPool
Strings(Out
, StrSection
);
522 SmallVector
<OwningBinary
<object::ObjectFile
>, 128> Objects
;
523 Objects
.reserve(Inputs
.size());
525 std::deque
<SmallString
<32>> UncompressedSections
;
527 for (const auto &Input
: Inputs
) {
528 auto ErrOrObj
= object::ObjectFile::createObjectFile(Input
);
530 return ErrOrObj
.takeError();
532 auto &Obj
= *ErrOrObj
->getBinary();
533 Objects
.push_back(std::move(*ErrOrObj
));
535 UnitIndexEntry CurEntry
= {};
537 StringRef CurStrSection
;
538 StringRef CurStrOffsetSection
;
539 std::vector
<StringRef
> CurTypesSection
;
540 StringRef InfoSection
;
541 StringRef AbbrevSection
;
542 StringRef CurCUIndexSection
;
543 StringRef CurTUIndexSection
;
545 for (const auto &Section
: Obj
.sections())
546 if (auto Err
= handleSection(
547 KnownSections
, StrSection
, StrOffsetSection
, TypesSection
,
548 CUIndexSection
, TUIndexSection
, Section
, Out
,
549 UncompressedSections
, ContributionOffsets
, CurEntry
,
550 CurStrSection
, CurStrOffsetSection
, CurTypesSection
, InfoSection
,
551 AbbrevSection
, CurCUIndexSection
, CurTUIndexSection
))
554 if (InfoSection
.empty())
557 writeStringsAndOffsets(Out
, Strings
, StrOffsetSection
, CurStrSection
,
558 CurStrOffsetSection
);
560 if (CurCUIndexSection
.empty()) {
561 Expected
<CompileUnitIdentifiers
> EID
= getCUIdentifiers(
562 AbbrevSection
, InfoSection
, CurStrOffsetSection
, CurStrSection
);
564 return EID
.takeError();
565 const auto &ID
= *EID
;
566 auto P
= IndexEntries
.insert(std::make_pair(ID
.Signature
, CurEntry
));
568 return buildDuplicateError(*P
.first
, ID
, "");
569 P
.first
->second
.Name
= ID
.Name
;
570 P
.first
->second
.DWOName
= ID
.DWOName
;
571 addAllTypes(Out
, TypeIndexEntries
, TypesSection
, CurTypesSection
,
572 CurEntry
, ContributionOffsets
[DW_SECT_TYPES
- DW_SECT_INFO
]);
576 DWARFUnitIndex
CUIndex(DW_SECT_INFO
);
577 DataExtractor
CUIndexData(CurCUIndexSection
, Obj
.isLittleEndian(), 0);
578 if (!CUIndex
.parse(CUIndexData
))
579 return make_error
<DWPError
>("Failed to parse cu_index");
581 for (const DWARFUnitIndex::Entry
&E
: CUIndex
.getRows()) {
582 auto *I
= E
.getOffsets();
585 auto P
= IndexEntries
.insert(std::make_pair(E
.getSignature(), CurEntry
));
586 Expected
<CompileUnitIdentifiers
> EID
= getCUIdentifiers(
587 getSubsection(AbbrevSection
, E
, DW_SECT_ABBREV
),
588 getSubsection(InfoSection
, E
, DW_SECT_INFO
),
589 getSubsection(CurStrOffsetSection
, E
, DW_SECT_STR_OFFSETS
),
592 return EID
.takeError();
593 const auto &ID
= *EID
;
595 return buildDuplicateError(*P
.first
, ID
, Input
);
596 auto &NewEntry
= P
.first
->second
;
597 NewEntry
.Name
= ID
.Name
;
598 NewEntry
.DWOName
= ID
.DWOName
;
599 NewEntry
.DWPName
= Input
;
600 for (auto Kind
: CUIndex
.getColumnKinds()) {
601 auto &C
= NewEntry
.Contributions
[Kind
- DW_SECT_INFO
];
602 C
.Offset
+= I
->Offset
;
603 C
.Length
= I
->Length
;
608 if (!CurTypesSection
.empty()) {
609 if (CurTypesSection
.size() != 1)
610 return make_error
<DWPError
>("multiple type unit sections in .dwp file");
611 DWARFUnitIndex
TUIndex(DW_SECT_TYPES
);
612 DataExtractor
TUIndexData(CurTUIndexSection
, Obj
.isLittleEndian(), 0);
613 if (!TUIndex
.parse(TUIndexData
))
614 return make_error
<DWPError
>("Failed to parse tu_index");
615 addAllTypesFromDWP(Out
, TypeIndexEntries
, TUIndex
, TypesSection
,
616 CurTypesSection
.front(), CurEntry
,
617 ContributionOffsets
[DW_SECT_TYPES
- DW_SECT_INFO
]);
621 // Lie about there being no info contributions so the TU index only includes
622 // the type unit contribution
623 ContributionOffsets
[0] = 0;
624 writeIndex(Out
, MCOFI
.getDwarfTUIndexSection(), ContributionOffsets
,
627 // Lie about the type contribution
628 ContributionOffsets
[DW_SECT_TYPES
- DW_SECT_INFO
] = 0;
629 // Unlie about the info contribution
630 ContributionOffsets
[0] = 1;
632 writeIndex(Out
, MCOFI
.getDwarfCUIndexSection(), ContributionOffsets
,
635 return Error::success();
638 static int error(const Twine
&Error
, const Twine
&Context
) {
639 errs() << Twine("while processing ") + Context
+ ":\n";
640 errs() << Twine("error: ") + Error
+ "\n";
644 int main(int argc
, char **argv
) {
645 InitLLVM
X(argc
, argv
);
647 cl::ParseCommandLineOptions(argc
, argv
, "merge split dwarf (.dwo) files\n");
649 llvm::InitializeAllTargetInfos();
650 llvm::InitializeAllTargetMCs();
651 llvm::InitializeAllTargets();
652 llvm::InitializeAllAsmPrinters();
654 std::string ErrorStr
;
655 StringRef Context
= "dwarf streamer init";
657 Triple
TheTriple("x86_64-linux-gnu");
660 const Target
*TheTarget
=
661 TargetRegistry::lookupTarget("", TheTriple
, ErrorStr
);
663 return error(ErrorStr
, Context
);
664 std::string TripleName
= TheTriple
.getTriple();
666 // Create all the MC Objects.
667 std::unique_ptr
<MCRegisterInfo
> MRI(TheTarget
->createMCRegInfo(TripleName
));
669 return error(Twine("no register info for target ") + TripleName
, Context
);
671 std::unique_ptr
<MCAsmInfo
> MAI(TheTarget
->createMCAsmInfo(*MRI
, TripleName
));
673 return error("no asm info for target " + TripleName
, Context
);
675 MCObjectFileInfo MOFI
;
676 MCContext
MC(MAI
.get(), MRI
.get(), &MOFI
);
677 MOFI
.InitMCObjectFileInfo(TheTriple
, /*PIC*/ false, MC
);
679 std::unique_ptr
<MCSubtargetInfo
> MSTI(
680 TheTarget
->createMCSubtargetInfo(TripleName
, "", ""));
682 return error("no subtarget info for target " + TripleName
, Context
);
684 MCTargetOptions Options
;
685 auto MAB
= TheTarget
->createMCAsmBackend(*MSTI
, *MRI
, Options
);
687 return error("no asm backend for target " + TripleName
, Context
);
689 std::unique_ptr
<MCInstrInfo
> MII(TheTarget
->createMCInstrInfo());
691 return error("no instr info info for target " + TripleName
, Context
);
693 MCCodeEmitter
*MCE
= TheTarget
->createMCCodeEmitter(*MII
, *MRI
, MC
);
695 return error("no code emitter for target " + TripleName
, Context
);
697 // Create the output file.
699 raw_fd_ostream
OutFile(OutputFilename
, EC
, sys::fs::F_None
);
700 Optional
<buffer_ostream
> BOS
;
701 raw_pwrite_stream
*OS
;
703 return error(Twine(OutputFilename
) + ": " + EC
.message(), Context
);
704 if (OutFile
.supportsSeeking()) {
707 BOS
.emplace(OutFile
);
708 OS
= BOS
.getPointer();
711 MCTargetOptions MCOptions
= InitMCTargetOptionsFromFlags();
712 std::unique_ptr
<MCStreamer
> MS(TheTarget
->createMCObjectStreamer(
713 TheTriple
, MC
, std::unique_ptr
<MCAsmBackend
>(MAB
),
714 MAB
->createObjectWriter(*OS
), std::unique_ptr
<MCCodeEmitter
>(MCE
),
715 *MSTI
, MCOptions
.MCRelaxAll
, MCOptions
.MCIncrementalLinkerCompatible
,
716 /*DWARFMustBeAtTheEnd*/ false));
718 return error("no object streamer for target " + TripleName
, Context
);
720 std::vector
<std::string
> DWOFilenames
= InputFiles
;
721 for (const auto &ExecFilename
: ExecFilenames
) {
722 auto DWOs
= getDWOFilenames(ExecFilename
);
724 logAllUnhandledErrors(DWOs
.takeError(), errs(), "error: ");
727 DWOFilenames
.insert(DWOFilenames
.end(),
728 std::make_move_iterator(DWOs
->begin()),
729 std::make_move_iterator(DWOs
->end()));
732 if (auto Err
= write(*MS
, DWOFilenames
)) {
733 logAllUnhandledErrors(std::move(Err
), errs(), "error: ");