Linux的nm查看动态和静态库中的符号

本文详细介绍了nm命令的功能与使用方法,包括列出目标文件中的符号信息、符号类型及其含义,并提供了实用的命令选项说明与应用场景示例。

功能

列出.o .a .so中的符号信息,包括诸如符号的值,符号类型及符号名称等。所谓符号,通常指定义出的函数,全局变量等等。

帮助

nm -h
$ nm -h
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
  -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
  -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-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex
Report bugs to <http://www.sourceware.org/bugzilla/>.

使用

nm [option(s)] [file(s)]

有用的options:

  • -A 在每个符号信息的前面打印所在对象文件名称;
  • -C 输出demangle过了的符号名称;
  • -D 打印动态符号;
  • -l 使用对象文件中的调试信息打印出所在源文件及行号;
  • -n 按照地址/符号值来排序;
  • -u 打印出那些未定义的符号;

常见的符号类型:

  • A 该符号的值在今后的链接中将不再改变;
  • B 该符号放在BSS段中,通常是那些未初始化的全局变量;
  • D 该符号放在普通的数据段中,通常是那些已经初始化的全局变量;
  • T 该符号放在代码段中,通常是那些全局非静态函数;
  • U 该符号未定义过,需要自其他对象文件中链接进来;
  • W 未明确指定的弱链接符号;同链接的其他对象文件中有它的定义就用上,否则就用一个系统特别指定的默认值。

注意几点:

  • -C 总是适用于c++编译出来的对象文件。还记得c++中有重载么?为了区分重载函数,c++编译器会将函数返回值/参数等信息附加到函数名称中去形成一个mangle过的符号,那用这个选项列出符号的时候,做一个逆操作,输出那些原始的、我们可理解的符号名称。
  • 使用 -l 时,必须保证你的对象文件中带有符号调式信息,这一般要求你在编译的时候指定一个 -g 选项,见 Linux:Gcc
  • 使用nm前,最好先用Linux:File查看对象文件所属处理器架构,然后再用相应交叉版本的nm工具。

举例

更详细的内容见man page。这里举例说明:

nm -u hello.o
	显示hello.o 中的未定义符号,需要和其他对象文件进行链接.
	
nm -A /usr/lib/* 2>/dev/null | grep "T memset"
在 /usr/lib/ 目录下找出哪个库文件定义了memset函数. 

参考

https://blog.youkuaiyun.com/qq_34488499/article/details/51873341

### Linux查看动态库依赖静态库的命令 在 Linux 系统中,动态库(`.so`)静态库(`.a`)的依赖关系可以通过一些工具进行分析。然而,需要注意的是,动态库本身并不直接依赖静态库,因为动态库是为运行时加载设计的,而静态库则是在编译时链接到目标文件中的[^2]。 #### 使用 `ldd` 命令 `ldd` 命令可以用来查看动态库的依赖关系,但它无法直接显示动态库对静态库的依赖,因为这种依赖通常是在编译阶段通过静态链接实现的。例如: ```bash ldd libexample.so ``` 上述命令会列出 `libexample.so` 动态库所依赖的其他动态库,但不会涉及静态库的信息[^3]。 #### 使用 `nm` `ar` 命令 如果需要检查动态库是否间接依赖某个静态库,可以通过以下步骤: 1. 检查动态库中包含的符号信息,使用 `nm` 命令: ```bash nm -D libexample.so ``` 此命令将列出动态库中导出的符号表,帮助识别可能来自静态库的函数或变量[^3]。 2. 如果已知某个静态库(如 `libstatic.a`),可以使用 `ar` 命令提取其内容并检查符号: ```bash ar -t libstatic.a nm libstatic.a ``` 通过对比动态静态库符号表,可以推测它们之间的依赖关系[^5]。 #### 使用 `readelf` 命令 `readelf` 命令可以提供动态库的详细信息,包括依赖的动态符号表。例如: ```bash readelf -d libexample.so ``` 此命令会显示动态库的动态段信息,帮助确认其依赖的其他动态库或符号[^4]。 #### 编译时的依赖关系 在实际开发中,动态库可能在编译时链接了静态库。例如,以下脚本展示了如何生成一个依赖静态库动态库: ```bash # 编译静态库 gcc -c fun_1.c -o fun_1.o ar rcs libfun_1.a fun_1.o # 编译动态库并链接静态库 gcc -shared -fPIC -o libexample.so example.c -L. -lfun_1 ``` 在这种情况下,动态库 `libexample.so` 间接依赖于静态库 `libfun_1.a`。要验证这一点,可以结合 `nm` `ar` 命令分析符号表[^5]。 ### 总结 Linux 下没有直接的命令可以查看动态库对静态库的依赖,但可以通过 `nm`、`ar` `readelf` 等工具分析动态静态库符号表,从而推断它们之间的关系[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值