llvm-readobj.cpp 28 KB

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