1054f422dSBenjamin Kramer //===- llvm-readobj.cpp - Dump contents of an Object File -----------------===//
22fc34c5fSDavid Meyer //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62fc34c5fSDavid Meyer //
72fc34c5fSDavid Meyer //===----------------------------------------------------------------------===//
82fc34c5fSDavid Meyer //
9d7e7003eSMichael J. Spencer // This is a tool similar to readelf, except it works on multiple object file
10d7e7003eSMichael J. Spencer // formats. The main purpose of this tool is to provide detailed output suitable
11d7e7003eSMichael J. Spencer // for FileCheck.
12ae11a78bSDavid Meyer //
13d7e7003eSMichael J. Spencer // Flags should be similar to readelf where supported, but the output format
14d7e7003eSMichael J. Spencer // does not need to be identical. The point is to not make users learn yet
15d7e7003eSMichael J. Spencer // another set of flags.
16ae11a78bSDavid Meyer //
17d7e7003eSMichael J. Spencer // Output should be specialized for each format where appropriate.
18ae11a78bSDavid Meyer //
19ae11a78bSDavid Meyer //===----------------------------------------------------------------------===//
202fc34c5fSDavid Meyer 
216a8746b7SMichael J. Spencer #include "llvm-readobj.h"
229cad53cfSEric Christopher #include "ObjDumper.h"
23c2189b83SMarek Sokolowski #include "WindowsResourceDumper.h"
24*1ae449f9SVy Nguyen #include "llvm/ADT/Optional.h"
25120366edSAlexandre Ganea #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
26ca6dbf14SZachary Turner #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
2789b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
289cad53cfSEric Christopher #include "llvm/Object/Archive.h"
2971ba9bddSRui Ueyama #include "llvm/Object/COFFImportFile.h"
303fe01f0eSGeorgii Rymar #include "llvm/Object/ELFObjectFile.h"
318448a243SRafael Espindola #include "llvm/Object/MachOUniversal.h"
324d88a1c2SChandler Carruth #include "llvm/Object/ObjectFile.h"
333fe01f0eSGeorgii Rymar #include "llvm/Object/Wasm.h"
34c2189b83SMarek Sokolowski #include "llvm/Object/WindowsResource.h"
353fe01f0eSGeorgii Rymar #include "llvm/Object/XCOFFObjectFile.h"
3646580d43SFangrui Song #include "llvm/Option/Arg.h"
3746580d43SFangrui Song #include "llvm/Option/ArgList.h"
3846580d43SFangrui Song #include "llvm/Option/Option.h"
399cad53cfSEric Christopher #include "llvm/Support/Casting.h"
402fc34c5fSDavid Meyer #include "llvm/Support/CommandLine.h"
419cad53cfSEric Christopher #include "llvm/Support/DataTypes.h"
422fc34c5fSDavid Meyer #include "llvm/Support/Debug.h"
433fe01f0eSGeorgii Rymar #include "llvm/Support/Errc.h"
449cad53cfSEric Christopher #include "llvm/Support/FileSystem.h"
4588e9a15bSSam Clegg #include "llvm/Support/FormatVariadic.h"
46197194b6SRui Ueyama #include "llvm/Support/InitLLVM.h"
47bf515501SPetr Hosek #include "llvm/Support/Path.h"
4888bb163fSZachary Turner #include "llvm/Support/ScopedPrinter.h"
4919bb1d57SStephen Tozer #include "llvm/Support/WithColor.h"
509cad53cfSEric Christopher 
512fc34c5fSDavid Meyer using namespace llvm;
522fc34c5fSDavid Meyer using namespace llvm::object;
532fc34c5fSDavid Meyer 
5446580d43SFangrui Song namespace {
5546580d43SFangrui Song using namespace llvm::opt; // for HelpHidden in Opts.inc
5646580d43SFangrui Song enum ID {
5746580d43SFangrui Song   OPT_INVALID = 0, // This is not an option ID.
5846580d43SFangrui Song #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
5946580d43SFangrui Song                HELPTEXT, METAVAR, VALUES)                                      \
6046580d43SFangrui Song   OPT_##ID,
6146580d43SFangrui Song #include "Opts.inc"
6246580d43SFangrui Song #undef OPTION
6346580d43SFangrui Song };
6446580d43SFangrui Song 
6546580d43SFangrui Song #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
6646580d43SFangrui Song #include "Opts.inc"
6746580d43SFangrui Song #undef PREFIX
6846580d43SFangrui Song 
69b68bf98cSFangrui Song const opt::OptTable::Info InfoTable[] = {
7046580d43SFangrui Song #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
7146580d43SFangrui Song                HELPTEXT, METAVAR, VALUES)                                      \
7246580d43SFangrui Song   {                                                                            \
7346580d43SFangrui Song       PREFIX,      NAME,      HELPTEXT,                                        \
7446580d43SFangrui Song       METAVAR,     OPT_##ID,  opt::Option::KIND##Class,                        \
7546580d43SFangrui Song       PARAM,       FLAGS,     OPT_##GROUP,                                     \
7646580d43SFangrui Song       OPT_##ALIAS, ALIASARGS, VALUES},
7746580d43SFangrui Song #include "Opts.inc"
7846580d43SFangrui Song #undef OPTION
7946580d43SFangrui Song };
8046580d43SFangrui Song 
8146580d43SFangrui Song class ReadobjOptTable : public opt::OptTable {
8246580d43SFangrui Song public:
ReadobjOptTable()8346580d43SFangrui Song   ReadobjOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); }
8446580d43SFangrui Song };
8546580d43SFangrui Song 
8646580d43SFangrui Song enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };
87*1ae449f9SVy Nguyen 
88*1ae449f9SVy Nguyen enum SortSymbolKeyTy {
89*1ae449f9SVy Nguyen   NAME = 0,
90*1ae449f9SVy Nguyen   TYPE = 1,
91*1ae449f9SVy Nguyen   UNKNOWN = 100,
92*1ae449f9SVy Nguyen   // TODO: add ADDRESS, SIZE as needed.
93*1ae449f9SVy Nguyen };
94*1ae449f9SVy Nguyen 
9546580d43SFangrui Song } // namespace
9646580d43SFangrui Song 
979cad53cfSEric Christopher namespace opts {
9846580d43SFangrui Song static bool Addrsig;
9946580d43SFangrui Song static bool All;
10046580d43SFangrui Song static bool ArchSpecificInfo;
10146580d43SFangrui Song static bool BBAddrMap;
10246580d43SFangrui Song bool ExpandRelocs;
10346580d43SFangrui Song static bool CGProfile;
10446580d43SFangrui Song bool Demangle;
10546580d43SFangrui Song static bool DependentLibraries;
10646580d43SFangrui Song static bool DynRelocs;
10746580d43SFangrui Song static bool DynamicSymbols;
10846580d43SFangrui Song static bool FileHeaders;
10946580d43SFangrui Song static bool Headers;
11046580d43SFangrui Song static std::vector<std::string> HexDump;
1111f35d7b5SJayson Yan static bool PrettyPrint;
11246580d43SFangrui Song static bool PrintStackMap;
11346580d43SFangrui Song static bool PrintStackSizes;
11446580d43SFangrui Song static bool Relocations;
11546580d43SFangrui Song bool SectionData;
11646580d43SFangrui Song static bool SectionDetails;
11746580d43SFangrui Song static bool SectionHeaders;
11846580d43SFangrui Song bool SectionRelocations;
11946580d43SFangrui Song bool SectionSymbols;
12046580d43SFangrui Song static std::vector<std::string> StringDump;
12146580d43SFangrui Song static bool StringTable;
12246580d43SFangrui Song static bool Symbols;
12346580d43SFangrui Song static bool UnwindInfo;
12446580d43SFangrui Song static cl::boolOrDefault SectionMapping;
125*1ae449f9SVy Nguyen static SmallVector<SortSymbolKeyTy> SortKeys;
1262fc34c5fSDavid Meyer 
12746580d43SFangrui Song // ELF specific options.
12846580d43SFangrui Song static bool DynamicTable;
12946580d43SFangrui Song static bool ELFLinkerOptions;
13046580d43SFangrui Song static bool GnuHashTable;
13146580d43SFangrui Song static bool HashSymbols;
13246580d43SFangrui Song static bool HashTable;
13346580d43SFangrui Song static bool HashHistogram;
13446580d43SFangrui Song static bool NeededLibraries;
13546580d43SFangrui Song static bool Notes;
13646580d43SFangrui Song static bool ProgramHeaders;
13746580d43SFangrui Song bool RawRelr;
13846580d43SFangrui Song static bool SectionGroups;
13946580d43SFangrui Song static bool VersionInfo;
140dbf552c4SJordan Rupprecht 
14146580d43SFangrui Song // Mach-O specific options.
14246580d43SFangrui Song static bool MachODataInCode;
14346580d43SFangrui Song static bool MachODysymtab;
14446580d43SFangrui Song static bool MachOIndirectSymbols;
14546580d43SFangrui Song static bool MachOLinkerOptions;
14646580d43SFangrui Song static bool MachOSegment;
14746580d43SFangrui Song static bool MachOVersionMin;
148cd2c409cSGeorgii Rymar 
14946580d43SFangrui Song // PE/COFF specific options.
15046580d43SFangrui Song static bool CodeView;
15146580d43SFangrui Song static bool CodeViewEnableGHash;
15246580d43SFangrui Song static bool CodeViewMergedTypes;
15346580d43SFangrui Song bool CodeViewSubsectionBytes;
15446580d43SFangrui Song static bool COFFBaseRelocs;
15546580d43SFangrui Song static bool COFFDebugDirectory;
15646580d43SFangrui Song static bool COFFDirectives;
15746580d43SFangrui Song static bool COFFExports;
15846580d43SFangrui Song static bool COFFImports;
15946580d43SFangrui Song static bool COFFLoadConfig;
16046580d43SFangrui Song static bool COFFResources;
16146580d43SFangrui Song static bool COFFTLSDirectory;
1624afeaac0SSid Manning 
163158083f0Szhijian // XCOFF specific options.
164158083f0Szhijian static bool XCOFFAuxiliaryHeader;
165158083f0Szhijian 
16646580d43SFangrui Song OutputStyleTy Output = OutputStyleTy::LLVM;
16746580d43SFangrui Song static std::vector<std::string> InputFilenames;
1689cad53cfSEric Christopher } // namespace opts
1699cad53cfSEric Christopher 
170f1337028SFangrui Song static StringRef ToolName;
171f1337028SFangrui Song 
17200ddb141SRafael Espindola namespace llvm {
17300ddb141SRafael Espindola 
error(Twine Msg)1746da3d8b1SFangrui Song [[noreturn]] static void error(Twine Msg) {
175e3fb2d54SGeorge Rimar   // Flush the standard output to print the error at a
176e3fb2d54SGeorge Rimar   // proper place.
177a1370877SGeorge Rimar   fouts().flush();
178f1337028SFangrui Song   WithColor::error(errs(), ToolName) << Msg << "\n";
179fb3acd62SRafael Espindola   exit(1);
180724d4b43SRafael Espindola }
181724d4b43SRafael Espindola 
reportError(Error Err,StringRef Input)1826da3d8b1SFangrui Song [[noreturn]] void reportError(Error Err, StringRef Input) {
18336f23182SGeorge Rimar   assert(Err);
184a1370877SGeorge Rimar   if (Input == "-")
185a1370877SGeorge Rimar     Input = "<stdin>";
18636f23182SGeorge Rimar   handleAllErrors(createFileError(Input, std::move(Err)),
187e3fb2d54SGeorge Rimar                   [&](const ErrorInfoBase &EI) { error(EI.message()); });
188e3fb2d54SGeorge Rimar   llvm_unreachable("error() call should never return");
189a1370877SGeorge Rimar }
190a1370877SGeorge Rimar 
reportWarning(Error Err,StringRef Input)191e3fb2d54SGeorge Rimar void reportWarning(Error Err, StringRef Input) {
192e3fb2d54SGeorge Rimar   assert(Err);
19367ea32a0SGeorge Rimar   if (Input == "-")
19467ea32a0SGeorge Rimar     Input = "<stdin>";
19567ea32a0SGeorge Rimar 
196e3fb2d54SGeorge Rimar   // Flush the standard output to print the warning at a
197e3fb2d54SGeorge Rimar   // proper place.
198e3fb2d54SGeorge Rimar   fouts().flush();
199f1337028SFangrui Song   handleAllErrors(
200f1337028SFangrui Song       createFileError(Input, std::move(Err)), [&](const ErrorInfoBase &EI) {
201f1337028SFangrui Song         WithColor::warning(errs(), ToolName) << EI.message() << "\n";
202dd4f253cSGeorge Rimar       });
203dd4f253cSGeorge Rimar }
204dd4f253cSGeorge Rimar 
205e3fb2d54SGeorge Rimar } // namespace llvm
206e3fb2d54SGeorge Rimar 
parseOptions(const opt::InputArgList & Args)20746580d43SFangrui Song static void parseOptions(const opt::InputArgList &Args) {
20846580d43SFangrui Song   opts::Addrsig = Args.hasArg(OPT_addrsig);
20946580d43SFangrui Song   opts::All = Args.hasArg(OPT_all);
21046580d43SFangrui Song   opts::ArchSpecificInfo = Args.hasArg(OPT_arch_specific);
21146580d43SFangrui Song   opts::BBAddrMap = Args.hasArg(OPT_bb_addr_map);
21246580d43SFangrui Song   opts::CGProfile = Args.hasArg(OPT_cg_profile);
21346580d43SFangrui Song   opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
21446580d43SFangrui Song   opts::DependentLibraries = Args.hasArg(OPT_dependent_libraries);
21546580d43SFangrui Song   opts::DynRelocs = Args.hasArg(OPT_dyn_relocations);
21646580d43SFangrui Song   opts::DynamicSymbols = Args.hasArg(OPT_dyn_syms);
21746580d43SFangrui Song   opts::ExpandRelocs = Args.hasArg(OPT_expand_relocs);
21846580d43SFangrui Song   opts::FileHeaders = Args.hasArg(OPT_file_header);
21946580d43SFangrui Song   opts::Headers = Args.hasArg(OPT_headers);
22046580d43SFangrui Song   opts::HexDump = Args.getAllArgValues(OPT_hex_dump_EQ);
22146580d43SFangrui Song   opts::Relocations = Args.hasArg(OPT_relocs);
22246580d43SFangrui Song   opts::SectionData = Args.hasArg(OPT_section_data);
22346580d43SFangrui Song   opts::SectionDetails = Args.hasArg(OPT_section_details);
22446580d43SFangrui Song   opts::SectionHeaders = Args.hasArg(OPT_section_headers);
22546580d43SFangrui Song   opts::SectionRelocations = Args.hasArg(OPT_section_relocations);
22646580d43SFangrui Song   opts::SectionSymbols = Args.hasArg(OPT_section_symbols);
22746580d43SFangrui Song   if (Args.hasArg(OPT_section_mapping))
22846580d43SFangrui Song     opts::SectionMapping = cl::BOU_TRUE;
22946580d43SFangrui Song   else if (Args.hasArg(OPT_section_mapping_EQ_false))
23046580d43SFangrui Song     opts::SectionMapping = cl::BOU_FALSE;
23146580d43SFangrui Song   else
23246580d43SFangrui Song     opts::SectionMapping = cl::BOU_UNSET;
23346580d43SFangrui Song   opts::PrintStackSizes = Args.hasArg(OPT_stack_sizes);
23446580d43SFangrui Song   opts::PrintStackMap = Args.hasArg(OPT_stackmap);
23546580d43SFangrui Song   opts::StringDump = Args.getAllArgValues(OPT_string_dump_EQ);
23646580d43SFangrui Song   opts::StringTable = Args.hasArg(OPT_string_table);
23746580d43SFangrui Song   opts::Symbols = Args.hasArg(OPT_symbols);
23846580d43SFangrui Song   opts::UnwindInfo = Args.hasArg(OPT_unwind);
23946580d43SFangrui Song 
24046580d43SFangrui Song   // ELF specific options.
24146580d43SFangrui Song   opts::DynamicTable = Args.hasArg(OPT_dynamic_table);
24246580d43SFangrui Song   opts::ELFLinkerOptions = Args.hasArg(OPT_elf_linker_options);
24346580d43SFangrui Song   if (Arg *A = Args.getLastArg(OPT_elf_output_style_EQ)) {
2441f35d7b5SJayson Yan     std::string OutputStyleChoice = A->getValue();
2451f35d7b5SJayson Yan     opts::Output = StringSwitch<opts::OutputStyleTy>(OutputStyleChoice)
2461f35d7b5SJayson Yan                        .Case("LLVM", opts::OutputStyleTy::LLVM)
2471f35d7b5SJayson Yan                        .Case("GNU", opts::OutputStyleTy::GNU)
2481f35d7b5SJayson Yan                        .Case("JSON", opts::OutputStyleTy::JSON)
2491f35d7b5SJayson Yan                        .Default(opts::OutputStyleTy::UNKNOWN);
2501f35d7b5SJayson Yan     if (opts::Output == opts::OutputStyleTy::UNKNOWN) {
2511f35d7b5SJayson Yan       error("--elf-output-style value should be either 'LLVM', 'GNU', or "
2521f35d7b5SJayson Yan             "'JSON', but was '" +
2531f35d7b5SJayson Yan             OutputStyleChoice + "'");
2541f35d7b5SJayson Yan     }
25546580d43SFangrui Song   }
25646580d43SFangrui Song   opts::GnuHashTable = Args.hasArg(OPT_gnu_hash_table);
25746580d43SFangrui Song   opts::HashSymbols = Args.hasArg(OPT_hash_symbols);
25846580d43SFangrui Song   opts::HashTable = Args.hasArg(OPT_hash_table);
25946580d43SFangrui Song   opts::HashHistogram = Args.hasArg(OPT_histogram);
26046580d43SFangrui Song   opts::NeededLibraries = Args.hasArg(OPT_needed_libs);
26146580d43SFangrui Song   opts::Notes = Args.hasArg(OPT_notes);
2621f35d7b5SJayson Yan   opts::PrettyPrint = Args.hasArg(OPT_pretty_print);
26346580d43SFangrui Song   opts::ProgramHeaders = Args.hasArg(OPT_program_headers);
26446580d43SFangrui Song   opts::RawRelr = Args.hasArg(OPT_raw_relr);
26546580d43SFangrui Song   opts::SectionGroups = Args.hasArg(OPT_section_groups);
266*1ae449f9SVy Nguyen   if (Arg *A = Args.getLastArg(OPT_sort_symbols_EQ)) {
267*1ae449f9SVy Nguyen     std::string SortKeysString = A->getValue();
268*1ae449f9SVy Nguyen     for (StringRef KeyStr : llvm::split(A->getValue(), ",")) {
269*1ae449f9SVy Nguyen       SortSymbolKeyTy KeyType = StringSwitch<SortSymbolKeyTy>(KeyStr)
270*1ae449f9SVy Nguyen                                     .Case("name", SortSymbolKeyTy::NAME)
271*1ae449f9SVy Nguyen                                     .Case("type", SortSymbolKeyTy::TYPE)
272*1ae449f9SVy Nguyen                                     .Default(SortSymbolKeyTy::UNKNOWN);
273*1ae449f9SVy Nguyen       if (KeyType == SortSymbolKeyTy::UNKNOWN)
274*1ae449f9SVy Nguyen         error("--sort-symbols value should be 'name' or 'type', but was '" +
275*1ae449f9SVy Nguyen               Twine(KeyStr) + "'");
276*1ae449f9SVy Nguyen       opts::SortKeys.push_back(KeyType);
277*1ae449f9SVy Nguyen     }
278*1ae449f9SVy Nguyen   }
27946580d43SFangrui Song   opts::VersionInfo = Args.hasArg(OPT_version_info);
28046580d43SFangrui Song 
28146580d43SFangrui Song   // Mach-O specific options.
28246580d43SFangrui Song   opts::MachODataInCode = Args.hasArg(OPT_macho_data_in_code);
28346580d43SFangrui Song   opts::MachODysymtab = Args.hasArg(OPT_macho_dysymtab);
28446580d43SFangrui Song   opts::MachOIndirectSymbols = Args.hasArg(OPT_macho_indirect_symbols);
28546580d43SFangrui Song   opts::MachOLinkerOptions = Args.hasArg(OPT_macho_linker_options);
28646580d43SFangrui Song   opts::MachOSegment = Args.hasArg(OPT_macho_segment);
28746580d43SFangrui Song   opts::MachOVersionMin = Args.hasArg(OPT_macho_version_min);
28846580d43SFangrui Song 
28946580d43SFangrui Song   // PE/COFF specific options.
29046580d43SFangrui Song   opts::CodeView = Args.hasArg(OPT_codeview);
29146580d43SFangrui Song   opts::CodeViewEnableGHash = Args.hasArg(OPT_codeview_ghash);
29246580d43SFangrui Song   opts::CodeViewMergedTypes = Args.hasArg(OPT_codeview_merged_types);
29346580d43SFangrui Song   opts::CodeViewSubsectionBytes = Args.hasArg(OPT_codeview_subsection_bytes);
29446580d43SFangrui Song   opts::COFFBaseRelocs = Args.hasArg(OPT_coff_basereloc);
29546580d43SFangrui Song   opts::COFFDebugDirectory = Args.hasArg(OPT_coff_debug_directory);
29646580d43SFangrui Song   opts::COFFDirectives = Args.hasArg(OPT_coff_directives);
29746580d43SFangrui Song   opts::COFFExports = Args.hasArg(OPT_coff_exports);
29846580d43SFangrui Song   opts::COFFImports = Args.hasArg(OPT_coff_imports);
29946580d43SFangrui Song   opts::COFFLoadConfig = Args.hasArg(OPT_coff_load_config);
30046580d43SFangrui Song   opts::COFFResources = Args.hasArg(OPT_coff_resources);
30146580d43SFangrui Song   opts::COFFTLSDirectory = Args.hasArg(OPT_coff_tls_directory);
30246580d43SFangrui Song 
303158083f0Szhijian   // XCOFF specific options.
304158083f0Szhijian   opts::XCOFFAuxiliaryHeader = Args.hasArg(OPT_auxiliary_header);
305158083f0Szhijian 
30646580d43SFangrui Song   opts::InputFilenames = Args.getAllArgValues(OPT_INPUT);
30746580d43SFangrui Song }
30846580d43SFangrui Song 
309c6d54da8SZachary Turner namespace {
3104efa0a42SZachary Turner struct ReadObjTypeTableBuilder {
ReadObjTypeTableBuilder__anon5b3fa7070411::ReadObjTypeTableBuilder3115d57752cSReid Kleckner   ReadObjTypeTableBuilder()
312f44473ecSKazu Hirata       : IDTable(Allocator), TypeTable(Allocator), GlobalIDTable(Allocator),
313f44473ecSKazu Hirata         GlobalTypeTable(Allocator) {}
31480433900SSimon Atanasyan 
315c6d54da8SZachary Turner   llvm::BumpPtrAllocator Allocator;
316ca6dbf14SZachary Turner   llvm::codeview::MergingTypeTableBuilder IDTable;
317ca6dbf14SZachary Turner   llvm::codeview::MergingTypeTableBuilder TypeTable;
318120366edSAlexandre Ganea   llvm::codeview::GlobalTypeTableBuilder GlobalIDTable;
319120366edSAlexandre Ganea   llvm::codeview::GlobalTypeTableBuilder GlobalTypeTable;
320120366edSAlexandre Ganea   std::vector<OwningBinary<Binary>> Binaries;
321c6d54da8SZachary Turner };
322120366edSAlexandre Ganea } // namespace
3234efa0a42SZachary Turner static ReadObjTypeTableBuilder CVTypes;
3240b269748SReid Kleckner 
3254dfcc4a7SAdrian Prantl /// Creates an format-specific object file dumper.
3263fe01f0eSGeorgii Rymar static Expected<std::unique_ptr<ObjDumper>>
createDumper(const ObjectFile & Obj,ScopedPrinter & Writer)3273fe01f0eSGeorgii Rymar createDumper(const ObjectFile &Obj, ScopedPrinter &Writer) {
3283fe01f0eSGeorgii Rymar   if (const COFFObjectFile *COFFObj = dyn_cast<COFFObjectFile>(&Obj))
3293fe01f0eSGeorgii Rymar     return createCOFFDumper(*COFFObj, Writer);
3309cad53cfSEric Christopher 
3313fe01f0eSGeorgii Rymar   if (const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj))
3323fe01f0eSGeorgii Rymar     return createELFDumper(*ELFObj, Writer);
3339cad53cfSEric Christopher 
3343fe01f0eSGeorgii Rymar   if (const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(&Obj))
3353fe01f0eSGeorgii Rymar     return createMachODumper(*MachOObj, Writer);
3363fe01f0eSGeorgii Rymar 
3373fe01f0eSGeorgii Rymar   if (const WasmObjectFile *WasmObj = dyn_cast<WasmObjectFile>(&Obj))
3383fe01f0eSGeorgii Rymar     return createWasmDumper(*WasmObj, Writer);
3393fe01f0eSGeorgii Rymar 
3403fe01f0eSGeorgii Rymar   if (const XCOFFObjectFile *XObj = dyn_cast<XCOFFObjectFile>(&Obj))
3413fe01f0eSGeorgii Rymar     return createXCOFFDumper(*XObj, Writer);
3423fe01f0eSGeorgii Rymar 
3433fe01f0eSGeorgii Rymar   return createStringError(errc::invalid_argument,
3443fe01f0eSGeorgii Rymar                            "unsupported object file format");
34563d52b1eSRafael Espindola }
34663d52b1eSRafael Espindola 
3474dfcc4a7SAdrian Prantl /// Dumps the specified object file.
dumpObject(ObjectFile & Obj,ScopedPrinter & Writer,const Archive * A=nullptr)34899a6401aSGeorgii Rymar static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
349a28dcf69SYuanfang Chen                        const Archive *A = nullptr) {
350a28dcf69SYuanfang Chen   std::string FileStr =
3513fe01f0eSGeorgii Rymar       A ? Twine(A->getFileName() + "(" + Obj.getFileName() + ")").str()
3523fe01f0eSGeorgii Rymar         : Obj.getFileName().str();
353a28dcf69SYuanfang Chen 
35499a6401aSGeorgii Rymar   std::string ContentErrString;
35599a6401aSGeorgii Rymar   if (Error ContentErr = Obj.initContent())
35699a6401aSGeorgii Rymar     ContentErrString = "unable to continue dumping, the file is corrupt: " +
35799a6401aSGeorgii Rymar                        toString(std::move(ContentErr));
35899a6401aSGeorgii Rymar 
3593fe01f0eSGeorgii Rymar   ObjDumper *Dumper;
360*1ae449f9SVy Nguyen   Optional<SymbolComparator> SymComp;
3613fe01f0eSGeorgii Rymar   Expected<std::unique_ptr<ObjDumper>> DumperOrErr = createDumper(Obj, Writer);
3623fe01f0eSGeorgii Rymar   if (!DumperOrErr)
3633fe01f0eSGeorgii Rymar     reportError(DumperOrErr.takeError(), FileStr);
3643fe01f0eSGeorgii Rymar   Dumper = (*DumperOrErr).get();
36521bd841dSRafael Espindola 
366*1ae449f9SVy Nguyen   if (!opts::SortKeys.empty()) {
367*1ae449f9SVy Nguyen     if (Dumper->canCompareSymbols()) {
368*1ae449f9SVy Nguyen       SymComp = SymbolComparator();
369*1ae449f9SVy Nguyen       for (SortSymbolKeyTy Key : opts::SortKeys) {
370*1ae449f9SVy Nguyen         switch (Key) {
371*1ae449f9SVy Nguyen         case NAME:
372*1ae449f9SVy Nguyen           SymComp->addPredicate([Dumper](SymbolRef LHS, SymbolRef RHS) {
373*1ae449f9SVy Nguyen             return Dumper->compareSymbolsByName(LHS, RHS);
374*1ae449f9SVy Nguyen           });
375*1ae449f9SVy Nguyen           break;
376*1ae449f9SVy Nguyen         case TYPE:
377*1ae449f9SVy Nguyen           SymComp->addPredicate([Dumper](SymbolRef LHS, SymbolRef RHS) {
378*1ae449f9SVy Nguyen             return Dumper->compareSymbolsByType(LHS, RHS);
379*1ae449f9SVy Nguyen           });
380*1ae449f9SVy Nguyen           break;
381*1ae449f9SVy Nguyen         case UNKNOWN:
382*1ae449f9SVy Nguyen           llvm_unreachable("Unsupported sort key");
383*1ae449f9SVy Nguyen         }
384*1ae449f9SVy Nguyen       }
385*1ae449f9SVy Nguyen 
386*1ae449f9SVy Nguyen     } else {
387*1ae449f9SVy Nguyen       reportWarning(createStringError(
388*1ae449f9SVy Nguyen                         errc::invalid_argument,
389*1ae449f9SVy Nguyen                         "--sort-symbols is not supported yet for this format"),
390*1ae449f9SVy Nguyen                     FileStr);
391*1ae449f9SVy Nguyen     }
392*1ae449f9SVy Nguyen   }
3931f35d7b5SJayson Yan   Dumper->printFileSummary(FileStr, Obj, opts::InputFilenames, A);
3949cad53cfSEric Christopher 
3959cad53cfSEric Christopher   if (opts::FileHeaders)
3969cad53cfSEric Christopher     Dumper->printFileHeaders();
397f855a553SGeorgii Rymar 
398158083f0Szhijian   if (Obj.isXCOFF() && opts::XCOFFAuxiliaryHeader)
399158083f0Szhijian     Dumper->printAuxiliaryHeader();
400158083f0Szhijian 
40199a6401aSGeorgii Rymar   // This is only used for ELF currently. In some cases, when an object is
40299a6401aSGeorgii Rymar   // corrupt (e.g. truncated), we can't dump anything except the file header.
40399a6401aSGeorgii Rymar   if (!ContentErrString.empty())
40499a6401aSGeorgii Rymar     reportError(createError(ContentErrString), FileStr);
40599a6401aSGeorgii Rymar 
406f855a553SGeorgii Rymar   if (opts::SectionDetails || opts::SectionHeaders) {
407f855a553SGeorgii Rymar     if (opts::Output == opts::GNU && opts::SectionDetails)
408f855a553SGeorgii Rymar       Dumper->printSectionDetails();
409f855a553SGeorgii Rymar     else
410dbf552c4SJordan Rupprecht       Dumper->printSectionHeaders();
411f855a553SGeorgii Rymar   }
412f855a553SGeorgii Rymar 
4135fc812f1SJames Henderson   if (opts::HashSymbols)
4145fc812f1SJames Henderson     Dumper->printHashSymbols();
4159e1319dfSFangrui Song   if (opts::ProgramHeaders || opts::SectionMapping == cl::BOU_TRUE)
4169e1319dfSFangrui Song     Dumper->printProgramHeaders(opts::ProgramHeaders, opts::SectionMapping);
4179cad53cfSEric Christopher   if (opts::DynamicTable)
4189cad53cfSEric Christopher     Dumper->printDynamicTable();
4199cad53cfSEric Christopher   if (opts::NeededLibraries)
4209cad53cfSEric Christopher     Dumper->printNeededLibraries();
4219e1319dfSFangrui Song   if (opts::Relocations)
4229e1319dfSFangrui Song     Dumper->printRelocations();
4239e1319dfSFangrui Song   if (opts::DynRelocs)
4249e1319dfSFangrui Song     Dumper->printDynamicRelocations();
4259e1319dfSFangrui Song   if (opts::UnwindInfo)
4269e1319dfSFangrui Song     Dumper->printUnwindInfo();
4279e1319dfSFangrui Song   if (opts::Symbols || opts::DynamicSymbols)
428*1ae449f9SVy Nguyen     Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols, SymComp);
429fa5597b2SPaul Semel   if (!opts::StringDump.empty())
430310af42eSGeorgii Rymar     Dumper->printSectionsAsString(Obj, opts::StringDump);
431b98f5048SPaul Semel   if (!opts::HexDump.empty())
432310af42eSGeorgii Rymar     Dumper->printSectionsAsHex(Obj, opts::HexDump);
43320546ffdSMichael J. Spencer   if (opts::HashTable)
43420546ffdSMichael J. Spencer     Dumper->printHashTable();
435496fb2f0SIgor Kudrin   if (opts::GnuHashTable)
436310af42eSGeorgii Rymar     Dumper->printGnuHashTable();
4374f05f32bSDavide Italiano   if (opts::VersionInfo)
4384f05f32bSDavide Italiano     Dumper->printVersionInfo();
4390dad3f6eSEsme-Yi   if (opts::StringTable)
4400dad3f6eSEsme-Yi     Dumper->printStringTable();
4413fe01f0eSGeorgii Rymar   if (Obj.isELF()) {
442cd2c409cSGeorgii Rymar     if (opts::DependentLibraries)
443cd2c409cSGeorgii Rymar       Dumper->printDependentLibs();
444b36fbbc3SSaleem Abdulrasool     if (opts::ELFLinkerOptions)
445b36fbbc3SSaleem Abdulrasool       Dumper->printELFLinkerOptions();
44657e764f9SSimon Atanasyan     if (opts::ArchSpecificInfo)
44757e764f9SSimon Atanasyan       Dumper->printArchSpecificInfo();
448ab4a46faSHemant Kulkarni     if (opts::SectionGroups)
449ab4a46faSHemant Kulkarni       Dumper->printGroupSections();
4509b1b7f08SHemant Kulkarni     if (opts::HashHistogram)
451d804b334SGeorgii Rymar       Dumper->printHashHistograms();
452ae6eeaeaSMichael J. Spencer     if (opts::CGProfile)
453ae6eeaeaSMichael J. Spencer       Dumper->printCGProfile();
454c245c21cSRahman Lavaee     if (opts::BBAddrMap)
455c245c21cSRahman Lavaee       Dumper->printBBAddrMaps();
4563e227336SPeter Collingbourne     if (opts::Addrsig)
4573e227336SPeter Collingbourne       Dumper->printAddrsig();
4586a405448SSaleem Abdulrasool     if (opts::Notes)
4596a405448SSaleem Abdulrasool       Dumper->printNotes();
460ab4a46faSHemant Kulkarni   }
4613fe01f0eSGeorgii Rymar   if (Obj.isCOFF()) {
4621e152d5eSRui Ueyama     if (opts::COFFImports)
4631e152d5eSRui Ueyama       Dumper->printCOFFImports();
464ddd92644SSaleem Abdulrasool     if (opts::COFFExports)
465ddd92644SSaleem Abdulrasool       Dumper->printCOFFExports();
466f9578632SSaleem Abdulrasool     if (opts::COFFDirectives)
467f9578632SSaleem Abdulrasool       Dumper->printCOFFDirectives();
46874e85130SRui Ueyama     if (opts::COFFBaseRelocs)
46974e85130SRui Ueyama       Dumper->printCOFFBaseReloc();
4702da433eaSReid Kleckner     if (opts::COFFDebugDirectory)
4712da433eaSReid Kleckner       Dumper->printCOFFDebugDirectory();
472568035acSLuqman Aden     if (opts::COFFTLSDirectory)
473568035acSLuqman Aden       Dumper->printCOFFTLSDirectory();
4748d6396d3SZachary Turner     if (opts::COFFResources)
4758d6396d3SZachary Turner       Dumper->printCOFFResources();
476b7d716c0SReid Kleckner     if (opts::COFFLoadConfig)
477b7d716c0SReid Kleckner       Dumper->printCOFFLoadConfig();
47879d7e9c7SZequan Wu     if (opts::CGProfile)
47979d7e9c7SZequan Wu       Dumper->printCGProfile();
480bc3089f4SPeter Collingbourne     if (opts::Addrsig)
481bc3089f4SPeter Collingbourne       Dumper->printAddrsig();
48283ebad37SReid Kleckner     if (opts::CodeView)
48383ebad37SReid Kleckner       Dumper->printCodeViewDebugInfo();
4840b269748SReid Kleckner     if (opts::CodeViewMergedTypes)
485120366edSAlexandre Ganea       Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable,
486120366edSAlexandre Ganea                                  CVTypes.GlobalIDTable, CVTypes.GlobalTypeTable,
487120366edSAlexandre Ganea                                  opts::CodeViewEnableGHash);
488cd1b6dbcSDavide Italiano   }
4893fe01f0eSGeorgii Rymar   if (Obj.isMachO()) {
49007e7acb6SDavide Italiano     if (opts::MachODataInCode)
49107e7acb6SDavide Italiano       Dumper->printMachODataInCode();
4924410b22cSDavide Italiano     if (opts::MachOIndirectSymbols)
4934410b22cSDavide Italiano       Dumper->printMachOIndirectSymbols();
4949a429b76SDavide Italiano     if (opts::MachOLinkerOptions)
4959a429b76SDavide Italiano       Dumper->printMachOLinkerOptions();
496d1f09968SDavide Italiano     if (opts::MachOSegment)
497d1f09968SDavide Italiano       Dumper->printMachOSegment();
498976f4da0SDavide Italiano     if (opts::MachOVersionMin)
499976f4da0SDavide Italiano       Dumper->printMachOVersionMin();
50035eebe13SDavide Italiano     if (opts::MachODysymtab)
50135eebe13SDavide Italiano       Dumper->printMachODysymtab();
5020f853930SLeonard Grey     if (opts::CGProfile)
5030f853930SLeonard Grey       Dumper->printCGProfile();
5041e12fc44SDavide Italiano   }
5050000afd8SLang Hames   if (opts::PrintStackMap)
5060000afd8SLang Hames     Dumper->printStackMap();
507c71c6299SWolfgang Pieb   if (opts::PrintStackSizes)
508c71c6299SWolfgang Pieb     Dumper->printStackSizes();
509c429b80dSDavid Meyer }
510c429b80dSDavid Meyer 
5114dfcc4a7SAdrian Prantl /// Dumps each object file in \a Arc;
dumpArchive(const Archive * Arc,ScopedPrinter & Writer)51288e9a15bSSam Clegg static void dumpArchive(const Archive *Arc, ScopedPrinter &Writer) {
51341af4309SMehdi Amini   Error Err = Error::success();
514fc209623SLang Hames   for (auto &Child : Arc->children(Err)) {
515ac9e1555SKevin Enderby     Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
516ac9e1555SKevin Enderby     if (!ChildOrErr) {
51736f23182SGeorge Rimar       if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
51836f23182SGeorge Rimar         reportError(std::move(E), Arc->getFileName());
5199cad53cfSEric Christopher       continue;
5209cad53cfSEric Christopher     }
5213d90a61cSGeorgii Rymar 
5223d90a61cSGeorgii Rymar     Binary *Bin = ChildOrErr->get();
5233d90a61cSGeorgii Rymar     if (ObjectFile *Obj = dyn_cast<ObjectFile>(Bin))
5243fe01f0eSGeorgii Rymar       dumpObject(*Obj, Writer, Arc);
5253d90a61cSGeorgii Rymar     else if (COFFImportFile *Imp = dyn_cast<COFFImportFile>(Bin))
52688e9a15bSSam Clegg       dumpCOFFImportFile(Imp, Writer);
5279cad53cfSEric Christopher     else
5283d90a61cSGeorgii Rymar       reportWarning(createStringError(errc::invalid_argument,
5293d90a61cSGeorgii Rymar                                       Bin->getFileName() +
5303d90a61cSGeorgii Rymar                                           " has an unsupported file type"),
531e54d3715SGeorge Rimar                     Arc->getFileName());
5329cad53cfSEric Christopher   }
533fc209623SLang Hames   if (Err)
53436f23182SGeorge Rimar     reportError(std::move(Err), Arc->getFileName());
5359cad53cfSEric Christopher }
5369cad53cfSEric Christopher 
5374dfcc4a7SAdrian Prantl /// Dumps each object file in \a MachO Universal Binary;
dumpMachOUniversalBinary(const MachOUniversalBinary * UBinary,ScopedPrinter & Writer)53888e9a15bSSam Clegg static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary,
53988e9a15bSSam Clegg                                      ScopedPrinter &Writer) {
5408448a243SRafael Espindola   for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) {
5419acb1099SKevin Enderby     Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile();
54229ac43c3SDavid Blaikie     if (ObjOrErr)
5433fe01f0eSGeorgii Rymar       dumpObject(*ObjOrErr.get(), Writer);
54436f23182SGeorge Rimar     else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError()))
54536f23182SGeorge Rimar       reportError(ObjOrErr.takeError(), UBinary->getFileName());
54642398051SKevin Enderby     else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
54788e9a15bSSam Clegg       dumpArchive(&*AOrErr.get(), Writer);
5488448a243SRafael Espindola   }
5498448a243SRafael Espindola }
5509cad53cfSEric Christopher 
5514dfcc4a7SAdrian Prantl /// Dumps \a WinRes, Windows Resource (.res) file;
dumpWindowsResourceFile(WindowsResource * WinRes,ScopedPrinter & Printer)552565f1e22SJordan Rupprecht static void dumpWindowsResourceFile(WindowsResource *WinRes,
553565f1e22SJordan Rupprecht                                     ScopedPrinter &Printer) {
554c2189b83SMarek Sokolowski   WindowsRes::Dumper Dumper(WinRes, Printer);
555c2189b83SMarek Sokolowski   if (auto Err = Dumper.printData())
55636f23182SGeorge Rimar     reportError(std::move(Err), WinRes->getFileName());
557c2189b83SMarek Sokolowski }
558c2189b83SMarek Sokolowski 
559c2189b83SMarek Sokolowski 
5604dfcc4a7SAdrian Prantl /// Opens \a File and dumps it.
dumpInput(StringRef File,ScopedPrinter & Writer)561565f1e22SJordan Rupprecht static void dumpInput(StringRef File, ScopedPrinter &Writer) {
562a5154ab9SGeorgii Rymar   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
563c83cd8feSAbhina Sreeskantharajan       MemoryBuffer::getFileOrSTDIN(File, /*IsText=*/false,
564a5154ab9SGeorgii Rymar                                    /*RequiresNullTerminator=*/false);
565a5154ab9SGeorgii Rymar   if (std::error_code EC = FileOrErr.getError())
566a5154ab9SGeorgii Rymar     return reportError(errorCodeToError(EC), File);
567a5154ab9SGeorgii Rymar 
568a5154ab9SGeorgii Rymar   std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
569a5154ab9SGeorgii Rymar   file_magic Type = identify_magic(Buffer->getBuffer());
570a5154ab9SGeorgii Rymar   if (Type == file_magic::bitcode) {
571a5154ab9SGeorgii Rymar     reportWarning(createStringError(errc::invalid_argument,
572a5154ab9SGeorgii Rymar                                     "bitcode files are not supported"),
573a5154ab9SGeorgii Rymar                   File);
574a5154ab9SGeorgii Rymar     return;
575a5154ab9SGeorgii Rymar   }
576a5154ab9SGeorgii Rymar 
577a5154ab9SGeorgii Rymar   Expected<std::unique_ptr<Binary>> BinaryOrErr = createBinary(
578a5154ab9SGeorgii Rymar       Buffer->getMemBufferRef(), /*Context=*/nullptr, /*InitContent=*/false);
5793fcdf6aeSKevin Enderby   if (!BinaryOrErr)
58036f23182SGeorge Rimar     reportError(BinaryOrErr.takeError(), File);
5819cad53cfSEric Christopher 
582a5154ab9SGeorgii Rymar   std::unique_ptr<Binary> Bin = std::move(*BinaryOrErr);
583a5154ab9SGeorgii Rymar   if (Archive *Arc = dyn_cast<Archive>(Bin.get()))
58488e9a15bSSam Clegg     dumpArchive(Arc, Writer);
5858448a243SRafael Espindola   else if (MachOUniversalBinary *UBinary =
586a5154ab9SGeorgii Rymar                dyn_cast<MachOUniversalBinary>(Bin.get()))
58788e9a15bSSam Clegg     dumpMachOUniversalBinary(UBinary, Writer);
588a5154ab9SGeorgii Rymar   else if (ObjectFile *Obj = dyn_cast<ObjectFile>(Bin.get()))
5893fe01f0eSGeorgii Rymar     dumpObject(*Obj, Writer);
590a5154ab9SGeorgii Rymar   else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(Bin.get()))
59188e9a15bSSam Clegg     dumpCOFFImportFile(Import, Writer);
592a5154ab9SGeorgii Rymar   else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(Bin.get()))
593565f1e22SJordan Rupprecht     dumpWindowsResourceFile(WinRes, Writer);
5949cad53cfSEric Christopher   else
5953d90a61cSGeorgii Rymar     llvm_unreachable("unrecognized file type");
596120366edSAlexandre Ganea 
597a5154ab9SGeorgii Rymar   CVTypes.Binaries.push_back(
598a5154ab9SGeorgii Rymar       OwningBinary<Binary>(std::move(Bin), std::move(Buffer)));
5999cad53cfSEric Christopher }
6009cad53cfSEric Christopher 
createWriter()6011f35d7b5SJayson Yan std::unique_ptr<ScopedPrinter> createWriter() {
6021f35d7b5SJayson Yan   if (opts::Output == opts::JSON)
6031f35d7b5SJayson Yan     return std::make_unique<JSONScopedPrinter>(
6041f35d7b5SJayson Yan         fouts(), opts::PrettyPrint ? 2 : 0, std::make_unique<ListScope>());
6051f35d7b5SJayson Yan   return std::make_unique<ScopedPrinter>(fouts());
6061f35d7b5SJayson Yan }
6071f35d7b5SJayson Yan 
main(int argc,char * argv[])60846580d43SFangrui Song int main(int argc, char *argv[]) {
609197194b6SRui Ueyama   InitLLVM X(argc, argv);
61046580d43SFangrui Song   BumpPtrAllocator A;
61146580d43SFangrui Song   StringSaver Saver(A);
61246580d43SFangrui Song   ReadobjOptTable Tbl;
613f1337028SFangrui Song   ToolName = argv[0];
61446580d43SFangrui Song   opt::InputArgList Args =
61546580d43SFangrui Song       Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
61646580d43SFangrui Song         error(Msg);
61746580d43SFangrui Song         exit(1);
61846580d43SFangrui Song       });
61946580d43SFangrui Song   if (Args.hasArg(OPT_help)) {
62046580d43SFangrui Song     Tbl.printHelp(
62146580d43SFangrui Song         outs(),
62246580d43SFangrui Song         (Twine(ToolName) + " [options] <input object files>").str().c_str(),
62346580d43SFangrui Song         "LLVM Object Reader");
62446580d43SFangrui Song     // TODO Replace this with OptTable API once it adds extrahelp support.
62546580d43SFangrui Song     outs() << "\nPass @FILE as argument to read options from FILE.\n";
62646580d43SFangrui Song     return 0;
62746580d43SFangrui Song   }
62846580d43SFangrui Song   if (Args.hasArg(OPT_version)) {
62946580d43SFangrui Song     cl::PrintVersionMessage();
63046580d43SFangrui Song     return 0;
631dbf552c4SJordan Rupprecht   }
632bf515501SPetr Hosek 
63346580d43SFangrui Song   if (sys::path::stem(argv[0]).contains("readelf"))
63446580d43SFangrui Song     opts::Output = opts::GNU;
63546580d43SFangrui Song   parseOptions(Args);
6362fc34c5fSDavid Meyer 
637df952cb9SElvina Yakubova   // Default to print error if no filename is specified.
638df952cb9SElvina Yakubova   if (opts::InputFilenames.empty()) {
639df952cb9SElvina Yakubova     error("no input files specified");
640df952cb9SElvina Yakubova   }
641df952cb9SElvina Yakubova 
642dbf552c4SJordan Rupprecht   if (opts::All) {
643dbf552c4SJordan Rupprecht     opts::FileHeaders = true;
644158083f0Szhijian     opts::XCOFFAuxiliaryHeader = true;
645dbf552c4SJordan Rupprecht     opts::ProgramHeaders = true;
646dbf552c4SJordan Rupprecht     opts::SectionHeaders = true;
647dbf552c4SJordan Rupprecht     opts::Symbols = true;
648dbf552c4SJordan Rupprecht     opts::Relocations = true;
649dbf552c4SJordan Rupprecht     opts::DynamicTable = true;
650dbf552c4SJordan Rupprecht     opts::Notes = true;
651dbf552c4SJordan Rupprecht     opts::VersionInfo = true;
652dbf552c4SJordan Rupprecht     opts::UnwindInfo = true;
653dbf552c4SJordan Rupprecht     opts::SectionGroups = true;
654dbf552c4SJordan Rupprecht     opts::HashHistogram = true;
6555ce8c391SGeorge Rimar     if (opts::Output == opts::LLVM) {
6565ce8c391SGeorge Rimar       opts::Addrsig = true;
6574e0faa33SGeorge Rimar       opts::PrintStackSizes = true;
658dbf552c4SJordan Rupprecht     }
6595ce8c391SGeorge Rimar   }
660dbf552c4SJordan Rupprecht 
6614afeaac0SSid Manning   if (opts::Headers) {
6624afeaac0SSid Manning     opts::FileHeaders = true;
663158083f0Szhijian     opts::XCOFFAuxiliaryHeader = true;
6644afeaac0SSid Manning     opts::ProgramHeaders = true;
6654afeaac0SSid Manning     opts::SectionHeaders = true;
6664afeaac0SSid Manning   }
6674afeaac0SSid Manning 
6681f35d7b5SJayson Yan   std::unique_ptr<ScopedPrinter> Writer = createWriter();
6691f35d7b5SJayson Yan 
670565f1e22SJordan Rupprecht   for (const std::string &I : opts::InputFilenames)
6711f35d7b5SJayson Yan     dumpInput(I, *Writer.get());
672278e891cSRafael Espindola 
6730b269748SReid Kleckner   if (opts::CodeViewMergedTypes) {
674120366edSAlexandre Ganea     if (opts::CodeViewEnableGHash)
6751f35d7b5SJayson Yan       dumpCodeViewMergedTypes(*Writer.get(), CVTypes.GlobalIDTable.records(),
676120366edSAlexandre Ganea                               CVTypes.GlobalTypeTable.records());
677120366edSAlexandre Ganea     else
6781f35d7b5SJayson Yan       dumpCodeViewMergedTypes(*Writer.get(), CVTypes.IDTable.records(),
679120366edSAlexandre Ganea                               CVTypes.TypeTable.records());
6800b269748SReid Kleckner   }
6810b269748SReid Kleckner 
682fb3acd62SRafael Espindola   return 0;
6832fc34c5fSDavid Meyer }
684