1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[llvm-nm] Switch command line parsing from llvm::cl to OptTable

Part of https://lists.llvm.org/pipermail/llvm-dev/2021-July/151622.html
"Binary utilities: switch command line parsing from llvm::cl to OptTable"

Users should generally observe no difference as long as they only use intended
option forms. Behavior changes:

* `-t=d` is removed. Use `-t d` instead.
* `--demangle=0` cannot be used. Omit the option or use `--no-demangle` instead.
* `--help-list` is removed. This is a `cl::` specific option.

Note:

* `-t` diagnostic gets improved.
* This patch avoids cl::opt collision if we decide to support multiplexing for binary utilities
* One-dash long options are still supported.
* The `-s` collision (`-s segment section` for Mach-O) is unfortunate. `-s` means `--print-armap` in GNU nm.
* This patch removes the last `cl::multi_val` use case from the `llvm/lib/Support/CommandLine.cpp` library

`-M` (`--print-armap`), `-U` (`--defined-only`), and `-W` (`--no-weak`)
are now deprecated. They could conflict with future GNU nm options.
(--print-armap has an existing alias -s, so GNU will unlikely add a new one.
--no-weak (not in GNU nm) is rarely used anyway.)

`--just-symbol-name` is now deprecated in favor of
`--format=just-symbols` and `-j`.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D105330
This commit is contained in:
Fangrui Song 2021-07-07 13:34:33 -07:00
parent aec8b8bed1
commit 3586ecfc1a
13 changed files with 295 additions and 249 deletions

View File

@ -130,7 +130,7 @@ OPTIONS
Show all symbols, even those usually suppressed.
.. option:: --defined-only, -U
.. option:: --defined-only
Print only symbols defined in this file.
@ -157,11 +157,7 @@ OPTIONS
Print a summary of command-line options and their meanings.
.. option:: --help-list
Print an uncategorized summary of command-line options and their meanings.
.. option:: --just-symbol-name, -j
.. option:: -j
Print just the symbol names. Alias for `--format=just-symbols``.
@ -181,7 +177,7 @@ OPTIONS
Show symbols in the order encountered.
.. option:: --no-weak, -W
.. option:: --no-weak
Don't print weak symbols.
@ -193,7 +189,7 @@ OPTIONS
Use POSIX.2 output format. Alias for ``--format=posix``.
.. option:: --print-armap, -M
.. option:: --print-armap
Print the archive symbol table, in addition to the symbols.
@ -235,10 +231,6 @@ OPTIONS
Display the version of the :program:`llvm-nm` executable, then exit. Does not
stack with other commands.
.. option:: --without-aliases
Exclude aliases from the output.
.. option:: @<FILE>
Read command-line options from response file `<FILE>`.
@ -267,7 +259,7 @@ MACH-O SPECIFIC OPTIONS
Do not add any symbols from the dyldinfo.
.. option:: -s=<segment section>
.. option:: -s <segment> <section>
Dump only symbols from this segment and section name.

View File

@ -169,6 +169,13 @@ Changes to the LLVM tools
``--section-details`` respectively, to match llvm-readelf.
(`D105055 <https://reviews.llvm.org/D105055>`_)
* The llvm-nm short aliases ``-M`` (``--print-armap``), ``-U``
(``--defined-only``), and ``-W`` (``--no-weak``) are now deprecated.
Use the long form versions instead.
The alias ``--just-symbol-name`` is now deprecated in favor of
``--format=just-symbols`` and ``-j``.
(`D105330 <https://reviews.llvm.org/D105330>`_)
Changes to LLDB
---------------------------------

View File

