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