这里的nm命令指的是GNU Linux版本,Ubuntu20.04,是name的缩写。
nm是一个命令行工具,用来列出object文件、库文件或可执行文件中的符号列表(name list, the symbol table of nlist structures)。
nm命令的输出结果为三列,symbol virtual address,symbol type和symbol name,即符号虚拟地址,类型和名字。
显示内容
举例:
testnm.c
#include <stdio.h>
int value;
static void func()
{
  printf("value is %d.\n", value);
}
int main()
{
  value = 1;
  func();
  return 0;
}
$ gcc -c testnm.c
$ nm  testnm.o
0000000000000000 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 T main
                 U printf
0000000000000004 C value
用一个字符表示类型,如果是小写字符,则是本地符号(local),如果是大写,则是外部符号(external)。类型符号表示的意义如下。
类型字符
含义
Decription
A
全局不可变符号,比如原文件名。
Global absolute symbol.
a
本地不可变符号
Local absolute symbol.
B
全局bss段符号(未初始化的全局或static变量)
Global bss symbol.
b
本地bss段符号
Local bss symbol.
D
全局变量(已初始化的全局或static变量)符号
Global data symbol.
d
本地变量符号
Local data symbol.
T
全局符号,比如全局函数名
Global text symbol.
t
本地符号,比如文件内static函数名
Local text symbol.
U
未定义符号
Undefined symbol.
。。。。。。
用途
这个命令看起来很酷,但只有合理的使用这个命令,这个命令才有存在的意义。那什么时候使用呢?
假设你有一个由许多不同object文件组成的可执行文件。现在假设在编译代码的时候,链接器给出了关于一个未解决的符号'temp'的错误。现在,如果代码规模太大,包括很多头文件,要找到代码中的符号'temp'的位置将成为一场噩梦。在这里,这个工具就起到了拯救作用。通过一些选项的配置,这个工具可以找到该符号所在的文件。
语法:
$ nm [options(s)]  [file(s)]
列出参数[file(s)]的文件中的符号,可以给出多个文件,如果没有指定文件名,则默认文件是a.out。
各个选项的使用:(同一个选项存在短格式和长格式形式则一并列出)
1,列出object文件里的全局(extern)符号,包括函数和变量:
nm -g <path/to/file.o>
nm --extern-only <path/to/file.o>
举例:
$ nm -g testnm.o
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 T main
                 U printf
0000000000000004 C value
$ nm  testnm.o
0000000000000000 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 T main
                 U printf
0000000000000004 C value
2,列出obj文件内的未定义符号:
nm -u <path/to/file.o>
nm --undefined-only <path/to/file.o>
举例:
$ nm -u testnm.o
                 U _GLOBAL_OFFSET_TABLE_
                 U printf
3,列出obj文件中所有的符号,包括debug所使用的符号,否则默认情况下不显示调试用的符号。
nm -a <path/to/file.o>
nm --debug-syms <path/to/file.o>
举例:
$ nm -a testnm.o
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 T main
0000000000000000 r .note.gnu.property
0000000000000000 n .note.GNU-stack
                 U printf
0000000000000000 r .rodata
0000000000000000 a testnm.c
0000000000000000 t .text
0000000000000004 C value
4,列出符号表示,前面显示obj文件名。
$ nm -A <path/to/file.o>
$ nm --print-file-name <path/to/file.o>
这个选项在显示多个多个obj文件的符号时会需要。
举例:
$ nm -A testnm.o
testnm.o:0000000000000000 t func
testnm.o:                 U _GLOBAL_OFFSET_TABLE_
testnm.o:0000000000000024 T main
testnm.o:                 U printf
testnm.o:0000000000000004 C value
5,恢复C++符号的名称改变,使其具有更好可读性:
nm -C <path/to/file.o>
nm --demangle <path/to/file.o>
nm --demangle[=STYLE] <path/to/file.o>
将编译器级的low-level的符号名,转换成用户可理解的名字类型。可以指定obj文件所使用的名称改编风格,有auto(默认), gnu, lucid, arm, hp, edg, gnu-v3, java 和gnat。
注意,这个参数对C语言编译出来的obj文件是无效的,上面的C语言的例子,使用-C选项,输出内容并没有变化。
举例:
testnm.cpp
#include <iostream>
static int value;
static void func(int a, int b)
{
if(a > b){
   std::cout<<"the value is " << value << std::endl;
}
}
int main()
{
  value = 3;
  func(2, 1);
  return 0;
}
$ g++ -c testnm.cpp
$ nm testnm.o
                 U __cxa_atexit
                 U __dso_handle
                 U _GLOBAL_OFFSET_TABLE_
