xref: /aosp_15_r20/external/llvm/tools/llvm-readobj/llvm-readobj.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- llvm-readobj.cpp - Dump contents of an Object File -----------------===//
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 // This is a tool similar to readelf, except it works on multiple object file
11*9880d681SAndroid Build Coastguard Worker // formats. The main purpose of this tool is to provide detailed output suitable
12*9880d681SAndroid Build Coastguard Worker // for FileCheck.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // Flags should be similar to readelf where supported, but the output format
15*9880d681SAndroid Build Coastguard Worker // does not need to be identical. The point is to not make users learn yet
16*9880d681SAndroid Build Coastguard Worker // another set of flags.
17*9880d681SAndroid Build Coastguard Worker //
18*9880d681SAndroid Build Coastguard Worker // Output should be specialized for each format where appropriate.
19*9880d681SAndroid Build Coastguard Worker //
20*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker #include "llvm-readobj.h"
23*9880d681SAndroid Build Coastguard Worker #include "Error.h"
24*9880d681SAndroid Build Coastguard Worker #include "ObjDumper.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Archive.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/COFFImportFile.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ELFObjectFile.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachOUniversal.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Casting.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataTypes.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/PrettyStackTrace.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ScopedPrinter.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Signals.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetSelect.h"
42*9880d681SAndroid Build Coastguard Worker #include <string>
43*9880d681SAndroid Build Coastguard Worker #include <system_error>
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker using namespace llvm;
46*9880d681SAndroid Build Coastguard Worker using namespace llvm::object;
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker namespace opts {
49*9880d681SAndroid Build Coastguard Worker   cl::list<std::string> InputFilenames(cl::Positional,
50*9880d681SAndroid Build Coastguard Worker     cl::desc("<input object files>"),
51*9880d681SAndroid Build Coastguard Worker     cl::ZeroOrMore);
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker   // -file-headers, -h
54*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> FileHeaders("file-headers",
55*9880d681SAndroid Build Coastguard Worker     cl::desc("Display file headers "));
56*9880d681SAndroid Build Coastguard Worker   cl::alias FileHeadersShort("h",
57*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --file-headers"),
58*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(FileHeaders));
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker   // -sections, -s
61*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> Sections("sections",
62*9880d681SAndroid Build Coastguard Worker     cl::desc("Display all sections."));
63*9880d681SAndroid Build Coastguard Worker   cl::alias SectionsShort("s",
64*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --sections"),
65*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(Sections));
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker   // -section-relocations, -sr
68*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> SectionRelocations("section-relocations",
69*9880d681SAndroid Build Coastguard Worker     cl::desc("Display relocations for each section shown."));
70*9880d681SAndroid Build Coastguard Worker   cl::alias SectionRelocationsShort("sr",
71*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --section-relocations"),
72*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(SectionRelocations));
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   // -section-symbols, -st
75*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> SectionSymbols("section-symbols",
76*9880d681SAndroid Build Coastguard Worker     cl::desc("Display symbols for each section shown."));
77*9880d681SAndroid Build Coastguard Worker   cl::alias SectionSymbolsShort("st",
78*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --section-symbols"),
79*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(SectionSymbols));
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker   // -section-data, -sd
82*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> SectionData("section-data",
83*9880d681SAndroid Build Coastguard Worker     cl::desc("Display section data for each section shown."));
84*9880d681SAndroid Build Coastguard Worker   cl::alias SectionDataShort("sd",
85*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --section-data"),
86*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(SectionData));
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   // -relocations, -r
89*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> Relocations("relocations",
90*9880d681SAndroid Build Coastguard Worker     cl::desc("Display the relocation entries in the file"));
91*9880d681SAndroid Build Coastguard Worker   cl::alias RelocationsShort("r",
92*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --relocations"),
93*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(Relocations));
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   // -dyn-relocations
96*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> DynRelocs("dyn-relocations",
97*9880d681SAndroid Build Coastguard Worker     cl::desc("Display the dynamic relocation entries in the file"));
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker   // -symbols, -t
100*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> Symbols("symbols",
101*9880d681SAndroid Build Coastguard Worker     cl::desc("Display the symbol table"));
102*9880d681SAndroid Build Coastguard Worker   cl::alias SymbolsShort("t",
103*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --symbols"),
104*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(Symbols));
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker   // -dyn-symbols, -dt
107*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> DynamicSymbols("dyn-symbols",
108*9880d681SAndroid Build Coastguard Worker     cl::desc("Display the dynamic symbol table"));
109*9880d681SAndroid Build Coastguard Worker   cl::alias DynamicSymbolsShort("dt",
110*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --dyn-symbols"),
111*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(DynamicSymbols));
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker   // -unwind, -u
114*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> UnwindInfo("unwind",
115*9880d681SAndroid Build Coastguard Worker     cl::desc("Display unwind information"));
116*9880d681SAndroid Build Coastguard Worker   cl::alias UnwindInfoShort("u",
117*9880d681SAndroid Build Coastguard Worker     cl::desc("Alias for --unwind"),
118*9880d681SAndroid Build Coastguard Worker     cl::aliasopt(UnwindInfo));
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker   // -dynamic-table
121*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> DynamicTable("dynamic-table",
122*9880d681SAndroid Build Coastguard Worker     cl::desc("Display the ELF .dynamic section table"));
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   // -needed-libs
125*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> NeededLibraries("needed-libs",
126*9880d681SAndroid Build Coastguard Worker     cl::desc("Display the needed libraries"));
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   // -program-headers
129*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> ProgramHeaders("program-headers",
130*9880d681SAndroid Build Coastguard Worker     cl::desc("Display ELF program headers"));
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker   // -hash-table
133*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> HashTable("hash-table",
134*9880d681SAndroid Build Coastguard Worker     cl::desc("Display ELF hash table"));
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker   // -gnu-hash-table
137*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> GnuHashTable("gnu-hash-table",
138*9880d681SAndroid Build Coastguard Worker     cl::desc("Display ELF .gnu.hash section"));
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker   // -expand-relocs
141*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> ExpandRelocs("expand-relocs",
142*9880d681SAndroid Build Coastguard Worker     cl::desc("Expand each shown relocation to multiple lines"));
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker   // -codeview
145*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> CodeView("codeview",
146*9880d681SAndroid Build Coastguard Worker                          cl::desc("Display CodeView debug information"));
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker   // -codeview-merged-types
149*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
150*9880d681SAndroid Build Coastguard Worker       CodeViewMergedTypes("codeview-merged-types",
151*9880d681SAndroid Build Coastguard Worker                           cl::desc("Display the merged CodeView type stream"));
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker   // -codeview-subsection-bytes
154*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> CodeViewSubsectionBytes(
155*9880d681SAndroid Build Coastguard Worker       "codeview-subsection-bytes",
156*9880d681SAndroid Build Coastguard Worker       cl::desc("Dump raw contents of codeview debug sections and records"));
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   // -arm-attributes, -a
159*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> ARMAttributes("arm-attributes",
160*9880d681SAndroid Build Coastguard Worker                               cl::desc("Display the ARM attributes section"));
161*9880d681SAndroid Build Coastguard Worker   cl::alias ARMAttributesShort("-a", cl::desc("Alias for --arm-attributes"),
162*9880d681SAndroid Build Coastguard Worker                                cl::aliasopt(ARMAttributes));
163*9880d681SAndroid Build Coastguard Worker 
164*9880d681SAndroid Build Coastguard Worker   // -mips-plt-got
165*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
166*9880d681SAndroid Build Coastguard Worker   MipsPLTGOT("mips-plt-got",
167*9880d681SAndroid Build Coastguard Worker              cl::desc("Display the MIPS GOT and PLT GOT sections"));
168*9880d681SAndroid Build Coastguard Worker 
169*9880d681SAndroid Build Coastguard Worker   // -mips-abi-flags
170*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> MipsABIFlags("mips-abi-flags",
171*9880d681SAndroid Build Coastguard Worker                              cl::desc("Display the MIPS.abiflags section"));
172*9880d681SAndroid Build Coastguard Worker 
173*9880d681SAndroid Build Coastguard Worker   // -mips-reginfo
174*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> MipsReginfo("mips-reginfo",
175*9880d681SAndroid Build Coastguard Worker                             cl::desc("Display the MIPS .reginfo section"));
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker   // -mips-options
178*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> MipsOptions("mips-options",
179*9880d681SAndroid Build Coastguard Worker                             cl::desc("Display the MIPS .MIPS.options section"));
180*9880d681SAndroid Build Coastguard Worker 
181*9880d681SAndroid Build Coastguard Worker   // -coff-imports
182*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
183*9880d681SAndroid Build Coastguard Worker   COFFImports("coff-imports", cl::desc("Display the PE/COFF import table"));
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker   // -coff-exports
186*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
187*9880d681SAndroid Build Coastguard Worker   COFFExports("coff-exports", cl::desc("Display the PE/COFF export table"));
188*9880d681SAndroid Build Coastguard Worker 
189*9880d681SAndroid Build Coastguard Worker   // -coff-directives
190*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
191*9880d681SAndroid Build Coastguard Worker   COFFDirectives("coff-directives",
192*9880d681SAndroid Build Coastguard Worker                  cl::desc("Display the PE/COFF .drectve section"));
193*9880d681SAndroid Build Coastguard Worker 
194*9880d681SAndroid Build Coastguard Worker   // -coff-basereloc
195*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
196*9880d681SAndroid Build Coastguard Worker   COFFBaseRelocs("coff-basereloc",
197*9880d681SAndroid Build Coastguard Worker                  cl::desc("Display the PE/COFF .reloc section"));
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker   // -coff-debug-directory
200*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
201*9880d681SAndroid Build Coastguard Worker   COFFDebugDirectory("coff-debug-directory",
202*9880d681SAndroid Build Coastguard Worker                      cl::desc("Display the PE/COFF debug directory"));
203*9880d681SAndroid Build Coastguard Worker 
204*9880d681SAndroid Build Coastguard Worker   // -macho-data-in-code
205*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
206*9880d681SAndroid Build Coastguard Worker   MachODataInCode("macho-data-in-code",
207*9880d681SAndroid Build Coastguard Worker                   cl::desc("Display MachO Data in Code command"));
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker   // -macho-indirect-symbols
210*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
211*9880d681SAndroid Build Coastguard Worker   MachOIndirectSymbols("macho-indirect-symbols",
212*9880d681SAndroid Build Coastguard Worker                   cl::desc("Display MachO indirect symbols"));
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker   // -macho-linker-options
215*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
216*9880d681SAndroid Build Coastguard Worker   MachOLinkerOptions("macho-linker-options",
217*9880d681SAndroid Build Coastguard Worker                   cl::desc("Display MachO linker options"));
218*9880d681SAndroid Build Coastguard Worker 
219*9880d681SAndroid Build Coastguard Worker   // -macho-segment
220*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
221*9880d681SAndroid Build Coastguard Worker   MachOSegment("macho-segment",
222*9880d681SAndroid Build Coastguard Worker                   cl::desc("Display MachO Segment command"));
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker   // -macho-version-min
225*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
226*9880d681SAndroid Build Coastguard Worker   MachOVersionMin("macho-version-min",
227*9880d681SAndroid Build Coastguard Worker                   cl::desc("Display MachO version min command"));
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker   // -macho-dysymtab
230*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
231*9880d681SAndroid Build Coastguard Worker   MachODysymtab("macho-dysymtab",
232*9880d681SAndroid Build Coastguard Worker                   cl::desc("Display MachO Dysymtab command"));
233*9880d681SAndroid Build Coastguard Worker 
234*9880d681SAndroid Build Coastguard Worker   // -stackmap
235*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
236*9880d681SAndroid Build Coastguard Worker   PrintStackMap("stackmap",
237*9880d681SAndroid Build Coastguard Worker                 cl::desc("Display contents of stackmap section"));
238*9880d681SAndroid Build Coastguard Worker 
239*9880d681SAndroid Build Coastguard Worker   // -version-info
240*9880d681SAndroid Build Coastguard Worker   cl::opt<bool>
241*9880d681SAndroid Build Coastguard Worker       VersionInfo("version-info",
242*9880d681SAndroid Build Coastguard Worker                   cl::desc("Display ELF version sections (if present)"));
243*9880d681SAndroid Build Coastguard Worker   cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"),
244*9880d681SAndroid Build Coastguard Worker                              cl::aliasopt(VersionInfo));
245*9880d681SAndroid Build Coastguard Worker 
246*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> SectionGroups("elf-section-groups",
247*9880d681SAndroid Build Coastguard Worker                               cl::desc("Display ELF section group contents"));
248*9880d681SAndroid Build Coastguard Worker   cl::alias SectionGroupsShort("g", cl::desc("Alias for -elf-sections-groups"),
249*9880d681SAndroid Build Coastguard Worker                                cl::aliasopt(SectionGroups));
250*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> HashHistogram(
251*9880d681SAndroid Build Coastguard Worker       "elf-hash-histogram",
252*9880d681SAndroid Build Coastguard Worker       cl::desc("Display bucket list histogram for hash sections"));
253*9880d681SAndroid Build Coastguard Worker   cl::alias HashHistogramShort("I", cl::desc("Alias for -elf-hash-histogram"),
254*9880d681SAndroid Build Coastguard Worker                                cl::aliasopt(HashHistogram));
255*9880d681SAndroid Build Coastguard Worker 
256*9880d681SAndroid Build Coastguard Worker   cl::opt<OutputStyleTy>
257*9880d681SAndroid Build Coastguard Worker       Output("elf-output-style", cl::desc("Specify ELF dump style"),
258*9880d681SAndroid Build Coastguard Worker              cl::values(clEnumVal(LLVM, "LLVM default style"),
259*9880d681SAndroid Build Coastguard Worker                         clEnumVal(GNU, "GNU readelf style"), clEnumValEnd),
260*9880d681SAndroid Build Coastguard Worker              cl::init(LLVM));
261*9880d681SAndroid Build Coastguard Worker } // namespace opts
262*9880d681SAndroid Build Coastguard Worker 
263*9880d681SAndroid Build Coastguard Worker namespace llvm {
264*9880d681SAndroid Build Coastguard Worker 
reportError(Twine Msg)265*9880d681SAndroid Build Coastguard Worker LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
266*9880d681SAndroid Build Coastguard Worker   errs() << "\nError reading file: " << Msg << ".\n";
267*9880d681SAndroid Build Coastguard Worker   errs().flush();
268*9880d681SAndroid Build Coastguard Worker   exit(1);
269*9880d681SAndroid Build Coastguard Worker }
270*9880d681SAndroid Build Coastguard Worker 
error(std::error_code EC)271*9880d681SAndroid Build Coastguard Worker void error(std::error_code EC) {
272*9880d681SAndroid Build Coastguard Worker   if (!EC)
273*9880d681SAndroid Build Coastguard Worker     return;
274*9880d681SAndroid Build Coastguard Worker 
275*9880d681SAndroid Build Coastguard Worker   reportError(EC.message());
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker 
relocAddressLess(RelocationRef a,RelocationRef b)278*9880d681SAndroid Build Coastguard Worker bool relocAddressLess(RelocationRef a, RelocationRef b) {
279*9880d681SAndroid Build Coastguard Worker   return a.getOffset() < b.getOffset();
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker 
282*9880d681SAndroid Build Coastguard Worker } // namespace llvm
283*9880d681SAndroid Build Coastguard Worker 
reportError(StringRef Input,std::error_code EC)284*9880d681SAndroid Build Coastguard Worker static void reportError(StringRef Input, std::error_code EC) {
285*9880d681SAndroid Build Coastguard Worker   if (Input == "-")
286*9880d681SAndroid Build Coastguard Worker     Input = "<stdin>";
287*9880d681SAndroid Build Coastguard Worker 
288*9880d681SAndroid Build Coastguard Worker   reportError(Twine(Input) + ": " + EC.message());
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker 
reportError(StringRef Input,StringRef Message)291*9880d681SAndroid Build Coastguard Worker static void reportError(StringRef Input, StringRef Message) {
292*9880d681SAndroid Build Coastguard Worker   if (Input == "-")
293*9880d681SAndroid Build Coastguard Worker     Input = "<stdin>";
294*9880d681SAndroid Build Coastguard Worker 
295*9880d681SAndroid Build Coastguard Worker   reportError(Twine(Input) + ": " + Message);
296*9880d681SAndroid Build Coastguard Worker }
297*9880d681SAndroid Build Coastguard Worker 
reportError(StringRef Input,Error Err)298*9880d681SAndroid Build Coastguard Worker static void reportError(StringRef Input, Error Err) {
299*9880d681SAndroid Build Coastguard Worker   if (Input == "-")
300*9880d681SAndroid Build Coastguard Worker     Input = "<stdin>";
301*9880d681SAndroid Build Coastguard Worker   std::string ErrMsg;
302*9880d681SAndroid Build Coastguard Worker   {
303*9880d681SAndroid Build Coastguard Worker     raw_string_ostream ErrStream(ErrMsg);
304*9880d681SAndroid Build Coastguard Worker     logAllUnhandledErrors(std::move(Err), ErrStream, Input + ": ");
305*9880d681SAndroid Build Coastguard Worker   }
306*9880d681SAndroid Build Coastguard Worker   reportError(ErrMsg);
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker 
isMipsArch(unsigned Arch)309*9880d681SAndroid Build Coastguard Worker static bool isMipsArch(unsigned Arch) {
310*9880d681SAndroid Build Coastguard Worker   switch (Arch) {
311*9880d681SAndroid Build Coastguard Worker   case llvm::Triple::mips:
312*9880d681SAndroid Build Coastguard Worker   case llvm::Triple::mipsel:
313*9880d681SAndroid Build Coastguard Worker   case llvm::Triple::mips64:
314*9880d681SAndroid Build Coastguard Worker   case llvm::Triple::mips64el:
315*9880d681SAndroid Build Coastguard Worker     return true;
316*9880d681SAndroid Build Coastguard Worker   default:
317*9880d681SAndroid Build Coastguard Worker     return false;
318*9880d681SAndroid Build Coastguard Worker   }
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker 
321*9880d681SAndroid Build Coastguard Worker static llvm::codeview::MemoryTypeTableBuilder CVTypes;
322*9880d681SAndroid Build Coastguard Worker 
323*9880d681SAndroid Build Coastguard Worker /// @brief Creates an format-specific object file dumper.
createDumper(const ObjectFile * Obj,ScopedPrinter & Writer,std::unique_ptr<ObjDumper> & Result)324*9880d681SAndroid Build Coastguard Worker static std::error_code createDumper(const ObjectFile *Obj,
325*9880d681SAndroid Build Coastguard Worker                                     ScopedPrinter &Writer,
326*9880d681SAndroid Build Coastguard Worker                                     std::unique_ptr<ObjDumper> &Result) {
327*9880d681SAndroid Build Coastguard Worker   if (!Obj)
328*9880d681SAndroid Build Coastguard Worker     return readobj_error::unsupported_file_format;
329*9880d681SAndroid Build Coastguard Worker 
330*9880d681SAndroid Build Coastguard Worker   if (Obj->isCOFF())
331*9880d681SAndroid Build Coastguard Worker     return createCOFFDumper(Obj, Writer, Result);
332*9880d681SAndroid Build Coastguard Worker   if (Obj->isELF())
333*9880d681SAndroid Build Coastguard Worker     return createELFDumper(Obj, Writer, Result);
334*9880d681SAndroid Build Coastguard Worker   if (Obj->isMachO())
335*9880d681SAndroid Build Coastguard Worker     return createMachODumper(Obj, Writer, Result);
336*9880d681SAndroid Build Coastguard Worker 
337*9880d681SAndroid Build Coastguard Worker   return readobj_error::unsupported_obj_file_format;
338*9880d681SAndroid Build Coastguard Worker }
339*9880d681SAndroid Build Coastguard Worker 
340*9880d681SAndroid Build Coastguard Worker /// @brief Dumps the specified object file.
dumpObject(const ObjectFile * Obj)341*9880d681SAndroid Build Coastguard Worker static void dumpObject(const ObjectFile *Obj) {
342*9880d681SAndroid Build Coastguard Worker   ScopedPrinter Writer(outs());
343*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<ObjDumper> Dumper;
344*9880d681SAndroid Build Coastguard Worker   if (std::error_code EC = createDumper(Obj, Writer, Dumper))
345*9880d681SAndroid Build Coastguard Worker     reportError(Obj->getFileName(), EC);
346*9880d681SAndroid Build Coastguard Worker 
347*9880d681SAndroid Build Coastguard Worker   if (opts::Output == opts::LLVM) {
348*9880d681SAndroid Build Coastguard Worker     outs() << '\n';
349*9880d681SAndroid Build Coastguard Worker     outs() << "File: " << Obj->getFileName() << "\n";
350*9880d681SAndroid Build Coastguard Worker     outs() << "Format: " << Obj->getFileFormatName() << "\n";
351*9880d681SAndroid Build Coastguard Worker     outs() << "Arch: " << Triple::getArchTypeName(
352*9880d681SAndroid Build Coastguard Worker                               (llvm::Triple::ArchType)Obj->getArch()) << "\n";
353*9880d681SAndroid Build Coastguard Worker     outs() << "AddressSize: " << (8 * Obj->getBytesInAddress()) << "bit\n";
354*9880d681SAndroid Build Coastguard Worker     Dumper->printLoadName();
355*9880d681SAndroid Build Coastguard Worker   }
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker   if (opts::FileHeaders)
358*9880d681SAndroid Build Coastguard Worker     Dumper->printFileHeaders();
359*9880d681SAndroid Build Coastguard Worker   if (opts::Sections)
360*9880d681SAndroid Build Coastguard Worker     Dumper->printSections();
361*9880d681SAndroid Build Coastguard Worker   if (opts::Relocations)
362*9880d681SAndroid Build Coastguard Worker     Dumper->printRelocations();
363*9880d681SAndroid Build Coastguard Worker   if (opts::DynRelocs)
364*9880d681SAndroid Build Coastguard Worker     Dumper->printDynamicRelocations();
365*9880d681SAndroid Build Coastguard Worker   if (opts::Symbols)
366*9880d681SAndroid Build Coastguard Worker     Dumper->printSymbols();
367*9880d681SAndroid Build Coastguard Worker   if (opts::DynamicSymbols)
368*9880d681SAndroid Build Coastguard Worker     Dumper->printDynamicSymbols();
369*9880d681SAndroid Build Coastguard Worker   if (opts::UnwindInfo)
370*9880d681SAndroid Build Coastguard Worker     Dumper->printUnwindInfo();
371*9880d681SAndroid Build Coastguard Worker   if (opts::DynamicTable)
372*9880d681SAndroid Build Coastguard Worker     Dumper->printDynamicTable();
373*9880d681SAndroid Build Coastguard Worker   if (opts::NeededLibraries)
374*9880d681SAndroid Build Coastguard Worker     Dumper->printNeededLibraries();
375*9880d681SAndroid Build Coastguard Worker   if (opts::ProgramHeaders)
376*9880d681SAndroid Build Coastguard Worker     Dumper->printProgramHeaders();
377*9880d681SAndroid Build Coastguard Worker   if (opts::HashTable)
378*9880d681SAndroid Build Coastguard Worker     Dumper->printHashTable();
379*9880d681SAndroid Build Coastguard Worker   if (opts::GnuHashTable)
380*9880d681SAndroid Build Coastguard Worker     Dumper->printGnuHashTable();
381*9880d681SAndroid Build Coastguard Worker   if (opts::VersionInfo)
382*9880d681SAndroid Build Coastguard Worker     Dumper->printVersionInfo();
383*9880d681SAndroid Build Coastguard Worker   if (Obj->isELF()) {
384*9880d681SAndroid Build Coastguard Worker     if (Obj->getArch() == llvm::Triple::arm)
385*9880d681SAndroid Build Coastguard Worker       if (opts::ARMAttributes)
386*9880d681SAndroid Build Coastguard Worker         Dumper->printAttributes();
387*9880d681SAndroid Build Coastguard Worker     if (isMipsArch(Obj->getArch())) {
388*9880d681SAndroid Build Coastguard Worker       if (opts::MipsPLTGOT)
389*9880d681SAndroid Build Coastguard Worker         Dumper->printMipsPLTGOT();
390*9880d681SAndroid Build Coastguard Worker       if (opts::MipsABIFlags)
391*9880d681SAndroid Build Coastguard Worker         Dumper->printMipsABIFlags();
392*9880d681SAndroid Build Coastguard Worker       if (opts::MipsReginfo)
393*9880d681SAndroid Build Coastguard Worker         Dumper->printMipsReginfo();
394*9880d681SAndroid Build Coastguard Worker       if (opts::MipsOptions)
395*9880d681SAndroid Build Coastguard Worker         Dumper->printMipsOptions();
396*9880d681SAndroid Build Coastguard Worker     }
397*9880d681SAndroid Build Coastguard Worker     if (opts::SectionGroups)
398*9880d681SAndroid Build Coastguard Worker       Dumper->printGroupSections();
399*9880d681SAndroid Build Coastguard Worker     if (opts::HashHistogram)
400*9880d681SAndroid Build Coastguard Worker       Dumper->printHashHistogram();
401*9880d681SAndroid Build Coastguard Worker   }
402*9880d681SAndroid Build Coastguard Worker   if (Obj->isCOFF()) {
403*9880d681SAndroid Build Coastguard Worker     if (opts::COFFImports)
404*9880d681SAndroid Build Coastguard Worker       Dumper->printCOFFImports();
405*9880d681SAndroid Build Coastguard Worker     if (opts::COFFExports)
406*9880d681SAndroid Build Coastguard Worker       Dumper->printCOFFExports();
407*9880d681SAndroid Build Coastguard Worker     if (opts::COFFDirectives)
408*9880d681SAndroid Build Coastguard Worker       Dumper->printCOFFDirectives();
409*9880d681SAndroid Build Coastguard Worker     if (opts::COFFBaseRelocs)
410*9880d681SAndroid Build Coastguard Worker       Dumper->printCOFFBaseReloc();
411*9880d681SAndroid Build Coastguard Worker     if (opts::COFFDebugDirectory)
412*9880d681SAndroid Build Coastguard Worker       Dumper->printCOFFDebugDirectory();
413*9880d681SAndroid Build Coastguard Worker     if (opts::CodeView)
414*9880d681SAndroid Build Coastguard Worker       Dumper->printCodeViewDebugInfo();
415*9880d681SAndroid Build Coastguard Worker     if (opts::CodeViewMergedTypes)
416*9880d681SAndroid Build Coastguard Worker       Dumper->mergeCodeViewTypes(CVTypes);
417*9880d681SAndroid Build Coastguard Worker   }
418*9880d681SAndroid Build Coastguard Worker   if (Obj->isMachO()) {
419*9880d681SAndroid Build Coastguard Worker     if (opts::MachODataInCode)
420*9880d681SAndroid Build Coastguard Worker       Dumper->printMachODataInCode();
421*9880d681SAndroid Build Coastguard Worker     if (opts::MachOIndirectSymbols)
422*9880d681SAndroid Build Coastguard Worker       Dumper->printMachOIndirectSymbols();
423*9880d681SAndroid Build Coastguard Worker     if (opts::MachOLinkerOptions)
424*9880d681SAndroid Build Coastguard Worker       Dumper->printMachOLinkerOptions();
425*9880d681SAndroid Build Coastguard Worker     if (opts::MachOSegment)
426*9880d681SAndroid Build Coastguard Worker       Dumper->printMachOSegment();
427*9880d681SAndroid Build Coastguard Worker     if (opts::MachOVersionMin)
428*9880d681SAndroid Build Coastguard Worker       Dumper->printMachOVersionMin();
429*9880d681SAndroid Build Coastguard Worker     if (opts::MachODysymtab)
430*9880d681SAndroid Build Coastguard Worker       Dumper->printMachODysymtab();
431*9880d681SAndroid Build Coastguard Worker   }
432*9880d681SAndroid Build Coastguard Worker   if (opts::PrintStackMap)
433*9880d681SAndroid Build Coastguard Worker     Dumper->printStackMap();
434*9880d681SAndroid Build Coastguard Worker }
435*9880d681SAndroid Build Coastguard Worker 
436*9880d681SAndroid Build Coastguard Worker /// @brief Dumps each object file in \a Arc;
dumpArchive(const Archive * Arc)437*9880d681SAndroid Build Coastguard Worker static void dumpArchive(const Archive *Arc) {
438*9880d681SAndroid Build Coastguard Worker   Error Err;
439*9880d681SAndroid Build Coastguard Worker   for (auto &Child : Arc->children(Err)) {
440*9880d681SAndroid Build Coastguard Worker     Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
441*9880d681SAndroid Build Coastguard Worker     if (!ChildOrErr) {
442*9880d681SAndroid Build Coastguard Worker       if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
443*9880d681SAndroid Build Coastguard Worker         std::string Buf;
444*9880d681SAndroid Build Coastguard Worker         raw_string_ostream OS(Buf);
445*9880d681SAndroid Build Coastguard Worker         logAllUnhandledErrors(ChildOrErr.takeError(), OS, "");
446*9880d681SAndroid Build Coastguard Worker         OS.flush();
447*9880d681SAndroid Build Coastguard Worker         reportError(Arc->getFileName(), Buf);
448*9880d681SAndroid Build Coastguard Worker       }
449*9880d681SAndroid Build Coastguard Worker       continue;
450*9880d681SAndroid Build Coastguard Worker     }
451*9880d681SAndroid Build Coastguard Worker     if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
452*9880d681SAndroid Build Coastguard Worker       dumpObject(Obj);
453*9880d681SAndroid Build Coastguard Worker     else
454*9880d681SAndroid Build Coastguard Worker       reportError(Arc->getFileName(), readobj_error::unrecognized_file_format);
455*9880d681SAndroid Build Coastguard Worker   }
456*9880d681SAndroid Build Coastguard Worker   if (Err)
457*9880d681SAndroid Build Coastguard Worker     reportError(Arc->getFileName(), std::move(Err));
458*9880d681SAndroid Build Coastguard Worker }
459*9880d681SAndroid Build Coastguard Worker 
460*9880d681SAndroid Build Coastguard Worker /// @brief Dumps each object file in \a MachO Universal Binary;
dumpMachOUniversalBinary(const MachOUniversalBinary * UBinary)461*9880d681SAndroid Build Coastguard Worker static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary) {
462*9880d681SAndroid Build Coastguard Worker   for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) {
463*9880d681SAndroid Build Coastguard Worker     Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile();
464*9880d681SAndroid Build Coastguard Worker     if (ObjOrErr)
465*9880d681SAndroid Build Coastguard Worker       dumpObject(&*ObjOrErr.get());
466*9880d681SAndroid Build Coastguard Worker     else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
467*9880d681SAndroid Build Coastguard Worker       std::string Buf;
468*9880d681SAndroid Build Coastguard Worker       raw_string_ostream OS(Buf);
469*9880d681SAndroid Build Coastguard Worker       logAllUnhandledErrors(ObjOrErr.takeError(), OS, "");
470*9880d681SAndroid Build Coastguard Worker       OS.flush();
471*9880d681SAndroid Build Coastguard Worker       reportError(UBinary->getFileName(), Buf);
472*9880d681SAndroid Build Coastguard Worker     }
473*9880d681SAndroid Build Coastguard Worker     else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
474*9880d681SAndroid Build Coastguard Worker       dumpArchive(&*AOrErr.get());
475*9880d681SAndroid Build Coastguard Worker   }
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker 
478*9880d681SAndroid Build Coastguard Worker /// @brief Opens \a File and dumps it.
dumpInput(StringRef File)479*9880d681SAndroid Build Coastguard Worker static void dumpInput(StringRef File) {
480*9880d681SAndroid Build Coastguard Worker 
481*9880d681SAndroid Build Coastguard Worker   // Attempt to open the binary.
482*9880d681SAndroid Build Coastguard Worker   Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
483*9880d681SAndroid Build Coastguard Worker   if (!BinaryOrErr)
484*9880d681SAndroid Build Coastguard Worker     reportError(File, errorToErrorCode(BinaryOrErr.takeError()));
485*9880d681SAndroid Build Coastguard Worker   Binary &Binary = *BinaryOrErr.get().getBinary();
486*9880d681SAndroid Build Coastguard Worker 
487*9880d681SAndroid Build Coastguard Worker   if (Archive *Arc = dyn_cast<Archive>(&Binary))
488*9880d681SAndroid Build Coastguard Worker     dumpArchive(Arc);
489*9880d681SAndroid Build Coastguard Worker   else if (MachOUniversalBinary *UBinary =
490*9880d681SAndroid Build Coastguard Worker                dyn_cast<MachOUniversalBinary>(&Binary))
491*9880d681SAndroid Build Coastguard Worker     dumpMachOUniversalBinary(UBinary);
492*9880d681SAndroid Build Coastguard Worker   else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
493*9880d681SAndroid Build Coastguard Worker     dumpObject(Obj);
494*9880d681SAndroid Build Coastguard Worker   else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary))
495*9880d681SAndroid Build Coastguard Worker     dumpCOFFImportFile(Import);
496*9880d681SAndroid Build Coastguard Worker   else
497*9880d681SAndroid Build Coastguard Worker     reportError(File, readobj_error::unrecognized_file_format);
498*9880d681SAndroid Build Coastguard Worker }
499*9880d681SAndroid Build Coastguard Worker 
main(int argc,const char * argv[])500*9880d681SAndroid Build Coastguard Worker int main(int argc, const char *argv[]) {
501*9880d681SAndroid Build Coastguard Worker   sys::PrintStackTraceOnErrorSignal(argv[0]);
502*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceProgram X(argc, argv);
503*9880d681SAndroid Build Coastguard Worker   llvm_shutdown_obj Y;
504*9880d681SAndroid Build Coastguard Worker 
505*9880d681SAndroid Build Coastguard Worker   // Register the target printer for --version.
506*9880d681SAndroid Build Coastguard Worker   cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
507*9880d681SAndroid Build Coastguard Worker 
508*9880d681SAndroid Build Coastguard Worker   cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n");
509*9880d681SAndroid Build Coastguard Worker 
510*9880d681SAndroid Build Coastguard Worker   // Default to stdin if no filename is specified.
511*9880d681SAndroid Build Coastguard Worker   if (opts::InputFilenames.size() == 0)
512*9880d681SAndroid Build Coastguard Worker     opts::InputFilenames.push_back("-");
513*9880d681SAndroid Build Coastguard Worker 
514*9880d681SAndroid Build Coastguard Worker   std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(),
515*9880d681SAndroid Build Coastguard Worker                 dumpInput);
516*9880d681SAndroid Build Coastguard Worker 
517*9880d681SAndroid Build Coastguard Worker   if (opts::CodeViewMergedTypes) {
518*9880d681SAndroid Build Coastguard Worker     ScopedPrinter W(outs());
519*9880d681SAndroid Build Coastguard Worker     dumpCodeViewMergedTypes(W, CVTypes);
520*9880d681SAndroid Build Coastguard Worker   }
521*9880d681SAndroid Build Coastguard Worker 
522*9880d681SAndroid Build Coastguard Worker   return 0;
523*9880d681SAndroid Build Coastguard Worker }
524