diff options
author | Fangrui Song <i@maskray.me> | 2021-07-12 10:14:42 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2021-07-12 10:14:42 -0700 |
commit | 46580d43fc70dcecf21d2cedceeb4910c756fa6e (patch) | |
tree | 6eeae71f07bdd67222f128839876f4f6c399dfa1 /llvm/tools/llvm-readobj/llvm-readobj.cpp | |
parent | fe892114e33b8f98bf3537a0dd6d6798821cb849 (diff) | |
download | llvm-46580d43fc70dcecf21d2cedceeb4910c756fa6e.zip llvm-46580d43fc70dcecf21d2cedceeb4910c756fa6e.tar.gz llvm-46580d43fc70dcecf21d2cedceeb4910c756fa6e.tar.bz2 |
[llvm-readobj] Switch command line parsing from llvm::cl to OptTable
Users should generally observe no difference as long as they don't use
unintended option forms. Behavior changes:
* `-t=d` is removed. Use `-t d` instead.
* `--demangle=false` and `--demangle=0` cannot be used. Omit the option or use `--no-demangle`. Other flag-style options don't have `--no-` forms.
* `--help-list` is removed. This is a `cl::` specific option.
* llvm-readobj now supports grouped short options as well.
* `--color` is removed. This is generally not useful (only apply to errors/warnings) but was inherited from Support.
Some adjustment to the canonical forms
(usually from GNU readelf; currently llvm-readobj has too many redundant aliases):
* --dyn-syms is canonical. --dyn-symbols is a hidden alias
* --file-header is canonical. --file-headers is a hidden alias
* --histogram is canonical. --elf-hash-histogram is a hidden alias
* --relocs is canonical. --relocations is a hidden alias
* --section-groups is canonical. --elf-section-groups is a hidden alias
OptTable avoids global option collision if we decide to support multiplexing for binary utilities.
* Most one-dash long options are still supported. `-dt, -sd, -st, -sr` are dropped due to their conflict with grouped short options.
* `--section-mapping=false` (D57365) is strange but is kept for now.
* Many `cl::opt` variables were unnecessarily external. I added `static` whenever appropriate.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D105532
Diffstat (limited to 'llvm/tools/llvm-readobj/llvm-readobj.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 596 |
1 files changed, 208 insertions, 388 deletions
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index 1608e02..0b49f03 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,356 +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), cl::NotHidden); - - // --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), - cl::NotHidden); - - // --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")); - static cl::alias SectionDetailsShort("t", - cl::desc("Alias for --section-details"), - cl::aliasopt(SectionDetails), - cl::NotHidden); - - // --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)); - static cl::alias SymbolsShort("s", cl::desc("Alias for --symbols"), - cl::aliasopt(Symbols), cl::NotHidden, - cl::Grouping); - - // --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), cl::NotHidden); - - // --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, - cl::NotHidden); - - // --string-table - cl::opt<bool> - StringTable("string-table", - cl::desc("Display the string table (only for XCOFF now)")); - - // --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, cl::NotHidden); - - // --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), cl::NotHidden); - - // --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), cl::NotHidden); - - // --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::NotHidden); - 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)); - - // --bb-addr-map - cl::opt<bool> BBAddrMap("bb-addr-map", - cl::desc("Display the BB address map section")); - - // -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; @@ -436,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() @@ -706,49 +541,34 @@ static void dumpInput(StringRef File, ScopedPrinter &Writer) { OwningBinary<Binary>(std::move(Bin), std::move(Buffer))); } -/// Registers aliases that should only be allowed by readobj. -static void registerReadobjAliases() { - // 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() { - // 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); - } -} - -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()) { |