可执行文件的符号表(symbol table)记录了某个可执行文件中的函数名、全局变量、宏定义等符号信息,这些信息对于我们调试十分重要。
目前,我正在DragonOS上开发内核栈traceback程序,因此需要导出内核文件的符号表.这个时候就需要用到Linux的nm命令。
nm命令属于GNU binutils的功能,能够输出可执行文件的符号表。它的用法是这样的:
代码语言:javascript复制用法: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的内核文件为例,我们输出来看看:
代码语言:javascript复制nm -n kernel.elf > nm.txt
为了便于查看,上面的命令把nm的输出重定向到了nm.txt之中。效果如下图:
图片中所看到的就是DragonOS内核的符号表。最左侧一栏指的是符号在内核文件中的地址,中间一栏表示符号类型,最右侧的表示符号的名称。
对于符号的类型的字母的含义,有下列的解释:
代码语言:javascript复制-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