1*9880d681SAndroid Build Coastguard Worker //===- llvm-cxxdump.cpp - Dump C++ data in an Object File -------*- C++ -*-===//
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 // Dumps C++ data resident in object files and archives.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm-cxxdump.h"
15*9880d681SAndroid Build Coastguard Worker #include "Error.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Archive.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/SymbolSize.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Endian.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/PrettyStackTrace.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Signals.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetSelect.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
29*9880d681SAndroid Build Coastguard Worker #include <map>
30*9880d681SAndroid Build Coastguard Worker #include <string>
31*9880d681SAndroid Build Coastguard Worker #include <system_error>
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker using namespace llvm;
34*9880d681SAndroid Build Coastguard Worker using namespace llvm::object;
35*9880d681SAndroid Build Coastguard Worker using namespace llvm::support;
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker namespace opts {
38*9880d681SAndroid Build Coastguard Worker cl::list<std::string> InputFilenames(cl::Positional,
39*9880d681SAndroid Build Coastguard Worker cl::desc("<input object files>"),
40*9880d681SAndroid Build Coastguard Worker cl::ZeroOrMore);
41*9880d681SAndroid Build Coastguard Worker } // namespace opts
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker namespace llvm {
44*9880d681SAndroid Build Coastguard Worker
error(std::error_code EC)45*9880d681SAndroid Build Coastguard Worker static void error(std::error_code EC) {
46*9880d681SAndroid Build Coastguard Worker if (!EC)
47*9880d681SAndroid Build Coastguard Worker return;
48*9880d681SAndroid Build Coastguard Worker outs() << "\nError reading file: " << EC.message() << ".\n";
49*9880d681SAndroid Build Coastguard Worker outs().flush();
50*9880d681SAndroid Build Coastguard Worker exit(1);
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker
error(Error Err)53*9880d681SAndroid Build Coastguard Worker static void error(Error Err) {
54*9880d681SAndroid Build Coastguard Worker if (Err) {
55*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(std::move(Err), outs(), "Error reading file: ");
56*9880d681SAndroid Build Coastguard Worker outs().flush();
57*9880d681SAndroid Build Coastguard Worker exit(1);
58*9880d681SAndroid Build Coastguard Worker }
59*9880d681SAndroid Build Coastguard Worker }
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker } // namespace llvm
62*9880d681SAndroid Build Coastguard Worker
reportError(StringRef Input,StringRef Message)63*9880d681SAndroid Build Coastguard Worker static void reportError(StringRef Input, StringRef Message) {
64*9880d681SAndroid Build Coastguard Worker if (Input == "-")
65*9880d681SAndroid Build Coastguard Worker Input = "<stdin>";
66*9880d681SAndroid Build Coastguard Worker errs() << Input << ": " << Message << "\n";
67*9880d681SAndroid Build Coastguard Worker errs().flush();
68*9880d681SAndroid Build Coastguard Worker exit(1);
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker
reportError(StringRef Input,std::error_code EC)71*9880d681SAndroid Build Coastguard Worker static void reportError(StringRef Input, std::error_code EC) {
72*9880d681SAndroid Build Coastguard Worker reportError(Input, EC.message());
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker static std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap;
76*9880d681SAndroid Build Coastguard Worker
collectRelocatedSymbols(const ObjectFile * Obj,const SectionRef & Sec,uint64_t SecAddress,uint64_t SymAddress,uint64_t SymSize,StringRef * I,StringRef * E)77*9880d681SAndroid Build Coastguard Worker static void collectRelocatedSymbols(const ObjectFile *Obj,
78*9880d681SAndroid Build Coastguard Worker const SectionRef &Sec, uint64_t SecAddress,
79*9880d681SAndroid Build Coastguard Worker uint64_t SymAddress, uint64_t SymSize,
80*9880d681SAndroid Build Coastguard Worker StringRef *I, StringRef *E) {
81*9880d681SAndroid Build Coastguard Worker uint64_t SymOffset = SymAddress - SecAddress;
82*9880d681SAndroid Build Coastguard Worker uint64_t SymEnd = SymOffset + SymSize;
83*9880d681SAndroid Build Coastguard Worker for (const SectionRef &SR : SectionRelocMap[Sec]) {
84*9880d681SAndroid Build Coastguard Worker for (const object::RelocationRef &Reloc : SR.relocations()) {
85*9880d681SAndroid Build Coastguard Worker if (I == E)
86*9880d681SAndroid Build Coastguard Worker break;
87*9880d681SAndroid Build Coastguard Worker const object::symbol_iterator RelocSymI = Reloc.getSymbol();
88*9880d681SAndroid Build Coastguard Worker if (RelocSymI == Obj->symbol_end())
89*9880d681SAndroid Build Coastguard Worker continue;
90*9880d681SAndroid Build Coastguard Worker Expected<StringRef> RelocSymName = RelocSymI->getName();
91*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(RelocSymName.takeError()));
92*9880d681SAndroid Build Coastguard Worker uint64_t Offset = Reloc.getOffset();
93*9880d681SAndroid Build Coastguard Worker if (Offset >= SymOffset && Offset < SymEnd) {
94*9880d681SAndroid Build Coastguard Worker *I = *RelocSymName;
95*9880d681SAndroid Build Coastguard Worker ++I;
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker
collectRelocationOffsets(const ObjectFile * Obj,const SectionRef & Sec,uint64_t SecAddress,uint64_t SymAddress,uint64_t SymSize,StringRef SymName,std::map<std::pair<StringRef,uint64_t>,StringRef> & Collection)101*9880d681SAndroid Build Coastguard Worker static void collectRelocationOffsets(
102*9880d681SAndroid Build Coastguard Worker const ObjectFile *Obj, const SectionRef &Sec, uint64_t SecAddress,
103*9880d681SAndroid Build Coastguard Worker uint64_t SymAddress, uint64_t SymSize, StringRef SymName,
104*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, StringRef> &Collection) {
105*9880d681SAndroid Build Coastguard Worker uint64_t SymOffset = SymAddress - SecAddress;
106*9880d681SAndroid Build Coastguard Worker uint64_t SymEnd = SymOffset + SymSize;
107*9880d681SAndroid Build Coastguard Worker for (const SectionRef &SR : SectionRelocMap[Sec]) {
108*9880d681SAndroid Build Coastguard Worker for (const object::RelocationRef &Reloc : SR.relocations()) {
109*9880d681SAndroid Build Coastguard Worker const object::symbol_iterator RelocSymI = Reloc.getSymbol();
110*9880d681SAndroid Build Coastguard Worker if (RelocSymI == Obj->symbol_end())
111*9880d681SAndroid Build Coastguard Worker continue;
112*9880d681SAndroid Build Coastguard Worker Expected<StringRef> RelocSymName = RelocSymI->getName();
113*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(RelocSymName.takeError()));
114*9880d681SAndroid Build Coastguard Worker uint64_t Offset = Reloc.getOffset();
115*9880d681SAndroid Build Coastguard Worker if (Offset >= SymOffset && Offset < SymEnd)
116*9880d681SAndroid Build Coastguard Worker Collection[std::make_pair(SymName, Offset - SymOffset)] = *RelocSymName;
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker }
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker
dumpCXXData(const ObjectFile * Obj)121*9880d681SAndroid Build Coastguard Worker static void dumpCXXData(const ObjectFile *Obj) {
122*9880d681SAndroid Build Coastguard Worker struct CompleteObjectLocator {
123*9880d681SAndroid Build Coastguard Worker StringRef Symbols[2];
124*9880d681SAndroid Build Coastguard Worker ArrayRef<little32_t> Data;
125*9880d681SAndroid Build Coastguard Worker };
126*9880d681SAndroid Build Coastguard Worker struct ClassHierarchyDescriptor {
127*9880d681SAndroid Build Coastguard Worker StringRef Symbols[1];
128*9880d681SAndroid Build Coastguard Worker ArrayRef<little32_t> Data;
129*9880d681SAndroid Build Coastguard Worker };
130*9880d681SAndroid Build Coastguard Worker struct BaseClassDescriptor {
131*9880d681SAndroid Build Coastguard Worker StringRef Symbols[2];
132*9880d681SAndroid Build Coastguard Worker ArrayRef<little32_t> Data;
133*9880d681SAndroid Build Coastguard Worker };
134*9880d681SAndroid Build Coastguard Worker struct TypeDescriptor {
135*9880d681SAndroid Build Coastguard Worker StringRef Symbols[1];
136*9880d681SAndroid Build Coastguard Worker uint64_t AlwaysZero;
137*9880d681SAndroid Build Coastguard Worker StringRef MangledName;
138*9880d681SAndroid Build Coastguard Worker };
139*9880d681SAndroid Build Coastguard Worker struct ThrowInfo {
140*9880d681SAndroid Build Coastguard Worker uint32_t Flags;
141*9880d681SAndroid Build Coastguard Worker };
142*9880d681SAndroid Build Coastguard Worker struct CatchableTypeArray {
143*9880d681SAndroid Build Coastguard Worker uint32_t NumEntries;
144*9880d681SAndroid Build Coastguard Worker };
145*9880d681SAndroid Build Coastguard Worker struct CatchableType {
146*9880d681SAndroid Build Coastguard Worker uint32_t Flags;
147*9880d681SAndroid Build Coastguard Worker uint32_t NonVirtualBaseAdjustmentOffset;
148*9880d681SAndroid Build Coastguard Worker int32_t VirtualBasePointerOffset;
149*9880d681SAndroid Build Coastguard Worker uint32_t VirtualBaseAdjustmentOffset;
150*9880d681SAndroid Build Coastguard Worker uint32_t Size;
151*9880d681SAndroid Build Coastguard Worker StringRef Symbols[2];
152*9880d681SAndroid Build Coastguard Worker };
153*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, StringRef> VFTableEntries;
154*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, StringRef> TIEntries;
155*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, StringRef> CTAEntries;
156*9880d681SAndroid Build Coastguard Worker std::map<StringRef, ArrayRef<little32_t>> VBTables;
157*9880d681SAndroid Build Coastguard Worker std::map<StringRef, CompleteObjectLocator> COLs;
158*9880d681SAndroid Build Coastguard Worker std::map<StringRef, ClassHierarchyDescriptor> CHDs;
159*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, StringRef> BCAEntries;
160*9880d681SAndroid Build Coastguard Worker std::map<StringRef, BaseClassDescriptor> BCDs;
161*9880d681SAndroid Build Coastguard Worker std::map<StringRef, TypeDescriptor> TDs;
162*9880d681SAndroid Build Coastguard Worker std::map<StringRef, ThrowInfo> TIs;
163*9880d681SAndroid Build Coastguard Worker std::map<StringRef, CatchableTypeArray> CTAs;
164*9880d681SAndroid Build Coastguard Worker std::map<StringRef, CatchableType> CTs;
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, StringRef> VTableSymEntries;
167*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, int64_t> VTableDataEntries;
168*9880d681SAndroid Build Coastguard Worker std::map<std::pair<StringRef, uint64_t>, StringRef> VTTEntries;
169*9880d681SAndroid Build Coastguard Worker std::map<StringRef, StringRef> TINames;
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker SectionRelocMap.clear();
172*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : Obj->sections()) {
173*9880d681SAndroid Build Coastguard Worker section_iterator Sec2 = Section.getRelocatedSection();
174*9880d681SAndroid Build Coastguard Worker if (Sec2 != Obj->section_end())
175*9880d681SAndroid Build Coastguard Worker SectionRelocMap[*Sec2].push_back(Section);
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker uint8_t BytesInAddress = Obj->getBytesInAddress();
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
181*9880d681SAndroid Build Coastguard Worker object::computeSymbolSizes(*Obj);
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker for (auto &P : SymAddr) {
184*9880d681SAndroid Build Coastguard Worker object::SymbolRef Sym = P.first;
185*9880d681SAndroid Build Coastguard Worker uint64_t SymSize = P.second;
186*9880d681SAndroid Build Coastguard Worker Expected<StringRef> SymNameOrErr = Sym.getName();
187*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(SymNameOrErr.takeError()));
188*9880d681SAndroid Build Coastguard Worker StringRef SymName = *SymNameOrErr;
189*9880d681SAndroid Build Coastguard Worker Expected<object::section_iterator> SecIOrErr = Sym.getSection();
190*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(SecIOrErr.takeError()));
191*9880d681SAndroid Build Coastguard Worker object::section_iterator SecI = *SecIOrErr;
192*9880d681SAndroid Build Coastguard Worker // Skip external symbols.
193*9880d681SAndroid Build Coastguard Worker if (SecI == Obj->section_end())
194*9880d681SAndroid Build Coastguard Worker continue;
195*9880d681SAndroid Build Coastguard Worker const SectionRef &Sec = *SecI;
196*9880d681SAndroid Build Coastguard Worker // Skip virtual or BSS sections.
197*9880d681SAndroid Build Coastguard Worker if (Sec.isBSS() || Sec.isVirtual())
198*9880d681SAndroid Build Coastguard Worker continue;
199*9880d681SAndroid Build Coastguard Worker StringRef SecContents;
200*9880d681SAndroid Build Coastguard Worker error(Sec.getContents(SecContents));
201*9880d681SAndroid Build Coastguard Worker Expected<uint64_t> SymAddressOrErr = Sym.getAddress();
202*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(SymAddressOrErr.takeError()));
203*9880d681SAndroid Build Coastguard Worker uint64_t SymAddress = *SymAddressOrErr;
204*9880d681SAndroid Build Coastguard Worker uint64_t SecAddress = Sec.getAddress();
205*9880d681SAndroid Build Coastguard Worker uint64_t SecSize = Sec.getSize();
206*9880d681SAndroid Build Coastguard Worker uint64_t SymOffset = SymAddress - SecAddress;
207*9880d681SAndroid Build Coastguard Worker StringRef SymContents = SecContents.substr(SymOffset, SymSize);
208*9880d681SAndroid Build Coastguard Worker
209*9880d681SAndroid Build Coastguard Worker // VFTables in the MS-ABI start with '??_7' and are contained within their
210*9880d681SAndroid Build Coastguard Worker // own COMDAT section. We then determine the contents of the VFTable by
211*9880d681SAndroid Build Coastguard Worker // looking at each relocation in the section.
212*9880d681SAndroid Build Coastguard Worker if (SymName.startswith("??_7")) {
213*9880d681SAndroid Build Coastguard Worker // Each relocation either names a virtual method or a thunk. We note the
214*9880d681SAndroid Build Coastguard Worker // offset into the section and the symbol used for the relocation.
215*9880d681SAndroid Build Coastguard Worker collectRelocationOffsets(Obj, Sec, SecAddress, SecAddress, SecSize,
216*9880d681SAndroid Build Coastguard Worker SymName, VFTableEntries);
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker // VBTables in the MS-ABI start with '??_8' and are filled with 32-bit
219*9880d681SAndroid Build Coastguard Worker // offsets of virtual bases.
220*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("??_8")) {
221*9880d681SAndroid Build Coastguard Worker ArrayRef<little32_t> VBTableData(
222*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const little32_t *>(SymContents.data()),
223*9880d681SAndroid Build Coastguard Worker SymContents.size() / sizeof(little32_t));
224*9880d681SAndroid Build Coastguard Worker VBTables[SymName] = VBTableData;
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker // Complete object locators in the MS-ABI start with '??_R4'
227*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("??_R4")) {
228*9880d681SAndroid Build Coastguard Worker CompleteObjectLocator COL;
229*9880d681SAndroid Build Coastguard Worker COL.Data = makeArrayRef(
230*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const little32_t *>(SymContents.data()), 3);
231*9880d681SAndroid Build Coastguard Worker StringRef *I = std::begin(COL.Symbols), *E = std::end(COL.Symbols);
232*9880d681SAndroid Build Coastguard Worker collectRelocatedSymbols(Obj, Sec, SecAddress, SymAddress, SymSize, I, E);
233*9880d681SAndroid Build Coastguard Worker COLs[SymName] = COL;
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker // Class hierarchy descriptors in the MS-ABI start with '??_R3'
236*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("??_R3")) {
237*9880d681SAndroid Build Coastguard Worker ClassHierarchyDescriptor CHD;
238*9880d681SAndroid Build Coastguard Worker CHD.Data = makeArrayRef(
239*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const little32_t *>(SymContents.data()), 3);
240*9880d681SAndroid Build Coastguard Worker StringRef *I = std::begin(CHD.Symbols), *E = std::end(CHD.Symbols);
241*9880d681SAndroid Build Coastguard Worker collectRelocatedSymbols(Obj, Sec, SecAddress, SymAddress, SymSize, I, E);
242*9880d681SAndroid Build Coastguard Worker CHDs[SymName] = CHD;
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker // Class hierarchy descriptors in the MS-ABI start with '??_R2'
245*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("??_R2")) {
246*9880d681SAndroid Build Coastguard Worker // Each relocation names a base class descriptor. We note the offset into
247*9880d681SAndroid Build Coastguard Worker // the section and the symbol used for the relocation.
248*9880d681SAndroid Build Coastguard Worker collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize,
249*9880d681SAndroid Build Coastguard Worker SymName, BCAEntries);
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker // Base class descriptors in the MS-ABI start with '??_R1'
252*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("??_R1")) {
253*9880d681SAndroid Build Coastguard Worker BaseClassDescriptor BCD;
254*9880d681SAndroid Build Coastguard Worker BCD.Data = makeArrayRef(
255*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const little32_t *>(SymContents.data()) + 1, 5);
256*9880d681SAndroid Build Coastguard Worker StringRef *I = std::begin(BCD.Symbols), *E = std::end(BCD.Symbols);
257*9880d681SAndroid Build Coastguard Worker collectRelocatedSymbols(Obj, Sec, SecAddress, SymAddress, SymSize, I, E);
258*9880d681SAndroid Build Coastguard Worker BCDs[SymName] = BCD;
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker // Type descriptors in the MS-ABI start with '??_R0'
261*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("??_R0")) {
262*9880d681SAndroid Build Coastguard Worker const char *DataPtr = SymContents.drop_front(BytesInAddress).data();
263*9880d681SAndroid Build Coastguard Worker TypeDescriptor TD;
264*9880d681SAndroid Build Coastguard Worker if (BytesInAddress == 8)
265*9880d681SAndroid Build Coastguard Worker TD.AlwaysZero = *reinterpret_cast<const little64_t *>(DataPtr);
266*9880d681SAndroid Build Coastguard Worker else
267*9880d681SAndroid Build Coastguard Worker TD.AlwaysZero = *reinterpret_cast<const little32_t *>(DataPtr);
268*9880d681SAndroid Build Coastguard Worker TD.MangledName = SymContents.drop_front(BytesInAddress * 2);
269*9880d681SAndroid Build Coastguard Worker StringRef *I = std::begin(TD.Symbols), *E = std::end(TD.Symbols);
270*9880d681SAndroid Build Coastguard Worker collectRelocatedSymbols(Obj, Sec, SecAddress, SymAddress, SymSize, I, E);
271*9880d681SAndroid Build Coastguard Worker TDs[SymName] = TD;
272*9880d681SAndroid Build Coastguard Worker }
273*9880d681SAndroid Build Coastguard Worker // Throw descriptors in the MS-ABI start with '_TI'
274*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("_TI") || SymName.startswith("__TI")) {
275*9880d681SAndroid Build Coastguard Worker ThrowInfo TI;
276*9880d681SAndroid Build Coastguard Worker TI.Flags = *reinterpret_cast<const little32_t *>(SymContents.data());
277*9880d681SAndroid Build Coastguard Worker collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize,
278*9880d681SAndroid Build Coastguard Worker SymName, TIEntries);
279*9880d681SAndroid Build Coastguard Worker TIs[SymName] = TI;
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker // Catchable type arrays in the MS-ABI start with _CTA or __CTA.
282*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("_CTA") || SymName.startswith("__CTA")) {
283*9880d681SAndroid Build Coastguard Worker CatchableTypeArray CTA;
284*9880d681SAndroid Build Coastguard Worker CTA.NumEntries =
285*9880d681SAndroid Build Coastguard Worker *reinterpret_cast<const little32_t *>(SymContents.data());
286*9880d681SAndroid Build Coastguard Worker collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize,
287*9880d681SAndroid Build Coastguard Worker SymName, CTAEntries);
288*9880d681SAndroid Build Coastguard Worker CTAs[SymName] = CTA;
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker // Catchable types in the MS-ABI start with _CT or __CT.
291*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("_CT") || SymName.startswith("__CT")) {
292*9880d681SAndroid Build Coastguard Worker const little32_t *DataPtr =
293*9880d681SAndroid Build Coastguard Worker reinterpret_cast<const little32_t *>(SymContents.data());
294*9880d681SAndroid Build Coastguard Worker CatchableType CT;
295*9880d681SAndroid Build Coastguard Worker CT.Flags = DataPtr[0];
296*9880d681SAndroid Build Coastguard Worker CT.NonVirtualBaseAdjustmentOffset = DataPtr[2];
297*9880d681SAndroid Build Coastguard Worker CT.VirtualBasePointerOffset = DataPtr[3];
298*9880d681SAndroid Build Coastguard Worker CT.VirtualBaseAdjustmentOffset = DataPtr[4];
299*9880d681SAndroid Build Coastguard Worker CT.Size = DataPtr[5];
300*9880d681SAndroid Build Coastguard Worker StringRef *I = std::begin(CT.Symbols), *E = std::end(CT.Symbols);
301*9880d681SAndroid Build Coastguard Worker collectRelocatedSymbols(Obj, Sec, SecAddress, SymAddress, SymSize, I, E);
302*9880d681SAndroid Build Coastguard Worker CTs[SymName] = CT;
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker // Construction vtables in the Itanium ABI start with '_ZTT' or '__ZTT'.
305*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("_ZTT") || SymName.startswith("__ZTT")) {
306*9880d681SAndroid Build Coastguard Worker collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize,
307*9880d681SAndroid Build Coastguard Worker SymName, VTTEntries);
308*9880d681SAndroid Build Coastguard Worker }
309*9880d681SAndroid Build Coastguard Worker // Typeinfo names in the Itanium ABI start with '_ZTS' or '__ZTS'.
310*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("_ZTS") || SymName.startswith("__ZTS")) {
311*9880d681SAndroid Build Coastguard Worker TINames[SymName] = SymContents.slice(0, SymContents.find('\0'));
312*9880d681SAndroid Build Coastguard Worker }
313*9880d681SAndroid Build Coastguard Worker // Vtables in the Itanium ABI start with '_ZTV' or '__ZTV'.
314*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("_ZTV") || SymName.startswith("__ZTV")) {
315*9880d681SAndroid Build Coastguard Worker collectRelocationOffsets(Obj, Sec, SecAddress, SymAddress, SymSize,
316*9880d681SAndroid Build Coastguard Worker SymName, VTableSymEntries);
317*9880d681SAndroid Build Coastguard Worker for (uint64_t SymOffI = 0; SymOffI < SymSize; SymOffI += BytesInAddress) {
318*9880d681SAndroid Build Coastguard Worker auto Key = std::make_pair(SymName, SymOffI);
319*9880d681SAndroid Build Coastguard Worker if (VTableSymEntries.count(Key))
320*9880d681SAndroid Build Coastguard Worker continue;
321*9880d681SAndroid Build Coastguard Worker const char *DataPtr =
322*9880d681SAndroid Build Coastguard Worker SymContents.substr(SymOffI, BytesInAddress).data();
323*9880d681SAndroid Build Coastguard Worker int64_t VData;
324*9880d681SAndroid Build Coastguard Worker if (BytesInAddress == 8)
325*9880d681SAndroid Build Coastguard Worker VData = *reinterpret_cast<const little64_t *>(DataPtr);
326*9880d681SAndroid Build Coastguard Worker else
327*9880d681SAndroid Build Coastguard Worker VData = *reinterpret_cast<const little32_t *>(DataPtr);
328*9880d681SAndroid Build Coastguard Worker VTableDataEntries[Key] = VData;
329*9880d681SAndroid Build Coastguard Worker }
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker // Typeinfo structures in the Itanium ABI start with '_ZTI' or '__ZTI'.
332*9880d681SAndroid Build Coastguard Worker else if (SymName.startswith("_ZTI") || SymName.startswith("__ZTI")) {
333*9880d681SAndroid Build Coastguard Worker // FIXME: Do something with these!
334*9880d681SAndroid Build Coastguard Worker }
335*9880d681SAndroid Build Coastguard Worker }
336*9880d681SAndroid Build Coastguard Worker for (const auto &VFTableEntry : VFTableEntries) {
337*9880d681SAndroid Build Coastguard Worker StringRef VFTableName = VFTableEntry.first.first;
338*9880d681SAndroid Build Coastguard Worker uint64_t Offset = VFTableEntry.first.second;
339*9880d681SAndroid Build Coastguard Worker StringRef SymName = VFTableEntry.second;
340*9880d681SAndroid Build Coastguard Worker outs() << VFTableName << '[' << Offset << "]: " << SymName << '\n';
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker for (const auto &VBTable : VBTables) {
343*9880d681SAndroid Build Coastguard Worker StringRef VBTableName = VBTable.first;
344*9880d681SAndroid Build Coastguard Worker uint32_t Idx = 0;
345*9880d681SAndroid Build Coastguard Worker for (little32_t Offset : VBTable.second) {
346*9880d681SAndroid Build Coastguard Worker outs() << VBTableName << '[' << Idx << "]: " << Offset << '\n';
347*9880d681SAndroid Build Coastguard Worker Idx += sizeof(Offset);
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker }
350*9880d681SAndroid Build Coastguard Worker for (const auto &COLPair : COLs) {
351*9880d681SAndroid Build Coastguard Worker StringRef COLName = COLPair.first;
352*9880d681SAndroid Build Coastguard Worker const CompleteObjectLocator &COL = COLPair.second;
353*9880d681SAndroid Build Coastguard Worker outs() << COLName << "[IsImageRelative]: " << COL.Data[0] << '\n';
354*9880d681SAndroid Build Coastguard Worker outs() << COLName << "[OffsetToTop]: " << COL.Data[1] << '\n';
355*9880d681SAndroid Build Coastguard Worker outs() << COLName << "[VFPtrOffset]: " << COL.Data[2] << '\n';
356*9880d681SAndroid Build Coastguard Worker outs() << COLName << "[TypeDescriptor]: " << COL.Symbols[0] << '\n';
357*9880d681SAndroid Build Coastguard Worker outs() << COLName << "[ClassHierarchyDescriptor]: " << COL.Symbols[1]
358*9880d681SAndroid Build Coastguard Worker << '\n';
359*9880d681SAndroid Build Coastguard Worker }
360*9880d681SAndroid Build Coastguard Worker for (const auto &CHDPair : CHDs) {
361*9880d681SAndroid Build Coastguard Worker StringRef CHDName = CHDPair.first;
362*9880d681SAndroid Build Coastguard Worker const ClassHierarchyDescriptor &CHD = CHDPair.second;
363*9880d681SAndroid Build Coastguard Worker outs() << CHDName << "[AlwaysZero]: " << CHD.Data[0] << '\n';
364*9880d681SAndroid Build Coastguard Worker outs() << CHDName << "[Flags]: " << CHD.Data[1] << '\n';
365*9880d681SAndroid Build Coastguard Worker outs() << CHDName << "[NumClasses]: " << CHD.Data[2] << '\n';
366*9880d681SAndroid Build Coastguard Worker outs() << CHDName << "[BaseClassArray]: " << CHD.Symbols[0] << '\n';
367*9880d681SAndroid Build Coastguard Worker }
368*9880d681SAndroid Build Coastguard Worker for (const auto &BCAEntry : BCAEntries) {
369*9880d681SAndroid Build Coastguard Worker StringRef BCAName = BCAEntry.first.first;
370*9880d681SAndroid Build Coastguard Worker uint64_t Offset = BCAEntry.first.second;
371*9880d681SAndroid Build Coastguard Worker StringRef SymName = BCAEntry.second;
372*9880d681SAndroid Build Coastguard Worker outs() << BCAName << '[' << Offset << "]: " << SymName << '\n';
373*9880d681SAndroid Build Coastguard Worker }
374*9880d681SAndroid Build Coastguard Worker for (const auto &BCDPair : BCDs) {
375*9880d681SAndroid Build Coastguard Worker StringRef BCDName = BCDPair.first;
376*9880d681SAndroid Build Coastguard Worker const BaseClassDescriptor &BCD = BCDPair.second;
377*9880d681SAndroid Build Coastguard Worker outs() << BCDName << "[TypeDescriptor]: " << BCD.Symbols[0] << '\n';
378*9880d681SAndroid Build Coastguard Worker outs() << BCDName << "[NumBases]: " << BCD.Data[0] << '\n';
379*9880d681SAndroid Build Coastguard Worker outs() << BCDName << "[OffsetInVBase]: " << BCD.Data[1] << '\n';
380*9880d681SAndroid Build Coastguard Worker outs() << BCDName << "[VBPtrOffset]: " << BCD.Data[2] << '\n';
381*9880d681SAndroid Build Coastguard Worker outs() << BCDName << "[OffsetInVBTable]: " << BCD.Data[3] << '\n';
382*9880d681SAndroid Build Coastguard Worker outs() << BCDName << "[Flags]: " << BCD.Data[4] << '\n';
383*9880d681SAndroid Build Coastguard Worker outs() << BCDName << "[ClassHierarchyDescriptor]: " << BCD.Symbols[1]
384*9880d681SAndroid Build Coastguard Worker << '\n';
385*9880d681SAndroid Build Coastguard Worker }
386*9880d681SAndroid Build Coastguard Worker for (const auto &TDPair : TDs) {
387*9880d681SAndroid Build Coastguard Worker StringRef TDName = TDPair.first;
388*9880d681SAndroid Build Coastguard Worker const TypeDescriptor &TD = TDPair.second;
389*9880d681SAndroid Build Coastguard Worker outs() << TDName << "[VFPtr]: " << TD.Symbols[0] << '\n';
390*9880d681SAndroid Build Coastguard Worker outs() << TDName << "[AlwaysZero]: " << TD.AlwaysZero << '\n';
391*9880d681SAndroid Build Coastguard Worker outs() << TDName << "[MangledName]: ";
392*9880d681SAndroid Build Coastguard Worker outs().write_escaped(TD.MangledName.rtrim(StringRef("\0", 1)),
393*9880d681SAndroid Build Coastguard Worker /*UseHexEscapes=*/true)
394*9880d681SAndroid Build Coastguard Worker << '\n';
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker for (const auto &TIPair : TIs) {
397*9880d681SAndroid Build Coastguard Worker StringRef TIName = TIPair.first;
398*9880d681SAndroid Build Coastguard Worker const ThrowInfo &TI = TIPair.second;
399*9880d681SAndroid Build Coastguard Worker auto dumpThrowInfoFlag = [&](const char *Name, uint32_t Flag) {
400*9880d681SAndroid Build Coastguard Worker outs() << TIName << "[Flags." << Name
401*9880d681SAndroid Build Coastguard Worker << "]: " << (TI.Flags & Flag ? "true" : "false") << '\n';
402*9880d681SAndroid Build Coastguard Worker };
403*9880d681SAndroid Build Coastguard Worker auto dumpThrowInfoSymbol = [&](const char *Name, int Offset) {
404*9880d681SAndroid Build Coastguard Worker outs() << TIName << '[' << Name << "]: ";
405*9880d681SAndroid Build Coastguard Worker auto Entry = TIEntries.find(std::make_pair(TIName, Offset));
406*9880d681SAndroid Build Coastguard Worker outs() << (Entry == TIEntries.end() ? "null" : Entry->second) << '\n';
407*9880d681SAndroid Build Coastguard Worker };
408*9880d681SAndroid Build Coastguard Worker outs() << TIName << "[Flags]: " << TI.Flags << '\n';
409*9880d681SAndroid Build Coastguard Worker dumpThrowInfoFlag("Const", 1);
410*9880d681SAndroid Build Coastguard Worker dumpThrowInfoFlag("Volatile", 2);
411*9880d681SAndroid Build Coastguard Worker dumpThrowInfoSymbol("CleanupFn", 4);
412*9880d681SAndroid Build Coastguard Worker dumpThrowInfoSymbol("ForwardCompat", 8);
413*9880d681SAndroid Build Coastguard Worker dumpThrowInfoSymbol("CatchableTypeArray", 12);
414*9880d681SAndroid Build Coastguard Worker }
415*9880d681SAndroid Build Coastguard Worker for (const auto &CTAPair : CTAs) {
416*9880d681SAndroid Build Coastguard Worker StringRef CTAName = CTAPair.first;
417*9880d681SAndroid Build Coastguard Worker const CatchableTypeArray &CTA = CTAPair.second;
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker outs() << CTAName << "[NumEntries]: " << CTA.NumEntries << '\n';
420*9880d681SAndroid Build Coastguard Worker
421*9880d681SAndroid Build Coastguard Worker unsigned Idx = 0;
422*9880d681SAndroid Build Coastguard Worker for (auto I = CTAEntries.lower_bound(std::make_pair(CTAName, 0)),
423*9880d681SAndroid Build Coastguard Worker E = CTAEntries.upper_bound(std::make_pair(CTAName, UINT64_MAX));
424*9880d681SAndroid Build Coastguard Worker I != E; ++I)
425*9880d681SAndroid Build Coastguard Worker outs() << CTAName << '[' << Idx++ << "]: " << I->second << '\n';
426*9880d681SAndroid Build Coastguard Worker }
427*9880d681SAndroid Build Coastguard Worker for (const auto &CTPair : CTs) {
428*9880d681SAndroid Build Coastguard Worker StringRef CTName = CTPair.first;
429*9880d681SAndroid Build Coastguard Worker const CatchableType &CT = CTPair.second;
430*9880d681SAndroid Build Coastguard Worker auto dumpCatchableTypeFlag = [&](const char *Name, uint32_t Flag) {
431*9880d681SAndroid Build Coastguard Worker outs() << CTName << "[Flags." << Name
432*9880d681SAndroid Build Coastguard Worker << "]: " << (CT.Flags & Flag ? "true" : "false") << '\n';
433*9880d681SAndroid Build Coastguard Worker };
434*9880d681SAndroid Build Coastguard Worker outs() << CTName << "[Flags]: " << CT.Flags << '\n';
435*9880d681SAndroid Build Coastguard Worker dumpCatchableTypeFlag("ScalarType", 1);
436*9880d681SAndroid Build Coastguard Worker dumpCatchableTypeFlag("VirtualInheritance", 4);
437*9880d681SAndroid Build Coastguard Worker outs() << CTName << "[TypeDescriptor]: " << CT.Symbols[0] << '\n';
438*9880d681SAndroid Build Coastguard Worker outs() << CTName << "[NonVirtualBaseAdjustmentOffset]: "
439*9880d681SAndroid Build Coastguard Worker << CT.NonVirtualBaseAdjustmentOffset << '\n';
440*9880d681SAndroid Build Coastguard Worker outs() << CTName
441*9880d681SAndroid Build Coastguard Worker << "[VirtualBasePointerOffset]: " << CT.VirtualBasePointerOffset
442*9880d681SAndroid Build Coastguard Worker << '\n';
443*9880d681SAndroid Build Coastguard Worker outs() << CTName << "[VirtualBaseAdjustmentOffset]: "
444*9880d681SAndroid Build Coastguard Worker << CT.VirtualBaseAdjustmentOffset << '\n';
445*9880d681SAndroid Build Coastguard Worker outs() << CTName << "[Size]: " << CT.Size << '\n';
446*9880d681SAndroid Build Coastguard Worker outs() << CTName
447*9880d681SAndroid Build Coastguard Worker << "[CopyCtor]: " << (CT.Symbols[1].empty() ? "null" : CT.Symbols[1])
448*9880d681SAndroid Build Coastguard Worker << '\n';
449*9880d681SAndroid Build Coastguard Worker }
450*9880d681SAndroid Build Coastguard Worker for (const auto &VTTPair : VTTEntries) {
451*9880d681SAndroid Build Coastguard Worker StringRef VTTName = VTTPair.first.first;
452*9880d681SAndroid Build Coastguard Worker uint64_t VTTOffset = VTTPair.first.second;
453*9880d681SAndroid Build Coastguard Worker StringRef VTTEntry = VTTPair.second;
454*9880d681SAndroid Build Coastguard Worker outs() << VTTName << '[' << VTTOffset << "]: " << VTTEntry << '\n';
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker for (const auto &TIPair : TINames) {
457*9880d681SAndroid Build Coastguard Worker StringRef TIName = TIPair.first;
458*9880d681SAndroid Build Coastguard Worker outs() << TIName << ": " << TIPair.second << '\n';
459*9880d681SAndroid Build Coastguard Worker }
460*9880d681SAndroid Build Coastguard Worker auto VTableSymI = VTableSymEntries.begin();
461*9880d681SAndroid Build Coastguard Worker auto VTableSymE = VTableSymEntries.end();
462*9880d681SAndroid Build Coastguard Worker auto VTableDataI = VTableDataEntries.begin();
463*9880d681SAndroid Build Coastguard Worker auto VTableDataE = VTableDataEntries.end();
464*9880d681SAndroid Build Coastguard Worker for (;;) {
465*9880d681SAndroid Build Coastguard Worker bool SymDone = VTableSymI == VTableSymE;
466*9880d681SAndroid Build Coastguard Worker bool DataDone = VTableDataI == VTableDataE;
467*9880d681SAndroid Build Coastguard Worker if (SymDone && DataDone)
468*9880d681SAndroid Build Coastguard Worker break;
469*9880d681SAndroid Build Coastguard Worker if (!SymDone && (DataDone || VTableSymI->first < VTableDataI->first)) {
470*9880d681SAndroid Build Coastguard Worker StringRef VTableName = VTableSymI->first.first;
471*9880d681SAndroid Build Coastguard Worker uint64_t Offset = VTableSymI->first.second;
472*9880d681SAndroid Build Coastguard Worker StringRef VTableEntry = VTableSymI->second;
473*9880d681SAndroid Build Coastguard Worker outs() << VTableName << '[' << Offset << "]: ";
474*9880d681SAndroid Build Coastguard Worker outs() << VTableEntry;
475*9880d681SAndroid Build Coastguard Worker outs() << '\n';
476*9880d681SAndroid Build Coastguard Worker ++VTableSymI;
477*9880d681SAndroid Build Coastguard Worker continue;
478*9880d681SAndroid Build Coastguard Worker }
479*9880d681SAndroid Build Coastguard Worker if (!DataDone && (SymDone || VTableDataI->first < VTableSymI->first)) {
480*9880d681SAndroid Build Coastguard Worker StringRef VTableName = VTableDataI->first.first;
481*9880d681SAndroid Build Coastguard Worker uint64_t Offset = VTableDataI->first.second;
482*9880d681SAndroid Build Coastguard Worker int64_t VTableEntry = VTableDataI->second;
483*9880d681SAndroid Build Coastguard Worker outs() << VTableName << '[' << Offset << "]: ";
484*9880d681SAndroid Build Coastguard Worker outs() << VTableEntry;
485*9880d681SAndroid Build Coastguard Worker outs() << '\n';
486*9880d681SAndroid Build Coastguard Worker ++VTableDataI;
487*9880d681SAndroid Build Coastguard Worker continue;
488*9880d681SAndroid Build Coastguard Worker }
489*9880d681SAndroid Build Coastguard Worker }
490*9880d681SAndroid Build Coastguard Worker }
491*9880d681SAndroid Build Coastguard Worker
dumpArchive(const Archive * Arc)492*9880d681SAndroid Build Coastguard Worker static void dumpArchive(const Archive *Arc) {
493*9880d681SAndroid Build Coastguard Worker Error Err;
494*9880d681SAndroid Build Coastguard Worker for (auto &ArcC : Arc->children(Err)) {
495*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<Binary>> ChildOrErr = ArcC.getAsBinary();
496*9880d681SAndroid Build Coastguard Worker if (!ChildOrErr) {
497*9880d681SAndroid Build Coastguard Worker // Ignore non-object files.
498*9880d681SAndroid Build Coastguard Worker if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
499*9880d681SAndroid Build Coastguard Worker std::string Buf;
500*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
501*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(std::move(E), OS, "");
502*9880d681SAndroid Build Coastguard Worker OS.flush();
503*9880d681SAndroid Build Coastguard Worker reportError(Arc->getFileName(), Buf);
504*9880d681SAndroid Build Coastguard Worker }
505*9880d681SAndroid Build Coastguard Worker ChildOrErr.takeError();
506*9880d681SAndroid Build Coastguard Worker continue;
507*9880d681SAndroid Build Coastguard Worker }
508*9880d681SAndroid Build Coastguard Worker
509*9880d681SAndroid Build Coastguard Worker if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
510*9880d681SAndroid Build Coastguard Worker dumpCXXData(Obj);
511*9880d681SAndroid Build Coastguard Worker else
512*9880d681SAndroid Build Coastguard Worker reportError(Arc->getFileName(), cxxdump_error::unrecognized_file_format);
513*9880d681SAndroid Build Coastguard Worker }
514*9880d681SAndroid Build Coastguard Worker error(std::move(Err));
515*9880d681SAndroid Build Coastguard Worker }
516*9880d681SAndroid Build Coastguard Worker
dumpInput(StringRef File)517*9880d681SAndroid Build Coastguard Worker static void dumpInput(StringRef File) {
518*9880d681SAndroid Build Coastguard Worker // Attempt to open the binary.
519*9880d681SAndroid Build Coastguard Worker Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
520*9880d681SAndroid Build Coastguard Worker if (!BinaryOrErr) {
521*9880d681SAndroid Build Coastguard Worker auto EC = errorToErrorCode(BinaryOrErr.takeError());
522*9880d681SAndroid Build Coastguard Worker reportError(File, EC);
523*9880d681SAndroid Build Coastguard Worker return;
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker Binary &Binary = *BinaryOrErr.get().getBinary();
526*9880d681SAndroid Build Coastguard Worker
527*9880d681SAndroid Build Coastguard Worker if (Archive *Arc = dyn_cast<Archive>(&Binary))
528*9880d681SAndroid Build Coastguard Worker dumpArchive(Arc);
529*9880d681SAndroid Build Coastguard Worker else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
530*9880d681SAndroid Build Coastguard Worker dumpCXXData(Obj);
531*9880d681SAndroid Build Coastguard Worker else
532*9880d681SAndroid Build Coastguard Worker reportError(File, cxxdump_error::unrecognized_file_format);
533*9880d681SAndroid Build Coastguard Worker }
534*9880d681SAndroid Build Coastguard Worker
main(int argc,const char * argv[])535*9880d681SAndroid Build Coastguard Worker int main(int argc, const char *argv[]) {
536*9880d681SAndroid Build Coastguard Worker sys::PrintStackTraceOnErrorSignal(argv[0]);
537*9880d681SAndroid Build Coastguard Worker PrettyStackTraceProgram X(argc, argv);
538*9880d681SAndroid Build Coastguard Worker llvm_shutdown_obj Y;
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker // Initialize targets.
541*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllTargetInfos();
542*9880d681SAndroid Build Coastguard Worker
543*9880d681SAndroid Build Coastguard Worker // Register the target printer for --version.
544*9880d681SAndroid Build Coastguard Worker cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
545*9880d681SAndroid Build Coastguard Worker
546*9880d681SAndroid Build Coastguard Worker cl::ParseCommandLineOptions(argc, argv, "LLVM C++ ABI Data Dumper\n");
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker // Default to stdin if no filename is specified.
549*9880d681SAndroid Build Coastguard Worker if (opts::InputFilenames.size() == 0)
550*9880d681SAndroid Build Coastguard Worker opts::InputFilenames.push_back("-");
551*9880d681SAndroid Build Coastguard Worker
552*9880d681SAndroid Build Coastguard Worker std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(),
553*9880d681SAndroid Build Coastguard Worker dumpInput);
554*9880d681SAndroid Build Coastguard Worker
555*9880d681SAndroid Build Coastguard Worker return EXIT_SUCCESS;
556*9880d681SAndroid Build Coastguard Worker }
557