@ -5,9 +5,9 @@ RUN: | FileCheck %s -check-prefix CHECK-64-OBJ
RUN: llvm-nm --arch=x86_64 %p/Inputs/macho-universal.x86_64.i386 \
RUN: | FileCheck %s -check-prefix CHECK-OBJ-x86_64
RUN: not llvm-nm --arch=armv7m %p/Inputs/macho-universal.x86_64.i386 2>&1 \
RUN: | FileCheck %s -check-prefix CHECK-OBJ-armv7m
RUN: | FileCheck %s --check-prefix=CHECK-OBJ-armv7m --implicit-check-not=error:
RUN: not llvm-nm --arch=foobar %p/Inputs/macho-universal.x86_64.i386 2>&1 \
RUN: | FileCheck %s -check-prefix CHECK-OBJ-foobar
RUN: | FileCheck %s --check-prefix=CHECK-OBJ-foobar --implicit-check-not=error:
RUN: llvm-nm --arch=all %p/Inputs/macho-universal-archive.x86_64.i386 \
RUN: | FileCheck %s -check-prefix CHECK-AR
RUN: llvm-nm --arch=all %p/Inputs/macho-universal64-archive.x86_64.i386 \
@ -31,11 +31,9 @@ CHECK-OBJ-x86_64: 0000000100000000 T __mh_execute_header
CHECK-OBJ-x86_64: 0000000100000f60 T _main
CHECK-OBJ-x86_64: U dyld_stub_binder
CHECK-OBJ-armv7m-NOT: Unknown architecture named
CHECK-OBJ-armv7m: does not contain architecture
CHECK-OBJ-armv7m: error: file: {{.*}} does not contain architecture
CHECK-OBJ-foobar: Unknown architecture named
CHECK-OBJ-foobar: does not contain architecture
CHECK-OBJ-foobar: error: for the --arch option: Unknown architecture named 'foobar'
CHECK-AR: macho-universal-archive.x86_64.i386(hello.o) (for architecture x86_64):
CHECK-AR: 0000000000000068 s EH_frame0

View File

@ -2,7 +2,8 @@
// RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t.o
// RUN: llvm-nm --radix=d %t.o | FileCheck %s
// RUN: llvm-nm --radix=o %t.o | FileCheck --check-prefix=OCTAL %s
// RUN: llvm-nm -t=x %t.o | FileCheck --check-prefix=HEX %s
// RUN: llvm-nm -tx %t.o | FileCheck --check-prefix=HEX %s
// RUN: llvm-nm -t x %t.o | FileCheck --check-prefix=HEX %s
.text
.file "1.c"

View File

@ -3,7 +3,7 @@
# RUN: yaml2obj %s -o %t.o
# RUN: llvm-nm %t.o --format=bsd > %t.formatbsd.txt
# RUN: llvm-nm %t.o -f=bsd > %t.fbsd.txt
# RUN: llvm-nm %t.o -f bsd > %t.fbsd.txt
# RUN: llvm-nm %t.o -B > %t.b.txt
# RUN: llvm-nm %t.o > %t.default.txt

View File

@ -1,6 +1,7 @@
# RUN: yaml2obj %s -o %t.o
# RUN: llvm-nm %t.o --debug-syms --format=sysv | FileCheck %s -DFILE=%t.o --strict-whitespace
# RUN: llvm-nm %t.o --debug-syms -f=sysv | FileCheck %s -DFILE=%t.o --strict-whitespace
# RUN: llvm-nm %t.o --debug-syms -fsysv | FileCheck %s -DFILE=%t.o --strict-whitespace
# RUN: llvm-nm %t.o --debug-syms -f sysv | FileCheck %s -DFILE=%t.o --strict-whitespace
!ELF
FileHeader:

View File

@ -1,3 +1,10 @@
RUN: llvm-nm --help 2>&1 | FileCheck --implicit-check-not="General Options:" %s
CHECK: Generic Options:
CHECK: llvm-nm Options:
RUN: llvm-nm -h 2>&1 | FileCheck --implicit-check-not="General Options:" %s
CHECK: OPTIONS:
CHECK: --debug-syms
CHECK: --demangle
CHECK: --format=<format>
CHECK: llvm-nm Mach-O Specific Options:
CHECK: --arch=<value>
CHECK: -s
CHECK: Pass @FILE {{.*}}

View File

@ -7,7 +7,7 @@
# RUN: llvm-nm --just-symbol-name %t.o | diff %t.txt -
# RUN: llvm-nm --format=just-symbols %t.o | diff %t.txt -
# RUN: llvm-nm --format=sysv -j %t.o | diff %t.txt -
# RUN: llvm-nm -j --format=posix %t.o | diff %t.txt -
# RUN: llvm-nm -j --format=posix %t.o | not diff -q %t.txt %t1.txt
# RUN: FileCheck %s --input-file=%t.txt --implicit-check-not={{.}} --check-prefix=COMMON

View File

@ -4,5 +4,5 @@
RUN: llvm-nm -V | FileCheck %s
RUN: llvm-nm --version | FileCheck %s
CHECK: LLVM version
CHECK: GNU
CHECK: LLVM version

View File

