可执行文件的符号表(symbol table)记录了某个可执行文件中的函数名、全局变量、宏定义等符号信息,这些信息对于我们调试十分重要。

目前,我正在DragonOS上开发内核栈traceback程序,因此需要导出内核文件的符号表.这个时候就需要用到Linux的nm命令。

nm命令属于GNU binutils的功能,能够输出可执行文件的符号表。它的用法是这样的:

用法:nm [选项] [文件]
列举 [文件] 中的符号 (默认为 a.out)。
 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
  -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:支持的目标: 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 plugin srec symbolsrec verilog tekhex binary ihex

看了上面的帮助信息,人都晕了。

按照字典序输出符号表

这里需要用到-n选项,就以DragonOS的内核文件为例,我们输出来看看:

nm -n kernel.elf > nm.txt

为了便于查看,上面的命令把nm的输出重定向到了nm.txt之中。效果如下图:

图片中所看到的就是DragonOS内核的符号表。最左侧一栏指的是符号在内核文件中的地址,中间一栏表示符号类型,最右侧的表示符号的名称。

对于符号的类型的字母的含义,有下列的解释:

-A, -o, --print-file-name
	在找到的各个符号的名字前加上文件名,而不是在此文件的所有符号前只出现文件名一次
-a, --debug-syms
	显示调试符号
-B, --format=bsd
	用来兼容 MIPS 的 nm
-C, --demangle[=STYLE]
	将低级符号名解码(demangle)成用户级名字,比如去除编译时添加的前置下划线,这样可以使得 C++ 函数名具有可读性。不同的编译器符号修饰风格不同,可以使用 =STYLE 参数来选择合适的解码风格
-D, --dynamic:显示动态符号。该任选项仅对于动态目标(例如特定类型的共享库)有意义
-f, --format=FORMAT
	FORMAT 可取值 bsd、sysv 或 posix,该选项在 GNU nm 中有用,默认为 bsd
-g, --extern-only
	仅显示外部符号
-h, --help
	显示帮助信息
-l, --line-numbers
	对每个符号,使用调试信息来试图找到文件名和行号。对于已定义的符号,查找符号地址的行号。对于未定义符号,查找指向符号重定位入口的行号。如果可以找到行号信息,显示在符号信息之后
-n, -v, --numeric-sort
	按符号对应地址的顺序排序,而非按符号名的字符顺序
-P, --portability
	使用 POSIX.2 标准输出格式代替默认的输出格式。等同于 -f posix
-p, --no-sort
	按目标文件中遇到的符号顺序显示,不排序
-r, --reverse-sort
	逆序排序。例如,升序变为降序
-S, --print-size
	以 BSD 输出样式输出已定义符号的值和大小。对于不记录符号大小的目标文件格式,此选项不起作用,除非使用了--size sort,在这种情况下,将显示计算的大小
-s, --print-armap
	当列出库中成员的符号时,同时列出索引。索引的内容包含:模块与其包含的名字的定义之间的映射
-t, --radix=RADIX
	使用基数 radix 进制显示符号值。radix 只能为 d(十进制)、o(八进制)或 x(十六进制)
-u, --undefined-only
	仅显示没有定义的符号
-V, --version
	显示版本信息并退出
-X
	为了与 AIX 版本的 nm 兼容,选项 -X 将被忽略。它可接受一个参数,该参数必须是字符串32_64。AIX nm 的默认模式对应于 -X 32,GNU nm 不支持模式 -X 32
--defined-only
	仅显示有定义的符号
--no-demangle
	不解码低级符号名,这是默认选项
--plugin NAME
	加载名为 name 的插件以添加对额外目标类型的支持。只有在启用插件支持的情况下构建了工具链时,此选项才可用
--size-sort
	按符号大小排列
--special-syms
	显示目标相关的具体特殊含义的符号。这些符号通常被特定目标文件用于某些特殊处理,当包含在正常符号列表中时通常不起作用。例如,对于ARM目标,此选项将跳过用于标记ARM代码、Thumb代码和数据之间转换的映射符号
--synthetic
	输出合成符号。合成符号是链接器为各种目的创建的特殊符号,默认情况下不会显示它们,因为它们不是二进制文件源代码的一部分
--target=BFDNAME
	指定系统默认格式以外的目标文件格式

以上就是nm命令的简单用法。

转载请注明来源:https://longjin666.cn/?p=1469

欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~

你也可能喜欢

发表评论