[llvm] 1035123 - [llvm-objdump] Switch command-line parsing from llvm::cl to OptTable
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 14 17:12:39 PDT 2021
Author: Nico Weber
Date: 2021-04-14T20:12:24-04:00
New Revision: 1035123ac50db21bb2f44f78c040a823d7d064b2
URL: https://github.com/llvm/llvm-project/commit/1035123ac50db21bb2f44f78c040a823d7d064b2
DIFF: https://github.com/llvm/llvm-project/commit/1035123ac50db21bb2f44f78c040a823d7d064b2.diff
LOG: [llvm-objdump] Switch command-line parsing from llvm::cl to OptTable
This is similar to D83530, but for llvm-objdump.
The motivation is the desire to add an `llvm-otool` symlink to
llvm-objdump that behaves like macOS's `otool`, using the same
technique the at llvm-objcopy uses to behave like `strip` (etc).
This change for the most part preserves behavior. In some cases,
it increases compatibility with GNU objdump a bit. For example,
the long options now require two dashes, and the long options
taking arguments for the most part now require a `=` in front
of the value. Exceptions are flags where tests passed the
value separately, for these the separate form is kept as
an alias to the = form.
The one-letter short form args are now joined or separate
and long longer accept a =, which also matches GNU objdump.
cl::opt<>s in libraries now have to be explicitly plumbed
through. This patch does that for --x86-asm-syntax=, but
there's hope that we can remove that again.
Differential Revision: https://reviews.llvm.org/D100433
Added:
llvm/tools/llvm-objdump/ObjdumpOptID.h
llvm/tools/llvm-objdump/ObjdumpOpts.td
Modified:
llvm/test/Support/check-default-options.txt
llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test
llvm/test/tools/llvm-objdump/help.test
llvm/test/tools/llvm-objdump/section-filter.test
llvm/tools/llvm-objdump/CMakeLists.txt
llvm/tools/llvm-objdump/MachODump.cpp
llvm/tools/llvm-objdump/MachODump.h
llvm/tools/llvm-objdump/llvm-objdump.cpp
llvm/tools/llvm-objdump/llvm-objdump.h
llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn
Removed:
################################################################################
diff --git a/llvm/test/Support/check-default-options.txt b/llvm/test/Support/check-default-options.txt
index 352471ed9ef2..46246e06210c 100644
--- a/llvm/test/Support/check-default-options.txt
+++ b/llvm/test/Support/check-default-options.txt
@@ -1,9 +1,7 @@
-# RUN: llvm-objdump --help-hidden %t | FileCheck --check-prefix=CHECK-OBJDUMP %s
# RUN: llvm-readobj --help-hidden %t | FileCheck --check-prefix=CHECK-READOBJ %s
# RUN: llvm-tblgen --help-hidden %t | FileCheck --check-prefix=CHECK-TBLGEN %s
# RUN: llvm-opt-report --help-hidden %t | FileCheck --check-prefix=CHECK-OPT-RPT %s
-# CHECK-OBJDUMP: -h - Alias for --section-headers
# CHECK-READOBJ: -h - Alias for --file-headers
# CHECK-TBLGEN: -h - Alias for --help
# CHECK-OPT-RPT: -h - Alias for --help
diff --git a/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test
index c2fc95ed4f02..e26db49e6d22 100644
--- a/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test
+++ b/llvm/test/tools/llvm-objdump/X86/source-interleave-prefix.test
@@ -83,7 +83,7 @@
; RUN: not llvm-objdump --prefix %p --prefix-strip '-1' --source %t-missing-prefix.o 2>&1 | \
; RUN: FileCheck %s --check-prefix=CHECK-INVALID-PREFIX-STRIP -DOPTION='-1'
-; CHECK-INVALID-PREFIX-STRIP: llvm-objdump{{.*}}: for the --prefix-strip option: '[[OPTION]]' value invalid for uint argument!
+; CHECK-INVALID-PREFIX-STRIP: {{.*}}llvm-objdump{{.*}}: error: --prefix-strip: expected a non-negative integer, but got '[[OPTION]]'
;; Test text value --prefix-strip. Reports an error.
diff --git a/llvm/test/tools/llvm-objdump/help.test b/llvm/test/tools/llvm-objdump/help.test
index 940eea3293af..ae0bf81e040f 100644
--- a/llvm/test/tools/llvm-objdump/help.test
+++ b/llvm/test/tools/llvm-objdump/help.test
@@ -1,6 +1,14 @@
RUN: llvm-objdump --help | FileCheck %s
+RUN: llvm-objdump --help-hidden | FileCheck --check-prefix=HIDDEN %s
CHECK: OVERVIEW: llvm object file dumper
CHECK: USAGE: llvm-objdump{{(.exe)?}} [options] <input object files>{{$}}
-CHECK: OPTIONS:
+CHECK: Generic Options:
+CHECK-NOT: {{ -w }}
CHECK: @FILE
+
+HIDDEN: OVERVIEW: llvm object file dumper
+HIDDEN: USAGE: llvm-objdump{{(.exe)?}} [options] <input object files>{{$}}
+HIDDEN: Generic Options:
+HIDDEN: {{ -w }}
+HIDDEN: @FILE
diff --git a/llvm/test/tools/llvm-objdump/section-filter.test b/llvm/test/tools/llvm-objdump/section-filter.test
index 77506320c20f..6b5c2bcf747a 100644
--- a/llvm/test/tools/llvm-objdump/section-filter.test
+++ b/llvm/test/tools/llvm-objdump/section-filter.test
@@ -2,7 +2,7 @@
## We test the LMA here too, because the code at the time of writing uses the
## value of --section when looking up section LMAs.
# RUN: yaml2obj %s --docnum=1 -o %t.h.elf
-# RUN: llvm-objdump -h %t.h.elf -j=.text --section=.bss \
+# RUN: llvm-objdump -h %t.h.elf -j.text --section=.bss \
# RUN: | FileCheck %s --check-prefix=SHDRS --implicit-check-not=.data --implicit-check-not=.text2
# SHDRS: Name Size VMA LMA
@@ -92,10 +92,9 @@ Sections:
Content: '666f6f626172' # "foobar"
## Test that the -j alias can be used flexibly. Create a baseline and ensure
-## all other combinations are identical.
+## all other combinations compatible with POSIX are identical.
# RUN: llvm-objdump %t.h.elf -h -s --section .symtab > %t.full
# RUN: llvm-objdump %t.h.elf -h -s -j .symtab > %t.1
-# RUN: llvm-objdump %t.h.elf -h -s -j=.symtab > %t.2
# RUN: llvm-objdump %t.h.elf -h -s -j.symtab > %t.3
# RUN: llvm-objdump %t.h.elf -hsj .symtab > %t.4
# RUN: llvm-objdump %t.h.elf -hsj=.symtab > %t.5
diff --git a/llvm/tools/llvm-objdump/CMakeLists.txt b/llvm/tools/llvm-objdump/CMakeLists.txt
index a8546fd77236..5a0c855b37cd 100644
--- a/llvm/tools/llvm-objdump/CMakeLists.txt
+++ b/llvm/tools/llvm-objdump/CMakeLists.txt
@@ -9,10 +9,15 @@ set(LLVM_LINK_COMPONENTS
MC
MCDisassembler
Object
+ Option
Support
Symbolize
)
+set(LLVM_TARGET_DEFINITIONS ObjdumpOpts.td)
+tablegen(LLVM ObjdumpOpts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(ObjdumpOptsTableGen)
+
add_llvm_tool(llvm-objdump
llvm-objdump.cpp
COFFDump.cpp
@@ -20,6 +25,8 @@ add_llvm_tool(llvm-objdump
MachODump.cpp
WasmDump.cpp
XCOFFDump.cpp
+ DEPENDS
+ ObjdumpOptsTableGen
)
if(HAVE_LIBXAR)
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 11d22a9cfb3d..fadb2999d209 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -12,6 +12,7 @@
#include "MachODump.h"
+#include "ObjdumpOptID.h"
#include "llvm-objdump.h"
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/STLExtras.h"
@@ -34,8 +35,8 @@
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Option/ArgList.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Format.h"
@@ -62,131 +63,61 @@ using namespace llvm;
using namespace llvm::object;
using namespace llvm::objdump;
-cl::OptionCategory objdump::MachOCat("llvm-objdump MachO Specific Options");
-
-cl::opt<bool> objdump::FirstPrivateHeader(
- "private-header",
- cl::desc("Display only the first format specific file header"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::ExportsTrie("exports-trie",
- cl::desc("Display mach-o exported symbols"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::Rebase("rebase",
- cl::desc("Display mach-o rebasing info"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::Bind("bind", cl::desc("Display mach-o binding info"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::LazyBind("lazy-bind",
- cl::desc("Display mach-o lazy binding info"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::WeakBind("weak-bind",
- cl::desc("Display mach-o weak binding info"),
- cl::cat(MachOCat));
-
-static cl::opt<bool>
- UseDbg("g", cl::Grouping,
- cl::desc("Print line information from debug info if available"),
- cl::cat(MachOCat));
-
-static cl::opt<std::string> DSYMFile("dsym",
- cl::desc("Use .dSYM file for debug info"),
- cl::cat(MachOCat));
-
-static cl::opt<bool> FullLeadingAddr("full-leading-addr",
- cl::desc("Print full leading address"),
- cl::cat(MachOCat));
-
-static cl::opt<bool> NoLeadingHeaders("no-leading-headers",
- cl::desc("Print no leading headers"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::UniversalHeaders(
- "universal-headers",
- cl::desc("Print Mach-O universal headers (requires --macho)"),
- cl::cat(MachOCat));
-
-static cl::opt<bool> ArchiveMemberOffsets(
- "archive-member-offsets",
- cl::desc("Print the offset to each archive member for Mach-O archives "
- "(requires --macho and --archive-headers)"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::IndirectSymbols(
- "indirect-symbols",
- cl::desc(
- "Print indirect symbol table for Mach-O objects (requires --macho)"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::DataInCode(
- "data-in-code",
- cl::desc(
- "Print the data in code table for Mach-O objects (requires --macho)"),
- cl::cat(MachOCat));
-
-cl::opt<bool>
- objdump::FunctionStarts("function-starts",
- cl::desc("Print the function starts table for "
- "Mach-O objects (requires --macho)"),
- cl::cat(MachOCat));
-
-cl::opt<bool>
- objdump::LinkOptHints("link-opt-hints",
- cl::desc("Print the linker optimization hints for "
- "Mach-O objects (requires --macho)"),
- cl::cat(MachOCat));
-
-cl::opt<bool>
- objdump::InfoPlist("info-plist",
- cl::desc("Print the info plist section as strings for "
- "Mach-O objects (requires --macho)"),
- cl::cat(MachOCat));
-
-cl::opt<bool>
- objdump::DylibsUsed("dylibs-used",
- cl::desc("Print the shared libraries used for linked "
- "Mach-O files (requires --macho)"),
- cl::cat(MachOCat));
-
-cl::opt<bool> objdump::DylibId("dylib-id",
- cl::desc("Print the shared library's id for the "
- "dylib Mach-O file (requires --macho)"),
- cl::cat(MachOCat));
-
-static cl::opt<bool>
- NonVerbose("non-verbose",
- cl::desc("Print the info for Mach-O objects in non-verbose or "
- "numeric form (requires --macho)"),
- cl::cat(MachOCat));
-
-cl::opt<bool>
- objdump::ObjcMetaData("objc-meta-data",
- cl::desc("Print the Objective-C runtime meta data "
- "for Mach-O files (requires --macho)"),
- cl::cat(MachOCat));
-
-static cl::opt<std::string> DisSymName(
- "dis-symname",
- cl::desc("disassemble just this symbol's instructions (requires --macho)"),
- cl::cat(MachOCat));
-
-static cl::opt<bool> NoSymbolicOperands(
- "no-symbolic-operands",
- cl::desc("do not symbolic operands when disassembling (requires --macho)"),
- cl::cat(MachOCat));
-
-static cl::list<std::string>
- ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
- cl::ZeroOrMore, cl::cat(MachOCat));
+bool objdump::FirstPrivateHeader;
+bool objdump::ExportsTrie;
+bool objdump::Rebase;
+bool objdump::Bind;
+bool objdump::LazyBind;
+bool objdump::WeakBind;
+static bool UseDbg;
+static std::string DSYMFile;
+static bool FullLeadingAddr;
+static bool NoLeadingHeaders;
+bool objdump::UniversalHeaders;
+static bool ArchiveMemberOffsets;
+bool objdump::IndirectSymbols;
+bool objdump::DataInCode;
+bool objdump::FunctionStarts;
+bool objdump::LinkOptHints;
+bool objdump::InfoPlist;
+bool objdump::DylibsUsed;
+bool objdump::DylibId;
+static bool NonVerbose;
+bool objdump::ObjcMetaData;
+static std::string DisSymName;
+static bool NoSymbolicOperands;
+static std::vector<std::string> ArchFlags;
static bool ArchAll = false;
-
static std::string ThumbTripleName;
+void objdump::parseMachOOptions(const llvm::opt::InputArgList &InputArgs) {
+ FirstPrivateHeader = InputArgs.hasArg(OBJDUMP_private_header);
+ ExportsTrie = InputArgs.hasArg(OBJDUMP_exports_trie);
+ Rebase = InputArgs.hasArg(OBJDUMP_rebase);
+ Bind = InputArgs.hasArg(OBJDUMP_bind);
+ LazyBind = InputArgs.hasArg(OBJDUMP_lazy_bind);
+ WeakBind = InputArgs.hasArg(OBJDUMP_weak_bind);
+ UseDbg = InputArgs.hasArg(OBJDUMP_g);
+ DSYMFile = InputArgs.getLastArgValue(OBJDUMP_dsym_EQ).str();
+ FullLeadingAddr = InputArgs.hasArg(OBJDUMP_full_leading_addr);
+ NoLeadingHeaders = InputArgs.hasArg(OBJDUMP_no_leading_headers);
+ UniversalHeaders = InputArgs.hasArg(OBJDUMP_universal_headers);
+ ArchiveMemberOffsets = InputArgs.hasArg(OBJDUMP_archive_member_offsets);
+ IndirectSymbols = InputArgs.hasArg(OBJDUMP_indirect_symbols);
+ DataInCode = InputArgs.hasArg(OBJDUMP_data_in_code);
+ FunctionStarts = InputArgs.hasArg(OBJDUMP_function_starts);
+ LinkOptHints = InputArgs.hasArg(OBJDUMP_link_opt_hints);
+ InfoPlist = InputArgs.hasArg(OBJDUMP_info_plist);
+ DylibsUsed = InputArgs.hasArg(OBJDUMP_dylibs_used);
+ DylibId = InputArgs.hasArg(OBJDUMP_dylib_id);
+ NonVerbose = InputArgs.hasArg(OBJDUMP_non_verbose);
+ ObjcMetaData = InputArgs.hasArg(OBJDUMP_objc_meta_data);
+ DisSymName = InputArgs.getLastArgValue(OBJDUMP_dis_symname).str();
+ NoSymbolicOperands = InputArgs.hasArg(OBJDUMP_no_symbolic_operands);
+ ArchFlags = InputArgs.getAllArgValues(OBJDUMP_arch_EQ);
+}
+
static const Target *GetTarget(const MachOObjectFile *MachOObj,
const char **McpuDefault,
const Target **ThumbTarget) {
diff --git a/llvm/tools/llvm-objdump/MachODump.h b/llvm/tools/llvm-objdump/MachODump.h
index a4cc7de0860c..447749a23e59 100644
--- a/llvm/tools/llvm-objdump/MachODump.h
+++ b/llvm/tools/llvm-objdump/MachODump.h
@@ -24,25 +24,31 @@ class ObjectFile;
class RelocationRef;
} // namespace object
+namespace opt {
+class InputArgList;
+} // namespace opt
+
namespace objdump {
+void parseMachOOptions(const llvm::opt::InputArgList &InputArgs);
+
// MachO specific options
extern cl::OptionCategory MachOCat;
-extern cl::opt<bool> Bind;
-extern cl::opt<bool> DataInCode;
-extern cl::opt<bool> DylibsUsed;
-extern cl::opt<bool> DylibId;
-extern cl::opt<bool> ExportsTrie;
-extern cl::opt<bool> FirstPrivateHeader;
-extern cl::opt<bool> FunctionStarts;
-extern cl::opt<bool> IndirectSymbols;
-extern cl::opt<bool> InfoPlist;
-extern cl::opt<bool> LazyBind;
-extern cl::opt<bool> LinkOptHints;
-extern cl::opt<bool> ObjcMetaData;
-extern cl::opt<bool> Rebase;
-extern cl::opt<bool> UniversalHeaders;
-extern cl::opt<bool> WeakBind;
+extern bool Bind;
+extern bool DataInCode;
+extern bool DylibsUsed;
+extern bool DylibId;
+extern bool ExportsTrie;
+extern bool FirstPrivateHeader;
+extern bool FunctionStarts;
+extern bool IndirectSymbols;
+extern bool InfoPlist;
+extern bool LazyBind;
+extern bool LinkOptHints;
+extern bool ObjcMetaData;
+extern bool Rebase;
+extern bool UniversalHeaders;
+extern bool WeakBind;
Error getMachORelocationValueString(const object::MachOObjectFile *Obj,
const object::RelocationRef &RelRef,
diff --git a/llvm/tools/llvm-objdump/ObjdumpOptID.h b/llvm/tools/llvm-objdump/ObjdumpOptID.h
new file mode 100644
index 000000000000..2c17f441a033
--- /dev/null
+++ b/llvm/tools/llvm-objdump/ObjdumpOptID.h
@@ -0,0 +1,13 @@
+#ifndef LLVM_TOOLS_LLVM_OBJDUMP_OBJDUMP_OPT_ID_H
+#define LLVM_TOOLS_LLVM_OBJDUMP_OBJDUMP_OPT_ID_H
+
+enum ID {
+ OBJDUMP_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OBJDUMP_##ID,
+#include "ObjdumpOpts.inc"
+#undef OPTION
+};
+
+#endif // LLVM_TOOLS_LLVM_OBJDUMP_OBJDUMP_OPT_ID_H
diff --git a/llvm/tools/llvm-objdump/ObjdumpOpts.td b/llvm/tools/llvm-objdump/ObjdumpOpts.td
new file mode 100644
index 000000000000..dfcb25938022
--- /dev/null
+++ b/llvm/tools/llvm-objdump/ObjdumpOpts.td
@@ -0,0 +1,398 @@
+include "llvm/Option/OptParser.td"
+
+def grp_generic : OptionGroup<"kind">, HelpText<"Generic Options">;
+
+def help : Flag<["--"], "help">,
+ HelpText<"Display available options (--help-hidden for more)">,
+ Group<grp_generic>;
+
+def help_hidden : Flag<["--"], "help-hidden">,
+ Flags<[HelpHidden]>,
+ HelpText<"Display all available options">,
+ Group<grp_generic>;
+
+def version : Flag<["--"], "version">,
+ HelpText<"Display the version of this program">,
+ Group<grp_generic>;
+
+
+
+def grp_objdump : OptionGroup<"objdump">, HelpText<"llvm-objdump Options">;
+
+def adjust_vma_EQ : Joined<["--"], "adjust-vma=">,
+ MetaVarName<"offset">,
+ HelpText<"Increase the displayed address by the specified offset">,
+ Group<grp_objdump>;
+
+def all_headers : Flag<["--"], "all-headers">,
+ HelpText<"Display all available header information">,
+ Group<grp_objdump>;
+def : Flag<["-"], "x">, Alias<all_headers>, HelpText<"Alias for --all-headers">,
+ Group<grp_objdump>;
+
+def arch_name_EQ : Joined<["--"], "arch-name=">,
+ HelpText<"Target arch to disassemble for, "
+ "see --version for available targets">,
+ Group<grp_objdump>;
+
+def archive_headers : Flag<["--"], "archive-headers">,
+ HelpText<"Display archive header information">,
+ Group<grp_objdump>;
+def : Flag<["-"], "a">, Alias<all_headers>,
+ HelpText<"Alias for --archive-headers">,
+ Group<grp_objdump>;
+
+def demangle : Flag<["--"], "demangle">, HelpText<"Demangle symbol names">,
+ Group<grp_objdump>;
+def : Flag<["-"], "C">, Alias<demangle>, HelpText<"Alias for --demangle">,
+ Group<grp_objdump>;
+
+def disassemble : Flag<["--"], "disassemble">,
+ HelpText<"Display assembler mnemonics for the machine instructions">,
+ Group<grp_objdump>;
+def : Flag<["-"], "d">, Alias<disassemble>, HelpText<"Alias for --disassemble">,
+ Group<grp_objdump>;
+
+def disassemble_all : Flag<["--"], "disassemble-all">,
+ HelpText<"Display assembler mnemonics for the machine instructions">,
+ Group<grp_objdump>;
+def : Flag<["-"], "D">, Alias<disassemble_all>,
+ HelpText<"Alias for --disassemble-all">,
+ Group<grp_objdump>;
+
+def symbol_description : Flag<["--"], "symbol-description">,
+ HelpText<"Add symbol description for disassembly. This "
+ "option is for XCOFF files only.">,
+ Group<grp_objdump>;
+
+def disassemble_symbols_EQ : Joined<["--"], "disassemble-symbols=">,
+ HelpText<"List of symbols to disassemble. "
+ "Accept demangled names when --demangle is "
+ "specified, otherwise accept mangled names">,
+ Group<grp_objdump>;
+
+def disassemble_zeroes : Flag<["--"], "disassemble-zeroes">,
+ HelpText<"Do not skip blocks of zeroes when disassembling">,
+ Group<grp_objdump>;
+def : Flag<["-"], "z">, Alias<disassemble_zeroes>,
+ HelpText<"Alias for --disassemble-zeroes">,
+ Group<grp_objdump>;
+
+def disassembler_options_EQ : Joined<["--"], "disassembler-options=">,
+ MetaVarName<"options">,
+ HelpText<"Pass target specific disassembler options">,
+ Group<grp_objdump>;
+def : JoinedOrSeparate<["-"], "M">, Alias<disassembler_options_EQ>,
+ HelpText<"Alias for --disassembler-options=">,
+ Group<grp_objdump>;
+
+def dynamic_reloc : Flag<["--"], "dynamic-reloc">,
+ HelpText<"Display the dynamic relocation entries in the file">,
+ Group<grp_objdump>;
+def : Flag<["-"], "R">, Alias<dynamic_reloc>,
+ HelpText<"Alias for --dynamic-reloc">,
+ Group<grp_objdump>;
+
+def dwarf_EQ : Joined<["--"], "dwarf=">,
+ HelpText<"Dump of dwarf debug sections">, Values<"frames">,
+ Group<grp_objdump>;
+
+def fault_map_section : Flag<["--"], "fault-map-section">,
+ HelpText<"Display contents of faultmap section">,
+ Group<grp_objdump>;
+
+def file_headers : Flag<["--"], "file-headers">,
+ HelpText<"Display the contents of the overall file header">,
+ Group<grp_objdump>;
+def : Flag<["-"], "f">, Alias<file_headers>,
+ HelpText<"Alias for --file-headers">,
+ Group<grp_objdump>;
+
+def full_contents : Flag<["--"], "full-contents">,
+ HelpText<"Display the content of each section">,
+ Group<grp_objdump>;
+def : Flag<["-"], "s">, Alias<full_contents>,
+ HelpText<"Alias for --full-contents">,
+ Group<grp_objdump>;
+
+def line_numbers : Flag<["--"], "line-numbers">,
+ HelpText<"Display source line numbers with "
+ "disassembly. Implies disassemble object">,
+ Group<grp_objdump>;
+def : Flag<["-"], "l">, Alias<line_numbers>,
+ HelpText<"Alias for --line-numbers">,
+ Group<grp_objdump>;
+
+def macho : Flag<["--"], "macho">,
+ HelpText<"Use MachO specific object file parser">,
+ Group<grp_objdump>;
+def : Flag<["-"], "m">, Alias<macho>, HelpText<"Alias for --macho">,
+ Group<grp_objdump>;
+
+def mcpu_EQ : Joined<["--"], "mcpu=">,
+ MetaVarName<"cpu-name">,
+ HelpText<"Target a specific cpu type (--mcpu=help for details)">,
+ Group<grp_objdump>;
+
+def mattr_EQ : Joined<["--"], "mattr=">,
+ MetaVarName<"a1,+a2,-a3,...">,
+ HelpText<"Target specific attributes (--mattr=help for details)">,
+ Group<grp_objdump>;
+
+def no_show_raw_insn : Flag<["--"], "no-show-raw-insn">,
+ HelpText<"When disassembling instructions, "
+ "do not print the instruction bytes.">,
+ Group<grp_objdump>;
+
+def no_leading_addr : Flag<["--"], "no-leading-addr">,
+ HelpText<"Print no leading address">,
+ Group<grp_objdump>;
+
+def raw_clang_ast : Flag<["--"], "raw-clang-ast">,
+ HelpText<"Dump the raw binary contents of the clang AST section">,
+ Group<grp_objdump>;
+
+def reloc : Flag<["--"], "reloc">,
+ HelpText<"Display the relocation entries in the file">,
+ Group<grp_objdump>;
+def : Flag<["-"], "r">, Alias<reloc>, HelpText<"Alias for --reloc">,
+ Group<grp_objdump>;
+
+def print_imm_hex : Flag<["--"], "print-imm-hex">,
+ HelpText<"Use hex format for immediate values">,
+ Group<grp_objdump>;
+
+def no_print_imm_hex : Flag<["--"], "no-print-imm-hex">,
+ HelpText<"Do not use hex format for immediate values (default)">,
+ Group<grp_objdump>;
+def : Flag<["--"], "print-imm-hex=false">, Alias<no_print_imm_hex>,
+ Group<grp_objdump>;
+
+def private_headers : Flag<["--"], "private-headers">,
+ HelpText<"Display format specific file headers">,
+ Group<grp_objdump>;
+def : Flag<["-"], "p">, Alias<private_headers>,
+ HelpText<"Alias for --private-headers">,
+ Group<grp_objdump>;
+
+def section_EQ : Joined<["--"], "section=">,
+ HelpText<"Operate on the specified sections only. "
+ "With --macho dump segment,section">,
+ Group<grp_objdump>;
+def : Separate<["--"], "section">, Alias<section_EQ>,
+ Group<grp_objdump>;
+def : JoinedOrSeparate<["-"], "j">, Alias<section_EQ>,
+ HelpText<"Alias for --section">,
+ Group<grp_objdump>;
+
+def section_headers : Flag<["--"], "section-headers">,
+ HelpText<"Display summaries of the headers for each section.">,
+ Group<grp_objdump>;
+def : Flag<["--"], "headers">, Alias<section_headers>,
+ HelpText<"Alias for --section-headers">,
+ Group<grp_objdump>;
+def : Flag<["-"], "h">, Alias<section_headers>,
+ HelpText<"Alias for --section-headers">,
+ Group<grp_objdump>;
+
+def show_lma : Flag<["--"], "show-lma">,
+ HelpText<"Display LMA column when dumping ELF section headers">,
+ Group<grp_objdump>;
+
+def source : Flag<["--"], "source">,
+ HelpText<"Display source inlined with disassembly. Implies disassemble object">,
+ Group<grp_objdump>;
+def : Flag<["-"], "S">, Alias<source>, HelpText<"Alias for --source">,
+ Group<grp_objdump>;
+
+def start_address_EQ : Joined<["--"], "start-address=">,
+ MetaVarName<"address">,
+ HelpText<"Disassemble beginning at address">,
+ Group<grp_objdump>;
+def stop_address_EQ : Joined<["--"], "stop-address=">,
+ MetaVarName<"address">,
+ HelpText<"Stop disassembly at address">,
+ Group<grp_objdump>;
+
+def syms : Flag<["--"], "syms">,
+ HelpText<"Display the symbol table">,
+ Group<grp_objdump>;
+def : Flag<["-"], "t">, Alias<syms>, HelpText<"Alias for --syms">,
+ Group<grp_objdump>;
+
+def symbolize_operands : Flag<["--"], "symbolize-operands">,
+ HelpText<"Symbolize instruction operands when disassembling">,
+ Group<grp_objdump>;
+
+def dynamic_syms : Flag<["--"], "dynamic-syms">,
+ HelpText<"Display the contents of the dynamic symbol table">,
+ Group<grp_objdump>;
+def : Flag<["-"], "T">, Alias<dynamic_syms>,
+ HelpText<"Alias for --dynamic-syms">,
+ Group<grp_objdump>;
+
+def triple_EQ : Joined<["--"], "triple=">,
+ HelpText<"Target triple to disassemble for, "
+ "see --version for available targets">,
+ Group<grp_objdump>;
+def : Separate<["--"], "triple">,
+ Alias<triple_EQ>,
+ Group<grp_objdump>;
+
+def unwind_info : Flag<["--"], "unwind-info">,
+ HelpText<"Display unwind information">,
+ Group<grp_objdump>;
+def : Flag<["-"], "u">, Alias<unwind_info>,
+ HelpText<"Alias for --unwind-info">,
+ Group<grp_objdump>;
+
+def wide : Flag<["--"], "wide">,
+ HelpText<"Ignored for compatibility with GNU objdump">,
+ Group<grp_objdump>;
+def : Flag<["-"], "w">, Alias<wide>,
+ Group<grp_objdump>;
+
+def prefix : Separate<["--"], "prefix">,
+ HelpText<"Add prefix to absolute paths">,
+ Group<grp_objdump>;
+
+def prefix_strip : Separate<["--"], "prefix-strip">,
+ HelpText<"Strip out initial directories from absolute "
+ "paths. No effect without --prefix">,
+ Group<grp_objdump>;
+
+def debug_vars_EQ : Joined<["--"], "debug-vars=">,
+ Values<"unicode,ascii">,
+ Group<grp_objdump>;
+def : Flag<["--"], "debug-vars">,
+ HelpText<"Print the locations (in registers or memory) of "
+ "source-level variables alongside disassembly">,
+ Alias<debug_vars_EQ>, AliasArgs<["unicode"]>,
+ Group<grp_objdump>;
+
+def debug_vars_indent_EQ : Joined<["--"], "debug-vars-indent=">,
+ HelpText<"Distance to indent the source-level variable display, "
+ "relative to the start of the disassembly">,
+ Group<grp_objdump>;
+
+def x86_asm_syntax_att : Flag<["--"], "x86-asm-syntax=att">,
+ HelpText<"Emit AT&T-style disassembly">,
+ Group<grp_objdump>;
+
+def x86_asm_syntax_intel : Flag<["--"], "x86-asm-syntax=intel">,
+ HelpText<"Emit Intel-style disassembly">,
+ Group<grp_objdump>;
+
+
+
+def grp_mach_o : OptionGroup<"kind">, HelpText<"llvm-objdump MachO Specific Options">;
+
+def private_header : Flag<["--"], "private-header">,
+ HelpText<"Display only the first format specific file header">,
+ Group<grp_mach_o>;
+
+def exports_trie : Flag<["--"], "exports-trie">,
+ HelpText<"Display mach-o exported symbols">,
+ Group<grp_mach_o>;
+
+def rebase : Flag<["--"], "rebase">,
+ HelpText<"Display mach-o rebasing info">,
+ Group<grp_mach_o>;
+
+def bind : Flag<["--"], "bind">,
+ HelpText<"Display mach-o binding info">,
+ Group<grp_mach_o>;
+
+def lazy_bind : Flag<["--"], "lazy-bind">,
+ HelpText<"Display mach-o lazy binding info">,
+ Group<grp_mach_o>;
+
+def weak_bind : Flag<["--"], "weak-bind">,
+ HelpText<"Display mach-o weak binding info">,
+ Group<grp_mach_o>;
+
+def g : Flag<["-"], "g">,
+ HelpText<"Print line information from debug info if available">,
+ Group<grp_mach_o>;
+
+def dsym_EQ : Joined<["--"], "dsym=">,
+ HelpText<"Use .dSYM file for debug info">,
+ Group<grp_mach_o>;
+def : Separate<["--"], "dsym">,
+ Alias<dsym_EQ>,
+ Group<grp_mach_o>;
+
+def full_leading_addr : Flag<["--"], "full-leading-addr">,
+ HelpText<"Print full leading address">,
+ Group<grp_mach_o>;
+
+def no_leading_headers : Flag<["--"], "no-leading-headers">,
+ HelpText<"Print no leading headers">,
+ Group<grp_mach_o>;
+
+def universal_headers : Flag<["--"], "universal-headers">,
+ HelpText<"Print Mach-O universal headers (requires --macho)">,
+ Group<grp_mach_o>;
+
+def archive_member_offsets : Flag<["--"], "archive-member-offsets">,
+ HelpText<"Print the offset to each archive member for Mach-O archives "
+ "(requires --macho and --archive-headers)">,
+ Group<grp_mach_o>;
+
+def indirect_symbols : Flag<["--"], "indirect-symbols">,
+ HelpText<"Print indirect symbol table for Mach-O objects (requires --macho)">,
+ Group<grp_mach_o>;
+
+def data_in_code : Flag<["--"], "data-in-code">,
+ HelpText<"Print the data in code table for Mach-O objects (requires --macho)">,
+ Group<grp_mach_o>;
+
+def function_starts : Flag<["--"], "function-starts">,
+ HelpText<"Print the function starts table for "
+ "Mach-O objects (requires --macho)">,
+ Group<grp_mach_o>;
+
+def link_opt_hints : Flag<["--"], "link-opt-hints">,
+ HelpText<"Print the linker optimization hints for "
+ "Mach-O objects (requires --macho)">,
+ Group<grp_mach_o>;
+
+def info_plist : Flag<["--"], "info-plist">,
+ HelpText<"Print the info plist section as strings for "
+ "Mach-O objects (requires --macho)">,
+ Group<grp_mach_o>;
+
+def dylibs_used : Flag<["--"], "dylibs-used">,
+ HelpText<"Print the shared libraries used for linked "
+ "Mach-O files (requires --macho)">,
+ Group<grp_mach_o>;
+
+def dylib_id : Flag<["--"], "dylib-id">,
+ HelpText<"Print the shared library's id for the "
+ "dylib Mach-O file (requires --macho)">,
+ Group<grp_mach_o>;
+
+def non_verbose : Flag<["--"], "non-verbose">,
+ HelpText<"Print the info for Mach-O objects in non-verbose or "
+ "numeric form (requires --macho)">,
+ Group<grp_mach_o>;
+
+def objc_meta_data : Flag<["--"], "objc-meta-data">,
+ HelpText<"Print the Objective-C runtime meta data "
+ "for Mach-O files (requires --macho)">,
+ Group<grp_mach_o>;
+
+def dis_symname : Separate<["--"], "dis-symname">,
+ HelpText<"disassemble just this symbol's instructions (requires --macho)">,
+ Group<grp_mach_o>;
+
+def no_symbolic_operands : Flag<["--"], "no-symbolic-operands">,
+ HelpText<"do not symbolic operands when disassembling (requires --macho)">,
+ Group<grp_mach_o>;
+
+def arch_EQ : Joined<["--"], "arch=">,
+ HelpText<"architecture(s) from a Mach-O file to dump">,
+ Group<grp_mach_o>;
+def : Separate<["--"], "arch">,
+ Alias<arch_EQ>,
+ Group<grp_mach_o>;
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 13d60f721add..54b9471d1ba3 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -19,13 +19,14 @@
#include "COFFDump.h"
#include "ELFDump.h"
#include "MachODump.h"
+#include "ObjdumpOptID.h"
#include "WasmDump.h"
#include "XCOFFDump.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetOperations.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
@@ -54,8 +55,10 @@
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/Wasm.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/Debug.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
@@ -81,313 +84,96 @@
using namespace llvm;
using namespace llvm::object;
using namespace llvm::objdump;
+using namespace llvm::opt;
+
+namespace {
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "ObjdumpOpts.inc"
+#undef PREFIX
+
+static constexpr opt::OptTable::Info ObjdumpInfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ {PREFIX, NAME, HELPTEXT, \
+ METAVAR, OBJDUMP_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OBJDUMP_##GROUP, \
+ OBJDUMP_##ALIAS, ALIASARGS, VALUES},
+#include "ObjdumpOpts.inc"
+#undef OPTION
+};
+
+class ObjdumpOptTable : public opt::OptTable {
+public:
+ ObjdumpOptTable() : OptTable(ObjdumpInfoTable) {}
+
+ void PrintObjdumpHelp(StringRef Argv0, bool ShowHidden = false) const {
+ Argv0 = sys::path::filename(Argv0);
+ PrintHelp(outs(), (Argv0 + " [options] <input object files>").str().c_str(),
+ "llvm object file dumper", ShowHidden, ShowHidden);
+ // TODO Replace this with OptTable API once it adds extrahelp support.
+ outs() << "\nPass @FILE as argument to read options from FILE.\n";
+ }
+};
+
+} // namespace
#define DEBUG_TYPE "objdump"
-static cl::OptionCategory ObjdumpCat("llvm-objdump Options");
-
-static cl::opt<uint64_t> AdjustVMA(
- "adjust-vma",
- cl::desc("Increase the displayed address by the specified offset"),
- cl::value_desc("offset"), cl::init(0), cl::cat(ObjdumpCat));
-
-static cl::opt<bool>
- AllHeaders("all-headers",
- cl::desc("Display all available header information"),
- cl::cat(ObjdumpCat));
-static cl::alias AllHeadersShort("x", cl::desc("Alias for --all-headers"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(AllHeaders));
-
-static cl::opt<std::string>
- ArchName("arch-name",
- cl::desc("Target arch to disassemble for, "
- "see --version for available targets"),
- cl::cat(ObjdumpCat));
-
-cl::opt<bool>
- objdump::ArchiveHeaders("archive-headers",
- cl::desc("Display archive header information"),
- cl::cat(ObjdumpCat));
-static cl::alias ArchiveHeadersShort("a",
- cl::desc("Alias for --archive-headers"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(ArchiveHeaders));
-
-cl::opt<bool> objdump::Demangle("demangle", cl::desc("Demangle symbols names"),
- cl::init(false), cl::cat(ObjdumpCat));
-static cl::alias DemangleShort("C", cl::desc("Alias for --demangle"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(Demangle));
-
-cl::opt<bool> objdump::Disassemble(
- "disassemble",
- cl::desc("Display assembler mnemonics for the machine instructions"),
- cl::cat(ObjdumpCat));
-static cl::alias DisassembleShort("d", cl::desc("Alias for --disassemble"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(Disassemble));
-
-cl::opt<bool> objdump::DisassembleAll(
- "disassemble-all",
- cl::desc("Display assembler mnemonics for the machine instructions"),
- cl::cat(ObjdumpCat));
-static cl::alias DisassembleAllShort("D",
- cl::desc("Alias for --disassemble-all"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(DisassembleAll));
-
-cl::opt<bool> objdump::SymbolDescription(
- "symbol-description",
- cl::desc("Add symbol description for disassembly. This "
- "option is for XCOFF files only"),
- cl::init(false), cl::cat(ObjdumpCat));
-
-static cl::list<std::string>
- DisassembleSymbols("disassemble-symbols", cl::CommaSeparated,
- cl::desc("List of symbols to disassemble. "
- "Accept demangled names when --demangle is "
- "specified, otherwise accept mangled names"),
- cl::cat(ObjdumpCat));
-
-static cl::opt<bool> DisassembleZeroes(
- "disassemble-zeroes",
- cl::desc("Do not skip blocks of zeroes when disassembling"),
- cl::cat(ObjdumpCat));
-static cl::alias
- DisassembleZeroesShort("z", cl::desc("Alias for --disassemble-zeroes"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(DisassembleZeroes));
-
-static cl::list<std::string>
- DisassemblerOptions("disassembler-options",
- cl::desc("Pass target specific disassembler options"),
- cl::value_desc("options"), cl::CommaSeparated,
- cl::cat(ObjdumpCat));
-static cl::alias
- DisassemblerOptionsShort("M", cl::desc("Alias for --disassembler-options"),
- cl::NotHidden, cl::Grouping, cl::Prefix,
- cl::CommaSeparated,
- cl::aliasopt(DisassemblerOptions));
-
-cl::opt<DIDumpType> objdump::DwarfDumpType(
- "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
- cl::values(clEnumValN(DIDT_DebugFrame, "frames", ".debug_frame")),
- cl::cat(ObjdumpCat));
-
-static cl::opt<bool> DynamicRelocations(
- "dynamic-reloc",
- cl::desc("Display the dynamic relocation entries in the file"),
- cl::cat(ObjdumpCat));
-static cl::alias DynamicRelocationShort("R",
- cl::desc("Alias for --dynamic-reloc"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(DynamicRelocations));
-
-static cl::opt<bool>
- FaultMapSection("fault-map-section",
- cl::desc("Display contents of faultmap section"),
- cl::cat(ObjdumpCat));
-
-static cl::opt<bool>
- FileHeaders("file-headers",
- cl::desc("Display the contents of the overall file header"),
- cl::cat(ObjdumpCat));
-static cl::alias FileHeadersShort("f", cl::desc("Alias for --file-headers"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(FileHeaders));
-
-cl::opt<bool>
- objdump::SectionContents("full-contents",
- cl::desc("Display the content of each section"),
- cl::cat(ObjdumpCat));
-static cl::alias SectionContentsShort("s",
- cl::desc("Alias for --full-contents"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(SectionContents));
-
-static cl::list<std::string> InputFilenames(cl::Positional,
- cl::desc("<input object files>"),
- cl::ZeroOrMore,
- cl::cat(ObjdumpCat));
-
-static cl::opt<bool>
- PrintLines("line-numbers",
- cl::desc("Display source line numbers with "
- "disassembly. Implies disassemble object"),
- cl::cat(ObjdumpCat));
-static cl::alias PrintLinesShort("l", cl::desc("Alias for --line-numbers"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(PrintLines));
-
-static cl::opt<bool> MachOOpt("macho",
- cl::desc("Use MachO specific object file parser"),
- cl::cat(ObjdumpCat));
-static cl::alias MachOm("m", cl::desc("Alias for --macho"), cl::NotHidden,
- cl::Grouping, cl::aliasopt(MachOOpt));
-
-cl::opt<std::string> objdump::MCPU(
- "mcpu", cl::desc("Target a specific cpu type (--mcpu=help for details)"),
- cl::value_desc("cpu-name"), cl::init(""), cl::cat(ObjdumpCat));
-
-cl::list<std::string> objdump::MAttrs(
- "mattr", cl::CommaSeparated,
- cl::desc("Target specific attributes (--mattr=help for details)"),
- cl::value_desc("a1,+a2,-a3,..."), cl::cat(ObjdumpCat));
-
-cl::opt<bool> objdump::NoShowRawInsn(
- "no-show-raw-insn",
- cl::desc(
- "When disassembling instructions, do not print the instruction bytes."),
- cl::cat(ObjdumpCat));
-
-cl::opt<bool> objdump::NoLeadingAddr("no-leading-addr",
- cl::desc("Print no leading address"),
- cl::cat(ObjdumpCat));
-
-static cl::opt<bool> RawClangAST(
- "raw-clang-ast",
- cl::desc("Dump the raw binary contents of the clang AST section"),
- cl::cat(ObjdumpCat));
-
-cl::opt<bool>
- objdump::Relocations("reloc",
- cl::desc("Display the relocation entries in the file"),
- cl::cat(ObjdumpCat));
-static cl::alias RelocationsShort("r", cl::desc("Alias for --reloc"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(Relocations));
-
-cl::opt<bool>
- objdump::PrintImmHex("print-imm-hex",
- cl::desc("Use hex format for immediate values"),
- cl::cat(ObjdumpCat));
-
-cl::opt<bool>
- objdump::PrivateHeaders("private-headers",
- cl::desc("Display format specific file headers"),
- cl::cat(ObjdumpCat));
-static cl::alias PrivateHeadersShort("p",
- cl::desc("Alias for --private-headers"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(PrivateHeaders));
-
-cl::list<std::string>
- objdump::FilterSections("section",
- cl::desc("Operate on the specified sections only. "
- "With --macho dump segment,section"),
- cl::cat(ObjdumpCat));
-static cl::alias FilterSectionsj("j", cl::desc("Alias for --section"),
- cl::NotHidden, cl::Grouping, cl::Prefix,
- cl::aliasopt(FilterSections));
-
-cl::opt<bool> objdump::SectionHeaders(
- "section-headers",
- cl::desc("Display summaries of the headers for each section."),
- cl::cat(ObjdumpCat));
-static cl::alias SectionHeadersShort("headers",
- cl::desc("Alias for --section-headers"),
- cl::NotHidden,
- cl::aliasopt(SectionHeaders));
-static cl::alias SectionHeadersShorter("h",
- cl::desc("Alias for --section-headers"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(SectionHeaders));
-
-static cl::opt<bool>
- ShowLMA("show-lma",
- cl::desc("Display LMA column when dumping ELF section headers"),
- cl::cat(ObjdumpCat));
-
-static cl::opt<bool> PrintSource(
- "source",
- cl::desc(
- "Display source inlined with disassembly. Implies disassemble object"),
- cl::cat(ObjdumpCat));
-static cl::alias PrintSourceShort("S", cl::desc("Alias for --source"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(PrintSource));
-
-static cl::opt<uint64_t>
- StartAddress("start-address", cl::desc("Disassemble beginning at address"),
- cl::value_desc("address"), cl::init(0), cl::cat(ObjdumpCat));
-static cl::opt<uint64_t> StopAddress("stop-address",
- cl::desc("Stop disassembly at address"),
- cl::value_desc("address"),
- cl::init(UINT64_MAX), cl::cat(ObjdumpCat));
-
-cl::opt<bool> objdump::SymbolTable("syms", cl::desc("Display the symbol table"),
- cl::cat(ObjdumpCat));
-static cl::alias SymbolTableShort("t", cl::desc("Alias for --syms"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(SymbolTable));
-
-static cl::opt<bool> SymbolizeOperands(
- "symbolize-operands",
- cl::desc("Symbolize instruction operands when disassembling"),
- cl::cat(ObjdumpCat));
-
-static cl::opt<bool> DynamicSymbolTable(
- "dynamic-syms",
- cl::desc("Display the contents of the dynamic symbol table"),
- cl::cat(ObjdumpCat));
-static cl::alias DynamicSymbolTableShort("T",
- cl::desc("Alias for --dynamic-syms"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(DynamicSymbolTable));
-
-cl::opt<std::string>
- objdump::TripleName("triple",
- cl::desc("Target triple to disassemble for, see "
- "--version for available targets"),
- cl::cat(ObjdumpCat));
-
-cl::opt<bool> objdump::UnwindInfo("unwind-info",
- cl::desc("Display unwind information"),
- cl::cat(ObjdumpCat));
-static cl::alias UnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
- cl::NotHidden, cl::Grouping,
- cl::aliasopt(UnwindInfo));
-
-static cl::opt<bool>
- Wide("wide", cl::desc("Ignored for compatibility with GNU objdump"),
- cl::cat(ObjdumpCat));
-static cl::alias WideShort("w", cl::Grouping, cl::aliasopt(Wide));
-
-cl::opt<std::string> objdump::Prefix("prefix",
- cl::desc("Add prefix to absolute paths"),
- cl::cat(ObjdumpCat));
-
-cl::opt<uint32_t>
- objdump::PrefixStrip("prefix-strip",
- cl::desc("Strip out initial directories from absolute "
- "paths. No effect without --prefix"),
- cl::init(0), cl::cat(ObjdumpCat));
+static uint64_t AdjustVMA;
+static bool AllHeaders;
+static std::string ArchName;
+bool objdump::ArchiveHeaders;
+bool objdump::Demangle;
+bool objdump::Disassemble;
+bool objdump::DisassembleAll;
+bool objdump::SymbolDescription;
+static std::vector<std::string> DisassembleSymbols;
+static bool DisassembleZeroes;
+static std::vector<std::string> DisassemblerOptions;
+DIDumpType objdump::DwarfDumpType;
+static bool DynamicRelocations;
+static bool FaultMapSection;
+static bool FileHeaders;
+bool objdump::SectionContents;
+static std::vector<std::string> InputFilenames;
+static bool PrintLines;
+static bool MachOOpt;
+std::string objdump::MCPU;
+std::vector<std::string> objdump::MAttrs;
+bool objdump::NoShowRawInsn;
+bool objdump::NoLeadingAddr;
+static bool RawClangAST;
+bool objdump::Relocations;
+bool objdump::PrintImmHex;
+bool objdump::PrivateHeaders;
+std::vector<std::string> objdump::FilterSections;
+bool objdump::SectionHeaders;
+static bool ShowLMA;
+static bool PrintSource;
+
+static uint64_t StartAddress;
+static bool HasStartAddressFlag;
+static uint64_t StopAddress = UINT64_MAX;
+static bool HasStopAddressFlag;
+
+bool objdump::SymbolTable;
+static bool SymbolizeOperands;
+static bool DynamicSymbolTable;
+std::string objdump::TripleName;
+bool objdump::UnwindInfo;
+static bool Wide;
+std::string objdump::Prefix;
+uint32_t objdump::PrefixStrip;
enum DebugVarsFormat {
DVDisabled,
DVUnicode,
DVASCII,
};
+static DebugVarsFormat DbgVariables = DVDisabled;
-static cl::opt<DebugVarsFormat> DbgVariables(
- "debug-vars", cl::init(DVDisabled),
- cl::desc("Print the locations (in registers or memory) of "
- "source-level variables alongside disassembly"),
- cl::ValueOptional,
- cl::values(clEnumValN(DVUnicode, "", "unicode"),
- clEnumValN(DVUnicode, "unicode", "unicode"),
- clEnumValN(DVASCII, "ascii", "unicode")),
- cl::cat(ObjdumpCat));
-
-static cl::opt<int>
- DbgIndent("debug-vars-indent", cl::init(40),
- cl::desc("Distance to indent the source-level variable display, "
- "relative to the start of the disassembly"),
- cl::cat(ObjdumpCat));
-
-static cl::extrahelp
- HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
+static int DbgIndent = 40;
static StringSet<> DisasmSymbolSet;
StringSet<> objdump::FoundSectionSet;
@@ -2829,11 +2615,11 @@ static void checkForInvalidStartStopAddress(ObjectFile *Obj,
return;
}
- if (StartAddress.getNumOccurrences() == 0)
+ if (!HasStartAddressFlag)
reportWarning("no section has address less than 0x" +
Twine::utohexstr(Stop) + " specified by --stop-address",
Obj->getFileName());
- else if (StopAddress.getNumOccurrences() == 0)
+ else if (!HasStopAddressFlag)
reportWarning("no section has address greater than or equal to 0x" +
Twine::utohexstr(Start) + " specified by --start-address",
Obj->getFileName());
@@ -2856,7 +2642,7 @@ static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
outs() << ":\tfile format " << O->getFileFormatName().lower() << "\n\n";
}
- if (StartAddress.getNumOccurrences() || StopAddress.getNumOccurrences())
+ if (HasStartAddressFlag || HasStopAddressFlag)
checkForInvalidStartStopAddress(O, StartAddress, StopAddress);
// Note: the order here matches GNU objdump for compatability.
@@ -2976,28 +2762,156 @@ static void dumpInput(StringRef file) {
reportError(errorCodeToError(object_error::invalid_file_type), file);
}
+template <typename T>
+static void parseIntArg(const llvm::opt::InputArgList &InputArgs, int ID,
+ T &Value) {
+ if (const opt::Arg *A = InputArgs.getLastArg(ID)) {
+ StringRef V(A->getValue());
+ if (!llvm::to_integer(V, Value, 0)) {
+ reportCmdLineError(A->getSpelling() +
+ ": expected a non-negative integer, but got '" + V +
+ "'");
+ }
+ }
+}
+
+static std::vector<std::string>
+commaSeparatedValues(const llvm::opt::InputArgList &InputArgs, int ID) {
+ std::vector<std::string> Values;
+ for (StringRef Value : InputArgs.getAllArgValues(ID)) {
+ llvm::SmallVector<StringRef, 2> SplitValues;
+ llvm::SplitString(Value, SplitValues, ",");
+ for (StringRef SplitValue : SplitValues)
+ Values.push_back(SplitValue.str());
+ }
+ return Values;
+}
+
+static void parseOptions(const llvm::opt::InputArgList &InputArgs) {
+ parseIntArg(InputArgs, OBJDUMP_adjust_vma_EQ, AdjustVMA);
+ AllHeaders = InputArgs.hasArg(OBJDUMP_all_headers);
+ ArchName = InputArgs.getLastArgValue(OBJDUMP_arch_name_EQ).str();
+ ArchiveHeaders = InputArgs.hasArg(OBJDUMP_archive_headers);
+ Demangle = InputArgs.hasArg(OBJDUMP_demangle);
+ Disassemble = InputArgs.hasArg(OBJDUMP_disassemble);
+ DisassembleAll = InputArgs.hasArg(OBJDUMP_disassemble_all);
+ SymbolDescription = InputArgs.hasArg(OBJDUMP_symbol_description);
+ DisassembleSymbols =
+ commaSeparatedValues(InputArgs, OBJDUMP_disassemble_symbols_EQ);
+ DisassembleZeroes = InputArgs.hasArg(OBJDUMP_disassemble_zeroes);
+ DisassemblerOptions =
+ commaSeparatedValues(InputArgs, OBJDUMP_disassembler_options_EQ);
+ if (const opt::Arg *A = InputArgs.getLastArg(OBJDUMP_dwarf_EQ)) {
+ DwarfDumpType =
+ StringSwitch<DIDumpType>(A->getValue()).Case("frames", DIDT_DebugFrame);
+ }
+ DynamicRelocations = InputArgs.hasArg(OBJDUMP_dynamic_reloc);
+ FaultMapSection = InputArgs.hasArg(OBJDUMP_fault_map_section);
+ FileHeaders = InputArgs.hasArg(OBJDUMP_file_headers);
+ SectionContents = InputArgs.hasArg(OBJDUMP_full_contents);
+ PrintLines = InputArgs.hasArg(OBJDUMP_line_numbers);
+ InputFilenames = InputArgs.getAllArgValues(OBJDUMP_INPUT);
+ MachOOpt = InputArgs.hasArg(OBJDUMP_macho);
+ MCPU = InputArgs.getLastArgValue(OBJDUMP_mcpu_EQ).str();
+ MAttrs = commaSeparatedValues(InputArgs, OBJDUMP_mattr_EQ);
+ NoShowRawInsn = InputArgs.hasArg(OBJDUMP_no_show_raw_insn);
+ NoLeadingAddr = InputArgs.hasArg(OBJDUMP_no_leading_addr);
+ RawClangAST = InputArgs.hasArg(OBJDUMP_raw_clang_ast);
+ Relocations = InputArgs.hasArg(OBJDUMP_reloc);
+ PrintImmHex =
+ InputArgs.hasFlag(OBJDUMP_print_imm_hex, OBJDUMP_no_print_imm_hex, false);
+ PrivateHeaders = InputArgs.hasArg(OBJDUMP_private_headers);
+ FilterSections = InputArgs.getAllArgValues(OBJDUMP_section_EQ);
+ SectionHeaders = InputArgs.hasArg(OBJDUMP_section_headers);
+ ShowLMA = InputArgs.hasArg(OBJDUMP_show_lma);
+ PrintSource = InputArgs.hasArg(OBJDUMP_source);
+ parseIntArg(InputArgs, OBJDUMP_start_address_EQ, StartAddress);
+ HasStartAddressFlag = InputArgs.hasArg(OBJDUMP_start_address_EQ);
+ parseIntArg(InputArgs, OBJDUMP_stop_address_EQ, StopAddress);
+ HasStopAddressFlag = InputArgs.hasArg(OBJDUMP_stop_address_EQ);
+ SymbolTable = InputArgs.hasArg(OBJDUMP_syms);
+ SymbolizeOperands = InputArgs.hasArg(OBJDUMP_symbolize_operands);
+ DynamicSymbolTable = InputArgs.hasArg(OBJDUMP_dynamic_syms);
+ TripleName = InputArgs.getLastArgValue(OBJDUMP_triple_EQ).str();
+ UnwindInfo = InputArgs.hasArg(OBJDUMP_unwind_info);
+ Wide = InputArgs.hasArg(OBJDUMP_wide);
+ Prefix = InputArgs.getLastArgValue(OBJDUMP_prefix).str();
+ parseIntArg(InputArgs, OBJDUMP_prefix_strip, PrefixStrip);
+ if (const opt::Arg *A = InputArgs.getLastArg(OBJDUMP_debug_vars_EQ)) {
+ DbgVariables = StringSwitch<DebugVarsFormat>(A->getValue())
+ .Case("ascii", DVASCII)
+ .Case("unicode", DVUnicode);
+ }
+ parseIntArg(InputArgs, OBJDUMP_debug_vars_indent_EQ, DbgIndent);
+
+ parseMachOOptions(InputArgs);
+
+ // Handle options that get forwarded to cl::opt<>s in libraries.
+ // FIXME: Depending on https://reviews.llvm.org/D84191#inline-946075 ,
+ // hopefully remove this again.
+ std::vector<const char *> LLVMArgs;
+ LLVMArgs.push_back("llvm-objdump (LLVM option parsing)");
+ if (const opt::Arg *A = InputArgs.getLastArg(OBJDUMP_x86_asm_syntax_att,
+ OBJDUMP_x86_asm_syntax_intel)) {
+ switch (A->getOption().getID()) {
+ case OBJDUMP_x86_asm_syntax_att:
+ LLVMArgs.push_back("--x86-asm-syntax=att");
+ break;
+ case OBJDUMP_x86_asm_syntax_intel:
+ LLVMArgs.push_back("--x86-asm-syntax=intel");
+ break;
+ }
+ }
+ LLVMArgs.push_back(nullptr);
+ llvm::cl::ParseCommandLineOptions(LLVMArgs.size() - 1, LLVMArgs.data());
+}
+
int main(int argc, char **argv) {
using namespace llvm;
InitLLVM X(argc, argv);
- const cl::OptionCategory *OptionFilters[] = {&ObjdumpCat, &MachOCat};
- cl::HideUnrelatedOptions(OptionFilters);
+
+ ToolName = argv[0];
+
+ ObjdumpOptTable T;
+ T.setGroupedShortOptions(true);
+
+ bool HasError = false;
+ BumpPtrAllocator A;
+ StringSaver Saver(A);
+ opt::InputArgList InputArgs =
+ T.parseArgs(argc, argv, OBJDUMP_UNKNOWN, Saver, [&](StringRef Msg) {
+ errs() << "error: " << Msg << '\n';
+ HasError = true;
+ });
+ if (HasError)
+ exit(1);
+
+ if (InputArgs.size() == 0 || InputArgs.hasArg(OBJDUMP_help)) {
+ T.PrintObjdumpHelp(ToolName);
+ return 0;
+ }
+ if (InputArgs.hasArg(OBJDUMP_help_hidden)) {
+ T.PrintObjdumpHelp(ToolName, /*show_hidden=*/true);
+ return 0;
+ }
// Initialize targets and assembly printers/parsers.
InitializeAllTargetInfos();
InitializeAllTargetMCs();
InitializeAllDisassemblers();
- // Register the target printer for --version.
- cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
+ if (InputArgs.hasArg(OBJDUMP_version)) {
+ cl::PrintVersionMessage();
+ outs() << '\n';
+ TargetRegistry::printRegisteredTargetsForVersion(outs());
+ exit(0);
+ }
- cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n", nullptr,
- /*EnvVar=*/nullptr,
- /*LongOptionsUseDoubleDash=*/true);
+ parseOptions(InputArgs);
if (StartAddress >= StopAddress)
reportCmdLineError("start address should be less than stop address");
- ToolName = argv[0];
// Defaults to a.out if no filenames specified.
if (InputFilenames.empty())
@@ -3024,7 +2938,7 @@ int main(int argc, char **argv) {
FirstPrivateHeader || FunctionStarts || IndirectSymbols || InfoPlist ||
LazyBind || LinkOptHints || ObjcMetaData || Rebase ||
UniversalHeaders || WeakBind || !FilterSections.empty()))) {
- cl::PrintHelpMessage();
+ T.PrintObjdumpHelp(ToolName);
return 2;
}
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 884702d11f85..601568d579be 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -13,7 +13,6 @@
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/Object/Archive.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -31,27 +30,27 @@ class RelocationRef;
namespace objdump {
-extern cl::opt<bool> ArchiveHeaders;
-extern cl::opt<bool> Demangle;
-extern cl::opt<bool> Disassemble;
-extern cl::opt<bool> DisassembleAll;
-extern cl::opt<DIDumpType> DwarfDumpType;
-extern cl::list<std::string> FilterSections;
-extern cl::list<std::string> MAttrs;
-extern cl::opt<std::string> MCPU;
-extern cl::opt<bool> NoShowRawInsn;
-extern cl::opt<bool> NoLeadingAddr;
-extern cl::opt<std::string> Prefix;
-extern cl::opt<uint32_t> PrefixStrip;
-extern cl::opt<bool> PrintImmHex;
-extern cl::opt<bool> PrivateHeaders;
-extern cl::opt<bool> Relocations;
-extern cl::opt<bool> SectionHeaders;
-extern cl::opt<bool> SectionContents;
-extern cl::opt<bool> SymbolDescription;
-extern cl::opt<bool> SymbolTable;
-extern cl::opt<std::string> TripleName;
-extern cl::opt<bool> UnwindInfo;
+extern bool ArchiveHeaders;
+extern bool Demangle;
+extern bool Disassemble;
+extern bool DisassembleAll;
+extern DIDumpType DwarfDumpType;
+extern std::vector<std::string> FilterSections;
+extern std::vector<std::string> MAttrs;
+extern std::string MCPU;
+extern bool NoShowRawInsn;
+extern bool NoLeadingAddr;
+extern std::string Prefix;
+extern uint32_t PrefixStrip;
+extern bool PrintImmHex;
+extern bool PrivateHeaders;
+extern bool Relocations;
+extern bool SectionHeaders;
+extern bool SectionContents;
+extern bool SymbolDescription;
+extern bool SymbolTable;
+extern std::string TripleName;
+extern bool UnwindInfo;
extern StringSet<> FoundSectionSet;
diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn
index c8ba176dd34f..bdf650b3a502 100644
--- a/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn
@@ -1,6 +1,12 @@
import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
+tablegen("ObjdumpOpts") {
+ visibility = [ ":llvm-objdump" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
if (llvm_install_binutils_symlinks) {
symlink_or_copy("objdump") {
deps = [ ":llvm-objdump" ]
@@ -19,6 +25,7 @@ group("symlinks") {
executable("llvm-objdump") {
deps = [
+ ":ObjdumpOpts",
"//llvm/include/llvm/Config:config",
"//llvm/lib/CodeGen",
"//llvm/lib/DebugInfo/DWARF",
@@ -28,6 +35,7 @@ executable("llvm-objdump") {
"//llvm/lib/MC",
"//llvm/lib/MC/MCDisassembler",
"//llvm/lib/Object",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
"//llvm/lib/Target:AllTargetsDescs",
"//llvm/lib/Target:AllTargetsDisassemblers",
More information about the llvm-commits
mailing list