@ -6,14 +6,20 @@ set(LLVM_LINK_COMPONENTS
Core
Demangle
Object
Option
Support
TextAPI
)
set(LLVM_TARGET_DEFINITIONS Opts.td)
tablegen(LLVM Opts.inc -gen-opt-parser-defs)
add_public_tablegen_target(NmOptsTableGen)
add_llvm_tool(llvm-nm
llvm-nm.cpp
DEPENDS
NmOptsTableGen
intrinsics_gen
)

76
tools/llvm-nm/Opts.td Normal file
View File

@ -0,0 +1,76 @@
include "llvm/Option/OptParser.td"
class F<string letter, string help> : Flag<["-"], letter>, HelpText<help>;
class FF<string name, string help> : Flag<["--", "-"], name>, HelpText<help>;
multiclass BB<string name, string help1, string help2> {
def NAME: Flag<["--", "-"], name>, HelpText<help1>;
def no_ # NAME: Flag<["--", "-"], "no-" # name>, HelpText<help2>;
}
multiclass Eq<string name, string help> {
def NAME #_EQ : Joined<["--", "-"], name #"=">,
HelpText<help>;
def : Separate<["--", "-"], name>, Alias<!cast<Joined>(NAME #_EQ)>;
}
def debug_syms : FF<"debug-syms", "Show all symbols, even debugger only">;
def defined_only : FF<"defined-only", "Show only defined symbols">;
defm demangle : BB<"demangle", "Demangle C++ symbol names", "Don't demangle symbol names">;
def dynamic : FF<"dynamic", "Display dynamic symbols instead of normal symbols">;
def extern_only : FF<"extern-only", "Show only external symbols">;
defm format : Eq<"format", "Specify output format: bsd (default), posix, sysv, darwin, just-symbols">, MetaVarName<"<format>">;
def help : FF<"help", "Display this help">;
def no_llvm_bc : FF<"no-llvm-bc", "Disable LLVM bitcode reader">;
def no_sort : FF<"no-sort", "Show symbols in order encountered">;
def no_weak : FF<"no-weak", "Show only non-weak symbols">;
def numeric_sort : FF<"numeric-sort", "Sort symbols by address">;
def print_armap : FF<"print-armap", "Print the archive map">;
def print_file_name : FF<"print-file-name", "Precede each symbol with the object file it came from">;
def print_size : FF<"print-size", "Show symbol size as well as address">;
def quiet : FF<"quiet", "Suppress 'no symbols' diagnostic">;
defm radix : Eq<"radix", "Radix (o/d/x) for printing symbol Values">, MetaVarName<"<radix>">;
def reverse_sort : FF<"reverse-sort", "Sort in reverse order">;
def size_sort : FF<"size-sort", "Sort symbols by size">;
def special_syms : FF<"special-syms", "Do not filter special symbols from the output">;
def undefined_only : FF<"undefined-only", "Show only undefined symbols">;
def version : FF<"version", "Display the version">;
def without_aliases : FF<"without-aliases", "Exclude aliases from output">, Flags<[HelpHidden]>;
// Mach-O specific options.
def grp_mach_o : OptionGroup<"kind">, HelpText<"llvm-nm Mach-O Specific Options">;
def add_dyldinfo : FF<"add-dyldinfo", "Add symbols from the dyldinfo not already in the symbol table">, Group<grp_mach_o>;
def add_inlinedinfo : FF<"add-inlinedinfo", "Add symbols from the inlined libraries, TBD only">, Group<grp_mach_o>;
defm arch : Eq<"arch", "architecture(s) from a Mach-O file to dump">, Group<grp_mach_o>;
def dyldinfo_only : FF<"dyldinfo-only", "Show only symbols from the dyldinfo">, Group<grp_mach_o>;
def no_dyldinfo : FF<"no-dyldinfo", "Don't add any symbols from the dyldinfo">, Group<grp_mach_o>;
def s : F<"s", "Dump only symbols from this segment and section name">, Group<grp_mach_o>;
def x : F<"x", "Print symbol entry in hex">, Group<grp_mach_o>;
def : FF<"just-symbol-name", "Alias for --format=just-symbols">, Alias<format_EQ>, AliasArgs<["just-symbols"]>, Flags<[HelpHidden]>;
def : FF<"portability", "Alias for --format=posix">, Alias<format_EQ>, AliasArgs<["posix"]>;
def : F<"a", "Alias for --debug-syms">, Alias<debug_syms>;
def : F<"A", "Alias for --print-file-name">, Alias<print_file_name>;
def : F<"B", "Alias for --format=bsd">, Alias<format_EQ>, AliasArgs<["bsd"]>;
def : F<"C", "Alias for --demangle">, Alias<demangle>;
def : F<"D", "Alias for --dynamic">, Alias<dynamic>;
def : JoinedOrSeparate<["-"], "f">, HelpText<"Alias for --format">, Alias<format_EQ>, MetaVarName<"<format>">;
def : F<"h", "Alias for --help">, Alias<help>;
def : F<"g", "Alias for --extern-only">, Alias<extern_only>;
def : F<"j", "Alias for --format=just-symbols">, Alias<format_EQ>, AliasArgs<["just-symbols"]>;
def : F<"m", "Alias for --format=darwin">, Alias<format_EQ>, AliasArgs<["darwin"]>;
def : F<"M", "Deprecated alias for --print-armap">, Alias<print_armap>, Flags<[HelpHidden]>;
def : F<"n", "Alias for --numeric-sort">, Alias<numeric_sort>;
def : F<"o", "Alias for --print-file-name">, Alias<print_file_name>;
def : F<"p", "Alias for --no-sort">, Alias<no_sort>;
def : F<"P", "Alias for --format=posix">, Alias<format_EQ>, AliasArgs<["posix"]>;
def : F<"r", "Alias for --reverse-sort">, Alias<reverse_sort>;
def : F<"S", "Alias for --print-size">, Alias<print_size>;
def : JoinedOrSeparate<["-"], "t">, HelpText<"Alias for --radix">, Alias<radix_EQ>, MetaVarName<"<radix>">;
def : F<"u", "Alias for --undefined-only">, Alias<undefined_only>;
def : F<"U", "Deprecated alias for --defined-only">, Alias<defined_only>, Flags<[HelpHidden]>;
def : F<"v", "Alias for --numeric-sort">, Alias<numeric_sort>;
def : F<"V", "Alias for --version">, Alias<version>;
def : F<"W", "Deprecated alias for --no-weak">, Alias<no_weak>, Flags<[HelpHidden]>;

View File

@ -31,6 +31,9 @@
#include "llvm/Object/TapiFile.h"
#include "llvm/Object/TapiUniversal.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
@ -47,200 +50,82 @@ using namespace llvm;
using namespace 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 NmOptTable : public opt::OptTable {
public:
NmOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); }
};
enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };
} // namespace
cl::OptionCategory NMCat("llvm-nm Options");
cl::opt<OutputFormatTy> OutputFormat(
"format", cl::desc("Specify output format"),
cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"),
clEnumVal(posix, "POSIX.2 format"),
clEnumVal(darwin, "Darwin -m format"),
cl::OptionEnumValue{"just-symbols", int(just_symbols),
"just symbol names"}),
cl::init(bsd), cl::cat(NMCat));
cl::alias OutputFormat2("f", cl::desc("Alias for --format"),
cl::aliasopt(OutputFormat), cl::NotHidden);
cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
cl::ZeroOrMore);
cl::opt<bool> UndefinedOnly("undefined-only",
cl::desc("Show only undefined symbols"),
cl::cat(NMCat));
cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"),
cl::aliasopt(UndefinedOnly), cl::Grouping,
cl::NotHidden);
cl::opt<bool> DynamicSyms("dynamic",
cl::desc("Display the dynamic symbols instead "
"of normal symbols."),
cl::cat(NMCat));
cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"),
cl::aliasopt(DynamicSyms), cl::Grouping, cl::NotHidden);
cl::opt<bool> DefinedOnly("defined-only", cl::desc("Show only defined symbols"),
cl::cat(NMCat));
cl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"),
cl::aliasopt(DefinedOnly), cl::Grouping, cl::NotHidden);
cl::opt<bool> ExternalOnly("extern-only",
cl::desc("Show only external symbols"),
cl::ZeroOrMore, cl::cat(NMCat));
cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"),
cl::aliasopt(ExternalOnly), cl::Grouping,
cl::ZeroOrMore, cl::NotHidden);
cl::opt<bool> NoWeakSymbols("no-weak", cl::desc("Show only non-weak symbols"),
cl::cat(NMCat));
cl::alias NoWeakSymbols2("W", cl::desc("Alias for --no-weak"),
cl::aliasopt(NoWeakSymbols), cl::Grouping,
cl::NotHidden);
cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"), cl::Grouping,
cl::cat(NMCat));
cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"),
cl::Grouping, cl::cat(NMCat));
cl::alias Portability("portability", cl::desc("Alias for --format=posix"),
cl::aliasopt(POSIXFormat), cl::NotHidden);
cl::opt<bool> DarwinFormat("m", cl::desc("Alias for --format=darwin"),
cl::Grouping, cl::cat(NMCat), cl::NotHidden);
static cl::list<std::string>
ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
cl::ZeroOrMore, cl::cat(NMCat));
bool ArchAll = false;
cl::opt<bool> PrintFileName(
"print-file-name",
cl::desc("Precede each symbol with the object file it came from"),
cl::cat(NMCat));
cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"),
cl::aliasopt(PrintFileName), cl::Grouping,
cl::NotHidden);
cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"),
cl::aliasopt(PrintFileName), cl::Grouping,
cl::NotHidden);
cl::opt<bool> Quiet("quiet", cl::desc("Suppress 'no symbols' diagnostic"),
cl::cat(NMCat));
cl::opt<bool> DebugSyms("debug-syms",
cl::desc("Show all symbols, even debugger only"),
cl::cat(NMCat));
cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"),
cl::aliasopt(DebugSyms), cl::Grouping, cl::NotHidden);
cl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address"),
cl::cat(NMCat));
cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"),
cl::aliasopt(NumericSort), cl::Grouping, cl::NotHidden);
cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"),
cl::aliasopt(NumericSort), cl::Grouping, cl::NotHidden);
cl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered"),
cl::cat(NMCat));
cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort),
cl::Grouping, cl::NotHidden);
cl::opt<bool> Demangle("demangle", cl::ZeroOrMore,
cl::desc("Demangle C++ symbol names"), cl::cat(NMCat));
cl::alias DemangleC("C", cl::desc("Alias for --demangle"),
cl::aliasopt(Demangle), cl::Grouping, cl::NotHidden);
cl::opt<bool> NoDemangle("no-demangle", cl::init(false), cl::ZeroOrMore,
cl::desc("Don't demangle symbol names"),
cl::cat(NMCat));
cl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order"),
cl::cat(NMCat));
cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"),
cl::aliasopt(ReverseSort), cl::Grouping, cl::NotHidden);
cl::opt<bool> PrintSize("print-size",
cl::desc("Show symbol size as well as address"),
cl::cat(NMCat));
cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"),
cl::aliasopt(PrintSize), cl::Grouping, cl::NotHidden);
bool MachOPrintSizeWarning = false;
cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size"),
cl::cat(NMCat));
cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden,
cl::desc("Exclude aliases from output"),
cl::cat(NMCat), cl::NotHidden);
cl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map"),
cl::cat(NMCat));
cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"),
cl::aliasopt(ArchiveMap), cl::Grouping, cl::NotHidden);
static bool ArchiveMap;
static bool DebugSyms;
static bool DefinedOnly;
static bool Demangle;
static bool DynamicSyms;
static bool ExternalOnly;
static OutputFormatTy OutputFormat;
static bool NoLLVMBitcode;
static bool NoSort;
static bool NoWeakSymbols;
static bool NumericSort;
static bool PrintFileName;
static bool PrintSize;
static bool Quiet;
static bool ReverseSort;
static bool SpecialSyms;
static bool SizeSort;
static bool UndefinedOnly;
static bool WithoutAliases;
namespace {
enum Radix { d, o, x };
cl::opt<Radix>
AddressRadix("radix", cl::desc("Radix (o/d/x) for printing symbol Values"),
cl::values(clEnumVal(d, "decimal"), clEnumVal(o, "octal"),
clEnumVal(x, "hexadecimal")),
cl::init(x), cl::cat(NMCat));
cl::alias RadixAlias("t", cl::desc("Alias for --radix"),
cl::aliasopt(AddressRadix), cl::NotHidden);
} // namespace
static Radix AddressRadix;
cl::opt<bool> JustSymbolName("just-symbol-name",
cl::desc("Alias for --format=just-symbols"),
cl::cat(NMCat), cl::NotHidden);
cl::alias JustSymbolNames("j", cl::desc("Alias for --format-just-symbols"),
cl::aliasopt(JustSymbolName), cl::Grouping,
cl::NotHidden);
// Mach-O specific options.
static bool ArchAll = false;
static std::vector<StringRef> ArchFlags;
static bool AddDyldInfo;
static bool AddInlinedInfo;
static bool DyldInfoOnly;
static bool FormatMachOasHex;
static bool NoDyldInfo;
static std::vector<StringRef> SegSect;
static bool MachOPrintSizeWarning = false;
cl::opt<bool>
SpecialSyms("special-syms",
cl::desc("Do not filter special symbols from the output"),
cl::cat(NMCat));
// Miscellaneous states.
static bool PrintAddress = true;
static bool MultipleFiles = false;
static bool HadError = false;
cl::list<std::string> SegSect("s", cl::multi_val(2), cl::ZeroOrMore,
cl::value_desc("segment section"), cl::Hidden,
cl::desc("Dump only symbols from this segment "
"and section name, Mach-O only"),
cl::cat(NMCat));
cl::opt<bool> FormatMachOasHex("x",
cl::desc("Print symbol entry in hex, "
"Mach-O only"),
cl::Grouping, cl::cat(NMCat));
cl::opt<bool> AddDyldInfo("add-dyldinfo",
cl::desc("Add symbols from the dyldinfo not already "
"in the symbol table, Mach-O only"),
cl::cat(NMCat));
cl::opt<bool> NoDyldInfo("no-dyldinfo",
cl::desc("Don't add any symbols from the dyldinfo, "
"Mach-O only"),
cl::cat(NMCat));
cl::opt<bool> DyldInfoOnly("dyldinfo-only",
cl::desc("Show only symbols from the dyldinfo, "
"Mach-O only"),
cl::cat(NMCat));
cl::opt<bool> NoLLVMBitcode("no-llvm-bc",
cl::desc("Disable LLVM bitcode reader"),
cl::cat(NMCat));
cl::opt<bool> AddInlinedInfo("add-inlinedinfo",
cl::desc("Add symbols from the inlined libraries, "
"TBD(Mach-O) only"),
cl::cat(NMCat));
cl::opt<bool> Version("V", cl::desc("Print version info"), cl::cat(NMCat));
cl::extrahelp HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
bool PrintAddress = true;
bool MultipleFiles = false;
bool HadError = false;
std::string ToolName;
} // anonymous namespace
static StringRef ToolName;
static void error(Twine Message, Twine Path = Twine()) {
HadError = true;
@ -2237,22 +2122,82 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
}
}
static void printExtraVersionInfo(raw_ostream &Outs) {
// This needs to contain the word "GNU", libtool looks for that string.
Outs << "llvm-nm, compatible with GNU nm\n";
}
int main(int argc, char **argv) {
InitLLVM X(argc, argv);
cl::HideUnrelatedOptions(NMCat);
cl::AddExtraVersionPrinter(printExtraVersionInfo);
cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n");
if (Version) {
cl::PrintVersionMessage();
printExtraVersionInfo(outs());
BumpPtrAllocator A;
StringSaver Saver(A);
NmOptTable Tbl;
ToolName = argv[0];
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 symbol table dumper");
// 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)) {
// This needs to contain the word "GNU", libtool looks for that string.
outs() << "llvm-nm, compatible with GNU nm" << '\n';
cl::PrintVersionMessage();
return 0;
}
DebugSyms = Args.hasArg(OPT_debug_syms);
DefinedOnly = Args.hasArg(OPT_defined_only);
Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
DynamicSyms = Args.hasArg(OPT_dynamic);
ExternalOnly = Args.hasArg(OPT_extern_only);
StringRef V = Args.getLastArgValue(OPT_format_EQ, "bsd");
if (V == "bsd")
OutputFormat = bsd;
else if (V == "posix")
OutputFormat = posix;
else if (V == "sysv")
OutputFormat = sysv;
else if (V == "darwin")
OutputFormat = darwin;
else if (V == "just-symbols")
OutputFormat = just_symbols;
else
error("--format value should be one of: bsd, posix, sysv, darwin, "
"just-symbols");
NoLLVMBitcode = Args.hasArg(OPT_no_llvm_bc);
NoSort = Args.hasArg(OPT_no_sort);
NoWeakSymbols = Args.hasArg(OPT_no_weak);
NumericSort = Args.hasArg(OPT_numeric_sort);
ArchiveMap = Args.hasArg(OPT_print_armap);
PrintFileName = Args.hasArg(OPT_print_file_name);
PrintSize = Args.hasArg(OPT_print_size);
ReverseSort = Args.hasArg(OPT_reverse_sort);
Quiet = Args.hasArg(OPT_quiet);
V = Args.getLastArgValue(OPT_radix_EQ, "x");
if (V == "o")
AddressRadix = Radix::o;
else if (V == "d")
AddressRadix = Radix::d;
else if (V == "x")
AddressRadix = Radix::x;
else
error("--radix value should be one of: 'o' (octal), 'd' (decimal), 'x' "
"(hexadecimal)");
SizeSort = Args.hasArg(OPT_size_sort);
SpecialSyms = Args.hasArg(OPT_special_syms);
UndefinedOnly = Args.hasArg(OPT_undefined_only);
WithoutAliases = Args.hasArg(OPT_without_aliases);
// Mach-O specific options.
FormatMachOasHex = Args.hasArg(OPT_x);
AddDyldInfo = Args.hasArg(OPT_add_dyldinfo);
AddInlinedInfo = Args.hasArg(OPT_add_inlinedinfo);
DyldInfoOnly = Args.hasArg(OPT_dyldinfo_only);
NoDyldInfo = Args.hasArg(OPT_no_dyldinfo);
// llvm-nm only reads binary files.
if (error(sys::ChangeStdinToBinary()))
@ -2263,16 +2208,6 @@ int main(int argc, char **argv) {
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
ToolName = argv[0];
if (BSDFormat)
OutputFormat = bsd;
if (POSIXFormat)
OutputFormat = posix;
if (DarwinFormat)
OutputFormat = darwin;
if (JustSymbolName)
OutputFormat = just_symbols;
// The relative order of these is important. If you pass --size-sort it should
// only print out the size. However, if you pass -S --size-sort, it should
// print out both the size and address.
@ -2280,29 +2215,44 @@ int main(int argc, char **argv) {
PrintAddress = false;
if (OutputFormat == sysv || SizeSort)
PrintSize = true;
if (InputFilenames.empty())
InputFilenames.push_back("a.out");
if (InputFilenames.size() > 1)
MultipleFiles = true;
// If both --demangle and --no-demangle are specified then pick the last one.
if (NoDemangle.getPosition() > Demangle.getPosition())
Demangle = !NoDemangle;
for (unsigned i = 0; i < ArchFlags.size(); ++i) {
if (ArchFlags[i] == "all") {
ArchAll = true;
} else {
if (!MachOObjectFile::isValidArch(ArchFlags[i]))
error("Unknown architecture named '" + ArchFlags[i] + "'",
for (const auto *A : Args.filtered(OPT_arch_EQ)) {
SmallVector<StringRef, 2> Values;
llvm::SplitString(A->getValue(), Values, ",");
for (StringRef V : Values) {
if (V == "all")
ArchAll = true;
else if (MachOObjectFile::isValidArch(V))
ArchFlags.push_back(V);
else
error("Unknown architecture named '" + V + "'",
"for the --arch option");
}
}
// Mach-O takes -s to accept two arguments. We emulate this by iterating over
// both OPT_s and OPT_INPUT.
std::vector<std::string> InputFilenames;
int SegSectArgs = 0;
for (opt::Arg *A : Args.filtered(OPT_s, OPT_INPUT)) {
if (SegSectArgs > 0) {
--SegSectArgs;
SegSect.push_back(A->getValue());
} else if (A->getOption().matches(OPT_s)) {
SegSectArgs = 2;
} else {
InputFilenames.push_back(A->getValue());
}
}
if (!SegSect.empty() && SegSect.size() != 2)
error("bad number of arguments (must be two arguments)",
"for the -s option");
if (InputFilenames.empty())
InputFilenames.push_back("a.out");
if (InputFilenames.size() > 1)
MultipleFiles = true;
if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly))
error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only");

View File

@ -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("Opts") {
visibility = [ ":llvm-nm" ]
args = [ "-gen-opt-parser-defs" ]
}
if (llvm_install_binutils_symlinks) {
symlink_or_copy("nm") {
deps = [ ":llvm-nm" ]
@ -19,10 +25,12 @@ group("symlinks") {
executable("llvm-nm") {
deps = [
":Opts",
"//llvm/lib/Bitcode/Reader",
"//llvm/lib/Demangle",
"//llvm/lib/IR",
"//llvm/lib/Object",
"//llvm/lib/Option",
"//llvm/lib/Support",
"//llvm/lib/Target:AllTargetsAsmParsers",
"//llvm/lib/Target:AllTargetsDescs",