00000000000000cd t _GLOBAL__sub_I_main
0000000000000058 T main
0000000000000080 t _Z41__static_initialization_and_destruction_0ii
0000000000000000 t _ZL4funcii
0000000000000004 b _ZL5value
                 U _ZNSolsEi
                 U _ZNSolsEPFRSoS_E
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
                 U _ZSt4cout
                 U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000000000000 r _ZStL19piecewise_construct
0000000000000000 b _ZStL8__ioinit
                 U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
$ nm --demangle testnm.o
                 U __cxa_atexit
                 U __dso_handle
                 U _GLOBAL_OFFSET_TABLE_
00000000000000cd t _GLOBAL__sub_I_main
0000000000000058 T main
0000000000000080 t __static_initialization_and_destruction_0(int, int)
0000000000000000 t func(int, int)
0000000000000004 b value
                 U std::ostream::operator<<(int)
                 U std::ostream::operator<<(std::ostream& (*)(std::ostream&))
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
                 U std::cout
                 U std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
0000000000000000 r std::piecewise_construct
0000000000000000 b std::__ioinit
                 U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
可以看到上面的例子,除了前面的下划线去掉了,C++的函数名字也变得可读性更好。不同的编译器使用不同的名称改变风格(mangling styles),可以使用上面提到的改变风格的选项来选择一种适合当前编译器。
6,显示动态链接的符号。
nm -D <path/to/file.o>
nm --dynamic <path/to/file.o>
举例:
$ gcc -o testnm testnm.c
$ ldd testnm
    linux-vdso.so.1 (0x00007ffd7dff0000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff2c819a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff2c83a3000)
$ nm -D testnm
                 w __cxa_finalize
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __libc_start_main
                 U printf
$ g++ -o testnmplus testnm.cpp
$ ldd testnmplus
    linux-vdso.so.1 (0x00007ffd82bd0000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff7716a4000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff7714b2000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff771363000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff77189d000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff771348000)
$ nm -D testnmplus
                 U __cxa_atexit
                 w __cxa_finalize
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __libc_start_main
                 U _ZNSolsEi
                 U _ZNSolsEPFRSoS_E
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
0000000000004040 B _ZSt4cout
                 U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
                 U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
这里编出来的obj文件,没有动态链接符号,而编出的可执行文件里才有。
这些动态链接的符号,只有在运行时(run time)才会解析。
7,更改输出内容的格式。
nm -f <FORMAT> <path/to/file.o>
nm --format=FORMAT <path/to/file.o>
可选的输出格式为bsd,sysv或posix,默认是bsd模式。
举例:
$ nm -f posix testnm.o
func t 0 24
_GLOBAL_OFFSET_TABLE_ U         
main T 24 23
printf U         
value C 4 4
$ nm --format posix testnm.o
func t 0 24
_GLOBAL_OFFSET_TABLE_ U         
main T 24 23
printf U         
value C 4 4
$ nm --format=posix testnm.o
func t 0 24
_GLOBAL_OFFSET_TABLE_ U         
main T 24 23
printf U         
value C 4 4
$ nm --format=sysv testnm.o
Symbols from testnm.o:
Name                  Value           Class        Type         Size             Line  Section
func                |0000000000000000|   t  |              FUNC|0000000000000024|     |.text
_GLOBAL_OFFSET_TABLE_|                |   U  |            NOTYPE|                |     |*UND*
main                |0000000000000024|   T  |              FUNC|0000000000000023|     |.text
printf              |                |   U  |            NOTYPE|                |     |*UND*
value               |0000000000000004|   C  |            OBJECT|0000000000000004|     |*COM*
8,使用排序选项。
默认情况下,符号列表根据字母顺序进行排序,但你可以选择根据地址进行排序。
nm -n <path/to/file.o>
nm --numeric-sort <path/to/file.o>
举例:
$ nm  -n  testnm.o
                 U _GLOBAL_OFFSET_TABLE_
                 U printf
