Path: blob/main/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.cpp
35231 views
//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This is a tool similar to readelf, except it works on multiple object file9// formats. The main purpose of this tool is to provide detailed output suitable10// for FileCheck.11//12// Flags should be similar to readelf where supported, but the output format13// does not need to be identical. The point is to not make users learn yet14// another set of flags.15//16// Output should be specialized for each format where appropriate.17//18//===----------------------------------------------------------------------===//1920#include "llvm-readobj.h"21#include "ObjDumper.h"22#include "WindowsResourceDumper.h"23#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"24#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"25#include "llvm/MC/TargetRegistry.h"26#include "llvm/Object/Archive.h"27#include "llvm/Object/COFFImportFile.h"28#include "llvm/Object/ELFObjectFile.h"29#include "llvm/Object/MachOUniversal.h"30#include "llvm/Object/ObjectFile.h"31#include "llvm/Object/Wasm.h"32#include "llvm/Object/WindowsResource.h"33#include "llvm/Object/XCOFFObjectFile.h"34#include "llvm/Option/Arg.h"35#include "llvm/Option/ArgList.h"36#include "llvm/Option/Option.h"37#include "llvm/Support/Casting.h"38#include "llvm/Support/CommandLine.h"39#include "llvm/Support/DataTypes.h"40#include "llvm/Support/Debug.h"41#include "llvm/Support/Errc.h"42#include "llvm/Support/FileSystem.h"43#include "llvm/Support/FormatVariadic.h"44#include "llvm/Support/LLVMDriver.h"45#include "llvm/Support/Path.h"46#include "llvm/Support/ScopedPrinter.h"47#include "llvm/Support/WithColor.h"4849using namespace llvm;50using namespace llvm::object;5152namespace {53using namespace llvm::opt; // for HelpHidden in Opts.inc54enum ID {55OPT_INVALID = 0, // This is not an option ID.56#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),57#include "Opts.inc"58#undef OPTION59};6061#define PREFIX(NAME, VALUE) \62static constexpr StringLiteral NAME##_init[] = VALUE; \63static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \64std::size(NAME##_init) - 1);65#include "Opts.inc"66#undef PREFIX6768static constexpr opt::OptTable::Info InfoTable[] = {69#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),70#include "Opts.inc"71#undef OPTION72};7374class ReadobjOptTable : public opt::GenericOptTable {75public:76ReadobjOptTable() : opt::GenericOptTable(InfoTable) {77setGroupedShortOptions(true);78}79};8081enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };8283enum SortSymbolKeyTy {84NAME = 0,85TYPE = 1,86UNKNOWN = 100,87// TODO: add ADDRESS, SIZE as needed.88};8990} // namespace9192namespace opts {93static bool Addrsig;94static bool All;95static bool ArchSpecificInfo;96static bool BBAddrMap;97static bool PrettyPGOAnalysisMap;98bool ExpandRelocs;99static bool CGProfile;100static bool Decompress;101bool Demangle;102static bool DependentLibraries;103static bool DynRelocs;104static bool DynamicSymbols;105static bool ExtraSymInfo;106static bool FileHeaders;107static bool Headers;108static std::vector<std::string> HexDump;109static bool PrettyPrint;110static bool PrintStackMap;111static bool PrintStackSizes;112static bool Relocations;113bool SectionData;114static bool SectionDetails;115static bool SectionHeaders;116bool SectionRelocations;117bool SectionSymbols;118static std::vector<std::string> StringDump;119static bool StringTable;120static bool Symbols;121static bool UnwindInfo;122static cl::boolOrDefault SectionMapping;123static SmallVector<SortSymbolKeyTy> SortKeys;124125// ELF specific options.126static bool DynamicTable;127static bool ELFLinkerOptions;128static bool GnuHashTable;129static bool HashSymbols;130static bool HashTable;131static bool HashHistogram;132static bool Memtag;133static bool NeededLibraries;134static bool Notes;135static bool ProgramHeaders;136static bool SectionGroups;137static bool VersionInfo;138139// Mach-O specific options.140static bool MachODataInCode;141static bool MachODysymtab;142static bool MachOIndirectSymbols;143static bool MachOLinkerOptions;144static bool MachOSegment;145static bool MachOVersionMin;146147// PE/COFF specific options.148static bool CodeView;149static bool CodeViewEnableGHash;150static bool CodeViewMergedTypes;151bool CodeViewSubsectionBytes;152static bool COFFBaseRelocs;153static bool COFFDebugDirectory;154static bool COFFDirectives;155static bool COFFExports;156static bool COFFImports;157static bool COFFLoadConfig;158static bool COFFResources;159static bool COFFTLSDirectory;160161// XCOFF specific options.162static bool XCOFFAuxiliaryHeader;163static bool XCOFFLoaderSectionHeader;164static bool XCOFFLoaderSectionSymbol;165static bool XCOFFLoaderSectionRelocation;166static bool XCOFFExceptionSection;167168OutputStyleTy Output = OutputStyleTy::LLVM;169static std::vector<std::string> InputFilenames;170} // namespace opts171172static StringRef ToolName;173174namespace llvm {175176[[noreturn]] static void error(Twine Msg) {177// Flush the standard output to print the error at a178// proper place.179fouts().flush();180WithColor::error(errs(), ToolName) << Msg << "\n";181exit(1);182}183184[[noreturn]] void reportError(Error Err, StringRef Input) {185assert(Err);186if (Input == "-")187Input = "<stdin>";188handleAllErrors(createFileError(Input, std::move(Err)),189[&](const ErrorInfoBase &EI) { error(EI.message()); });190llvm_unreachable("error() call should never return");191}192193void reportWarning(Error Err, StringRef Input) {194assert(Err);195if (Input == "-")196Input = "<stdin>";197198// Flush the standard output to print the warning at a199// proper place.200fouts().flush();201handleAllErrors(202createFileError(Input, std::move(Err)), [&](const ErrorInfoBase &EI) {203WithColor::warning(errs(), ToolName) << EI.message() << "\n";204});205}206207} // namespace llvm208209static void parseOptions(const opt::InputArgList &Args) {210opts::Addrsig = Args.hasArg(OPT_addrsig);211opts::All = Args.hasArg(OPT_all);212opts::ArchSpecificInfo = Args.hasArg(OPT_arch_specific);213opts::BBAddrMap = Args.hasArg(OPT_bb_addr_map);214opts::PrettyPGOAnalysisMap = Args.hasArg(OPT_pretty_pgo_analysis_map);215if (opts::PrettyPGOAnalysisMap && !opts::BBAddrMap)216WithColor::warning(errs(), ToolName)217<< "--bb-addr-map must be enabled for --pretty-pgo-analysis-map to "218"have an effect\n";219opts::CGProfile = Args.hasArg(OPT_cg_profile);220opts::Decompress = Args.hasArg(OPT_decompress);221opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);222opts::DependentLibraries = Args.hasArg(OPT_dependent_libraries);223opts::DynRelocs = Args.hasArg(OPT_dyn_relocations);224opts::DynamicSymbols = Args.hasArg(OPT_dyn_syms);225opts::ExpandRelocs = Args.hasArg(OPT_expand_relocs);226opts::ExtraSymInfo = Args.hasArg(OPT_extra_sym_info);227opts::FileHeaders = Args.hasArg(OPT_file_header);228opts::Headers = Args.hasArg(OPT_headers);229opts::HexDump = Args.getAllArgValues(OPT_hex_dump_EQ);230opts::Relocations = Args.hasArg(OPT_relocs);231opts::SectionData = Args.hasArg(OPT_section_data);232opts::SectionDetails = Args.hasArg(OPT_section_details);233opts::SectionHeaders = Args.hasArg(OPT_section_headers);234opts::SectionRelocations = Args.hasArg(OPT_section_relocations);235opts::SectionSymbols = Args.hasArg(OPT_section_symbols);236if (Args.hasArg(OPT_section_mapping))237opts::SectionMapping = cl::BOU_TRUE;238else if (Args.hasArg(OPT_section_mapping_EQ_false))239opts::SectionMapping = cl::BOU_FALSE;240else241opts::SectionMapping = cl::BOU_UNSET;242opts::PrintStackSizes = Args.hasArg(OPT_stack_sizes);243opts::PrintStackMap = Args.hasArg(OPT_stackmap);244opts::StringDump = Args.getAllArgValues(OPT_string_dump_EQ);245opts::StringTable = Args.hasArg(OPT_string_table);246opts::Symbols = Args.hasArg(OPT_symbols);247opts::UnwindInfo = Args.hasArg(OPT_unwind);248249// ELF specific options.250opts::DynamicTable = Args.hasArg(OPT_dynamic_table);251opts::ELFLinkerOptions = Args.hasArg(OPT_elf_linker_options);252if (Arg *A = Args.getLastArg(OPT_elf_output_style_EQ)) {253std::string OutputStyleChoice = A->getValue();254opts::Output = StringSwitch<opts::OutputStyleTy>(OutputStyleChoice)255.Case("LLVM", opts::OutputStyleTy::LLVM)256.Case("GNU", opts::OutputStyleTy::GNU)257.Case("JSON", opts::OutputStyleTy::JSON)258.Default(opts::OutputStyleTy::UNKNOWN);259if (opts::Output == opts::OutputStyleTy::UNKNOWN) {260error("--elf-output-style value should be either 'LLVM', 'GNU', or "261"'JSON', but was '" +262OutputStyleChoice + "'");263}264}265opts::GnuHashTable = Args.hasArg(OPT_gnu_hash_table);266opts::HashSymbols = Args.hasArg(OPT_hash_symbols);267opts::HashTable = Args.hasArg(OPT_hash_table);268opts::HashHistogram = Args.hasArg(OPT_histogram);269opts::Memtag = Args.hasArg(OPT_memtag);270opts::NeededLibraries = Args.hasArg(OPT_needed_libs);271opts::Notes = Args.hasArg(OPT_notes);272opts::PrettyPrint = Args.hasArg(OPT_pretty_print);273opts::ProgramHeaders = Args.hasArg(OPT_program_headers);274opts::SectionGroups = Args.hasArg(OPT_section_groups);275if (Arg *A = Args.getLastArg(OPT_sort_symbols_EQ)) {276std::string SortKeysString = A->getValue();277for (StringRef KeyStr : llvm::split(A->getValue(), ",")) {278SortSymbolKeyTy KeyType = StringSwitch<SortSymbolKeyTy>(KeyStr)279.Case("name", SortSymbolKeyTy::NAME)280.Case("type", SortSymbolKeyTy::TYPE)281.Default(SortSymbolKeyTy::UNKNOWN);282if (KeyType == SortSymbolKeyTy::UNKNOWN)283error("--sort-symbols value should be 'name' or 'type', but was '" +284Twine(KeyStr) + "'");285opts::SortKeys.push_back(KeyType);286}287}288opts::VersionInfo = Args.hasArg(OPT_version_info);289290// Mach-O specific options.291opts::MachODataInCode = Args.hasArg(OPT_macho_data_in_code);292opts::MachODysymtab = Args.hasArg(OPT_macho_dysymtab);293opts::MachOIndirectSymbols = Args.hasArg(OPT_macho_indirect_symbols);294opts::MachOLinkerOptions = Args.hasArg(OPT_macho_linker_options);295opts::MachOSegment = Args.hasArg(OPT_macho_segment);296opts::MachOVersionMin = Args.hasArg(OPT_macho_version_min);297298// PE/COFF specific options.299opts::CodeView = Args.hasArg(OPT_codeview);300opts::CodeViewEnableGHash = Args.hasArg(OPT_codeview_ghash);301opts::CodeViewMergedTypes = Args.hasArg(OPT_codeview_merged_types);302opts::CodeViewSubsectionBytes = Args.hasArg(OPT_codeview_subsection_bytes);303opts::COFFBaseRelocs = Args.hasArg(OPT_coff_basereloc);304opts::COFFDebugDirectory = Args.hasArg(OPT_coff_debug_directory);305opts::COFFDirectives = Args.hasArg(OPT_coff_directives);306opts::COFFExports = Args.hasArg(OPT_coff_exports);307opts::COFFImports = Args.hasArg(OPT_coff_imports);308opts::COFFLoadConfig = Args.hasArg(OPT_coff_load_config);309opts::COFFResources = Args.hasArg(OPT_coff_resources);310opts::COFFTLSDirectory = Args.hasArg(OPT_coff_tls_directory);311312// XCOFF specific options.313opts::XCOFFAuxiliaryHeader = Args.hasArg(OPT_auxiliary_header);314opts::XCOFFLoaderSectionHeader = Args.hasArg(OPT_loader_section_header);315opts::XCOFFLoaderSectionSymbol = Args.hasArg(OPT_loader_section_symbols);316opts::XCOFFLoaderSectionRelocation =317Args.hasArg(OPT_loader_section_relocations);318opts::XCOFFExceptionSection = Args.hasArg(OPT_exception_section);319320opts::InputFilenames = Args.getAllArgValues(OPT_INPUT);321}322323namespace {324struct ReadObjTypeTableBuilder {325ReadObjTypeTableBuilder()326: IDTable(Allocator), TypeTable(Allocator), GlobalIDTable(Allocator),327GlobalTypeTable(Allocator) {}328329llvm::BumpPtrAllocator Allocator;330llvm::codeview::MergingTypeTableBuilder IDTable;331llvm::codeview::MergingTypeTableBuilder TypeTable;332llvm::codeview::GlobalTypeTableBuilder GlobalIDTable;333llvm::codeview::GlobalTypeTableBuilder GlobalTypeTable;334std::vector<OwningBinary<Binary>> Binaries;335};336} // namespace337static ReadObjTypeTableBuilder CVTypes;338339/// Creates an format-specific object file dumper.340static Expected<std::unique_ptr<ObjDumper>>341createDumper(const ObjectFile &Obj, ScopedPrinter &Writer) {342if (const COFFObjectFile *COFFObj = dyn_cast<COFFObjectFile>(&Obj))343return createCOFFDumper(*COFFObj, Writer);344345if (const ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj))346return createELFDumper(*ELFObj, Writer);347348if (const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(&Obj))349return createMachODumper(*MachOObj, Writer);350351if (const WasmObjectFile *WasmObj = dyn_cast<WasmObjectFile>(&Obj))352return createWasmDumper(*WasmObj, Writer);353354if (const XCOFFObjectFile *XObj = dyn_cast<XCOFFObjectFile>(&Obj))355return createXCOFFDumper(*XObj, Writer);356357return createStringError(errc::invalid_argument,358"unsupported object file format");359}360361/// Dumps the specified object file.362static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,363const Archive *A = nullptr) {364std::string FileStr =365A ? Twine(A->getFileName() + "(" + Obj.getFileName() + ")").str()366: Obj.getFileName().str();367368std::string ContentErrString;369if (Error ContentErr = Obj.initContent())370ContentErrString = "unable to continue dumping, the file is corrupt: " +371toString(std::move(ContentErr));372373ObjDumper *Dumper;374std::optional<SymbolComparator> SymComp;375Expected<std::unique_ptr<ObjDumper>> DumperOrErr = createDumper(Obj, Writer);376if (!DumperOrErr)377reportError(DumperOrErr.takeError(), FileStr);378Dumper = (*DumperOrErr).get();379380if (!opts::SortKeys.empty()) {381if (Dumper->canCompareSymbols()) {382SymComp = SymbolComparator();383for (SortSymbolKeyTy Key : opts::SortKeys) {384switch (Key) {385case NAME:386SymComp->addPredicate([Dumper](SymbolRef LHS, SymbolRef RHS) {387return Dumper->compareSymbolsByName(LHS, RHS);388});389break;390case TYPE:391SymComp->addPredicate([Dumper](SymbolRef LHS, SymbolRef RHS) {392return Dumper->compareSymbolsByType(LHS, RHS);393});394break;395case UNKNOWN:396llvm_unreachable("Unsupported sort key");397}398}399400} else {401reportWarning(createStringError(402errc::invalid_argument,403"--sort-symbols is not supported yet for this format"),404FileStr);405}406}407Dumper->printFileSummary(FileStr, Obj, opts::InputFilenames, A);408409if (opts::FileHeaders)410Dumper->printFileHeaders();411412// Auxiliary header in XOCFF is right after the file header, so print the data413// here.414if (Obj.isXCOFF() && opts::XCOFFAuxiliaryHeader)415Dumper->printAuxiliaryHeader();416417// This is only used for ELF currently. In some cases, when an object is418// corrupt (e.g. truncated), we can't dump anything except the file header.419if (!ContentErrString.empty())420reportError(createError(ContentErrString), FileStr);421422if (opts::SectionDetails || opts::SectionHeaders) {423if (opts::Output == opts::GNU && opts::SectionDetails)424Dumper->printSectionDetails();425else426Dumper->printSectionHeaders();427}428429if (opts::HashSymbols)430Dumper->printHashSymbols();431if (opts::ProgramHeaders || opts::SectionMapping == cl::BOU_TRUE)432Dumper->printProgramHeaders(opts::ProgramHeaders, opts::SectionMapping);433if (opts::DynamicTable)434Dumper->printDynamicTable();435if (opts::NeededLibraries)436Dumper->printNeededLibraries();437if (opts::Relocations)438Dumper->printRelocations();439if (opts::DynRelocs)440Dumper->printDynamicRelocations();441if (opts::UnwindInfo)442Dumper->printUnwindInfo();443if (opts::Symbols || opts::DynamicSymbols)444Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols,445opts::ExtraSymInfo, SymComp);446if (!opts::StringDump.empty())447Dumper->printSectionsAsString(Obj, opts::StringDump, opts::Decompress);448if (!opts::HexDump.empty())449Dumper->printSectionsAsHex(Obj, opts::HexDump, opts::Decompress);450if (opts::HashTable)451Dumper->printHashTable();452if (opts::GnuHashTable)453Dumper->printGnuHashTable();454if (opts::VersionInfo)455Dumper->printVersionInfo();456if (opts::StringTable)457Dumper->printStringTable();458if (Obj.isELF()) {459if (opts::DependentLibraries)460Dumper->printDependentLibs();461if (opts::ELFLinkerOptions)462Dumper->printELFLinkerOptions();463if (opts::ArchSpecificInfo)464Dumper->printArchSpecificInfo();465if (opts::SectionGroups)466Dumper->printGroupSections();467if (opts::HashHistogram)468Dumper->printHashHistograms();469if (opts::CGProfile)470Dumper->printCGProfile();471if (opts::BBAddrMap)472Dumper->printBBAddrMaps(opts::PrettyPGOAnalysisMap);473if (opts::Addrsig)474Dumper->printAddrsig();475if (opts::Notes)476Dumper->printNotes();477if (opts::Memtag)478Dumper->printMemtag();479}480if (Obj.isCOFF()) {481if (opts::COFFImports)482Dumper->printCOFFImports();483if (opts::COFFExports)484Dumper->printCOFFExports();485if (opts::COFFDirectives)486Dumper->printCOFFDirectives();487if (opts::COFFBaseRelocs)488Dumper->printCOFFBaseReloc();489if (opts::COFFDebugDirectory)490Dumper->printCOFFDebugDirectory();491if (opts::COFFTLSDirectory)492Dumper->printCOFFTLSDirectory();493if (opts::COFFResources)494Dumper->printCOFFResources();495if (opts::COFFLoadConfig)496Dumper->printCOFFLoadConfig();497if (opts::CGProfile)498Dumper->printCGProfile();499if (opts::Addrsig)500Dumper->printAddrsig();501if (opts::CodeView)502Dumper->printCodeViewDebugInfo();503if (opts::CodeViewMergedTypes)504Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable,505CVTypes.GlobalIDTable, CVTypes.GlobalTypeTable,506opts::CodeViewEnableGHash);507}508if (Obj.isMachO()) {509if (opts::MachODataInCode)510Dumper->printMachODataInCode();511if (opts::MachOIndirectSymbols)512Dumper->printMachOIndirectSymbols();513if (opts::MachOLinkerOptions)514Dumper->printMachOLinkerOptions();515if (opts::MachOSegment)516Dumper->printMachOSegment();517if (opts::MachOVersionMin)518Dumper->printMachOVersionMin();519if (opts::MachODysymtab)520Dumper->printMachODysymtab();521if (opts::CGProfile)522Dumper->printCGProfile();523}524525if (Obj.isXCOFF()) {526if (opts::XCOFFLoaderSectionHeader || opts::XCOFFLoaderSectionSymbol ||527opts::XCOFFLoaderSectionRelocation)528Dumper->printLoaderSection(opts::XCOFFLoaderSectionHeader,529opts::XCOFFLoaderSectionSymbol,530opts::XCOFFLoaderSectionRelocation);531532if (opts::XCOFFExceptionSection)533Dumper->printExceptionSection();534}535536if (opts::PrintStackMap)537Dumper->printStackMap();538if (opts::PrintStackSizes)539Dumper->printStackSizes();540}541542/// Dumps each object file in \a Arc;543static void dumpArchive(const Archive *Arc, ScopedPrinter &Writer) {544Error Err = Error::success();545for (auto &Child : Arc->children(Err)) {546Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();547if (!ChildOrErr) {548if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))549reportError(std::move(E), Arc->getFileName());550continue;551}552553Binary *Bin = ChildOrErr->get();554if (ObjectFile *Obj = dyn_cast<ObjectFile>(Bin))555dumpObject(*Obj, Writer, Arc);556else if (COFFImportFile *Imp = dyn_cast<COFFImportFile>(Bin))557dumpCOFFImportFile(Imp, Writer);558else559reportWarning(createStringError(errc::invalid_argument,560Bin->getFileName() +561" has an unsupported file type"),562Arc->getFileName());563}564if (Err)565reportError(std::move(Err), Arc->getFileName());566}567568/// Dumps each object file in \a MachO Universal Binary;569static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary,570ScopedPrinter &Writer) {571for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) {572Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile();573if (ObjOrErr)574dumpObject(*ObjOrErr.get(), Writer);575else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError()))576reportError(ObjOrErr.takeError(), UBinary->getFileName());577else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())578dumpArchive(&*AOrErr.get(), Writer);579}580}581582/// Dumps \a WinRes, Windows Resource (.res) file;583static void dumpWindowsResourceFile(WindowsResource *WinRes,584ScopedPrinter &Printer) {585WindowsRes::Dumper Dumper(WinRes, Printer);586if (auto Err = Dumper.printData())587reportError(std::move(Err), WinRes->getFileName());588}589590591/// Opens \a File and dumps it.592static void dumpInput(StringRef File, ScopedPrinter &Writer) {593ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =594MemoryBuffer::getFileOrSTDIN(File, /*IsText=*/false,595/*RequiresNullTerminator=*/false);596if (std::error_code EC = FileOrErr.getError())597return reportError(errorCodeToError(EC), File);598599std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();600file_magic Type = identify_magic(Buffer->getBuffer());601if (Type == file_magic::bitcode) {602reportWarning(createStringError(errc::invalid_argument,603"bitcode files are not supported"),604File);605return;606}607608Expected<std::unique_ptr<Binary>> BinaryOrErr = createBinary(609Buffer->getMemBufferRef(), /*Context=*/nullptr, /*InitContent=*/false);610if (!BinaryOrErr)611reportError(BinaryOrErr.takeError(), File);612613std::unique_ptr<Binary> Bin = std::move(*BinaryOrErr);614if (Archive *Arc = dyn_cast<Archive>(Bin.get()))615dumpArchive(Arc, Writer);616else if (MachOUniversalBinary *UBinary =617dyn_cast<MachOUniversalBinary>(Bin.get()))618dumpMachOUniversalBinary(UBinary, Writer);619else if (ObjectFile *Obj = dyn_cast<ObjectFile>(Bin.get()))620dumpObject(*Obj, Writer);621else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(Bin.get()))622dumpCOFFImportFile(Import, Writer);623else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(Bin.get()))624dumpWindowsResourceFile(WinRes, Writer);625else626llvm_unreachable("unrecognized file type");627628CVTypes.Binaries.push_back(629OwningBinary<Binary>(std::move(Bin), std::move(Buffer)));630}631632std::unique_ptr<ScopedPrinter> createWriter() {633if (opts::Output == opts::JSON)634return std::make_unique<JSONScopedPrinter>(635fouts(), opts::PrettyPrint ? 2 : 0, std::make_unique<ListScope>());636return std::make_unique<ScopedPrinter>(fouts());637}638639int llvm_readobj_main(int argc, char **argv, const llvm::ToolContext &) {640BumpPtrAllocator A;641StringSaver Saver(A);642ReadobjOptTable Tbl;643ToolName = argv[0];644opt::InputArgList Args =645Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {646error(Msg);647exit(1);648});649if (Args.hasArg(OPT_help)) {650Tbl.printHelp(651outs(),652(Twine(ToolName) + " [options] <input object files>").str().c_str(),653"LLVM Object Reader");654// TODO Replace this with OptTable API once it adds extrahelp support.655outs() << "\nPass @FILE as argument to read options from FILE.\n";656return 0;657}658if (Args.hasArg(OPT_version)) {659cl::PrintVersionMessage();660return 0;661}662663if (sys::path::stem(argv[0]).contains("readelf"))664opts::Output = opts::GNU;665parseOptions(Args);666667// Default to print error if no filename is specified.668if (opts::InputFilenames.empty()) {669error("no input files specified");670}671672if (opts::All) {673opts::FileHeaders = true;674opts::XCOFFAuxiliaryHeader = true;675opts::ProgramHeaders = true;676opts::SectionHeaders = true;677opts::Symbols = true;678opts::Relocations = true;679opts::DynamicTable = true;680opts::Notes = true;681opts::VersionInfo = true;682opts::UnwindInfo = true;683opts::SectionGroups = true;684opts::HashHistogram = true;685if (opts::Output == opts::LLVM) {686opts::Addrsig = true;687opts::PrintStackSizes = true;688}689opts::Memtag = true;690}691692if (opts::Headers) {693opts::FileHeaders = true;694opts::XCOFFAuxiliaryHeader = true;695opts::ProgramHeaders = true;696opts::SectionHeaders = true;697}698699std::unique_ptr<ScopedPrinter> Writer = createWriter();700701for (const std::string &I : opts::InputFilenames)702dumpInput(I, *Writer);703704if (opts::CodeViewMergedTypes) {705if (opts::CodeViewEnableGHash)706dumpCodeViewMergedTypes(*Writer, CVTypes.GlobalIDTable.records(),707CVTypes.GlobalTypeTable.records());708else709dumpCodeViewMergedTypes(*Writer, CVTypes.IDTable.records(),710CVTypes.TypeTable.records());711}712713return 0;714}715716717