1*9880d681SAndroid Build Coastguard Worker //===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF
11*9880d681SAndroid Build Coastguard Worker // package files).
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker #include "DWPError.h"
15*9880d681SAndroid Build Coastguard Worker #include "DWPStringPool.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/MapVector.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSet.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/AsmPrinter.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectFileInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionELF.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCTargetOptionsCommandFlags.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Compression.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataExtractor.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Error.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Options.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetSelect.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
42*9880d681SAndroid Build Coastguard Worker #include <deque>
43*9880d681SAndroid Build Coastguard Worker #include <iostream>
44*9880d681SAndroid Build Coastguard Worker #include <memory>
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker using namespace llvm;
47*9880d681SAndroid Build Coastguard Worker using namespace llvm::object;
48*9880d681SAndroid Build Coastguard Worker using namespace cl;
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker OptionCategory DwpCategory("Specific Options");
51*9880d681SAndroid Build Coastguard Worker static list<std::string> InputFiles(Positional, OneOrMore,
52*9880d681SAndroid Build Coastguard Worker desc("<input files>"), cat(DwpCategory));
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker static opt<std::string> OutputFilename(Required, "o",
55*9880d681SAndroid Build Coastguard Worker desc("Specify the output file."),
56*9880d681SAndroid Build Coastguard Worker value_desc("filename"),
57*9880d681SAndroid Build Coastguard Worker cat(DwpCategory));
58*9880d681SAndroid Build Coastguard Worker
writeStringsAndOffsets(MCStreamer & Out,DWPStringPool & Strings,MCSection * StrOffsetSection,StringRef CurStrSection,StringRef CurStrOffsetSection)59*9880d681SAndroid Build Coastguard Worker static void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
60*9880d681SAndroid Build Coastguard Worker MCSection *StrOffsetSection,
61*9880d681SAndroid Build Coastguard Worker StringRef CurStrSection,
62*9880d681SAndroid Build Coastguard Worker StringRef CurStrOffsetSection) {
63*9880d681SAndroid Build Coastguard Worker // Could possibly produce an error or warning if one of these was non-null but
64*9880d681SAndroid Build Coastguard Worker // the other was null.
65*9880d681SAndroid Build Coastguard Worker if (CurStrSection.empty() || CurStrOffsetSection.empty())
66*9880d681SAndroid Build Coastguard Worker return;
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker DenseMap<uint32_t, uint32_t> OffsetRemapping;
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker DataExtractor Data(CurStrSection, true, 0);
71*9880d681SAndroid Build Coastguard Worker uint32_t LocalOffset = 0;
72*9880d681SAndroid Build Coastguard Worker uint32_t PrevOffset = 0;
73*9880d681SAndroid Build Coastguard Worker while (const char *s = Data.getCStr(&LocalOffset)) {
74*9880d681SAndroid Build Coastguard Worker OffsetRemapping[PrevOffset] =
75*9880d681SAndroid Build Coastguard Worker Strings.getOffset(s, LocalOffset - PrevOffset);
76*9880d681SAndroid Build Coastguard Worker PrevOffset = LocalOffset;
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker Data = DataExtractor(CurStrOffsetSection, true, 0);
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker Out.SwitchSection(StrOffsetSection);
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
84*9880d681SAndroid Build Coastguard Worker uint64_t Size = CurStrOffsetSection.size();
85*9880d681SAndroid Build Coastguard Worker while (Offset < Size) {
86*9880d681SAndroid Build Coastguard Worker auto OldOffset = Data.getU32(&Offset);
87*9880d681SAndroid Build Coastguard Worker auto NewOffset = OffsetRemapping[OldOffset];
88*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(NewOffset, 4);
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker
getCUAbbrev(StringRef Abbrev,uint64_t AbbrCode)92*9880d681SAndroid Build Coastguard Worker static uint32_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
93*9880d681SAndroid Build Coastguard Worker uint64_t CurCode;
94*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
95*9880d681SAndroid Build Coastguard Worker DataExtractor AbbrevData(Abbrev, true, 0);
96*9880d681SAndroid Build Coastguard Worker while ((CurCode = AbbrevData.getULEB128(&Offset)) != AbbrCode) {
97*9880d681SAndroid Build Coastguard Worker // Tag
98*9880d681SAndroid Build Coastguard Worker AbbrevData.getULEB128(&Offset);
99*9880d681SAndroid Build Coastguard Worker // DW_CHILDREN
100*9880d681SAndroid Build Coastguard Worker AbbrevData.getU8(&Offset);
101*9880d681SAndroid Build Coastguard Worker // Attributes
102*9880d681SAndroid Build Coastguard Worker while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
103*9880d681SAndroid Build Coastguard Worker ;
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker return Offset;
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker struct CompileUnitIdentifiers {
109*9880d681SAndroid Build Coastguard Worker uint64_t Signature = 0;
110*9880d681SAndroid Build Coastguard Worker const char *Name = "";
111*9880d681SAndroid Build Coastguard Worker const char *DWOName = "";
112*9880d681SAndroid Build Coastguard Worker };
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker static Expected<const char *>
getIndexedString(uint32_t Form,DataExtractor InfoData,uint32_t & InfoOffset,StringRef StrOffsets,StringRef Str)115*9880d681SAndroid Build Coastguard Worker getIndexedString(uint32_t Form, DataExtractor InfoData, uint32_t &InfoOffset,
116*9880d681SAndroid Build Coastguard Worker StringRef StrOffsets, StringRef Str) {
117*9880d681SAndroid Build Coastguard Worker if (Form == dwarf::DW_FORM_string)
118*9880d681SAndroid Build Coastguard Worker return InfoData.getCStr(&InfoOffset);
119*9880d681SAndroid Build Coastguard Worker if (Form != dwarf::DW_FORM_GNU_str_index)
120*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>(
121*9880d681SAndroid Build Coastguard Worker "string field encoded without DW_FORM_string or DW_FORM_GNU_str_index");
122*9880d681SAndroid Build Coastguard Worker auto StrIndex = InfoData.getULEB128(&InfoOffset);
123*9880d681SAndroid Build Coastguard Worker DataExtractor StrOffsetsData(StrOffsets, true, 0);
124*9880d681SAndroid Build Coastguard Worker uint32_t StrOffsetsOffset = 4 * StrIndex;
125*9880d681SAndroid Build Coastguard Worker uint32_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
126*9880d681SAndroid Build Coastguard Worker DataExtractor StrData(Str, true, 0);
127*9880d681SAndroid Build Coastguard Worker return StrData.getCStr(&StrOffset);
128*9880d681SAndroid Build Coastguard Worker }
129*9880d681SAndroid Build Coastguard Worker
getCUIdentifiers(StringRef Abbrev,StringRef Info,StringRef StrOffsets,StringRef Str)130*9880d681SAndroid Build Coastguard Worker static Expected<CompileUnitIdentifiers> getCUIdentifiers(StringRef Abbrev,
131*9880d681SAndroid Build Coastguard Worker StringRef Info,
132*9880d681SAndroid Build Coastguard Worker StringRef StrOffsets,
133*9880d681SAndroid Build Coastguard Worker StringRef Str) {
134*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
135*9880d681SAndroid Build Coastguard Worker DataExtractor InfoData(Info, true, 0);
136*9880d681SAndroid Build Coastguard Worker InfoData.getU32(&Offset); // Length
137*9880d681SAndroid Build Coastguard Worker uint16_t Version = InfoData.getU16(&Offset);
138*9880d681SAndroid Build Coastguard Worker InfoData.getU32(&Offset); // Abbrev offset (should be zero)
139*9880d681SAndroid Build Coastguard Worker uint8_t AddrSize = InfoData.getU8(&Offset);
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker uint32_t AbbrCode = InfoData.getULEB128(&Offset);
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker DataExtractor AbbrevData(Abbrev, true, 0);
144*9880d681SAndroid Build Coastguard Worker uint32_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
145*9880d681SAndroid Build Coastguard Worker uint64_t Tag = AbbrevData.getULEB128(&AbbrevOffset);
146*9880d681SAndroid Build Coastguard Worker if (Tag != dwarf::DW_TAG_compile_unit)
147*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>("top level DIE is not a compile unit");
148*9880d681SAndroid Build Coastguard Worker // DW_CHILDREN
149*9880d681SAndroid Build Coastguard Worker AbbrevData.getU8(&AbbrevOffset);
150*9880d681SAndroid Build Coastguard Worker uint32_t Name;
151*9880d681SAndroid Build Coastguard Worker uint32_t Form;
152*9880d681SAndroid Build Coastguard Worker CompileUnitIdentifiers ID;
153*9880d681SAndroid Build Coastguard Worker while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
154*9880d681SAndroid Build Coastguard Worker (Form = AbbrevData.getULEB128(&AbbrevOffset)) &&
155*9880d681SAndroid Build Coastguard Worker (Name != 0 || Form != 0)) {
156*9880d681SAndroid Build Coastguard Worker switch (Name) {
157*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_name: {
158*9880d681SAndroid Build Coastguard Worker Expected<const char *> EName =
159*9880d681SAndroid Build Coastguard Worker getIndexedString(Form, InfoData, Offset, StrOffsets, Str);
160*9880d681SAndroid Build Coastguard Worker if (!EName)
161*9880d681SAndroid Build Coastguard Worker return EName.takeError();
162*9880d681SAndroid Build Coastguard Worker ID.Name = *EName;
163*9880d681SAndroid Build Coastguard Worker break;
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_GNU_dwo_name: {
166*9880d681SAndroid Build Coastguard Worker Expected<const char *> EName =
167*9880d681SAndroid Build Coastguard Worker getIndexedString(Form, InfoData, Offset, StrOffsets, Str);
168*9880d681SAndroid Build Coastguard Worker if (!EName)
169*9880d681SAndroid Build Coastguard Worker return EName.takeError();
170*9880d681SAndroid Build Coastguard Worker ID.DWOName = *EName;
171*9880d681SAndroid Build Coastguard Worker break;
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker case dwarf::DW_AT_GNU_dwo_id:
174*9880d681SAndroid Build Coastguard Worker ID.Signature = InfoData.getU64(&Offset);
175*9880d681SAndroid Build Coastguard Worker break;
176*9880d681SAndroid Build Coastguard Worker default:
177*9880d681SAndroid Build Coastguard Worker DWARFFormValue::skipValue(Form, InfoData, &Offset, Version, AddrSize);
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker return ID;
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker struct UnitIndexEntry {
184*9880d681SAndroid Build Coastguard Worker DWARFUnitIndex::Entry::SectionContribution Contributions[8];
185*9880d681SAndroid Build Coastguard Worker std::string Name;
186*9880d681SAndroid Build Coastguard Worker std::string DWOName;
187*9880d681SAndroid Build Coastguard Worker StringRef DWPName;
188*9880d681SAndroid Build Coastguard Worker };
189*9880d681SAndroid Build Coastguard Worker
getSubsection(StringRef Section,const DWARFUnitIndex::Entry & Entry,DWARFSectionKind Kind)190*9880d681SAndroid Build Coastguard Worker static StringRef getSubsection(StringRef Section,
191*9880d681SAndroid Build Coastguard Worker const DWARFUnitIndex::Entry &Entry,
192*9880d681SAndroid Build Coastguard Worker DWARFSectionKind Kind) {
193*9880d681SAndroid Build Coastguard Worker const auto *Off = Entry.getOffset(Kind);
194*9880d681SAndroid Build Coastguard Worker if (!Off)
195*9880d681SAndroid Build Coastguard Worker return StringRef();
196*9880d681SAndroid Build Coastguard Worker return Section.substr(Off->Offset, Off->Length);
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker
addAllTypesFromDWP(MCStreamer & Out,MapVector<uint64_t,UnitIndexEntry> & TypeIndexEntries,const DWARFUnitIndex & TUIndex,MCSection * OutputTypes,StringRef Types,const UnitIndexEntry & TUEntry,uint32_t & TypesOffset)199*9880d681SAndroid Build Coastguard Worker static void addAllTypesFromDWP(
200*9880d681SAndroid Build Coastguard Worker MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
201*9880d681SAndroid Build Coastguard Worker const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types,
202*9880d681SAndroid Build Coastguard Worker const UnitIndexEntry &TUEntry, uint32_t &TypesOffset) {
203*9880d681SAndroid Build Coastguard Worker Out.SwitchSection(OutputTypes);
204*9880d681SAndroid Build Coastguard Worker for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
205*9880d681SAndroid Build Coastguard Worker auto *I = E.getOffsets();
206*9880d681SAndroid Build Coastguard Worker if (!I)
207*9880d681SAndroid Build Coastguard Worker continue;
208*9880d681SAndroid Build Coastguard Worker auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
209*9880d681SAndroid Build Coastguard Worker if (!P.second)
210*9880d681SAndroid Build Coastguard Worker continue;
211*9880d681SAndroid Build Coastguard Worker auto &Entry = P.first->second;
212*9880d681SAndroid Build Coastguard Worker // Zero out the debug_info contribution
213*9880d681SAndroid Build Coastguard Worker Entry.Contributions[0] = {};
214*9880d681SAndroid Build Coastguard Worker for (auto Kind : TUIndex.getColumnKinds()) {
215*9880d681SAndroid Build Coastguard Worker auto &C = Entry.Contributions[Kind - DW_SECT_INFO];
216*9880d681SAndroid Build Coastguard Worker C.Offset += I->Offset;
217*9880d681SAndroid Build Coastguard Worker C.Length = I->Length;
218*9880d681SAndroid Build Coastguard Worker ++I;
219*9880d681SAndroid Build Coastguard Worker }
220*9880d681SAndroid Build Coastguard Worker auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
221*9880d681SAndroid Build Coastguard Worker Out.EmitBytes(Types.substr(
222*9880d681SAndroid Build Coastguard Worker C.Offset - TUEntry.Contributions[DW_SECT_TYPES - DW_SECT_INFO].Offset,
223*9880d681SAndroid Build Coastguard Worker C.Length));
224*9880d681SAndroid Build Coastguard Worker C.Offset = TypesOffset;
225*9880d681SAndroid Build Coastguard Worker TypesOffset += C.Length;
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker
addAllTypes(MCStreamer & Out,MapVector<uint64_t,UnitIndexEntry> & TypeIndexEntries,MCSection * OutputTypes,const std::vector<StringRef> & TypesSections,const UnitIndexEntry & CUEntry,uint32_t & TypesOffset)229*9880d681SAndroid Build Coastguard Worker static void addAllTypes(MCStreamer &Out,
230*9880d681SAndroid Build Coastguard Worker MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
231*9880d681SAndroid Build Coastguard Worker MCSection *OutputTypes,
232*9880d681SAndroid Build Coastguard Worker const std::vector<StringRef> &TypesSections,
233*9880d681SAndroid Build Coastguard Worker const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
234*9880d681SAndroid Build Coastguard Worker for (StringRef Types : TypesSections) {
235*9880d681SAndroid Build Coastguard Worker Out.SwitchSection(OutputTypes);
236*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
237*9880d681SAndroid Build Coastguard Worker DataExtractor Data(Types, true, 0);
238*9880d681SAndroid Build Coastguard Worker while (Data.isValidOffset(Offset)) {
239*9880d681SAndroid Build Coastguard Worker UnitIndexEntry Entry = CUEntry;
240*9880d681SAndroid Build Coastguard Worker // Zero out the debug_info contribution
241*9880d681SAndroid Build Coastguard Worker Entry.Contributions[0] = {};
242*9880d681SAndroid Build Coastguard Worker auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO];
243*9880d681SAndroid Build Coastguard Worker C.Offset = TypesOffset;
244*9880d681SAndroid Build Coastguard Worker auto PrevOffset = Offset;
245*9880d681SAndroid Build Coastguard Worker // Length of the unit, including the 4 byte length field.
246*9880d681SAndroid Build Coastguard Worker C.Length = Data.getU32(&Offset) + 4;
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker Data.getU16(&Offset); // Version
249*9880d681SAndroid Build Coastguard Worker Data.getU32(&Offset); // Abbrev offset
250*9880d681SAndroid Build Coastguard Worker Data.getU8(&Offset); // Address size
251*9880d681SAndroid Build Coastguard Worker auto Signature = Data.getU64(&Offset);
252*9880d681SAndroid Build Coastguard Worker Offset = PrevOffset + C.Length;
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
255*9880d681SAndroid Build Coastguard Worker if (!P.second)
256*9880d681SAndroid Build Coastguard Worker continue;
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker Out.EmitBytes(Types.substr(PrevOffset, C.Length));
259*9880d681SAndroid Build Coastguard Worker TypesOffset += C.Length;
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker static void
writeIndexTable(MCStreamer & Out,ArrayRef<unsigned> ContributionOffsets,const MapVector<uint64_t,UnitIndexEntry> & IndexEntries,uint32_t DWARFUnitIndex::Entry::SectionContribution::* Field)265*9880d681SAndroid Build Coastguard Worker writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
266*9880d681SAndroid Build Coastguard Worker const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
267*9880d681SAndroid Build Coastguard Worker uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) {
268*9880d681SAndroid Build Coastguard Worker for (const auto &E : IndexEntries)
269*9880d681SAndroid Build Coastguard Worker for (size_t i = 0; i != array_lengthof(E.second.Contributions); ++i)
270*9880d681SAndroid Build Coastguard Worker if (ContributionOffsets[i])
271*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(E.second.Contributions[i].*Field, 4);
272*9880d681SAndroid Build Coastguard Worker }
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker static void
writeIndex(MCStreamer & Out,MCSection * Section,ArrayRef<unsigned> ContributionOffsets,const MapVector<uint64_t,UnitIndexEntry> & IndexEntries)275*9880d681SAndroid Build Coastguard Worker writeIndex(MCStreamer &Out, MCSection *Section,
276*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> ContributionOffsets,
277*9880d681SAndroid Build Coastguard Worker const MapVector<uint64_t, UnitIndexEntry> &IndexEntries) {
278*9880d681SAndroid Build Coastguard Worker if (IndexEntries.empty())
279*9880d681SAndroid Build Coastguard Worker return;
280*9880d681SAndroid Build Coastguard Worker
281*9880d681SAndroid Build Coastguard Worker unsigned Columns = 0;
282*9880d681SAndroid Build Coastguard Worker for (auto &C : ContributionOffsets)
283*9880d681SAndroid Build Coastguard Worker if (C)
284*9880d681SAndroid Build Coastguard Worker ++Columns;
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
287*9880d681SAndroid Build Coastguard Worker uint64_t Mask = Buckets.size() - 1;
288*9880d681SAndroid Build Coastguard Worker size_t i = 0;
289*9880d681SAndroid Build Coastguard Worker for (const auto &P : IndexEntries) {
290*9880d681SAndroid Build Coastguard Worker auto S = P.first;
291*9880d681SAndroid Build Coastguard Worker auto H = S & Mask;
292*9880d681SAndroid Build Coastguard Worker auto HP = ((S >> 32) & Mask) | 1;
293*9880d681SAndroid Build Coastguard Worker while (Buckets[H]) {
294*9880d681SAndroid Build Coastguard Worker assert(S != IndexEntries.begin()[Buckets[H] - 1].first &&
295*9880d681SAndroid Build Coastguard Worker "Duplicate unit");
296*9880d681SAndroid Build Coastguard Worker H = (H + HP) & Mask;
297*9880d681SAndroid Build Coastguard Worker }
298*9880d681SAndroid Build Coastguard Worker Buckets[H] = i + 1;
299*9880d681SAndroid Build Coastguard Worker ++i;
300*9880d681SAndroid Build Coastguard Worker }
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker Out.SwitchSection(Section);
303*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(2, 4); // Version
304*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(Columns, 4); // Columns
305*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(IndexEntries.size(), 4); // Num Units
306*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(Buckets.size(), 4); // Num Buckets
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker // Write the signatures.
309*9880d681SAndroid Build Coastguard Worker for (const auto &I : Buckets)
310*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8);
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Worker // Write the indexes.
313*9880d681SAndroid Build Coastguard Worker for (const auto &I : Buckets)
314*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(I, 4);
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker // Write the column headers (which sections will appear in the table)
317*9880d681SAndroid Build Coastguard Worker for (size_t i = 0; i != ContributionOffsets.size(); ++i)
318*9880d681SAndroid Build Coastguard Worker if (ContributionOffsets[i])
319*9880d681SAndroid Build Coastguard Worker Out.EmitIntValue(i + DW_SECT_INFO, 4);
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker // Write the offsets.
322*9880d681SAndroid Build Coastguard Worker writeIndexTable(Out, ContributionOffsets, IndexEntries,
323*9880d681SAndroid Build Coastguard Worker &DWARFUnitIndex::Entry::SectionContribution::Offset);
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker // Write the lengths.
326*9880d681SAndroid Build Coastguard Worker writeIndexTable(Out, ContributionOffsets, IndexEntries,
327*9880d681SAndroid Build Coastguard Worker &DWARFUnitIndex::Entry::SectionContribution::Length);
328*9880d681SAndroid Build Coastguard Worker }
consumeCompressedDebugSectionHeader(StringRef & data,uint64_t & OriginalSize)329*9880d681SAndroid Build Coastguard Worker static bool consumeCompressedDebugSectionHeader(StringRef &data,
330*9880d681SAndroid Build Coastguard Worker uint64_t &OriginalSize) {
331*9880d681SAndroid Build Coastguard Worker // Consume "ZLIB" prefix.
332*9880d681SAndroid Build Coastguard Worker if (!data.startswith("ZLIB"))
333*9880d681SAndroid Build Coastguard Worker return false;
334*9880d681SAndroid Build Coastguard Worker data = data.substr(4);
335*9880d681SAndroid Build Coastguard Worker // Consume uncompressed section size (big-endian 8 bytes).
336*9880d681SAndroid Build Coastguard Worker DataExtractor extractor(data, false, 8);
337*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
338*9880d681SAndroid Build Coastguard Worker OriginalSize = extractor.getU64(&Offset);
339*9880d681SAndroid Build Coastguard Worker if (Offset == 0)
340*9880d681SAndroid Build Coastguard Worker return false;
341*9880d681SAndroid Build Coastguard Worker data = data.substr(Offset);
342*9880d681SAndroid Build Coastguard Worker return true;
343*9880d681SAndroid Build Coastguard Worker }
344*9880d681SAndroid Build Coastguard Worker
buildDWODescription(StringRef Name,StringRef DWPName,StringRef DWOName)345*9880d681SAndroid Build Coastguard Worker std::string buildDWODescription(StringRef Name, StringRef DWPName, StringRef DWOName) {
346*9880d681SAndroid Build Coastguard Worker std::string Text = "\'";
347*9880d681SAndroid Build Coastguard Worker Text += Name;
348*9880d681SAndroid Build Coastguard Worker Text += '\'';
349*9880d681SAndroid Build Coastguard Worker if (!DWPName.empty()) {
350*9880d681SAndroid Build Coastguard Worker Text += " (from ";
351*9880d681SAndroid Build Coastguard Worker if (!DWOName.empty()) {
352*9880d681SAndroid Build Coastguard Worker Text += '\'';
353*9880d681SAndroid Build Coastguard Worker Text += DWOName;
354*9880d681SAndroid Build Coastguard Worker Text += "' in ";
355*9880d681SAndroid Build Coastguard Worker }
356*9880d681SAndroid Build Coastguard Worker Text += '\'';
357*9880d681SAndroid Build Coastguard Worker Text += DWPName;
358*9880d681SAndroid Build Coastguard Worker Text += "')";
359*9880d681SAndroid Build Coastguard Worker }
360*9880d681SAndroid Build Coastguard Worker return Text;
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker
handleCompressedSection(std::deque<SmallString<32>> & UncompressedSections,StringRef & Name,StringRef & Contents)363*9880d681SAndroid Build Coastguard Worker static Error handleCompressedSection(
364*9880d681SAndroid Build Coastguard Worker std::deque<SmallString<32>> &UncompressedSections, StringRef &Name,
365*9880d681SAndroid Build Coastguard Worker StringRef &Contents) {
366*9880d681SAndroid Build Coastguard Worker if (!Name.startswith("zdebug_"))
367*9880d681SAndroid Build Coastguard Worker return Error();
368*9880d681SAndroid Build Coastguard Worker UncompressedSections.emplace_back();
369*9880d681SAndroid Build Coastguard Worker uint64_t OriginalSize;
370*9880d681SAndroid Build Coastguard Worker if (!zlib::isAvailable())
371*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>("zlib not available");
372*9880d681SAndroid Build Coastguard Worker if (!consumeCompressedDebugSectionHeader(Contents, OriginalSize) ||
373*9880d681SAndroid Build Coastguard Worker zlib::uncompress(Contents, UncompressedSections.back(), OriginalSize) !=
374*9880d681SAndroid Build Coastguard Worker zlib::StatusOK)
375*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>(
376*9880d681SAndroid Build Coastguard Worker ("failure while decompressing compressed section: '" + Name + "\'")
377*9880d681SAndroid Build Coastguard Worker .str());
378*9880d681SAndroid Build Coastguard Worker Name = Name.substr(1);
379*9880d681SAndroid Build Coastguard Worker Contents = UncompressedSections.back();
380*9880d681SAndroid Build Coastguard Worker return Error();
381*9880d681SAndroid Build Coastguard Worker }
382*9880d681SAndroid Build Coastguard Worker
handleSection(const StringMap<std::pair<MCSection *,DWARFSectionKind>> & KnownSections,const MCSection * StrSection,const MCSection * StrOffsetSection,const MCSection * TypesSection,const MCSection * CUIndexSection,const MCSection * TUIndexSection,const SectionRef & Section,MCStreamer & Out,std::deque<SmallString<32>> & UncompressedSections,uint32_t (& ContributionOffsets)[8],UnitIndexEntry & CurEntry,StringRef & CurStrSection,StringRef & CurStrOffsetSection,std::vector<StringRef> & CurTypesSection,StringRef & InfoSection,StringRef & AbbrevSection,StringRef & CurCUIndexSection,StringRef & CurTUIndexSection)383*9880d681SAndroid Build Coastguard Worker static Error handleSection(
384*9880d681SAndroid Build Coastguard Worker const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
385*9880d681SAndroid Build Coastguard Worker const MCSection *StrSection, const MCSection *StrOffsetSection,
386*9880d681SAndroid Build Coastguard Worker const MCSection *TypesSection, const MCSection *CUIndexSection,
387*9880d681SAndroid Build Coastguard Worker const MCSection *TUIndexSection, const SectionRef &Section, MCStreamer &Out,
388*9880d681SAndroid Build Coastguard Worker std::deque<SmallString<32>> &UncompressedSections,
389*9880d681SAndroid Build Coastguard Worker uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
390*9880d681SAndroid Build Coastguard Worker StringRef &CurStrSection, StringRef &CurStrOffsetSection,
391*9880d681SAndroid Build Coastguard Worker std::vector<StringRef> &CurTypesSection, StringRef &InfoSection,
392*9880d681SAndroid Build Coastguard Worker StringRef &AbbrevSection, StringRef &CurCUIndexSection,
393*9880d681SAndroid Build Coastguard Worker StringRef &CurTUIndexSection) {
394*9880d681SAndroid Build Coastguard Worker if (Section.isBSS())
395*9880d681SAndroid Build Coastguard Worker return Error();
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker if (Section.isVirtual())
398*9880d681SAndroid Build Coastguard Worker return Error();
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker StringRef Name;
401*9880d681SAndroid Build Coastguard Worker if (std::error_code Err = Section.getName(Name))
402*9880d681SAndroid Build Coastguard Worker return errorCodeToError(Err);
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker Name = Name.substr(Name.find_first_not_of("._"));
405*9880d681SAndroid Build Coastguard Worker
406*9880d681SAndroid Build Coastguard Worker StringRef Contents;
407*9880d681SAndroid Build Coastguard Worker if (auto Err = Section.getContents(Contents))
408*9880d681SAndroid Build Coastguard Worker return errorCodeToError(Err);
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Worker if (auto Err = handleCompressedSection(UncompressedSections, Name, Contents))
411*9880d681SAndroid Build Coastguard Worker return Err;
412*9880d681SAndroid Build Coastguard Worker
413*9880d681SAndroid Build Coastguard Worker auto SectionPair = KnownSections.find(Name);
414*9880d681SAndroid Build Coastguard Worker if (SectionPair == KnownSections.end())
415*9880d681SAndroid Build Coastguard Worker return Error();
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker if (DWARFSectionKind Kind = SectionPair->second.second) {
418*9880d681SAndroid Build Coastguard Worker auto Index = Kind - DW_SECT_INFO;
419*9880d681SAndroid Build Coastguard Worker if (Kind != DW_SECT_TYPES) {
420*9880d681SAndroid Build Coastguard Worker CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
421*9880d681SAndroid Build Coastguard Worker ContributionOffsets[Index] +=
422*9880d681SAndroid Build Coastguard Worker (CurEntry.Contributions[Index].Length = Contents.size());
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker
425*9880d681SAndroid Build Coastguard Worker switch (Kind) {
426*9880d681SAndroid Build Coastguard Worker case DW_SECT_INFO:
427*9880d681SAndroid Build Coastguard Worker InfoSection = Contents;
428*9880d681SAndroid Build Coastguard Worker break;
429*9880d681SAndroid Build Coastguard Worker case DW_SECT_ABBREV:
430*9880d681SAndroid Build Coastguard Worker AbbrevSection = Contents;
431*9880d681SAndroid Build Coastguard Worker break;
432*9880d681SAndroid Build Coastguard Worker default:
433*9880d681SAndroid Build Coastguard Worker break;
434*9880d681SAndroid Build Coastguard Worker }
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker MCSection *OutSection = SectionPair->second.first;
438*9880d681SAndroid Build Coastguard Worker if (OutSection == StrOffsetSection)
439*9880d681SAndroid Build Coastguard Worker CurStrOffsetSection = Contents;
440*9880d681SAndroid Build Coastguard Worker else if (OutSection == StrSection)
441*9880d681SAndroid Build Coastguard Worker CurStrSection = Contents;
442*9880d681SAndroid Build Coastguard Worker else if (OutSection == TypesSection)
443*9880d681SAndroid Build Coastguard Worker CurTypesSection.push_back(Contents);
444*9880d681SAndroid Build Coastguard Worker else if (OutSection == CUIndexSection)
445*9880d681SAndroid Build Coastguard Worker CurCUIndexSection = Contents;
446*9880d681SAndroid Build Coastguard Worker else if (OutSection == TUIndexSection)
447*9880d681SAndroid Build Coastguard Worker CurTUIndexSection = Contents;
448*9880d681SAndroid Build Coastguard Worker else {
449*9880d681SAndroid Build Coastguard Worker Out.SwitchSection(OutSection);
450*9880d681SAndroid Build Coastguard Worker Out.EmitBytes(Contents);
451*9880d681SAndroid Build Coastguard Worker }
452*9880d681SAndroid Build Coastguard Worker return Error();
453*9880d681SAndroid Build Coastguard Worker }
454*9880d681SAndroid Build Coastguard Worker
455*9880d681SAndroid Build Coastguard Worker static Error
buildDuplicateError(const std::pair<uint64_t,UnitIndexEntry> & PrevE,const CompileUnitIdentifiers & ID,StringRef DWPName)456*9880d681SAndroid Build Coastguard Worker buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
457*9880d681SAndroid Build Coastguard Worker const CompileUnitIdentifiers &ID, StringRef DWPName) {
458*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>(
459*9880d681SAndroid Build Coastguard Worker std::string("Duplicate DWO ID (") + utohexstr(PrevE.first) + ") in " +
460*9880d681SAndroid Build Coastguard Worker buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
461*9880d681SAndroid Build Coastguard Worker PrevE.second.DWOName) +
462*9880d681SAndroid Build Coastguard Worker " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
463*9880d681SAndroid Build Coastguard Worker }
464*9880d681SAndroid Build Coastguard Worker
write(MCStreamer & Out,ArrayRef<std::string> Inputs)465*9880d681SAndroid Build Coastguard Worker static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
466*9880d681SAndroid Build Coastguard Worker const auto &MCOFI = *Out.getContext().getObjectFileInfo();
467*9880d681SAndroid Build Coastguard Worker MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
468*9880d681SAndroid Build Coastguard Worker MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
469*9880d681SAndroid Build Coastguard Worker MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
470*9880d681SAndroid Build Coastguard Worker MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
471*9880d681SAndroid Build Coastguard Worker MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
472*9880d681SAndroid Build Coastguard Worker const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
473*9880d681SAndroid Build Coastguard Worker {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
474*9880d681SAndroid Build Coastguard Worker {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_TYPES}},
475*9880d681SAndroid Build Coastguard Worker {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
476*9880d681SAndroid Build Coastguard Worker {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
477*9880d681SAndroid Build Coastguard Worker {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_LOC}},
478*9880d681SAndroid Build Coastguard Worker {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
479*9880d681SAndroid Build Coastguard Worker {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
480*9880d681SAndroid Build Coastguard Worker {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
481*9880d681SAndroid Build Coastguard Worker {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Worker MapVector<uint64_t, UnitIndexEntry> IndexEntries;
484*9880d681SAndroid Build Coastguard Worker MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker uint32_t ContributionOffsets[8] = {};
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Worker DWPStringPool Strings(Out, StrSection);
489*9880d681SAndroid Build Coastguard Worker
490*9880d681SAndroid Build Coastguard Worker SmallVector<OwningBinary<object::ObjectFile>, 128> Objects;
491*9880d681SAndroid Build Coastguard Worker Objects.reserve(Inputs.size());
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Worker std::deque<SmallString<32>> UncompressedSections;
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker for (const auto &Input : Inputs) {
496*9880d681SAndroid Build Coastguard Worker auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
497*9880d681SAndroid Build Coastguard Worker if (!ErrOrObj)
498*9880d681SAndroid Build Coastguard Worker return ErrOrObj.takeError();
499*9880d681SAndroid Build Coastguard Worker
500*9880d681SAndroid Build Coastguard Worker auto &Obj = *ErrOrObj->getBinary();
501*9880d681SAndroid Build Coastguard Worker Objects.push_back(std::move(*ErrOrObj));
502*9880d681SAndroid Build Coastguard Worker
503*9880d681SAndroid Build Coastguard Worker UnitIndexEntry CurEntry = {};
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Worker StringRef CurStrSection;
506*9880d681SAndroid Build Coastguard Worker StringRef CurStrOffsetSection;
507*9880d681SAndroid Build Coastguard Worker std::vector<StringRef> CurTypesSection;
508*9880d681SAndroid Build Coastguard Worker StringRef InfoSection;
509*9880d681SAndroid Build Coastguard Worker StringRef AbbrevSection;
510*9880d681SAndroid Build Coastguard Worker StringRef CurCUIndexSection;
511*9880d681SAndroid Build Coastguard Worker StringRef CurTUIndexSection;
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker for (const auto &Section : Obj.sections())
514*9880d681SAndroid Build Coastguard Worker if (auto Err = handleSection(
515*9880d681SAndroid Build Coastguard Worker KnownSections, StrSection, StrOffsetSection, TypesSection,
516*9880d681SAndroid Build Coastguard Worker CUIndexSection, TUIndexSection, Section, Out,
517*9880d681SAndroid Build Coastguard Worker UncompressedSections, ContributionOffsets, CurEntry,
518*9880d681SAndroid Build Coastguard Worker CurStrSection, CurStrOffsetSection, CurTypesSection, InfoSection,
519*9880d681SAndroid Build Coastguard Worker AbbrevSection, CurCUIndexSection, CurTUIndexSection))
520*9880d681SAndroid Build Coastguard Worker return Err;
521*9880d681SAndroid Build Coastguard Worker
522*9880d681SAndroid Build Coastguard Worker if (InfoSection.empty())
523*9880d681SAndroid Build Coastguard Worker continue;
524*9880d681SAndroid Build Coastguard Worker
525*9880d681SAndroid Build Coastguard Worker writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
526*9880d681SAndroid Build Coastguard Worker CurStrOffsetSection);
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker if (CurCUIndexSection.empty()) {
529*9880d681SAndroid Build Coastguard Worker Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
530*9880d681SAndroid Build Coastguard Worker AbbrevSection, InfoSection, CurStrOffsetSection, CurStrSection);
531*9880d681SAndroid Build Coastguard Worker if (!EID)
532*9880d681SAndroid Build Coastguard Worker return EID.takeError();
533*9880d681SAndroid Build Coastguard Worker const auto &ID = *EID;
534*9880d681SAndroid Build Coastguard Worker auto P = IndexEntries.insert(std::make_pair(ID.Signature, CurEntry));
535*9880d681SAndroid Build Coastguard Worker if (!P.second)
536*9880d681SAndroid Build Coastguard Worker return buildDuplicateError(*P.first, ID, "");
537*9880d681SAndroid Build Coastguard Worker P.first->second.Name = ID.Name;
538*9880d681SAndroid Build Coastguard Worker P.first->second.DWOName = ID.DWOName;
539*9880d681SAndroid Build Coastguard Worker addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
540*9880d681SAndroid Build Coastguard Worker CurEntry, ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
541*9880d681SAndroid Build Coastguard Worker continue;
542*9880d681SAndroid Build Coastguard Worker }
543*9880d681SAndroid Build Coastguard Worker
544*9880d681SAndroid Build Coastguard Worker DWARFUnitIndex CUIndex(DW_SECT_INFO);
545*9880d681SAndroid Build Coastguard Worker DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
546*9880d681SAndroid Build Coastguard Worker if (!CUIndex.parse(CUIndexData))
547*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>("Failed to parse cu_index");
548*9880d681SAndroid Build Coastguard Worker
549*9880d681SAndroid Build Coastguard Worker for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
550*9880d681SAndroid Build Coastguard Worker auto *I = E.getOffsets();
551*9880d681SAndroid Build Coastguard Worker if (!I)
552*9880d681SAndroid Build Coastguard Worker continue;
553*9880d681SAndroid Build Coastguard Worker auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
554*9880d681SAndroid Build Coastguard Worker Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
555*9880d681SAndroid Build Coastguard Worker getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
556*9880d681SAndroid Build Coastguard Worker getSubsection(InfoSection, E, DW_SECT_INFO),
557*9880d681SAndroid Build Coastguard Worker getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
558*9880d681SAndroid Build Coastguard Worker CurStrSection);
559*9880d681SAndroid Build Coastguard Worker if (!EID)
560*9880d681SAndroid Build Coastguard Worker return EID.takeError();
561*9880d681SAndroid Build Coastguard Worker const auto &ID = *EID;
562*9880d681SAndroid Build Coastguard Worker if (!P.second)
563*9880d681SAndroid Build Coastguard Worker return buildDuplicateError(*P.first, ID, Input);
564*9880d681SAndroid Build Coastguard Worker auto &NewEntry = P.first->second;
565*9880d681SAndroid Build Coastguard Worker NewEntry.Name = ID.Name;
566*9880d681SAndroid Build Coastguard Worker NewEntry.DWOName = ID.DWOName;
567*9880d681SAndroid Build Coastguard Worker NewEntry.DWPName = Input;
568*9880d681SAndroid Build Coastguard Worker for (auto Kind : CUIndex.getColumnKinds()) {
569*9880d681SAndroid Build Coastguard Worker auto &C = NewEntry.Contributions[Kind - DW_SECT_INFO];
570*9880d681SAndroid Build Coastguard Worker C.Offset += I->Offset;
571*9880d681SAndroid Build Coastguard Worker C.Length = I->Length;
572*9880d681SAndroid Build Coastguard Worker ++I;
573*9880d681SAndroid Build Coastguard Worker }
574*9880d681SAndroid Build Coastguard Worker }
575*9880d681SAndroid Build Coastguard Worker
576*9880d681SAndroid Build Coastguard Worker if (!CurTypesSection.empty()) {
577*9880d681SAndroid Build Coastguard Worker if (CurTypesSection.size() != 1)
578*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>("multiple type unit sections in .dwp file");
579*9880d681SAndroid Build Coastguard Worker DWARFUnitIndex TUIndex(DW_SECT_TYPES);
580*9880d681SAndroid Build Coastguard Worker DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
581*9880d681SAndroid Build Coastguard Worker if (!TUIndex.parse(TUIndexData))
582*9880d681SAndroid Build Coastguard Worker return make_error<DWPError>("Failed to parse tu_index");
583*9880d681SAndroid Build Coastguard Worker addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, TypesSection,
584*9880d681SAndroid Build Coastguard Worker CurTypesSection.front(), CurEntry,
585*9880d681SAndroid Build Coastguard Worker ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
586*9880d681SAndroid Build Coastguard Worker }
587*9880d681SAndroid Build Coastguard Worker }
588*9880d681SAndroid Build Coastguard Worker
589*9880d681SAndroid Build Coastguard Worker // Lie about there being no info contributions so the TU index only includes
590*9880d681SAndroid Build Coastguard Worker // the type unit contribution
591*9880d681SAndroid Build Coastguard Worker ContributionOffsets[0] = 0;
592*9880d681SAndroid Build Coastguard Worker writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
593*9880d681SAndroid Build Coastguard Worker TypeIndexEntries);
594*9880d681SAndroid Build Coastguard Worker
595*9880d681SAndroid Build Coastguard Worker // Lie about the type contribution
596*9880d681SAndroid Build Coastguard Worker ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO] = 0;
597*9880d681SAndroid Build Coastguard Worker // Unlie about the info contribution
598*9880d681SAndroid Build Coastguard Worker ContributionOffsets[0] = 1;
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
601*9880d681SAndroid Build Coastguard Worker IndexEntries);
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker return Error();
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker
error(const Twine & Error,const Twine & Context)606*9880d681SAndroid Build Coastguard Worker static int error(const Twine &Error, const Twine &Context) {
607*9880d681SAndroid Build Coastguard Worker errs() << Twine("while processing ") + Context + ":\n";
608*9880d681SAndroid Build Coastguard Worker errs() << Twine("error: ") + Error + "\n";
609*9880d681SAndroid Build Coastguard Worker return 1;
610*9880d681SAndroid Build Coastguard Worker }
611*9880d681SAndroid Build Coastguard Worker
main(int argc,char ** argv)612*9880d681SAndroid Build Coastguard Worker int main(int argc, char **argv) {
613*9880d681SAndroid Build Coastguard Worker
614*9880d681SAndroid Build Coastguard Worker ParseCommandLineOptions(argc, argv, "merge split dwarf (.dwo) files");
615*9880d681SAndroid Build Coastguard Worker
616*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllTargetInfos();
617*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllTargetMCs();
618*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllTargets();
619*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllAsmPrinters();
620*9880d681SAndroid Build Coastguard Worker
621*9880d681SAndroid Build Coastguard Worker std::string ErrorStr;
622*9880d681SAndroid Build Coastguard Worker StringRef Context = "dwarf streamer init";
623*9880d681SAndroid Build Coastguard Worker
624*9880d681SAndroid Build Coastguard Worker Triple TheTriple("x86_64-linux-gnu");
625*9880d681SAndroid Build Coastguard Worker
626*9880d681SAndroid Build Coastguard Worker // Get the target.
627*9880d681SAndroid Build Coastguard Worker const Target *TheTarget =
628*9880d681SAndroid Build Coastguard Worker TargetRegistry::lookupTarget("", TheTriple, ErrorStr);
629*9880d681SAndroid Build Coastguard Worker if (!TheTarget)
630*9880d681SAndroid Build Coastguard Worker return error(ErrorStr, Context);
631*9880d681SAndroid Build Coastguard Worker std::string TripleName = TheTriple.getTriple();
632*9880d681SAndroid Build Coastguard Worker
633*9880d681SAndroid Build Coastguard Worker // Create all the MC Objects.
634*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
635*9880d681SAndroid Build Coastguard Worker if (!MRI)
636*9880d681SAndroid Build Coastguard Worker return error(Twine("no register info for target ") + TripleName, Context);
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
639*9880d681SAndroid Build Coastguard Worker if (!MAI)
640*9880d681SAndroid Build Coastguard Worker return error("no asm info for target " + TripleName, Context);
641*9880d681SAndroid Build Coastguard Worker
642*9880d681SAndroid Build Coastguard Worker MCObjectFileInfo MOFI;
643*9880d681SAndroid Build Coastguard Worker MCContext MC(MAI.get(), MRI.get(), &MOFI);
644*9880d681SAndroid Build Coastguard Worker MOFI.InitMCObjectFileInfo(TheTriple, /*PIC*/ false, CodeModel::Default, MC);
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker auto MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, "");
647*9880d681SAndroid Build Coastguard Worker if (!MAB)
648*9880d681SAndroid Build Coastguard Worker return error("no asm backend for target " + TripleName, Context);
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
651*9880d681SAndroid Build Coastguard Worker if (!MII)
652*9880d681SAndroid Build Coastguard Worker return error("no instr info info for target " + TripleName, Context);
653*9880d681SAndroid Build Coastguard Worker
654*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCSubtargetInfo> MSTI(
655*9880d681SAndroid Build Coastguard Worker TheTarget->createMCSubtargetInfo(TripleName, "", ""));
656*9880d681SAndroid Build Coastguard Worker if (!MSTI)
657*9880d681SAndroid Build Coastguard Worker return error("no subtarget info for target " + TripleName, Context);
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker MCCodeEmitter *MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, MC);
660*9880d681SAndroid Build Coastguard Worker if (!MCE)
661*9880d681SAndroid Build Coastguard Worker return error("no code emitter for target " + TripleName, Context);
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Worker // Create the output file.
664*9880d681SAndroid Build Coastguard Worker std::error_code EC;
665*9880d681SAndroid Build Coastguard Worker raw_fd_ostream OutFile(OutputFilename, EC, sys::fs::F_None);
666*9880d681SAndroid Build Coastguard Worker if (EC)
667*9880d681SAndroid Build Coastguard Worker return error(Twine(OutputFilename) + ": " + EC.message(), Context);
668*9880d681SAndroid Build Coastguard Worker
669*9880d681SAndroid Build Coastguard Worker MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
670*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCStreamer> MS(TheTarget->createMCObjectStreamer(
671*9880d681SAndroid Build Coastguard Worker TheTriple, MC, *MAB, OutFile, MCE, *MSTI, MCOptions.MCRelaxAll,
672*9880d681SAndroid Build Coastguard Worker MCOptions.MCIncrementalLinkerCompatible,
673*9880d681SAndroid Build Coastguard Worker /*DWARFMustBeAtTheEnd*/ false));
674*9880d681SAndroid Build Coastguard Worker if (!MS)
675*9880d681SAndroid Build Coastguard Worker return error("no object streamer for target " + TripleName, Context);
676*9880d681SAndroid Build Coastguard Worker
677*9880d681SAndroid Build Coastguard Worker if (auto Err = write(*MS, InputFiles)) {
678*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(std::move(Err), errs(), "error: ");
679*9880d681SAndroid Build Coastguard Worker return 1;
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Worker MS->Finish();
683*9880d681SAndroid Build Coastguard Worker }
684