0000000000000000 t func
0000000000000004 C value
0000000000000024 T main
默认使用的是字母排序,也可以不使用排序功能。
nm -p <path/to/file.o>
nm --no-sort <path/to/file.o>
举例:
$ nm  -p  testnm.o
0000000000000000 t func
0000000000000004 C value
                 U _GLOBAL_OFFSET_TABLE_
                 U printf
0000000000000024 T main
$ nm  testnm.o
0000000000000000 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 T main
                 U printf
0000000000000004 C value
还可以按照符号占用空间的大小排序。
nm --size-sort <path/to/file.o>
如果想使用相反的顺序,使用-r选项。
nm -r <path/to/file.o>
nm --reverse-sort <path/to/file.o>
举例:
$ nm -n testnm.o
                 U _GLOBAL_OFFSET_TABLE_
                 U printf
0000000000000000 t func
0000000000000004 C value
0000000000000024 T main
$ nm -rn testnm.o
0000000000000024 T main
0000000000000004 C value
0000000000000000 t func
                 U printf
                 U _GLOBAL_OFFSET_TABLE_
9,只显示未定义的符号。
nm -u <path/to/file.o>
nm --undefined-only <path/to/file.o>
举例:
$ nm -u testnm.o
                 U _GLOBAL_OFFSET_TABLE_
                 U printf
如果在一个可执行文件中发现未定义的符号,可能是这个符号存在于动态链接库中(shared libraries)。
10,只显示已定义的符号。
nm --defined-only <path/to/file.o>
举例:
$ nm --defined-only testnm.o
0000000000000000 t func
0000000000000024 T main
0000000000000004 C value
11,显示符号占用空间的大小
nm -S <path/to/file.o>
nm --print-size <path/to/file.o>
举例:
$ nm  testnm.o
0000000000000000 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 T main
                 U printf
0000000000000004 C value
$ nm -S testnm.o
0000000000000000 0000000000000024 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 0000000000000023 T main
                 U printf
0000000000000004 0000000000000004 C value
12,使用文件来指定选项。
nm命令还有一个功能,可以从一个文件里读取命令行的选项。
举例:
$ cat file
-S testnm.o
$ nm @file
0000000000000000 0000000000000024 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 0000000000000023 T main
                 U printf
0000000000000004 0000000000000004 C value
$ nm -S testnm.o
0000000000000000 0000000000000024 t func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 0000000000000023 T main
                 U printf
