1234285Sdim//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// 2234285Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6234285Sdim// 7234285Sdim//===----------------------------------------------------------------------===// 8234285Sdim// 9249423Sdim// This is a tool similar to readelf, except it works on multiple object file 10249423Sdim// formats. The main purpose of this tool is to provide detailed output suitable 11249423Sdim// for FileCheck. 12234285Sdim// 13249423Sdim// Flags should be similar to readelf where supported, but the output format 14249423Sdim// does not need to be identical. The point is to not make users learn yet 15249423Sdim// another set of flags. 16234285Sdim// 17249423Sdim// Output should be specialized for each format where appropriate. 18234285Sdim// 19234285Sdim//===----------------------------------------------------------------------===// 20234285Sdim 21249423Sdim#include "llvm-readobj.h" 22249423Sdim#include "Error.h" 23249423Sdim#include "ObjDumper.h" 24327952Sdim#include "WindowsResourceDumper.h" 25353358Sdim#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" 26327952Sdim#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" 27249423Sdim#include "llvm/Object/Archive.h" 28296417Sdim#include "llvm/Object/COFFImportFile.h" 29288943Sdim#include "llvm/Object/MachOUniversal.h" 30234285Sdim#include "llvm/Object/ObjectFile.h" 31327952Sdim#include "llvm/Object/WindowsResource.h" 32249423Sdim#include "llvm/Support/Casting.h" 33234285Sdim#include "llvm/Support/CommandLine.h" 34249423Sdim#include "llvm/Support/DataTypes.h" 35249423Sdim#include "llvm/Support/Debug.h" 36249423Sdim#include "llvm/Support/FileSystem.h" 37341825Sdim#include "llvm/Support/FormatVariadic.h" 38341825Sdim#include "llvm/Support/InitLLVM.h" 39321369Sdim#include "llvm/Support/Path.h" 40309124Sdim#include "llvm/Support/ScopedPrinter.h" 41249423Sdim#include "llvm/Support/TargetRegistry.h" 42353358Sdim#include "llvm/Support/WithColor.h" 43249423Sdim 44234285Sdimusing namespace llvm; 45234285Sdimusing namespace llvm::object; 46234285Sdim 47249423Sdimnamespace opts { 48249423Sdim cl::list<std::string> InputFilenames(cl::Positional, 49249423Sdim cl::desc("<input object files>"), 50249423Sdim cl::ZeroOrMore); 51234285Sdim 52353358Sdim // --all, -a 53344779Sdim cl::opt<bool> 54344779Sdim All("all", 55344779Sdim cl::desc("Equivalent to setting: --file-headers, --program-headers, " 56344779Sdim "--section-headers, --symbols, --relocations, " 57344779Sdim "--dynamic-table, --notes, --version-info, --unwind, " 58344779Sdim "--section-groups and --elf-hash-histogram.")); 59344779Sdim cl::alias AllShort("a", cl::desc("Alias for --all"), cl::aliasopt(All)); 60344779Sdim 61360784Sdim // --dependent-libraries 62360784Sdim cl::opt<bool> 63360784Sdim DependentLibraries("dependent-libraries", 64360784Sdim cl::desc("Display the dependent libraries section")); 65360784Sdim 66344779Sdim // --headers -e 67344779Sdim cl::opt<bool> 68344779Sdim Headers("headers", 69344779Sdim cl::desc("Equivalent to setting: --file-headers, --program-headers, " 70344779Sdim "--section-headers")); 71344779Sdim cl::alias HeadersShort("e", cl::desc("Alias for --headers"), 72344779Sdim cl::aliasopt(Headers)); 73344779Sdim 74353358Sdim // --wide, -W 75344779Sdim cl::opt<bool> 76344779Sdim WideOutput("wide", cl::desc("Ignored for compatibility with GNU readelf"), 77344779Sdim cl::Hidden); 78321369Sdim cl::alias WideOutputShort("W", 79321369Sdim cl::desc("Alias for --wide"), 80321369Sdim cl::aliasopt(WideOutput)); 81321369Sdim 82353358Sdim // --file-headers, --file-header, -h 83249423Sdim cl::opt<bool> FileHeaders("file-headers", 84249423Sdim cl::desc("Display file headers ")); 85344779Sdim cl::alias FileHeadersShort("h", cl::desc("Alias for --file-headers"), 86344779Sdim cl::aliasopt(FileHeaders), cl::NotHidden); 87344779Sdim cl::alias FileHeadersSingular("file-header", 88344779Sdim cl::desc("Alias for --file-headers"), 89344779Sdim cl::aliasopt(FileHeaders)); 90249423Sdim 91353358Sdim // --section-headers, --sections, -S 92344779Sdim // Also -s in llvm-readobj mode. 93344779Sdim cl::opt<bool> SectionHeaders("section-headers", 94344779Sdim cl::desc("Display all section headers.")); 95344779Sdim cl::alias SectionsShortUpper("S", cl::desc("Alias for --section-headers"), 96344779Sdim cl::aliasopt(SectionHeaders), cl::NotHidden); 97344779Sdim cl::alias SectionHeadersAlias("sections", 98344779Sdim cl::desc("Alias for --section-headers"), 99344779Sdim cl::aliasopt(SectionHeaders), cl::NotHidden); 100249423Sdim 101353358Sdim // --section-relocations 102353358Sdim // Also --sr in llvm-readobj mode. 103249423Sdim cl::opt<bool> SectionRelocations("section-relocations", 104249423Sdim cl::desc("Display relocations for each section shown.")); 105249423Sdim 106353358Sdim // --section-symbols 107353358Sdim // Also --st in llvm-readobj mode. 108249423Sdim cl::opt<bool> SectionSymbols("section-symbols", 109249423Sdim cl::desc("Display symbols for each section shown.")); 110249423Sdim 111353358Sdim // --section-data 112353358Sdim // Also --sd in llvm-readobj mode. 113249423Sdim cl::opt<bool> SectionData("section-data", 114249423Sdim cl::desc("Display section data for each section shown.")); 115249423Sdim 116353358Sdim // --section-mapping 117353358Sdim cl::opt<cl::boolOrDefault> 118353358Sdim SectionMapping("section-mapping", 119353358Sdim cl::desc("Display the section to segment mapping.")); 120353358Sdim 121353358Sdim // --relocations, --relocs, -r 122249423Sdim cl::opt<bool> Relocations("relocations", 123249423Sdim cl::desc("Display the relocation entries in the file")); 124344779Sdim cl::alias RelocationsShort("r", cl::desc("Alias for --relocations"), 125344779Sdim cl::aliasopt(Relocations), cl::NotHidden); 126344779Sdim cl::alias RelocationsGNU("relocs", cl::desc("Alias for --relocations"), 127344779Sdim cl::aliasopt(Relocations)); 128249423Sdim 129353358Sdim // --notes, -n 130314564Sdim cl::opt<bool> Notes("notes", cl::desc("Display the ELF notes in the file")); 131314564Sdim cl::alias NotesShort("n", cl::desc("Alias for --notes"), cl::aliasopt(Notes)); 132314564Sdim 133353358Sdim // --dyn-relocations 134288943Sdim cl::opt<bool> DynRelocs("dyn-relocations", 135288943Sdim cl::desc("Display the dynamic relocation entries in the file")); 136288943Sdim 137353358Sdim // --symbols 138344779Sdim // Also -s in llvm-readelf mode, or -t in llvm-readobj mode. 139353358Sdim cl::opt<bool> 140353358Sdim Symbols("symbols", 141353358Sdim cl::desc("Display the symbol table. Also display the dynamic " 142353358Sdim "symbol table when using GNU output style for ELF")); 143344779Sdim cl::alias SymbolsGNU("syms", cl::desc("Alias for --symbols"), 144344779Sdim cl::aliasopt(Symbols)); 145249423Sdim 146353358Sdim // --dyn-symbols, --dyn-syms 147353358Sdim // Also --dt in llvm-readobj mode. 148249423Sdim cl::opt<bool> DynamicSymbols("dyn-symbols", 149249423Sdim cl::desc("Display the dynamic symbol table")); 150344779Sdim cl::alias DynSymsGNU("dyn-syms", cl::desc("Alias for --dyn-symbols"), 151344779Sdim cl::aliasopt(DynamicSymbols)); 152249423Sdim 153353358Sdim // --hash-symbols 154353358Sdim cl::opt<bool> HashSymbols( 155353358Sdim "hash-symbols", 156353358Sdim cl::desc("Display the dynamic symbols derived from the hash section")); 157353358Sdim 158353358Sdim // --unwind, -u 159249423Sdim cl::opt<bool> UnwindInfo("unwind", 160249423Sdim cl::desc("Display unwind information")); 161249423Sdim cl::alias UnwindInfoShort("u", 162249423Sdim cl::desc("Alias for --unwind"), 163249423Sdim cl::aliasopt(UnwindInfo)); 164249423Sdim 165353358Sdim // --dynamic-table, --dynamic, -d 166249423Sdim cl::opt<bool> DynamicTable("dynamic-table", 167249423Sdim cl::desc("Display the ELF .dynamic section table")); 168314564Sdim cl::alias DynamicTableShort("d", cl::desc("Alias for --dynamic-table"), 169344779Sdim cl::aliasopt(DynamicTable), cl::NotHidden); 170344779Sdim cl::alias DynamicTableAlias("dynamic", cl::desc("Alias for --dynamic-table"), 171314564Sdim cl::aliasopt(DynamicTable)); 172249423Sdim 173353358Sdim // --needed-libs 174249423Sdim cl::opt<bool> NeededLibraries("needed-libs", 175249423Sdim cl::desc("Display the needed libraries")); 176251662Sdim 177353358Sdim // --program-headers, --segments, -l 178251662Sdim cl::opt<bool> ProgramHeaders("program-headers", 179251662Sdim cl::desc("Display ELF program headers")); 180314564Sdim cl::alias ProgramHeadersShort("l", cl::desc("Alias for --program-headers"), 181344779Sdim cl::aliasopt(ProgramHeaders), cl::NotHidden); 182344779Sdim cl::alias SegmentsAlias("segments", cl::desc("Alias for --program-headers"), 183344779Sdim cl::aliasopt(ProgramHeaders)); 184251662Sdim 185353358Sdim // --string-dump, -p 186341825Sdim cl::list<std::string> StringDump("string-dump", cl::desc("<number|name>"), 187341825Sdim cl::ZeroOrMore); 188341825Sdim cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"), 189353358Sdim cl::aliasopt(StringDump), cl::Prefix); 190341825Sdim 191353358Sdim // --hex-dump, -x 192341825Sdim cl::list<std::string> HexDump("hex-dump", cl::desc("<number|name>"), 193341825Sdim cl::ZeroOrMore); 194341825Sdim cl::alias HexDumpShort("x", cl::desc("Alias for --hex-dump"), 195353358Sdim cl::aliasopt(HexDump), cl::Prefix); 196341825Sdim 197353358Sdim // --demangle, -C 198353358Sdim cl::opt<bool> Demangle("demangle", 199353358Sdim cl::desc("Demangle symbol names in output")); 200353358Sdim cl::alias DemangleShort("C", cl::desc("Alias for --demangle"), 201353358Sdim cl::aliasopt(Demangle), cl::NotHidden); 202353358Sdim 203353358Sdim // --hash-table 204288943Sdim cl::opt<bool> HashTable("hash-table", 205288943Sdim cl::desc("Display ELF hash table")); 206288943Sdim 207353358Sdim // --gnu-hash-table 208296417Sdim cl::opt<bool> GnuHashTable("gnu-hash-table", 209296417Sdim cl::desc("Display ELF .gnu.hash section")); 210296417Sdim 211353358Sdim // --expand-relocs 212251662Sdim cl::opt<bool> ExpandRelocs("expand-relocs", 213251662Sdim cl::desc("Expand each shown relocation to multiple lines")); 214276479Sdim 215353358Sdim // --raw-relr 216341825Sdim cl::opt<bool> RawRelr("raw-relr", 217341825Sdim cl::desc("Do not decode relocations in SHT_RELR section, display raw contents")); 218341825Sdim 219353358Sdim // --codeview 220288943Sdim cl::opt<bool> CodeView("codeview", 221288943Sdim cl::desc("Display CodeView debug information")); 222276479Sdim 223353358Sdim // --codeview-merged-types 224309124Sdim cl::opt<bool> 225309124Sdim CodeViewMergedTypes("codeview-merged-types", 226309124Sdim cl::desc("Display the merged CodeView type stream")); 227309124Sdim 228353358Sdim // --codeview-ghash 229353358Sdim cl::opt<bool> CodeViewEnableGHash( 230353358Sdim "codeview-ghash", 231353358Sdim cl::desc( 232353358Sdim "Enable global hashing for CodeView type stream de-duplication")); 233353358Sdim 234353358Sdim // --codeview-subsection-bytes 235288943Sdim cl::opt<bool> CodeViewSubsectionBytes( 236288943Sdim "codeview-subsection-bytes", 237288943Sdim cl::desc("Dump raw contents of codeview debug sections and records")); 238288943Sdim 239360784Sdim // --arch-specific 240360784Sdim cl::opt<bool> ArchSpecificInfo("arch-specific", 241360784Sdim cl::desc("Displays architecture-specific information, if there is any.")); 242360784Sdim cl::alias ArchSpecifcInfoShort("A", cl::desc("Alias for --arch-specific"), 243360784Sdim cl::aliasopt(ArchSpecificInfo), cl::NotHidden); 244276479Sdim 245353358Sdim // --coff-imports 246280031Sdim cl::opt<bool> 247280031Sdim COFFImports("coff-imports", cl::desc("Display the PE/COFF import table")); 248280031Sdim 249353358Sdim // --coff-exports 250280031Sdim cl::opt<bool> 251280031Sdim COFFExports("coff-exports", cl::desc("Display the PE/COFF export table")); 252280031Sdim 253353358Sdim // --coff-directives 254280031Sdim cl::opt<bool> 255280031Sdim COFFDirectives("coff-directives", 256280031Sdim cl::desc("Display the PE/COFF .drectve section")); 257280031Sdim 258353358Sdim // --coff-basereloc 259280031Sdim cl::opt<bool> 260280031Sdim COFFBaseRelocs("coff-basereloc", 261280031Sdim cl::desc("Display the PE/COFF .reloc section")); 262288943Sdim 263353358Sdim // --coff-debug-directory 264309124Sdim cl::opt<bool> 265309124Sdim COFFDebugDirectory("coff-debug-directory", 266309124Sdim cl::desc("Display the PE/COFF debug directory")); 267309124Sdim 268353358Sdim // --coff-resources 269321369Sdim cl::opt<bool> COFFResources("coff-resources", 270321369Sdim cl::desc("Display the PE/COFF .rsrc section")); 271321369Sdim 272353358Sdim // --coff-load-config 273321369Sdim cl::opt<bool> 274321369Sdim COFFLoadConfig("coff-load-config", 275321369Sdim cl::desc("Display the PE/COFF load config")); 276321369Sdim 277353358Sdim // --elf-linker-options 278341825Sdim cl::opt<bool> 279341825Sdim ELFLinkerOptions("elf-linker-options", 280341825Sdim cl::desc("Display the ELF .linker-options section")); 281341825Sdim 282353358Sdim // --macho-data-in-code 283296417Sdim cl::opt<bool> 284296417Sdim MachODataInCode("macho-data-in-code", 285296417Sdim cl::desc("Display MachO Data in Code command")); 286296417Sdim 287353358Sdim // --macho-indirect-symbols 288296417Sdim cl::opt<bool> 289296417Sdim MachOIndirectSymbols("macho-indirect-symbols", 290296417Sdim cl::desc("Display MachO indirect symbols")); 291296417Sdim 292353358Sdim // --macho-linker-options 293296417Sdim cl::opt<bool> 294296417Sdim MachOLinkerOptions("macho-linker-options", 295296417Sdim cl::desc("Display MachO linker options")); 296296417Sdim 297353358Sdim // --macho-segment 298296417Sdim cl::opt<bool> 299296417Sdim MachOSegment("macho-segment", 300296417Sdim cl::desc("Display MachO Segment command")); 301296417Sdim 302353358Sdim // --macho-version-min 303296417Sdim cl::opt<bool> 304296417Sdim MachOVersionMin("macho-version-min", 305296417Sdim cl::desc("Display MachO version min command")); 306296417Sdim 307353358Sdim // --macho-dysymtab 308296417Sdim cl::opt<bool> 309296417Sdim MachODysymtab("macho-dysymtab", 310296417Sdim cl::desc("Display MachO Dysymtab command")); 311296417Sdim 312353358Sdim // --stackmap 313288943Sdim cl::opt<bool> 314288943Sdim PrintStackMap("stackmap", 315288943Sdim cl::desc("Display contents of stackmap section")); 316288943Sdim 317360784Sdim // --stack-sizes 318360784Sdim cl::opt<bool> 319360784Sdim PrintStackSizes("stack-sizes", 320360784Sdim cl::desc("Display contents of all stack sizes sections")); 321360784Sdim 322353358Sdim // --version-info, -V 323296417Sdim cl::opt<bool> 324296417Sdim VersionInfo("version-info", 325296417Sdim cl::desc("Display ELF version sections (if present)")); 326296417Sdim cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"), 327296417Sdim cl::aliasopt(VersionInfo)); 328309124Sdim 329353358Sdim // --elf-section-groups, --section-groups, -g 330309124Sdim cl::opt<bool> SectionGroups("elf-section-groups", 331309124Sdim cl::desc("Display ELF section group contents")); 332344779Sdim cl::alias SectionGroupsAlias("section-groups", 333344779Sdim cl::desc("Alias for -elf-sections-groups"), 334344779Sdim cl::aliasopt(SectionGroups)); 335309124Sdim cl::alias SectionGroupsShort("g", cl::desc("Alias for -elf-sections-groups"), 336309124Sdim cl::aliasopt(SectionGroups)); 337344779Sdim 338353358Sdim // --elf-hash-histogram, --histogram, -I 339309124Sdim cl::opt<bool> HashHistogram( 340309124Sdim "elf-hash-histogram", 341309124Sdim cl::desc("Display bucket list histogram for hash sections")); 342309124Sdim cl::alias HashHistogramShort("I", cl::desc("Alias for -elf-hash-histogram"), 343309124Sdim cl::aliasopt(HashHistogram)); 344344779Sdim cl::alias HistogramAlias("histogram", 345344779Sdim cl::desc("Alias for --elf-hash-histogram"), 346344779Sdim cl::aliasopt(HashHistogram)); 347309124Sdim 348353358Sdim // --elf-cg-profile 349341825Sdim cl::opt<bool> CGProfile("elf-cg-profile", cl::desc("Display callgraph profile section")); 350341825Sdim 351344779Sdim // -addrsig 352344779Sdim cl::opt<bool> Addrsig("addrsig", 353341825Sdim cl::desc("Display address-significance table")); 354341825Sdim 355344779Sdim // -elf-output-style 356309124Sdim cl::opt<OutputStyleTy> 357309124Sdim Output("elf-output-style", cl::desc("Specify ELF dump style"), 358309124Sdim cl::values(clEnumVal(LLVM, "LLVM default style"), 359314564Sdim clEnumVal(GNU, "GNU readelf style")), 360309124Sdim cl::init(LLVM)); 361353358Sdim 362353358Sdim cl::extrahelp 363353358Sdim HelpResponse("\nPass @FILE as argument to read options from FILE.\n"); 364249423Sdim} // namespace opts 365249423Sdim 366360784Sdimstatic StringRef ToolName; 367360784Sdim 368249423Sdimnamespace llvm { 369249423Sdim 370360784SdimLLVM_ATTRIBUTE_NORETURN static void error(Twine Msg) { 371360784Sdim // Flush the standard output to print the error at a 372360784Sdim // proper place. 373353358Sdim fouts().flush(); 374360784Sdim WithColor::error(errs(), ToolName) << Msg << "\n"; 375296417Sdim exit(1); 376296417Sdim} 377296417Sdim 378360784SdimLLVM_ATTRIBUTE_NORETURN void reportError(Error Err, StringRef Input) { 379360784Sdim assert(Err); 380353358Sdim if (Input == "-") 381353358Sdim Input = "<stdin>"; 382360784Sdim handleAllErrors(createFileError(Input, std::move(Err)), 383360784Sdim [&](const ErrorInfoBase &EI) { error(EI.message()); }); 384360784Sdim llvm_unreachable("error() call should never return"); 385353358Sdim} 386353358Sdim 387360784Sdimvoid reportWarning(Error Err, StringRef Input) { 388360784Sdim assert(Err); 389360784Sdim if (Input == "-") 390360784Sdim Input = "<stdin>"; 391360784Sdim 392360784Sdim // Flush the standard output to print the warning at a 393360784Sdim // proper place. 394353358Sdim fouts().flush(); 395360784Sdim handleAllErrors( 396360784Sdim createFileError(Input, std::move(Err)), [&](const ErrorInfoBase &EI) { 397360784Sdim WithColor::warning(errs(), ToolName) << EI.message() << "\n"; 398360784Sdim }); 399353358Sdim} 400353358Sdim 401249423Sdim} // namespace llvm 402234285Sdim 403314564Sdimnamespace { 404314564Sdimstruct ReadObjTypeTableBuilder { 405321369Sdim ReadObjTypeTableBuilder() 406353358Sdim : Allocator(), IDTable(Allocator), TypeTable(Allocator), 407353358Sdim GlobalIDTable(Allocator), GlobalTypeTable(Allocator) {} 408276479Sdim 409314564Sdim llvm::BumpPtrAllocator Allocator; 410327952Sdim llvm::codeview::MergingTypeTableBuilder IDTable; 411327952Sdim llvm::codeview::MergingTypeTableBuilder TypeTable; 412353358Sdim llvm::codeview::GlobalTypeTableBuilder GlobalIDTable; 413353358Sdim llvm::codeview::GlobalTypeTableBuilder GlobalTypeTable; 414353358Sdim std::vector<OwningBinary<Binary>> Binaries; 415314564Sdim}; 416353358Sdim} // namespace 417314564Sdimstatic ReadObjTypeTableBuilder CVTypes; 418309124Sdim 419341825Sdim/// Creates an format-specific object file dumper. 420309124Sdimstatic std::error_code createDumper(const ObjectFile *Obj, 421309124Sdim ScopedPrinter &Writer, 422276479Sdim std::unique_ptr<ObjDumper> &Result) { 423249423Sdim if (!Obj) 424249423Sdim return readobj_error::unsupported_file_format; 425249423Sdim 426249423Sdim if (Obj->isCOFF()) 427249423Sdim return createCOFFDumper(Obj, Writer, Result); 428249423Sdim if (Obj->isELF()) 429249423Sdim return createELFDumper(Obj, Writer, Result); 430249423Sdim if (Obj->isMachO()) 431249423Sdim return createMachODumper(Obj, Writer, Result); 432321369Sdim if (Obj->isWasm()) 433321369Sdim return createWasmDumper(Obj, Writer, Result); 434353358Sdim if (Obj->isXCOFF()) 435353358Sdim return createXCOFFDumper(Obj, Writer, Result); 436249423Sdim 437249423Sdim return readobj_error::unsupported_obj_file_format; 438234285Sdim} 439234285Sdim 440341825Sdim/// Dumps the specified object file. 441353358Sdimstatic void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer, 442353358Sdim const Archive *A = nullptr) { 443353358Sdim std::string FileStr = 444353358Sdim A ? Twine(A->getFileName() + "(" + Obj->getFileName() + ")").str() 445353358Sdim : Obj->getFileName().str(); 446353358Sdim 447276479Sdim std::unique_ptr<ObjDumper> Dumper; 448296417Sdim if (std::error_code EC = createDumper(Obj, Writer, Dumper)) 449360784Sdim reportError(errorCodeToError(EC), FileStr); 450249423Sdim 451360784Sdim if (opts::Output == opts::LLVM || opts::InputFilenames.size() > 1 || A) { 452360784Sdim Writer.startLine() << "\n"; 453360784Sdim Writer.printString("File", FileStr); 454360784Sdim } 455309124Sdim if (opts::Output == opts::LLVM) { 456341825Sdim Writer.printString("Format", Obj->getFileFormatName()); 457341825Sdim Writer.printString("Arch", Triple::getArchTypeName( 458341825Sdim (llvm::Triple::ArchType)Obj->getArch())); 459341825Sdim Writer.printString("AddressSize", 460341825Sdim formatv("{0}bit", 8 * Obj->getBytesInAddress())); 461309124Sdim Dumper->printLoadName(); 462309124Sdim } 463249423Sdim 464249423Sdim if (opts::FileHeaders) 465249423Sdim Dumper->printFileHeaders(); 466344779Sdim if (opts::SectionHeaders) 467344779Sdim Dumper->printSectionHeaders(); 468249423Sdim if (opts::Relocations) 469249423Sdim Dumper->printRelocations(); 470288943Sdim if (opts::DynRelocs) 471288943Sdim Dumper->printDynamicRelocations(); 472353358Sdim if (opts::Symbols || opts::DynamicSymbols) 473353358Sdim Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols); 474353358Sdim if (opts::HashSymbols) 475353358Sdim Dumper->printHashSymbols(); 476249423Sdim if (opts::UnwindInfo) 477249423Sdim Dumper->printUnwindInfo(); 478249423Sdim if (opts::DynamicTable) 479249423Sdim Dumper->printDynamicTable(); 480249423Sdim if (opts::NeededLibraries) 481249423Sdim Dumper->printNeededLibraries(); 482353358Sdim if (opts::ProgramHeaders || opts::SectionMapping == cl::BOU_TRUE) 483353358Sdim Dumper->printProgramHeaders(opts::ProgramHeaders, opts::SectionMapping); 484341825Sdim if (!opts::StringDump.empty()) 485353358Sdim Dumper->printSectionsAsString(Obj, opts::StringDump); 486341825Sdim if (!opts::HexDump.empty()) 487353358Sdim Dumper->printSectionsAsHex(Obj, opts::HexDump); 488288943Sdim if (opts::HashTable) 489288943Sdim Dumper->printHashTable(); 490296417Sdim if (opts::GnuHashTable) 491296417Sdim Dumper->printGnuHashTable(); 492296417Sdim if (opts::VersionInfo) 493296417Sdim Dumper->printVersionInfo(); 494309124Sdim if (Obj->isELF()) { 495360784Sdim if (opts::DependentLibraries) 496360784Sdim Dumper->printDependentLibs(); 497341825Sdim if (opts::ELFLinkerOptions) 498341825Sdim Dumper->printELFLinkerOptions(); 499360784Sdim if (opts::ArchSpecificInfo) 500360784Sdim Dumper->printArchSpecificInfo(); 501309124Sdim if (opts::SectionGroups) 502309124Sdim Dumper->printGroupSections(); 503309124Sdim if (opts::HashHistogram) 504309124Sdim Dumper->printHashHistogram(); 505341825Sdim if (opts::CGProfile) 506341825Sdim Dumper->printCGProfile(); 507341825Sdim if (opts::Addrsig) 508341825Sdim Dumper->printAddrsig(); 509314564Sdim if (opts::Notes) 510314564Sdim Dumper->printNotes(); 511288943Sdim } 512296417Sdim if (Obj->isCOFF()) { 513296417Sdim if (opts::COFFImports) 514296417Sdim Dumper->printCOFFImports(); 515296417Sdim if (opts::COFFExports) 516296417Sdim Dumper->printCOFFExports(); 517296417Sdim if (opts::COFFDirectives) 518296417Sdim Dumper->printCOFFDirectives(); 519296417Sdim if (opts::COFFBaseRelocs) 520296417Sdim Dumper->printCOFFBaseReloc(); 521309124Sdim if (opts::COFFDebugDirectory) 522309124Sdim Dumper->printCOFFDebugDirectory(); 523321369Sdim if (opts::COFFResources) 524321369Sdim Dumper->printCOFFResources(); 525321369Sdim if (opts::COFFLoadConfig) 526321369Sdim Dumper->printCOFFLoadConfig(); 527344779Sdim if (opts::Addrsig) 528344779Sdim Dumper->printAddrsig(); 529296417Sdim if (opts::CodeView) 530296417Sdim Dumper->printCodeViewDebugInfo(); 531309124Sdim if (opts::CodeViewMergedTypes) 532353358Sdim Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable, 533353358Sdim CVTypes.GlobalIDTable, CVTypes.GlobalTypeTable, 534353358Sdim opts::CodeViewEnableGHash); 535296417Sdim } 536296417Sdim if (Obj->isMachO()) { 537296417Sdim if (opts::MachODataInCode) 538296417Sdim Dumper->printMachODataInCode(); 539296417Sdim if (opts::MachOIndirectSymbols) 540296417Sdim Dumper->printMachOIndirectSymbols(); 541296417Sdim if (opts::MachOLinkerOptions) 542296417Sdim Dumper->printMachOLinkerOptions(); 543296417Sdim if (opts::MachOSegment) 544296417Sdim Dumper->printMachOSegment(); 545296417Sdim if (opts::MachOVersionMin) 546296417Sdim Dumper->printMachOVersionMin(); 547296417Sdim if (opts::MachODysymtab) 548296417Sdim Dumper->printMachODysymtab(); 549296417Sdim } 550288943Sdim if (opts::PrintStackMap) 551288943Sdim Dumper->printStackMap(); 552360784Sdim if (opts::PrintStackSizes) 553360784Sdim Dumper->printStackSizes(); 554234285Sdim} 555234285Sdim 556341825Sdim/// Dumps each object file in \a Arc; 557341825Sdimstatic void dumpArchive(const Archive *Arc, ScopedPrinter &Writer) { 558314564Sdim Error Err = Error::success(); 559309124Sdim for (auto &Child : Arc->children(Err)) { 560309124Sdim Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary(); 561309124Sdim if (!ChildOrErr) { 562360784Sdim if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) 563360784Sdim reportError(std::move(E), Arc->getFileName()); 564249423Sdim continue; 565249423Sdim } 566276479Sdim if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get())) 567353358Sdim dumpObject(Obj, Writer, Arc); 568314564Sdim else if (COFFImportFile *Imp = dyn_cast<COFFImportFile>(&*ChildOrErr.get())) 569341825Sdim dumpCOFFImportFile(Imp, Writer); 570249423Sdim else 571360784Sdim reportError(errorCodeToError(readobj_error::unrecognized_file_format), 572360784Sdim Arc->getFileName()); 573234285Sdim } 574309124Sdim if (Err) 575360784Sdim reportError(std::move(Err), Arc->getFileName()); 576234285Sdim} 577234285Sdim 578341825Sdim/// Dumps each object file in \a MachO Universal Binary; 579341825Sdimstatic void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary, 580341825Sdim ScopedPrinter &Writer) { 581288943Sdim for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) { 582309124Sdim Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile(); 583288943Sdim if (ObjOrErr) 584341825Sdim dumpObject(&*ObjOrErr.get(), Writer); 585360784Sdim else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) 586360784Sdim reportError(ObjOrErr.takeError(), UBinary->getFileName()); 587309124Sdim else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive()) 588341825Sdim dumpArchive(&*AOrErr.get(), Writer); 589288943Sdim } 590288943Sdim} 591234285Sdim 592341825Sdim/// Dumps \a WinRes, Windows Resource (.res) file; 593353358Sdimstatic void dumpWindowsResourceFile(WindowsResource *WinRes, 594353358Sdim ScopedPrinter &Printer) { 595327952Sdim WindowsRes::Dumper Dumper(WinRes, Printer); 596327952Sdim if (auto Err = Dumper.printData()) 597360784Sdim reportError(std::move(Err), WinRes->getFileName()); 598327952Sdim} 599327952Sdim 600327952Sdim 601341825Sdim/// Opens \a File and dumps it. 602353358Sdimstatic void dumpInput(StringRef File, ScopedPrinter &Writer) { 603249423Sdim // Attempt to open the binary. 604309124Sdim Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File); 605309124Sdim if (!BinaryOrErr) 606360784Sdim reportError(BinaryOrErr.takeError(), File); 607280031Sdim Binary &Binary = *BinaryOrErr.get().getBinary(); 608249423Sdim 609280031Sdim if (Archive *Arc = dyn_cast<Archive>(&Binary)) 610341825Sdim dumpArchive(Arc, Writer); 611288943Sdim else if (MachOUniversalBinary *UBinary = 612288943Sdim dyn_cast<MachOUniversalBinary>(&Binary)) 613341825Sdim dumpMachOUniversalBinary(UBinary, Writer); 614280031Sdim else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary)) 615341825Sdim dumpObject(Obj, Writer); 616296417Sdim else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary)) 617341825Sdim dumpCOFFImportFile(Import, Writer); 618327952Sdim else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(&Binary)) 619353358Sdim dumpWindowsResourceFile(WinRes, Writer); 620249423Sdim else 621360784Sdim reportError(errorCodeToError(readobj_error::unrecognized_file_format), 622360784Sdim File); 623353358Sdim 624353358Sdim CVTypes.Binaries.push_back(std::move(*BinaryOrErr)); 625234285Sdim} 626234285Sdim 627344779Sdim/// Registers aliases that should only be allowed by readobj. 628344779Sdimstatic void registerReadobjAliases() { 629344779Sdim // -s has meant --sections for a very long time in llvm-readobj despite 630344779Sdim // meaning --symbols in readelf. 631344779Sdim static cl::alias SectionsShort("s", cl::desc("Alias for --section-headers"), 632344779Sdim cl::aliasopt(opts::SectionHeaders), 633344779Sdim cl::NotHidden); 634344779Sdim 635344779Sdim // Only register -t in llvm-readobj, as readelf reserves it for 636344779Sdim // --section-details (not implemented yet). 637344779Sdim static cl::alias SymbolsShort("t", cl::desc("Alias for --symbols"), 638344779Sdim cl::aliasopt(opts::Symbols), cl::NotHidden); 639344779Sdim 640344779Sdim // The following two-letter aliases are only provided for readobj, as readelf 641344779Sdim // allows single-letter args to be grouped together. 642344779Sdim static cl::alias SectionRelocationsShort( 643344779Sdim "sr", cl::desc("Alias for --section-relocations"), 644344779Sdim cl::aliasopt(opts::SectionRelocations)); 645344779Sdim static cl::alias SectionDataShort("sd", cl::desc("Alias for --section-data"), 646344779Sdim cl::aliasopt(opts::SectionData)); 647344779Sdim static cl::alias SectionSymbolsShort("st", 648344779Sdim cl::desc("Alias for --section-symbols"), 649344779Sdim cl::aliasopt(opts::SectionSymbols)); 650344779Sdim static cl::alias DynamicSymbolsShort("dt", 651344779Sdim cl::desc("Alias for --dyn-symbols"), 652344779Sdim cl::aliasopt(opts::DynamicSymbols)); 653344779Sdim} 654344779Sdim 655344779Sdim/// Registers aliases that should only be allowed by readelf. 656344779Sdimstatic void registerReadelfAliases() { 657344779Sdim // -s is here because for readobj it means --sections. 658344779Sdim static cl::alias SymbolsShort("s", cl::desc("Alias for --symbols"), 659344779Sdim cl::aliasopt(opts::Symbols), cl::NotHidden, 660344779Sdim cl::Grouping); 661344779Sdim 662344779Sdim // Allow all single letter flags to be grouped together. 663344779Sdim for (auto &OptEntry : cl::getRegisteredOptions()) { 664344779Sdim StringRef ArgName = OptEntry.getKey(); 665344779Sdim cl::Option *Option = OptEntry.getValue(); 666344779Sdim if (ArgName.size() == 1) 667353358Sdim apply(Option, cl::Grouping); 668344779Sdim } 669344779Sdim} 670344779Sdim 671249423Sdimint main(int argc, const char *argv[]) { 672341825Sdim InitLLVM X(argc, argv); 673360784Sdim ToolName = argv[0]; 674234285Sdim 675249423Sdim // Register the target printer for --version. 676249423Sdim cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); 677234285Sdim 678344779Sdim if (sys::path::stem(argv[0]).contains("readelf")) { 679321369Sdim opts::Output = opts::GNU; 680344779Sdim registerReadelfAliases(); 681344779Sdim } else { 682344779Sdim registerReadobjAliases(); 683344779Sdim } 684321369Sdim 685249423Sdim cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n"); 686234285Sdim 687344779Sdim if (opts::All) { 688344779Sdim opts::FileHeaders = true; 689344779Sdim opts::ProgramHeaders = true; 690344779Sdim opts::SectionHeaders = true; 691344779Sdim opts::Symbols = true; 692344779Sdim opts::Relocations = true; 693344779Sdim opts::DynamicTable = true; 694344779Sdim opts::Notes = true; 695344779Sdim opts::VersionInfo = true; 696344779Sdim opts::UnwindInfo = true; 697344779Sdim opts::SectionGroups = true; 698344779Sdim opts::HashHistogram = true; 699360784Sdim if (opts::Output == opts::LLVM) { 700360784Sdim opts::Addrsig = true; 701360784Sdim opts::PrintStackSizes = true; 702360784Sdim } 703344779Sdim } 704344779Sdim 705344779Sdim if (opts::Headers) { 706344779Sdim opts::FileHeaders = true; 707344779Sdim opts::ProgramHeaders = true; 708344779Sdim opts::SectionHeaders = true; 709344779Sdim } 710344779Sdim 711249423Sdim // Default to stdin if no filename is specified. 712344779Sdim if (opts::InputFilenames.empty()) 713249423Sdim opts::InputFilenames.push_back("-"); 714234285Sdim 715353358Sdim ScopedPrinter Writer(fouts()); 716353358Sdim for (const std::string &I : opts::InputFilenames) 717353358Sdim dumpInput(I, Writer); 718249423Sdim 719309124Sdim if (opts::CodeViewMergedTypes) { 720353358Sdim if (opts::CodeViewEnableGHash) 721353358Sdim dumpCodeViewMergedTypes(Writer, CVTypes.GlobalIDTable.records(), 722353358Sdim CVTypes.GlobalTypeTable.records()); 723353358Sdim else 724353358Sdim dumpCodeViewMergedTypes(Writer, CVTypes.IDTable.records(), 725353358Sdim CVTypes.TypeTable.records()); 726309124Sdim } 727309124Sdim 728296417Sdim return 0; 729234285Sdim} 730