aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-readobj/llvm-readobj.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/tools/llvm-readobj/llvm-readobj.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/tools/llvm-readobj/llvm-readobj.cpp')
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp638
1 files changed, 237 insertions, 401 deletions
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 41cd4414d051..0b49f03f4275 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -31,6 +31,9 @@
#include "llvm/Object/Wasm.h"
#include "llvm/Object/WindowsResource.h"
#include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/Option.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataTypes.h"
@@ -47,339 +50,107 @@
using namespace llvm;
using namespace llvm::object;
+namespace {
+using namespace llvm::opt; // for HelpHidden in Opts.inc
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "Opts.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "Opts.inc"
+#undef PREFIX
+
+static const opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ { \
+ PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "Opts.inc"
+#undef OPTION
+};
+
+class ReadobjOptTable : public opt::OptTable {
+public:
+ ReadobjOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); }
+};
+
+enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };
+} // namespace
+
namespace opts {
- cl::list<std::string> InputFilenames(cl::Positional,
- cl::desc("<input object files>"),
- cl::ZeroOrMore);
-
- // --all, -a
- cl::opt<bool>
- All("all",
- cl::desc("Equivalent to setting: --file-headers, --program-headers, "
- "--section-headers, --symbols, --relocations, "
- "--dynamic-table, --notes, --version-info, --unwind, "
- "--section-groups and --elf-hash-histogram."));
- cl::alias AllShort("a", cl::desc("Alias for --all"), cl::aliasopt(All));
-
- // --dependent-libraries
- cl::opt<bool>
- DependentLibraries("dependent-libraries",
- cl::desc("Display the dependent libraries section"));
-
- // --headers, -e
- cl::opt<bool>
- Headers("headers",
- cl::desc("Equivalent to setting: --file-headers, --program-headers, "
- "--section-headers"));
- cl::alias HeadersShort("e", cl::desc("Alias for --headers"),
- cl::aliasopt(Headers));
-
- // --wide, -W
- cl::opt<bool>
- WideOutput("wide", cl::desc("Ignored for compatibility with GNU readelf"),
- cl::Hidden);
- cl::alias WideOutputShort("W",
- cl::desc("Alias for --wide"),
- cl::aliasopt(WideOutput));
-
- // --file-headers, --file-header, -h
- cl::opt<bool> FileHeaders("file-headers",
- cl::desc("Display file headers "));
- cl::alias FileHeadersShort("h", cl::desc("Alias for --file-headers"),
- cl::aliasopt(FileHeaders), cl::NotHidden);
- cl::alias FileHeadersSingular("file-header",
- cl::desc("Alias for --file-headers"),
- cl::aliasopt(FileHeaders));
-
- // --section-headers, --sections, -S
- // Also -s in llvm-readobj mode.
- cl::opt<bool> SectionHeaders("section-headers",
- cl::desc("Display all section headers."));
- cl::alias SectionsShortUpper("S", cl::desc("Alias for --section-headers"),
- cl::aliasopt(SectionHeaders), cl::NotHidden);
- cl::alias SectionHeadersAlias("sections",
- cl::desc("Alias for --section-headers"),
- cl::aliasopt(SectionHeaders), cl::NotHidden);
-
- // --section-relocations
- // Also --sr in llvm-readobj mode.
- cl::opt<bool> SectionRelocations("section-relocations",
- cl::desc("Display relocations for each section shown."));
-
- // --section-symbols
- // Also --st in llvm-readobj mode.
- cl::opt<bool> SectionSymbols("section-symbols",
- cl::desc("Display symbols for each section shown."));
-
- // --section-data
- // Also --sd in llvm-readobj mode.
- cl::opt<bool> SectionData("section-data",
- cl::desc("Display section data for each section shown."));
-
- // --section-mapping
- cl::opt<cl::boolOrDefault>
- SectionMapping("section-mapping",
- cl::desc("Display the section to segment mapping."));
-
- // --relocations, --relocs, -r
- cl::opt<bool> Relocations("relocations",
- cl::desc("Display the relocation entries in the file"));
- cl::alias RelocationsShort("r", cl::desc("Alias for --relocations"),
- cl::aliasopt(Relocations), cl::NotHidden);
- cl::alias RelocationsGNU("relocs", cl::desc("Alias for --relocations"),
- cl::aliasopt(Relocations));
-
- // --notes, -n
- cl::opt<bool> Notes("notes", cl::desc("Display the ELF notes in the file"));
- cl::alias NotesShort("n", cl::desc("Alias for --notes"), cl::aliasopt(Notes));
-
- // --dyn-relocations
- cl::opt<bool> DynRelocs("dyn-relocations",
- cl::desc("Display the dynamic relocation entries in the file"));
-
- // --section-details
- // Also -t in llvm-readelf mode.
- cl::opt<bool> SectionDetails("section-details",
- cl::desc("Display the section details"));
-
- // --symbols
- // Also -s in llvm-readelf mode, or -t in llvm-readobj mode.
- cl::opt<bool>
- Symbols("symbols",
- cl::desc("Display the symbol table. Also display the dynamic "
- "symbol table when using GNU output style for ELF"));
- cl::alias SymbolsGNU("syms", cl::desc("Alias for --symbols"),
- cl::aliasopt(Symbols));
-
- // --dyn-symbols, --dyn-syms
- // Also --dt in llvm-readobj mode.
- cl::opt<bool> DynamicSymbols("dyn-symbols",
- cl::desc("Display the dynamic symbol table"));
- cl::alias DynSymsGNU("dyn-syms", cl::desc("Alias for --dyn-symbols"),
- cl::aliasopt(DynamicSymbols));
-
- // --hash-symbols
- cl::opt<bool> HashSymbols(
- "hash-symbols",
- cl::desc("Display the dynamic symbols derived from the hash section"));
-
- // --unwind, -u
- cl::opt<bool> UnwindInfo("unwind",
- cl::desc("Display unwind information"));
- cl::alias UnwindInfoShort("u",
- cl::desc("Alias for --unwind"),
- cl::aliasopt(UnwindInfo));
-
- // --dynamic-table, --dynamic, -d
- cl::opt<bool> DynamicTable("dynamic-table",
- cl::desc("Display the ELF .dynamic section table"));
- cl::alias DynamicTableShort("d", cl::desc("Alias for --dynamic-table"),
- cl::aliasopt(DynamicTable), cl::NotHidden);
- cl::alias DynamicTableAlias("dynamic", cl::desc("Alias for --dynamic-table"),
- cl::aliasopt(DynamicTable));
-
- // --needed-libs
- cl::opt<bool> NeededLibraries("needed-libs",
- cl::desc("Display the needed libraries"));
-
- // --program-headers, --segments, -l
- cl::opt<bool> ProgramHeaders("program-headers",
- cl::desc("Display ELF program headers"));
- cl::alias ProgramHeadersShort("l", cl::desc("Alias for --program-headers"),
- cl::aliasopt(ProgramHeaders), cl::NotHidden);
- cl::alias SegmentsAlias("segments", cl::desc("Alias for --program-headers"),
- cl::aliasopt(ProgramHeaders));
-
- // --string-dump, -p
- cl::list<std::string> StringDump(
- "string-dump", cl::value_desc("number|name"),
- cl::desc("Display the specified section(s) as a list of strings"),
- cl::ZeroOrMore);
- cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"),
- cl::aliasopt(StringDump), cl::Prefix);
-
- // --hex-dump, -x
- cl::list<std::string>
- HexDump("hex-dump", cl::value_desc("number|name"),
- cl::desc("Display the specified section(s) as hexadecimal bytes"),
- cl::ZeroOrMore);
- cl::alias HexDumpShort("x", cl::desc("Alias for --hex-dump"),
- cl::aliasopt(HexDump), cl::Prefix);
-
- // --demangle, -C
- cl::opt<bool> Demangle("demangle",
- cl::desc("Demangle symbol names in output"));
- cl::alias DemangleShort("C", cl::desc("Alias for --demangle"),
- cl::aliasopt(Demangle), cl::NotHidden);
-
- // --hash-table
- cl::opt<bool> HashTable("hash-table",
- cl::desc("Display ELF hash table"));
-
- // --gnu-hash-table
- cl::opt<bool> GnuHashTable("gnu-hash-table",
- cl::desc("Display ELF .gnu.hash section"));
-
- // --expand-relocs
- cl::opt<bool> ExpandRelocs("expand-relocs",
- cl::desc("Expand each shown relocation to multiple lines"));
-
- // --raw-relr
- cl::opt<bool> RawRelr("raw-relr",
- cl::desc("Do not decode relocations in SHT_RELR section, display raw contents"));
-
- // --codeview
- cl::opt<bool> CodeView("codeview",
- cl::desc("Display CodeView debug information"));
-
- // --codeview-merged-types
- cl::opt<bool>
- CodeViewMergedTypes("codeview-merged-types",
- cl::desc("Display the merged CodeView type stream"));
-
- // --codeview-ghash
- cl::opt<bool> CodeViewEnableGHash(
- "codeview-ghash",
- cl::desc(
- "Enable global hashing for CodeView type stream de-duplication"));
-
- // --codeview-subsection-bytes
- cl::opt<bool> CodeViewSubsectionBytes(
- "codeview-subsection-bytes",
- cl::desc("Dump raw contents of codeview debug sections and records"));
-
- // --arch-specific
- cl::opt<bool> ArchSpecificInfo("arch-specific",
- cl::desc("Displays architecture-specific information, if there is any."));
- cl::alias ArchSpecifcInfoShort("A", cl::desc("Alias for --arch-specific"),
- cl::aliasopt(ArchSpecificInfo), cl::NotHidden);
-
- // --coff-imports
- cl::opt<bool>
- COFFImports("coff-imports", cl::desc("Display the PE/COFF import table"));
-
- // --coff-exports
- cl::opt<bool>
- COFFExports("coff-exports", cl::desc("Display the PE/COFF export table"));
-
- // --coff-directives
- cl::opt<bool>
- COFFDirectives("coff-directives",
- cl::desc("Display the PE/COFF .drectve section"));
-
- // --coff-basereloc
- cl::opt<bool>
- COFFBaseRelocs("coff-basereloc",
- cl::desc("Display the PE/COFF .reloc section"));
-
- // --coff-debug-directory
- cl::opt<bool>
- COFFDebugDirectory("coff-debug-directory",
- cl::desc("Display the PE/COFF debug directory"));
-
- // --coff-tls-directory
- cl::opt<bool> COFFTLSDirectory("coff-tls-directory",
- cl::desc("Display the PE/COFF TLS directory"));
-
- // --coff-resources
- cl::opt<bool> COFFResources("coff-resources",
- cl::desc("Display the PE/COFF .rsrc section"));
-
- // --coff-load-config
- cl::opt<bool>
- COFFLoadConfig("coff-load-config",
- cl::desc("Display the PE/COFF load config"));
-
- // --elf-linker-options
- cl::opt<bool>
- ELFLinkerOptions("elf-linker-options",
- cl::desc("Display the ELF .linker-options section"));
-
- // --macho-data-in-code
- cl::opt<bool>
- MachODataInCode("macho-data-in-code",
- cl::desc("Display MachO Data in Code command"));
-
- // --macho-indirect-symbols
- cl::opt<bool>
- MachOIndirectSymbols("macho-indirect-symbols",
- cl::desc("Display MachO indirect symbols"));
-
- // --macho-linker-options
- cl::opt<bool>
- MachOLinkerOptions("macho-linker-options",
- cl::desc("Display MachO linker options"));
-
- // --macho-segment
- cl::opt<bool>
- MachOSegment("macho-segment",
- cl::desc("Display MachO Segment command"));
-
- // --macho-version-min
- cl::opt<bool>
- MachOVersionMin("macho-version-min",
- cl::desc("Display MachO version min command"));
-
- // --macho-dysymtab
- cl::opt<bool>
- MachODysymtab("macho-dysymtab",
- cl::desc("Display MachO Dysymtab command"));
-
- // --stackmap
- cl::opt<bool>
- PrintStackMap("stackmap",
- cl::desc("Display contents of stackmap section"));
-
- // --stack-sizes
- cl::opt<bool>
- PrintStackSizes("stack-sizes",
- cl::desc("Display contents of all stack sizes sections"));
-
- // --version-info, -V
- cl::opt<bool>
- VersionInfo("version-info",
- cl::desc("Display ELF version sections (if present)"));
- cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"),
- cl::aliasopt(VersionInfo));
-
- // --elf-section-groups, --section-groups, -g
- cl::opt<bool> SectionGroups("elf-section-groups",
- cl::desc("Display ELF section group contents"));
- cl::alias SectionGroupsAlias("section-groups",
- cl::desc("Alias for -elf-sections-groups"),
- cl::aliasopt(SectionGroups));
- cl::alias SectionGroupsShort("g", cl::desc("Alias for -elf-sections-groups"),
- cl::aliasopt(SectionGroups));
-
- // --elf-hash-histogram, --histogram, -I
- cl::opt<bool> HashHistogram(
- "elf-hash-histogram",
- cl::desc("Display bucket list histogram for hash sections"));
- cl::alias HashHistogramShort("I", cl::desc("Alias for -elf-hash-histogram"),
- cl::aliasopt(HashHistogram));
- cl::alias HistogramAlias("histogram",
- cl::desc("Alias for --elf-hash-histogram"),
- cl::aliasopt(HashHistogram));
-
- // --cg-profile
- cl::opt<bool> CGProfile("cg-profile",
- cl::desc("Display callgraph profile section"));
- cl::alias ELFCGProfile("elf-cg-profile", cl::desc("Alias for --cg-profile"),
- cl::aliasopt(CGProfile));
-
- // -addrsig
- cl::opt<bool> Addrsig("addrsig",
- cl::desc("Display address-significance table"));
-
- // -elf-output-style
- cl::opt<OutputStyleTy>
- Output("elf-output-style", cl::desc("Specify ELF dump style"),
- cl::values(clEnumVal(LLVM, "LLVM default style"),
- clEnumVal(GNU, "GNU readelf style")),
- cl::init(LLVM));
-
- cl::extrahelp
- HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
+static bool Addrsig;
+static bool All;
+static bool ArchSpecificInfo;
+static bool BBAddrMap;
+bool ExpandRelocs;
+static bool CGProfile;
+bool Demangle;
+static bool DependentLibraries;
+static bool DynRelocs;
+static bool DynamicSymbols;
+static bool FileHeaders;
+static bool Headers;
+static std::vector<std::string> HexDump;
+static bool PrintStackMap;
+static bool PrintStackSizes;
+static bool Relocations;
+bool SectionData;
+static bool SectionDetails;
+static bool SectionHeaders;
+bool SectionRelocations;
+bool SectionSymbols;
+static std::vector<std::string> StringDump;
+static bool StringTable;
+static bool Symbols;
+static bool UnwindInfo;
+static cl::boolOrDefault SectionMapping;
+
+// ELF specific options.
+static bool DynamicTable;
+static bool ELFLinkerOptions;
+static bool GnuHashTable;
+static bool HashSymbols;
+static bool HashTable;
+static bool HashHistogram;
+static bool NeededLibraries;
+static bool Notes;
+static bool ProgramHeaders;
+bool RawRelr;
+static bool SectionGroups;
+static bool VersionInfo;
+
+// Mach-O specific options.
+static bool MachODataInCode;
+static bool MachODysymtab;
+static bool MachOIndirectSymbols;
+static bool MachOLinkerOptions;
+static bool MachOSegment;
+static bool MachOVersionMin;
+
+// PE/COFF specific options.
+static bool CodeView;
+static bool CodeViewEnableGHash;
+static bool CodeViewMergedTypes;
+bool CodeViewSubsectionBytes;
+static bool COFFBaseRelocs;
+static bool COFFDebugDirectory;
+static bool COFFDirectives;
+static bool COFFExports;
+static bool COFFImports;
+static bool COFFLoadConfig;
+static bool COFFResources;
+static bool COFFTLSDirectory;
+
+OutputStyleTy Output = OutputStyleTy::LLVM;
+static std::vector<std::string> InputFilenames;
} // namespace opts
static StringRef ToolName;
@@ -419,6 +190,87 @@ void reportWarning(Error Err, StringRef Input) {
} // namespace llvm
+static void parseOptions(const opt::InputArgList &Args) {
+ opts::Addrsig = Args.hasArg(OPT_addrsig);
+ opts::All = Args.hasArg(OPT_all);
+ opts::ArchSpecificInfo = Args.hasArg(OPT_arch_specific);
+ opts::BBAddrMap = Args.hasArg(OPT_bb_addr_map);
+ opts::CGProfile = Args.hasArg(OPT_cg_profile);
+ opts::Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
+ opts::DependentLibraries = Args.hasArg(OPT_dependent_libraries);
+ opts::DynRelocs = Args.hasArg(OPT_dyn_relocations);
+ opts::DynamicSymbols = Args.hasArg(OPT_dyn_syms);
+ opts::ExpandRelocs = Args.hasArg(OPT_expand_relocs);
+ opts::FileHeaders = Args.hasArg(OPT_file_header);
+ opts::Headers = Args.hasArg(OPT_headers);
+ opts::HexDump = Args.getAllArgValues(OPT_hex_dump_EQ);
+ opts::Relocations = Args.hasArg(OPT_relocs);
+ opts::SectionData = Args.hasArg(OPT_section_data);
+ opts::SectionDetails = Args.hasArg(OPT_section_details);
+ opts::SectionHeaders = Args.hasArg(OPT_section_headers);
+ opts::SectionRelocations = Args.hasArg(OPT_section_relocations);
+ opts::SectionSymbols = Args.hasArg(OPT_section_symbols);
+ if (Args.hasArg(OPT_section_mapping))
+ opts::SectionMapping = cl::BOU_TRUE;
+ else if (Args.hasArg(OPT_section_mapping_EQ_false))
+ opts::SectionMapping = cl::BOU_FALSE;
+ else
+ opts::SectionMapping = cl::BOU_UNSET;
+ opts::PrintStackSizes = Args.hasArg(OPT_stack_sizes);
+ opts::PrintStackMap = Args.hasArg(OPT_stackmap);
+ opts::StringDump = Args.getAllArgValues(OPT_string_dump_EQ);
+ opts::StringTable = Args.hasArg(OPT_string_table);
+ opts::Symbols = Args.hasArg(OPT_symbols);
+ opts::UnwindInfo = Args.hasArg(OPT_unwind);
+
+ // ELF specific options.
+ opts::DynamicTable = Args.hasArg(OPT_dynamic_table);
+ opts::ELFLinkerOptions = Args.hasArg(OPT_elf_linker_options);
+ if (Arg *A = Args.getLastArg(OPT_elf_output_style_EQ)) {
+ StringRef V(A->getValue());
+ if (V == "LLVM")
+ opts::Output = opts::OutputStyleTy::LLVM;
+ else if (V == "GNU")
+ opts::Output = opts::OutputStyleTy::GNU;
+ else
+ error("--elf-output-style value should be either 'LLVM' or 'GNU'");
+ }
+ opts::GnuHashTable = Args.hasArg(OPT_gnu_hash_table);
+ opts::HashSymbols = Args.hasArg(OPT_hash_symbols);
+ opts::HashTable = Args.hasArg(OPT_hash_table);
+ opts::HashHistogram = Args.hasArg(OPT_histogram);
+ opts::NeededLibraries = Args.hasArg(OPT_needed_libs);
+ opts::Notes = Args.hasArg(OPT_notes);
+ opts::ProgramHeaders = Args.hasArg(OPT_program_headers);
+ opts::RawRelr = Args.hasArg(OPT_raw_relr);
+ opts::SectionGroups = Args.hasArg(OPT_section_groups);
+ opts::VersionInfo = Args.hasArg(OPT_version_info);
+
+ // Mach-O specific options.
+ opts::MachODataInCode = Args.hasArg(OPT_macho_data_in_code);
+ opts::MachODysymtab = Args.hasArg(OPT_macho_dysymtab);
+ opts::MachOIndirectSymbols = Args.hasArg(OPT_macho_indirect_symbols);
+ opts::MachOLinkerOptions = Args.hasArg(OPT_macho_linker_options);
+ opts::MachOSegment = Args.hasArg(OPT_macho_segment);
+ opts::MachOVersionMin = Args.hasArg(OPT_macho_version_min);
+
+ // PE/COFF specific options.
+ opts::CodeView = Args.hasArg(OPT_codeview);
+ opts::CodeViewEnableGHash = Args.hasArg(OPT_codeview_ghash);
+ opts::CodeViewMergedTypes = Args.hasArg(OPT_codeview_merged_types);
+ opts::CodeViewSubsectionBytes = Args.hasArg(OPT_codeview_subsection_bytes);
+ opts::COFFBaseRelocs = Args.hasArg(OPT_coff_basereloc);
+ opts::COFFDebugDirectory = Args.hasArg(OPT_coff_debug_directory);
+ opts::COFFDirectives = Args.hasArg(OPT_coff_directives);
+ opts::COFFExports = Args.hasArg(OPT_coff_exports);
+ opts::COFFImports = Args.hasArg(OPT_coff_imports);
+ opts::COFFLoadConfig = Args.hasArg(OPT_coff_load_config);
+ opts::COFFResources = Args.hasArg(OPT_coff_resources);
+ opts::COFFTLSDirectory = Args.hasArg(OPT_coff_tls_directory);
+
+ opts::InputFilenames = Args.getAllArgValues(OPT_INPUT);
+}
+
namespace {
struct ReadObjTypeTableBuilder {
ReadObjTypeTableBuilder()
@@ -529,6 +381,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printGnuHashTable();
if (opts::VersionInfo)
Dumper->printVersionInfo();
+ if (opts::StringTable)
+ Dumper->printStringTable();
if (Obj.isELF()) {
if (opts::DependentLibraries)
Dumper->printDependentLibs();
@@ -542,6 +396,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printHashHistograms();
if (opts::CGProfile)
Dumper->printCGProfile();
+ if (opts::BBAddrMap)
+ Dumper->printBBAddrMaps();
if (opts::Addrsig)
Dumper->printAddrsig();
if (opts::Notes)
@@ -646,93 +502,73 @@ static void dumpWindowsResourceFile(WindowsResource *WinRes,
/// Opens \a File and dumps it.
static void dumpInput(StringRef File, ScopedPrinter &Writer) {
- // Attempt to open the binary.
- Expected<OwningBinary<Binary>> BinaryOrErr =
- createBinary(File, /*Context=*/nullptr, /*InitContent=*/false);
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFileOrSTDIN(File, /*IsText=*/false,
+ /*RequiresNullTerminator=*/false);
+ if (std::error_code EC = FileOrErr.getError())
+ return reportError(errorCodeToError(EC), File);
+
+ std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
+ file_magic Type = identify_magic(Buffer->getBuffer());
+ if (Type == file_magic::bitcode) {
+ reportWarning(createStringError(errc::invalid_argument,
+ "bitcode files are not supported"),
+ File);
+ return;
+ }
+
+ Expected<std::unique_ptr<Binary>> BinaryOrErr = createBinary(
+ Buffer->getMemBufferRef(), /*Context=*/nullptr, /*InitContent=*/false);
if (!BinaryOrErr)
reportError(BinaryOrErr.takeError(), File);
- Binary &Binary = *BinaryOrErr.get().getBinary();
- if (Archive *Arc = dyn_cast<Archive>(&Binary))
+ std::unique_ptr<Binary> Bin = std::move(*BinaryOrErr);
+ if (Archive *Arc = dyn_cast<Archive>(Bin.get()))
dumpArchive(Arc, Writer);
else if (MachOUniversalBinary *UBinary =
- dyn_cast<MachOUniversalBinary>(&Binary))
+ dyn_cast<MachOUniversalBinary>(Bin.get()))
dumpMachOUniversalBinary(UBinary, Writer);
- else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
+ else if (ObjectFile *Obj = dyn_cast<ObjectFile>(Bin.get()))
dumpObject(*Obj, Writer);
- else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary))
+ else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(Bin.get()))
dumpCOFFImportFile(Import, Writer);
- else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(&Binary))
+ else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(Bin.get()))
dumpWindowsResourceFile(WinRes, Writer);
else
llvm_unreachable("unrecognized file type");
- CVTypes.Binaries.push_back(std::move(*BinaryOrErr));
-}
-
-/// Registers aliases that should only be allowed by readobj.
-static void registerReadobjAliases() {
- // -s has meant --sections for a very long time in llvm-readobj despite
- // meaning --symbols in readelf.
- static cl::alias SectionsShort("s", cl::desc("Alias for --section-headers"),
- cl::aliasopt(opts::SectionHeaders),
- cl::NotHidden);
-
- // llvm-readelf reserves it for --section-details.
- static cl::alias SymbolsShort("t", cl::desc("Alias for --symbols"),
- cl::aliasopt(opts::Symbols), cl::NotHidden);
-
- // The following two-letter aliases are only provided for readobj, as readelf
- // allows single-letter args to be grouped together.
- static cl::alias SectionRelocationsShort(
- "sr", cl::desc("Alias for --section-relocations"),
- cl::aliasopt(opts::SectionRelocations));
- static cl::alias SectionDataShort("sd", cl::desc("Alias for --section-data"),
- cl::aliasopt(opts::SectionData));
- static cl::alias SectionSymbolsShort("st",
- cl::desc("Alias for --section-symbols"),
- cl::aliasopt(opts::SectionSymbols));
- static cl::alias DynamicSymbolsShort("dt",
- cl::desc("Alias for --dyn-symbols"),
- cl::aliasopt(opts::DynamicSymbols));
-}
-
-/// Registers aliases that should only be allowed by readelf.
-static void registerReadelfAliases() {
- // -s is here because for readobj it means --sections.
- static cl::alias SymbolsShort("s", cl::desc("Alias for --symbols"),
- cl::aliasopt(opts::Symbols), cl::NotHidden,
- cl::Grouping);
-
- // -t is here because for readobj it is an alias for --symbols.
- static cl::alias SectionDetailsShort(
- "t", cl::desc("Alias for --section-details"),
- cl::aliasopt(opts::SectionDetails), cl::NotHidden);
-
- // Allow all single letter flags to be grouped together.
- for (auto &OptEntry : cl::getRegisteredOptions()) {
- StringRef ArgName = OptEntry.getKey();
- cl::Option *Option = OptEntry.getValue();
- if (ArgName.size() == 1)
- apply(Option, cl::Grouping);
- }
+ CVTypes.Binaries.push_back(
+ OwningBinary<Binary>(std::move(Bin), std::move(Buffer)));
}
-int main(int argc, const char *argv[]) {
+int main(int argc, char *argv[]) {
InitLLVM X(argc, argv);
+ BumpPtrAllocator A;
+ StringSaver Saver(A);
+ ReadobjOptTable Tbl;
ToolName = argv[0];
-
- // Register the target printer for --version.
- cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
-
- if (sys::path::stem(argv[0]).contains("readelf")) {
- opts::Output = opts::GNU;
- registerReadelfAliases();
- } else {
- registerReadobjAliases();
+ opt::InputArgList Args =
+ Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
+ error(Msg);
+ exit(1);
+ });
+ if (Args.hasArg(OPT_help)) {
+ Tbl.printHelp(
+ outs(),
+ (Twine(ToolName) + " [options] <input object files>").str().c_str(),
+ "LLVM Object Reader");
+ // TODO Replace this with OptTable API once it adds extrahelp support.
+ outs() << "\nPass @FILE as argument to read options from FILE.\n";
+ return 0;
+ }
+ if (Args.hasArg(OPT_version)) {
+ cl::PrintVersionMessage();
+ return 0;
}
- cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n");
+ if (sys::path::stem(argv[0]).contains("readelf"))
+ opts::Output = opts::GNU;
+ parseOptions(Args);
// Default to print error if no filename is specified.
if (opts::InputFilenames.empty()) {