0000000000000004 0000000000000004 C value
13,使用案例
在当前文件夹的obj文件中,找寻包含func字符串的符号名称。
$ nm  -A ./*.o | grep func
./hello2.o:0000000000000000 T func_1
./hello3.o:0000000000000000 T func_2
./hello4.o:0000000000000000 T func_3
./main.o:                   U func
./reloc.o:                  U func
./reloc.o:0000000000000000  T func1
./test1.o:0000000000000000  T func
./test.o:                   U func
上面介绍的各个功能选项可以组合使用来满足自己的需求。比如:
$ nm -g -S testnm.o
$ nm -gS testnm.o
                 U _GLOBAL_OFFSET_TABLE_
0000000000000024 0000000000000023 T main
                 U printf
0000000000000004 0000000000000004 C value
另外,输出内容里的符号地址,其基数(radix)是可变的,默认是16进制(hexadecimal),使用的参数是:  
-t, --radix=RADIX      // Use RADIX for printing symbol values
备注1:
可以在linux源码中查询到符号列表条目的类型定义nlist结构体:
struct nlist {
union {
     char *n_name;
     struct nlist *n_next;
     long n_strx;
} n_un;
unsigned char n_type;
char n_other;
short n_desc;
unsigned long n_value;
};
备注2:
nm命令的简单help信息:
$ nm --help
Usage: nm [option(s)] [file(s)]
List symbols in [file(s)] (a.out by default).
The options are:
  -a, --debug-syms       Display debugger-only symbols
  -A, --print-file-name  Print name of the input file before every symbol
  -B                     Same as --format=bsd
  -C, --demangle[=STYLE] Decode low-level symbol names into user-level names
                          The STYLE, if specified, can be `auto' (the default),
                          `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'
                          or `gnat'
      --no-demangle      Do not demangle low-level symbol names
      --recurse-limit    Enable a demangling recursion limit.  This is the default.
      --no-recurse-limit Disable a demangling recursion limit.
  -D, --dynamic          Display dynamic symbols instead of normal symbols
      --defined-only     Display only defined symbols
  -e                     (ignored)
  -f, --format=FORMAT    Use the output format FORMAT.  FORMAT can be `bsd',
                           `sysv' or `posix'.  The default is `bsd'
  -g, --extern-only      Display only external symbols
  -l, --line-numbers     Use debugging information to find a filename and
                           line number for each symbol
  -n, --numeric-sort     Sort symbols numerically by address
  -o                     Same as -A
  -p, --no-sort          Do not sort the symbols
  -P, --portability      Same as --format=posix
  -r, --reverse-sort     Reverse the sense of the sort
      --plugin NAME      Load the specified plugin
  -S, --print-size       Print size of defined symbols
  -s, --print-armap      Include index for symbols from archive members
      --size-sort        Sort symbols by size
      --special-syms     Include special symbols in the output
      --synthetic        Display synthetic symbols as well
  -t, --radix=RADIX      Use RADIX for printing symbol values
      --target=BFDNAME   Specify the target object format as BFDNAME
  -u, --undefined-only   Display only undefined symbols
      --with-symbol-versions  Display version strings after symbol names
  -X 32_64               (ignored)
  @FILE                  Read options from FILE
  -h, --help             Display this information
  -V, --version          Display this program's version number
nm: supported targets: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 srec symbolsrec verilog tekhex binary ihex plugin
Report bugs to <http://www.sourceware.org/bugzilla/>.
备注3:
Ubuntu中的manual中关于符号意义的解释:
       •   The symbol type.  At least the following types are used; others are, as well, depending on the object file format.  If lowercase, the symbol is usually local; if uppercase, the symbol is
           global (external).  There are however a few lowercase symbols that are shown for special global symbols ("u", "v" and "w").
           "A" The symbol's value is absolute, and will not be changed by further linking.
           "B"
           "b" The symbol is in the BSS data section.  This section typically contains zero-initialized or uninitialized data, although the exact behavior is system dependent.
           "C" The symbol is common.  Common symbols are uninitialized data.  When linking, multiple common symbols may appear with the same name.  If the symbol is defined anywhere, the common
               symbols are treated as undefined references.
           "D"
           "d" The symbol is in the initialized data section.
           "G"
           "g" The symbol is in an initialized data section for small objects.  Some object file formats permit more efficient access to small data objects, such as a global int variable as opposed
               to a large global array.
           "i" For PE format files this indicates that the symbol is in a section specific to the implementation of DLLs.  For ELF format files this indicates that the symbol is an indirect
               function.  This is a GNU extension to the standard set of ELF symbol types.  It indicates a symbol which if referenced by a relocation does not evaluate to its address, but instead
               must be invoked at runtime.  The runtime execution will then return the value to be used in the relocation.
           "I" The symbol is an indirect reference to another symbol.
           "N" The symbol is a debugging symbol.
           "n" The symbol is in the read-only data section.
           "p" The symbol is in a stack unwind section.
           "R"
           "r" The symbol is in a read only data section.
           "S"
           "s" The symbol is in an uninitialized or zero-initialized data section for small objects.
           "T"
           "t" The symbol is in the text (code) section.
           "U" The symbol is undefined.
           "u" The symbol is a unique global symbol.  This is a GNU extension to the standard set of ELF symbol bindings.  For such a symbol the dynamic linker will make sure that in the entire
               process there is just one symbol with this name and type in use.
           "V"
           "v" The symbol is a weak object.  When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error.  When a weak undefined symbol is
               linked and the symbol is not defined, the value of the weak symbol becomes zero with no error.  On some systems, uppercase indicates that a default value has been specified.
           "W"
           "w" The symbol is a weak symbol that has not been specifically tagged as a weak object symbol.  When a weak defined symbol is linked with a normal defined symbol, the normal defined
               symbol is used with no error.  When a weak undefined symbol is linked and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error.
               On some systems, uppercase indicates that a default value has been specified.
           "-" The symbol is a stabs symbol in an a.out object file.  In this case, the next values printed are the stabs other field, the stabs desc field, and the stab type.  Stabs symbols are
               used to hold debugging information.
           "?" The symbol type is unknown, or object file format specific.
备注4:
在Ubuntu里,使用PC平台的nm命令,也可以解析cross toolchain编译的程序。
$ cat testuart.c
include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY | O_CLOEXEC);
printf("fd is %d.\n", fd);
return 0;
}
使用工具链进行编译:
X86:
$ gcc -o testuartgcc testuart.c
ARM:
$ /opt/poky/SDK220804V0/sysroots/x86_64-pokyXXXsdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++ -o testuartarm testuart.c --sysroot=/opt/poky/SDK220804V0/sysroots/cortexa7t2hf-neon-poky-linux-gnueabi/ -march=armv7ve -marm -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7
MIPS:
$ ~/x2000br/buildroot/buildroot/output/host/usr/bin/mipsel-linux-gcc -o testuartmips testuart.c
得到可执行文件:
$ file testuartgcc
testuartgcc: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7502376cbab0f5ea2a13197d89a126dffdc32876, for GNU/Linux 3.2.0, not stripped
$ file testuartarm
testuartarm: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=aeea22788a340f6862e60c02021fc5718dbb1d12, for GNU/Linux 3.2.0, with debug_info, not stripped
$ file testuartmips
testuartmips: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-mipsn8.so.1, for GNU/Linux 5.4.0, not stripped
$ which nm
/usr/bin/nm
$ ll /usr/bin/nm
lrwxrwxrwx 1 root root 19 10月 20  2021 /usr/bin/nm -> x86_64-linux-gnu-nm*
使用X86平台, mips toolchain和arm toolchain的nm命令分别读取x86程序的符号列表:
ARM不能读,其他两个结果一样。
$ ~/x2000br/buildroot/buildroot/output/host/usr/bin/mipsel-linux-nm -g -n testuartgcc
                 w __cxa_finalize@@GLIBC_2.2.5
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __libc_start_main@@GLIBC_2.2.5
                 U open@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
0000000000001080 T _start
0000000000001169 T main
00000000000011b0 T __libc_csu_init
0000000000001220 T __libc_csu_fini
0000000000001228 T _fini
0000000000002000 R _IO_stdin_used
0000000000004000 D __data_start
0000000000004000 W data_start
0000000000004008 D __dso_handle
0000000000004010 B __bss_start
0000000000004010 D _edata
0000000000004010 D __TMC_END__
0000000000004018 B _end
$ nm -g -n testuartgcc
                 w __cxa_finalize@@GLIBC_2.2.5
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __libc_start_main@@GLIBC_2.2.5
                 U open@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
0000000000001080 T _start
0000000000001169 T main
00000000000011b0 T __libc_csu_init
0000000000001220 T __libc_csu_fini
0000000000001228 T _fini
0000000000002000 R _IO_stdin_used
0000000000004000 D __data_start
0000000000004000 W data_start
0000000000004008 D __dso_handle
0000000000004010 B __bss_start
0000000000004010 D _edata
0000000000004010 D __TMC_END__
0000000000004018 B _end
$ /opt/poky/SDK220804V0/sysroots/x86_64-pokyXXXsdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-nm -g -n testuartgcc
/opt/poky/SDK220804V0/sysroots/x86_64-pokyXXXsdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-nm: testuartgcc: file format not recognized
使用X86平台, mips toolchain和arm toolchain的nm命令分别读取mips程序的符号列表:
都可以读,内容一样。
$ nm -g -n testuartmips
         w __cxa_finalize@GLIBC_2.2
         w __gmon_start__
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         U __libc_start_main@GLIBC_2.34
         U open@GLIBC_2.0
         U printf@GLIBC_2.0
         U __stack_chk_fail@GLIBC_2.4
         U __stack_chk_guard@GLIBC_2.4
000005d0 T _init
00000660 T _ftext
00000660 T __start
00000840 T main
000009b0 T _fini
00000a00 R _IO_stdin_used
00011000 D __data_start
00011000 W data_start
00011000 D _fdata
00011010 D __RLD_MAP
00011074 B __bss_start
00011074 G _edata
00011074 B _fbss
00011090 B _end
$ ~/x2000br/buildroot/buildroot/output/host/usr/bin/mipsel-linux-nm -g -n testuartmips
         w __cxa_finalize@GLIBC_2.2
         w __gmon_start__
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         U __libc_start_main@GLIBC_2.34
         U open@GLIBC_2.0
         U printf@GLIBC_2.0
         U __stack_chk_fail@GLIBC_2.4
         U __stack_chk_guard@GLIBC_2.4
000005d0 T _init
00000660 T _ftext
00000660 T __start
00000840 T main
000009b0 T _fini
00000a00 R _IO_stdin_used
00011000 D __data_start
00011000 W data_start
00011000 D _fdata
00011010 D __RLD_MAP
00011074 B __bss_start
00011074 D _edata
00011074 B _fbss
00011090 B _end
$ /opt/poky/SDK220804V0/sysroots/x86_64-pokyXXXsdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-nm -g -n testuartmips
         w __cxa_finalize@GLIBC_2.2
         w __gmon_start__
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         U __libc_start_main@GLIBC_2.34
         U open@GLIBC_2.0
         U printf@GLIBC_2.0
         U __stack_chk_fail@GLIBC_2.4
         U __stack_chk_guard@GLIBC_2.4
000005d0 T _init
00000660 T _ftext
00000660 T __start
00000840 T main
000009b0 T _fini
00000a00 R _IO_stdin_used
00011000 D __data_start
00011000 W data_start
00011000 D _fdata
00011010 D __RLD_MAP
00011074 B __bss_start
00011074 D _edata
00011074 B _fbss
00011090 B _end
使用X86平台, mips toolchain和arm toolchain的nm命令分别读取arm程序的符号列表:
$ nm -g -n testuartarm
         U abort@@GLIBC_2.4
         U __aeabi_unwind_cpp_pr1@@GCC_3.5
         w __cxa_finalize@@GLIBC_2.4
         w __gmon_start__
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         U __libc_start_main@@GLIBC_2.34
         U open@@GLIBC_2.4
         U printf@@GLIBC_2.4
00000444 T _init
000004ad T _start
000005a8 T main
00000600 T _fini
00000608 R _IO_stdin_used
00011038 D __data_start
00011038 W data_start
0001103c D __dso_handle
00011040 B __bss_start
00011040 B __bss_start__
00011040 D _edata
00011040 D __TMC_END__
00011044 B __bss_end__
00011044 B _bss_end__
00011044 B __end__
00011044 B _end
$ ~/x2000br/buildroot/buildroot/output/host/usr/bin/mipsel-linux-nm -g -n testuartarm
         U abort@@GLIBC_2.4
         U __aeabi_unwind_cpp_pr1@@GCC_3.5
         w __cxa_finalize@@GLIBC_2.4
         w __gmon_start__
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         U __libc_start_main@@GLIBC_2.34
         U open@@GLIBC_2.4
         U printf@@GLIBC_2.4
00000444 T _init
000004ad T _start
000005a8 T main
00000600 T _fini
00000608 R _IO_stdin_used
00011038 D __data_start
00011038 W data_start
0001103c D __dso_handle
00011040 B __bss_start
00011040 B __bss_start__
00011040 D _edata
00011040 D __TMC_END__
00011044 B __bss_end__
00011044 B _bss_end__
00011044 B __end__
00011044 B _end
$ /opt/poky/SDK220804V0/sysroots/x86_64-pokyXXXsdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-nm -g -n testuartarm
         U abort@@GLIBC_2.4
         U __aeabi_unwind_cpp_pr1@@GCC_3.5
         w __cxa_finalize@@GLIBC_2.4
         w __gmon_start__
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
         U __libc_start_main@@GLIBC_2.34
         U open@@GLIBC_2.4
         U printf@@GLIBC_2.4
00000444 T _init
000004ac T _start
000005a8 T main
00000600 T _fini
00000608 R _IO_stdin_used
00011038 D __data_start
00011038 W data_start
0001103c D __dso_handle
00011040 B __bss_start
00011040 B __bss_start__
00011040 D _edata
00011040 D __TMC_END__
00011044 B __bss_end__
00011044 B _bss_end__
00011044 B __end__
00011044 B _end
结论就是,对于nm命令,不一定要使用cross-toolchain的版本,用Ubuntu里自带的nm也一样用,结果一样。如果有问题,再换成toolchain里面的nm命令。
因为nm查询的是符号名称,这部分功能可能和芯片类型关系不大,各个不同的toolchain,编译出来的格式是类似的,大致上是使用的相同的框架来管理符号。
参考:
nm man | Linux Command Library
https://www.howtoforge.com/linux-nm-command/
10 Practical Linux nm Command Examples
IBM Documentation

Linux - nm命令相关推荐

  1. 【Linux】一步一步学Linux——nm命令(250)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 nm命令被用于显示二进制目标文件的符号表. 02. 命令格 ...

  2. Linux nm命令详解

    1.nm命令 nm命令是Linux下自带的强大的文本分析工具,是命令来源于name的简写.该命令用来列出指定文件中的符号(如常用的函数名.变量等,以及这些符号存储的区域).它显示指定文件中的符号信息, ...

  3. linux 下nm命令输出,Linux nm命令介绍

    nm用来列出目标文件的符号清单.下面是nm命令的格式: nm [-a | --debug-syms] [-g | --extern-only] [-B][-C | --demangle] [-D | ...

  4. linux NM 命令使用介绍

    快速使用 nm -Au file | grep XXX -A 每行或者显示全路径名称或者显示对象库名. -u 未定义符号. XXX 你需要查找的变量名或者函数名 nm 用途介绍 nm命令被用于显示二进 ...

  5. linux nm命令_Linux的networkmanager

    [ active(running)表示启动 命令:systemctl status NetworkManager 作用:查看NetworkManager服务是否启动 (注意大小写) NetworkMa ...

  6. Linux nm命令

    一.简介 显示关于对象文件.可执行文件以及对象文件库里的符号信息. 二.选项 http://www.cnblogs.com/wangkangluo1/archive/2012/07/02/257243 ...

  7. linux中的nm命令

    代码在git 是names的缩写, nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等). 下面, 我们一起来看看. linux中的nm命令简介 nm * nm: main.c: ...

  8. Linux 命令(63)—— nm 命令

    1.命令简介 nm 命令是 GNU Binutils 二进制工具集的一员,用于显示目标文件中的符号.如果没有为 nm 命令指明目标文件,则 nm 假定目标文件是 a.out. nm 命令显示的符号类型 ...

  9. nm linux 输出含义,nm 命令输出项解析

    Linux下的nm命令详解 nm命令的输出包含三个部分:1 符号值.默认显示十六进制,也可以指定: 2 符号类型.小写表示是本地符号,大写表示全局符号(external); 3 符号名称. 给个例子: ...

最新文章

  1. Java实现文件分割和文件合并实例
  2. 产生指定长度的随机字符串
  3. python 需要多久能够学精通_python入门到精通需要学多久-史上最详细python学习路线-从入门到精通,只需5个月时间...
  4. Linux下的压缩文件剖析
  5. 什么是 SAP Commerce Cloud 的 catalog
  6. 《.NET内存管理宝典》在京东上架销售啦!
  7. 韩国政府计划从Windows 7迁移到Linux
  8. 【Elasticsearch】Elasticsearch 索引 模板 template
  9. cygwin安装好了如何添加cmake make_在windows上使用cmake
  10. SNPE安装+Qualcomm高通AI神经网络处理SDK部署流程
  11. mybatis中使用in查询时的注意事项
  12. 基于链表的模拟21点游戏 C语言
  13. 时间序列-Auto-ARIMA模型
  14. C语言根号作用,c语言开根号(开根号编程)
  15. 国内外常见DNS汇总 (更新:201904)
  16. 2021年知识付费创业新方向该如何掌舵?
  17. Python开发案例:制作二维码
  18. python 类函数 实例函数,python_30期【实例函数 类里面的函数】
  19. oracle10g闪回恢复数据表
  20. phpbb3 风格定制

热门文章

  1. JQuery放大镜效果实现实例
  2. 切换组件echarts宽高不正常,100%变成100px问题
  3. androidapp打开微信小程序
  4. 【每日新闻早报简报】9月30日 星期一
  5. Shiro安全框架【SpringBoot版】
  6. MySQL 进阶 视图 -- 视图介绍、视图CRUD语法、检查选项(CASCADED、LOCAL)、视图的更新、视图作用、视图案例
  7. 部分mp4视频在ios上无法播放问题
  8. 针对数能同传SWIPT的个人理解与总结Part1
  9. 练习C++简单的代码
  10. 2012年08月20日