llvm-readobj.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. //===- llvm-readobj.cpp - Dump contents of an Object File -----------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This is a tool similar to readelf, except it works on multiple object file
  10. // formats. The main purpose of this tool is to provide detailed output suitable
  11. // for FileCheck.
  12. //
  13. // Flags should be similar to readelf where supported, but the output format
  14. // does not need to be identical. The point is to not make users learn yet
  15. // another set of flags.
  16. //
  17. // Output should be specialized for each format where appropriate.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #include "llvm-readobj.h"
  21. #include "Error.h"
  22. #include "ObjDumper.h"
  23. #include "WindowsResourceDumper.h"
  24. #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
  25. #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
  26. #include "llvm/Object/Archive.h"
  27. #include "llvm/Object/COFFImportFile.h"
  28. #include "llvm/Object/MachOUniversal.h"
  29. #include "llvm/Object/ObjectFile.h"
  30. #include "llvm/Object/WindowsResource.h"
  31. #include "llvm/Support/Casting.h"
  32. #include "llvm/Support/CommandLine.h"
  33. #include "llvm/Support/DataTypes.h"
  34. #include "llvm/Support/Debug.h"
  35. #include "llvm/Support/FileSystem.h"
  36. #include "llvm/Support/FormatVariadic.h"
  37. #include "llvm/Support/InitLLVM.h"
  38. #include "llvm/Support/Path.h"
  39. #include "llvm/Support/ScopedPrinter.h"
  40. #include "llvm/Support/TargetRegistry.h"
  41. #include "llvm/Support/WithColor.h"
  42. using namespace llvm;
  43. using namespace llvm::object;
  44. namespace opts {
  45. cl::list<std::string> InputFilenames(cl::Positional,
  46. cl::desc("<input object files>"),
  47. cl::ZeroOrMore);
  48. // --all, -a
  49. cl::opt<bool>
  50. All("all",
  51. cl::desc("Equivalent to setting: --file-headers, --program-headers, "
  52. "--section-headers, --symbols, --relocations, "
  53. "--dynamic-table, --notes, --version-info, --unwind, "
  54. "--section-groups and --elf-hash-histogram."));
  55. cl::alias AllShort("a", cl::desc("Alias for --all"), cl::aliasopt(All));
  56. // --headers -e
  57. cl::opt<bool>
  58. Headers("headers",
  59. cl::desc("Equivalent to setting: --file-headers, --program-headers, "
  60. "--section-headers"));
  61. cl::alias HeadersShort("e", cl::desc("Alias for --headers"),
  62. cl::aliasopt(Headers));
  63. // --wide, -W
  64. cl::opt<bool>
  65. WideOutput("wide", cl::desc("Ignored for compatibility with GNU readelf"),
  66. cl::Hidden);
  67. cl::alias WideOutputShort("W",
  68. cl::desc("Alias for --wide"),
  69. cl::aliasopt(WideOutput));
  70. // --file-headers, --file-header, -h
  71. cl::opt<bool> FileHeaders("file-headers",
  72. cl::desc("Display file headers "));
  73. cl::alias FileHeadersShort("h", cl::desc("Alias for --file-headers"),
  74. cl::aliasopt(FileHeaders), cl::NotHidden);
  75. cl::alias FileHeadersSingular("file-header",
  76. cl::desc("Alias for --file-headers"),
  77. cl::aliasopt(FileHeaders));
  78. // --section-headers, --sections, -S
  79. // Also -s in llvm-readobj mode.
  80. cl::opt<bool> SectionHeaders("section-headers",
  81. cl::desc("Display all section headers."));
  82. cl::alias SectionsShortUpper("S", cl::desc("Alias for --section-headers"),
  83. cl::aliasopt(SectionHeaders), cl::NotHidden);
  84. cl::alias SectionHeadersAlias("sections",
  85. cl::desc("Alias for --section-headers"),
  86. cl::aliasopt(SectionHeaders), cl::NotHidden);
  87. // --section-relocations
  88. // Also --sr in llvm-readobj mode.
  89. cl::opt<bool> SectionRelocations("section-relocations",
  90. cl::desc("Display relocations for each section shown."));
  91. // --section-symbols
  92. // Also --st in llvm-readobj mode.
  93. cl::opt<bool> SectionSymbols("section-symbols",
  94. cl::desc("Display symbols for each section shown."));
  95. // --section-data
  96. // Also --sd in llvm-readobj mode.
  97. cl::opt<bool> SectionData("section-data",
  98. cl::desc("Display section data for each section shown."));
  99. // --section-mapping
  100. cl::opt<cl::boolOrDefault>
  101. SectionMapping("section-mapping",
  102. cl::desc("Display the section to segment mapping."));
  103. // --relocations, --relocs, -r
  104. cl::opt<bool> Relocations("relocations",
  105. cl::desc("Display the relocation entries in the file"));
  106. cl::alias RelocationsShort("r", cl::desc("Alias for --relocations"),
  107. cl::aliasopt(Relocations), cl::NotHidden);
  108. cl::alias RelocationsGNU("relocs", cl::desc("Alias for --relocations"),
  109. cl::aliasopt(Relocations));
  110. // --notes, -n
  111. cl::opt<bool> Notes("notes", cl::desc("Display the ELF notes in the file"));
  112. cl::alias NotesShort("n", cl::desc("Alias for --notes"), cl::aliasopt(Notes));
  113. // --dyn-relocations
  114. cl::opt<bool> DynRelocs("dyn-relocations",
  115. cl::desc("Display the dynamic relocation entries in the file"));
  116. // --symbols
  117. // Also -s in llvm-readelf mode, or -t in llvm-readobj mode.
  118. cl::opt<bool>
  119. Symbols("symbols",
  120. cl::desc("Display the symbol table. Also display the dynamic "
  121. "symbol table when using GNU output style for ELF"));
  122. cl::alias SymbolsGNU("syms", cl::desc("Alias for --symbols"),
  123. cl::aliasopt(Symbols));
  124. // --dyn-symbols, --dyn-syms
  125. // Also --dt in llvm-readobj mode.
  126. cl::opt<bool> DynamicSymbols("dyn-symbols",
  127. cl::desc("Display the dynamic symbol table"));
  128. cl::alias DynSymsGNU("dyn-syms", cl::desc("Alias for --dyn-symbols"),
  129. cl::aliasopt(DynamicSymbols));
  130. // --hash-symbols
  131. cl::opt<bool> HashSymbols(
  132. "hash-symbols",
  133. cl::desc("Display the dynamic symbols derived from the hash section"));
  134. // --unwind, -u
  135. cl::opt<bool> UnwindInfo("unwind",
  136. cl::desc("Display unwind information"));
  137. cl::alias UnwindInfoShort("u",
  138. cl::desc("Alias for --unwind"),
  139. cl::aliasopt(UnwindInfo));
  140. // --dynamic-table, --dynamic, -d
  141. cl::opt<bool> DynamicTable("dynamic-table",
  142. cl::desc("Display the ELF .dynamic section table"));
  143. cl::alias DynamicTableShort("d", cl::desc("Alias for --dynamic-table"),
  144. cl::aliasopt(DynamicTable), cl::NotHidden);
  145. cl::alias DynamicTableAlias("dynamic", cl::desc("Alias for --dynamic-table"),
  146. cl::aliasopt(DynamicTable));
  147. // --needed-libs
  148. cl::opt<bool> NeededLibraries("needed-libs",
  149. cl::desc("Display the needed libraries"));
  150. // --program-headers, --segments, -l
  151. cl::opt<bool> ProgramHeaders("program-headers",
  152. cl::desc("Display ELF program headers"));
  153. cl::alias ProgramHeadersShort("l", cl::desc("Alias for --program-headers"),
  154. cl::aliasopt(ProgramHeaders), cl::NotHidden);
  155. cl::alias SegmentsAlias("segments", cl::desc("Alias for --program-headers"),
  156. cl::aliasopt(ProgramHeaders));
  157. // --string-dump, -p
  158. cl::list<std::string> StringDump("string-dump", cl::desc("<number|name>"),
  159. cl::ZeroOrMore);
  160. cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"),
  161. cl::aliasopt(StringDump), cl::Prefix);
  162. // --hex-dump, -x
  163. cl::list<std::string> HexDump("hex-dump", cl::desc("<number|name>"),
  164. cl::ZeroOrMore);
  165. cl::alias HexDumpShort("x", cl::desc("Alias for --hex-dump"),
  166. cl::aliasopt(HexDump), cl::Prefix);
  167. // --demangle, -C
  168. cl::opt<bool> Demangle("demangle",
  169. cl::desc("Demangle symbol names in output"));
  170. cl::alias DemangleShort("C", cl::desc("Alias for --demangle"),
  171. cl::aliasopt(Demangle), cl::NotHidden);
  172. // --hash-table
  173. cl::opt<bool> HashTable("hash-table",
  174. cl::desc("Display ELF hash table"));
  175. // --gnu-hash-table
  176. cl::opt<bool> GnuHashTable("gnu-hash-table",
  177. cl::desc("Display ELF .gnu.hash section"));
  178. // --expand-relocs
  179. cl::opt<bool> ExpandRelocs("expand-relocs",
  180. cl::desc("Expand each shown relocation to multiple lines"));
  181. // --raw-relr
  182. cl::opt<bool> RawRelr("raw-relr",
  183. cl::desc("Do not decode relocations in SHT_RELR section, display raw contents"));
  184. // --codeview
  185. cl::opt<bool> CodeView("codeview",
  186. cl::desc("Display CodeView debug information"));
  187. // --codeview-merged-types
  188. cl::opt<bool>
  189. CodeViewMergedTypes("codeview-merged-types",
  190. cl::desc("Display the merged CodeView type stream"));
  191. // --codeview-ghash
  192. cl::opt<bool> CodeViewEnableGHash(
  193. "codeview-ghash",
  194. cl::desc(
  195. "Enable global hashing for CodeView type stream de-duplication"));
  196. // --codeview-subsection-bytes
  197. cl::opt<bool> CodeViewSubsectionBytes(
  198. "codeview-subsection-bytes",
  199. cl::desc("Dump raw contents of codeview debug sections and records"));
  200. // --arm-attributes
  201. cl::opt<bool> ARMAttributes("arm-attributes",
  202. cl::desc("Display the ARM attributes section"));
  203. // --mips-plt-got
  204. cl::opt<bool>
  205. MipsPLTGOT("mips-plt-got",
  206. cl::desc("Display the MIPS GOT and PLT GOT sections"));
  207. // --mips-abi-flags
  208. cl::opt<bool> MipsABIFlags("mips-abi-flags",
  209. cl::desc("Display the MIPS.abiflags section"));
  210. // --mips-reginfo
  211. cl::opt<bool> MipsReginfo("mips-reginfo",
  212. cl::desc("Display the MIPS .reginfo section"));
  213. // --mips-options
  214. cl::opt<bool> MipsOptions("mips-options",
  215. cl::desc("Display the MIPS .MIPS.options section"));
  216. // --coff-imports
  217. cl::opt<bool>
  218. COFFImports("coff-imports", cl::desc("Display the PE/COFF import table"));
  219. // --coff-exports
  220. cl::opt<bool>
  221. COFFExports("coff-exports", cl::desc("Display the PE/COFF export table"));
  222. // --coff-directives
  223. cl::opt<bool>
  224. COFFDirectives("coff-directives",
  225. cl::desc("Display the PE/COFF .drectve section"));
  226. // --coff-basereloc
  227. cl::opt<bool>
  228. COFFBaseRelocs("coff-basereloc",
  229. cl::desc("Display the PE/COFF .reloc section"));
  230. // --coff-debug-directory
  231. cl::opt<bool>
  232. COFFDebugDirectory("coff-debug-directory",
  233. cl::desc("Display the PE/COFF debug directory"));
  234. // --coff-resources
  235. cl::opt<bool> COFFResources("coff-resources",
  236. cl::desc("Display the PE/COFF .rsrc section"));
  237. // --coff-load-config
  238. cl::opt<bool>
  239. COFFLoadConfig("coff-load-config",
  240. cl::desc("Display the PE/COFF load config"));
  241. // --elf-linker-options
  242. cl::opt<bool>
  243. ELFLinkerOptions("elf-linker-options",
  244. cl::desc("Display the ELF .linker-options section"));
  245. // --macho-data-in-code
  246. cl::opt<bool>
  247. MachODataInCode("macho-data-in-code",
  248. cl::desc("Display MachO Data in Code command"));
  249. // --macho-indirect-symbols
  250. cl::opt<bool>
  251. MachOIndirectSymbols("macho-indirect-symbols",
  252. cl::desc("Display MachO indirect symbols"));
  253. // --macho-linker-options
  254. cl::opt<bool>
  255. MachOLinkerOptions("macho-linker-options",
  256. cl::desc("Display MachO linker options"));
  257. // --macho-segment
  258. cl::opt<bool>
  259. MachOSegment("macho-segment",
  260. cl::desc("Display MachO Segment command"));
  261. // --macho-version-min
  262. cl::opt<bool>
  263. MachOVersionMin("macho-version-min",
  264. cl::desc("Display MachO version min command"));
  265. // --macho-dysymtab
  266. cl::opt<bool>
  267. MachODysymtab("macho-dysymtab",
  268. cl::desc("Display MachO Dysymtab command"));
  269. // --stackmap
  270. cl::opt<bool>
  271. PrintStackMap("stackmap",
  272. cl::desc("Display contents of stackmap section"));
  273. // --stack-sizes
  274. cl::opt<bool>
  275. PrintStackSizes("stack-sizes",
  276. cl::desc("Display contents of all stack sizes sections"));
  277. // --version-info, -V
  278. cl::opt<bool>
  279. VersionInfo("version-info",
  280. cl::desc("Display ELF version sections (if present)"));
  281. cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"),
  282. cl::aliasopt(VersionInfo));
  283. // --elf-section-groups, --section-groups, -g
  284. cl::opt<bool> SectionGroups("elf-section-groups",
  285. cl::desc("Display ELF section group contents"));
  286. cl::alias SectionGroupsAlias("section-groups",
  287. cl::desc("Alias for -elf-sections-groups"),
  288. cl::aliasopt(SectionGroups));
  289. cl::alias SectionGroupsShort("g", cl::desc("Alias for -elf-sections-groups"),
  290. cl::aliasopt(SectionGroups));
  291. // --elf-hash-histogram, --histogram, -I
  292. cl::opt<bool> HashHistogram(
  293. "elf-hash-histogram",
  294. cl::desc("Display bucket list histogram for hash sections"));
  295. cl::alias HashHistogramShort("I", cl::desc("Alias for -elf-hash-histogram"),
  296. cl::aliasopt(HashHistogram));
  297. cl::alias HistogramAlias("histogram",
  298. cl::desc("Alias for --elf-hash-histogram"),
  299. cl::aliasopt(HashHistogram));
  300. // --elf-cg-profile
  301. cl::opt<bool> CGProfile("elf-cg-profile", cl::desc("Display callgraph profile section"));
  302. // -addrsig
  303. cl::opt<bool> Addrsig("addrsig",
  304. cl::desc("Display address-significance table"));
  305. // -elf-output-style
  306. cl::opt<OutputStyleTy>
  307. Output("elf-output-style", cl::desc("Specify ELF dump style"),
  308. cl::values(clEnumVal(LLVM, "LLVM default style"),
  309. clEnumVal(GNU, "GNU readelf style")),
  310. cl::init(LLVM));
  311. cl::extrahelp
  312. HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
  313. } // namespace opts
  314. namespace llvm {
  315. LLVM_ATTRIBUTE_NORETURN static void error(Twine Msg) {
  316. // Flush the standard output to print the error at a
  317. // proper place.
  318. fouts().flush();
  319. errs() << "\n";
  320. WithColor::error(errs()) << Msg << "\n";
  321. exit(1);
  322. }
  323. LLVM_ATTRIBUTE_NORETURN void reportError(Error Err, StringRef Input) {
  324. assert(Err);
  325. if (Input == "-")
  326. Input = "<stdin>";
  327. handleAllErrors(createFileError(Input, std::move(Err)),
  328. [&](const ErrorInfoBase &EI) { error(EI.message()); });
  329. llvm_unreachable("error() call should never return");
  330. }
  331. void reportWarning(Error Err, StringRef Input) {
  332. assert(Err);
  333. if (Input == "-")
  334. Input = "<stdin>";
  335. handleAllErrors(createFileError(Input, std::move(Err)),
  336. [&](const ErrorInfoBase &EI) {
  337. // Flush the standard output to print the warning at a
  338. // proper place.
  339. fouts().flush();
  340. errs() << "\n";
  341. WithColor::warning(errs()) << EI.message() << "\n";
  342. });
  343. }
  344. LLVM_ATTRIBUTE_NORETURN void reportError(std::error_code EC, StringRef Input) {
  345. assert(EC != readobj_error::success);
  346. reportError(errorCodeToError(EC), Input);
  347. }
  348. } // namespace llvm
  349. static bool isMipsArch(unsigned Arch) {
  350. switch (Arch) {
  351. case llvm::Triple::mips:
  352. case llvm::Triple::mipsel:
  353. case llvm::Triple::mips64:
  354. case llvm::Triple::mips64el:
  355. return true;
  356. default:
  357. return false;
  358. }
  359. }
  360. namespace {
  361. struct ReadObjTypeTableBuilder {
  362. ReadObjTypeTableBuilder()
  363. : Allocator(), IDTable(Allocator), TypeTable(Allocator),
  364. GlobalIDTable(Allocator), GlobalTypeTable(Allocator) {}
  365. llvm::BumpPtrAllocator Allocator;
  366. llvm::codeview::MergingTypeTableBuilder IDTable;
  367. llvm::codeview::MergingTypeTableBuilder TypeTable;
  368. llvm::codeview::GlobalTypeTableBuilder GlobalIDTable;
  369. llvm::codeview::GlobalTypeTableBuilder GlobalTypeTable;
  370. std::vector<OwningBinary<Binary>> Binaries;
  371. };
  372. } // namespace
  373. static ReadObjTypeTableBuilder CVTypes;
  374. /// Creates an format-specific object file dumper.
  375. static std::error_code createDumper(const ObjectFile *Obj,
  376. ScopedPrinter &Writer,
  377. std::unique_ptr<ObjDumper> &Result) {
  378. if (!Obj)
  379. return readobj_error::unsupported_file_format;
  380. if (Obj->isCOFF())
  381. return createCOFFDumper(Obj, Writer, Result);
  382. if (Obj->isELF())
  383. return createELFDumper(Obj, Writer, Result);
  384. if (Obj->isMachO())
  385. return createMachODumper(Obj, Writer, Result);
  386. if (Obj->isWasm())
  387. return createWasmDumper(Obj, Writer, Result);
  388. if (Obj->isXCOFF())
  389. return createXCOFFDumper(Obj, Writer, Result);
  390. return readobj_error::unsupported_obj_file_format;
  391. }
  392. /// Dumps the specified object file.
  393. static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer,
  394. const Archive *A = nullptr) {
  395. std::string FileStr =
  396. A ? Twine(A->getFileName() + "(" + Obj->getFileName() + ")").str()
  397. : Obj->getFileName().str();
  398. std::unique_ptr<ObjDumper> Dumper;
  399. if (std::error_code EC = createDumper(Obj, Writer, Dumper))
  400. reportError(EC, FileStr);
  401. if (opts::Output == opts::LLVM || opts::InputFilenames.size() > 1 || A) {
  402. Writer.startLine() << "\n";
  403. Writer.printString("File", FileStr);
  404. }
  405. if (opts::Output == opts::LLVM) {
  406. Writer.printString("Format", Obj->getFileFormatName());
  407. Writer.printString("Arch", Triple::getArchTypeName(
  408. (llvm::Triple::ArchType)Obj->getArch()));
  409. Writer.printString("AddressSize",
  410. formatv("{0}bit", 8 * Obj->getBytesInAddress()));
  411. Dumper->printLoadName();
  412. }
  413. if (opts::FileHeaders)
  414. Dumper->printFileHeaders();
  415. if (opts::SectionHeaders)
  416. Dumper->printSectionHeaders();
  417. if (opts::Relocations)
  418. Dumper->printRelocations();
  419. if (opts::DynRelocs)
  420. Dumper->printDynamicRelocations();
  421. if (opts::Symbols || opts::DynamicSymbols)
  422. Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols);
  423. if (opts::HashSymbols)
  424. Dumper->printHashSymbols();
  425. if (opts::UnwindInfo)
  426. Dumper->printUnwindInfo();
  427. if (opts::DynamicTable)
  428. Dumper->printDynamicTable();
  429. if (opts::NeededLibraries)
  430. Dumper->printNeededLibraries();
  431. if (opts::ProgramHeaders || opts::SectionMapping == cl::BOU_TRUE)
  432. Dumper->printProgramHeaders(opts::ProgramHeaders, opts::SectionMapping);
  433. if (!opts::StringDump.empty())
  434. Dumper->printSectionsAsString(Obj, opts::StringDump);
  435. if (!opts::HexDump.empty())
  436. Dumper->printSectionsAsHex(Obj, opts::HexDump);
  437. if (opts::HashTable)
  438. Dumper->printHashTable();
  439. if (opts::GnuHashTable)
  440. Dumper->printGnuHashTable();
  441. if (opts::VersionInfo)
  442. Dumper->printVersionInfo();
  443. if (Obj->isELF()) {
  444. if (opts::ELFLinkerOptions)
  445. Dumper->printELFLinkerOptions();
  446. if (Obj->getArch() == llvm::Triple::arm)
  447. if (opts::ARMAttributes)
  448. Dumper->printAttributes();
  449. if (isMipsArch(Obj->getArch())) {
  450. if (opts::MipsPLTGOT)
  451. Dumper->printMipsPLTGOT();
  452. if (opts::MipsABIFlags)
  453. Dumper->printMipsABIFlags();
  454. if (opts::MipsReginfo)
  455. Dumper->printMipsReginfo();
  456. if (opts::MipsOptions)
  457. Dumper->printMipsOptions();
  458. }
  459. if (opts::SectionGroups)
  460. Dumper->printGroupSections();
  461. if (opts::HashHistogram)
  462. Dumper->printHashHistogram();
  463. if (opts::CGProfile)
  464. Dumper->printCGProfile();
  465. if (opts::Addrsig)
  466. Dumper->printAddrsig();
  467. if (opts::Notes)
  468. Dumper->printNotes();
  469. }
  470. if (Obj->isCOFF()) {
  471. if (opts::COFFImports)
  472. Dumper->printCOFFImports();
  473. if (opts::COFFExports)
  474. Dumper->printCOFFExports();
  475. if (opts::COFFDirectives)
  476. Dumper->printCOFFDirectives();
  477. if (opts::COFFBaseRelocs)
  478. Dumper->printCOFFBaseReloc();
  479. if (opts::COFFDebugDirectory)
  480. Dumper->printCOFFDebugDirectory();
  481. if (opts::COFFResources)
  482. Dumper->printCOFFResources();
  483. if (opts::COFFLoadConfig)
  484. Dumper->printCOFFLoadConfig();
  485. if (opts::Addrsig)
  486. Dumper->printAddrsig();
  487. if (opts::CodeView)
  488. Dumper->printCodeViewDebugInfo();
  489. if (opts::CodeViewMergedTypes)
  490. Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable,
  491. CVTypes.GlobalIDTable, CVTypes.GlobalTypeTable,
  492. opts::CodeViewEnableGHash);
  493. }
  494. if (Obj->isMachO()) {
  495. if (opts::MachODataInCode)
  496. Dumper->printMachODataInCode();
  497. if (opts::MachOIndirectSymbols)
  498. Dumper->printMachOIndirectSymbols();
  499. if (opts::MachOLinkerOptions)
  500. Dumper->printMachOLinkerOptions();
  501. if (opts::MachOSegment)
  502. Dumper->printMachOSegment();
  503. if (opts::MachOVersionMin)
  504. Dumper->printMachOVersionMin();
  505. if (opts::MachODysymtab)
  506. Dumper->printMachODysymtab();
  507. }
  508. if (opts::PrintStackMap)
  509. Dumper->printStackMap();
  510. if (opts::PrintStackSizes)
  511. Dumper->printStackSizes();
  512. }
  513. /// Dumps each object file in \a Arc;
  514. static void dumpArchive(const Archive *Arc, ScopedPrinter &Writer) {
  515. Error Err = Error::success();
  516. for (auto &Child : Arc->children(Err)) {
  517. Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
  518. if (!ChildOrErr) {
  519. if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
  520. reportError(std::move(E), Arc->getFileName());
  521. continue;
  522. }
  523. if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
  524. dumpObject(Obj, Writer, Arc);
  525. else if (COFFImportFile *Imp = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
  526. dumpCOFFImportFile(Imp, Writer);
  527. else
  528. reportError(readobj_error::unrecognized_file_format, Arc->getFileName());
  529. }
  530. if (Err)
  531. reportError(std::move(Err), Arc->getFileName());
  532. }
  533. /// Dumps each object file in \a MachO Universal Binary;
  534. static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary,
  535. ScopedPrinter &Writer) {
  536. for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) {
  537. Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile();
  538. if (ObjOrErr)
  539. dumpObject(&*ObjOrErr.get(), Writer);
  540. else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError()))
  541. reportError(ObjOrErr.takeError(), UBinary->getFileName());
  542. else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
  543. dumpArchive(&*AOrErr.get(), Writer);
  544. }
  545. }
  546. /// Dumps \a WinRes, Windows Resource (.res) file;
  547. static void dumpWindowsResourceFile(WindowsResource *WinRes,
  548. ScopedPrinter &Printer) {
  549. WindowsRes::Dumper Dumper(WinRes, Printer);
  550. if (auto Err = Dumper.printData())
  551. reportError(std::move(Err), WinRes->getFileName());
  552. }
  553. /// Opens \a File and dumps it.
  554. static void dumpInput(StringRef File, ScopedPrinter &Writer) {
  555. // Attempt to open the binary.
  556. Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
  557. if (!BinaryOrErr)
  558. reportError(BinaryOrErr.takeError(), File);
  559. Binary &Binary = *BinaryOrErr.get().getBinary();
  560. if (Archive *Arc = dyn_cast<Archive>(&Binary))
  561. dumpArchive(Arc, Writer);
  562. else if (MachOUniversalBinary *UBinary =
  563. dyn_cast<MachOUniversalBinary>(&Binary))
  564. dumpMachOUniversalBinary(UBinary, Writer);
  565. else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
  566. dumpObject(Obj, Writer);
  567. else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary))
  568. dumpCOFFImportFile(Import, Writer);
  569. else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(&Binary))
  570. dumpWindowsResourceFile(WinRes, Writer);
  571. else
  572. reportError(readobj_error::unrecognized_file_format, File);
  573. CVTypes.Binaries.push_back(std::move(*BinaryOrErr));
  574. }
  575. /// Registers aliases that should only be allowed by readobj.
  576. static void registerReadobjAliases() {
  577. // -s has meant --sections for a very long time in llvm-readobj despite
  578. // meaning --symbols in readelf.
  579. static cl::alias SectionsShort("s", cl::desc("Alias for --section-headers"),
  580. cl::aliasopt(opts::SectionHeaders),
  581. cl::NotHidden);
  582. // Only register -t in llvm-readobj, as readelf reserves it for
  583. // --section-details (not implemented yet).
  584. static cl::alias SymbolsShort("t", cl::desc("Alias for --symbols"),
  585. cl::aliasopt(opts::Symbols), cl::NotHidden);
  586. // The following two-letter aliases are only provided for readobj, as readelf
  587. // allows single-letter args to be grouped together.
  588. static cl::alias SectionRelocationsShort(
  589. "sr", cl::desc("Alias for --section-relocations"),
  590. cl::aliasopt(opts::SectionRelocations));
  591. static cl::alias SectionDataShort("sd", cl::desc("Alias for --section-data"),
  592. cl::aliasopt(opts::SectionData));
  593. static cl::alias SectionSymbolsShort("st",
  594. cl::desc("Alias for --section-symbols"),
  595. cl::aliasopt(opts::SectionSymbols));
  596. static cl::alias DynamicSymbolsShort("dt",
  597. cl::desc("Alias for --dyn-symbols"),
  598. cl::aliasopt(opts::DynamicSymbols));
  599. }
  600. /// Registers aliases that should only be allowed by readelf.
  601. static void registerReadelfAliases() {
  602. // -s is here because for readobj it means --sections.
  603. static cl::alias SymbolsShort("s", cl::desc("Alias for --symbols"),
  604. cl::aliasopt(opts::Symbols), cl::NotHidden,
  605. cl::Grouping);
  606. // Allow all single letter flags to be grouped together.
  607. for (auto &OptEntry : cl::getRegisteredOptions()) {
  608. StringRef ArgName = OptEntry.getKey();
  609. cl::Option *Option = OptEntry.getValue();
  610. if (ArgName.size() == 1)
  611. apply(Option, cl::Grouping);
  612. }
  613. }
  614. int main(int argc, const char *argv[]) {
  615. InitLLVM X(argc, argv);
  616. // Register the target printer for --version.
  617. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
  618. if (sys::path::stem(argv[0]).contains("readelf")) {
  619. opts::Output = opts::GNU;
  620. registerReadelfAliases();
  621. } else {
  622. registerReadobjAliases();
  623. }
  624. cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n");
  625. if (opts::All) {
  626. opts::FileHeaders = true;
  627. opts::ProgramHeaders = true;
  628. opts::SectionHeaders = true;
  629. opts::Symbols = true;
  630. opts::Relocations = true;
  631. opts::DynamicTable = true;
  632. opts::Notes = true;
  633. opts::VersionInfo = true;
  634. opts::UnwindInfo = true;
  635. opts::SectionGroups = true;
  636. opts::HashHistogram = true;
  637. // FIXME: As soon as we implement LLVM-style printing of the .stack_size
  638. // section, we will enable it with --all (only for LLVM-style).
  639. if (opts::Output == opts::LLVM)
  640. opts::PrintStackSizes = false;
  641. }
  642. if (opts::Headers) {
  643. opts::FileHeaders = true;
  644. opts::ProgramHeaders = true;
  645. opts::SectionHeaders = true;
  646. }
  647. // Default to stdin if no filename is specified.
  648. if (opts::InputFilenames.empty())
  649. opts::InputFilenames.push_back("-");
  650. ScopedPrinter Writer(fouts());
  651. for (const std::string &I : opts::InputFilenames)
  652. dumpInput(I, Writer);
  653. if (opts::CodeViewMergedTypes) {
  654. if (opts::CodeViewEnableGHash)
  655. dumpCodeViewMergedTypes(Writer, CVTypes.GlobalIDTable.records(),
  656. CVTypes.GlobalTypeTable.records());
  657. else
  658. dumpCodeViewMergedTypes(Writer, CVTypes.IDTable.records(),
  659. CVTypes.TypeTable.records());
  660. }
  661. return 0;
  662. }