首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

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

  • 23-11-18 13:41
  • 2798
  • 10806
blog.csdn.net

00. 目录

文章目录

    • 00. 目录
    • 01. 命令概述
    • 02. 命令格式
    • 03. 常用选项
    • 04. 参考示例
    • 05. 附录

01. 命令概述

nm命令被用于显示二进制目标文件的符号表。

02. 命令格式

用法:nm [选项] [文件]
  • 1

03. 常用选项

如果没有为nm命令指出目标文件,则nm假定目标文件是a.out。下面列出该命令的任选项,大部分支持“-”开头的短格式和“—“开头的长格式。
-A、-o或--print-file-name:在找到的各个符号的名字前加上文件名,而不是在此文件的所有符号前只出现文件名一次。

-a或--debug-syms:显示调试符号。
-B:等同于--format=bsd,用来兼容MIPS的nm。
-C或--demangle:将低级符号名解码(demangle)成用户级名字。这样可以使得C++函数名具有可读性。
-D或--dynamic:显示动态符号。该任选项仅对于动态目标(例如特定类型的共享库)有意义。
-f format:使用format格式输出。format可以选取bsd、sysv或posix,该选项在GNU的nm中有用。默认为bsd。
-g或--extern-only:仅显示外部符号。
-n、-v或--numeric-sort:按符号对应地址的顺序排序,而非按符号名的字符顺序。
-p或--no-sort:按目标文件中遇到的符号顺序显示,不排序。
-P或--portability:使用POSIX.2标准输出格式代替默认的输出格式。等同于使用任选项-f posix。
-s或--print-armap:当列出库中成员的符号时,包含索引。索引的内容包含:哪些模块包含哪些名字的映射。
-r或--reverse-sort:反转排序的顺序(例如,升序变为降序)。
--size-sort:按大小排列符号顺序。该大小是按照一个符号的值与它下一个符号的值进行计算的。
-t radix或--radix=radix:使用radix进制显示符号值。radix只能为“d”表示十进制、“o”表示八进制或“x”表示十六进制。
--target=bfdname:指定一个目标代码的格式,而非使用系统的默认格式。
-u或--undefined-only:仅显示没有定义的符号(那些外部符号)。
-l或--line-numbers:对每个符号,使用调试信息来试图找到文件名和行号。对于已定义的符号,查找符号地址的行号。对于未定义符号,查找指向符号重定位入口的行号。如果可以找到行号信息,显示在符号信息之后。
-V或--version:显示nm的版本号。
--help:显示nm的任选项。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

输出符号类型说明

A
该符号的值是绝对的,在以后的链接过程中,不允许进行改变。这样的符号值,常常出现在中断向量表中,例如用符号来表示各个中断向量函数在中断向量表中的位置。
B
该符号的值出现在非初始化数据段(bss)中。例如,在一个文件中定义全局static int test。则该符号test的类型为b,位于bss section中。其值表示该符号在bss段中的偏移。一般而言,bss段分配于RAM中
C
该符号为common。common symbol是未初始话数据段。该符号没有包含于一个普通section中。只有在链接过程中才进行分配。符号的值表示该符号需要的字节数。例如在一个c文件中,定义int test,并且该符号在别的地方会被引用,则该符号类型即为C。否则其类型为B。
D
该符号位于初始话数据段中。一般来说,分配到data section中。例如定义全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},则会分配于初始化数据段中。
G
该符号也位于初始化数据段中。主要用于small object提高访问small data object的一种方式。
I
该符号是对另一个符号的间接引用。
N
该符号是一个debugging符号。
R
该符号位于只读数据区。例如定义全局const int test[] = {123, 123};则test就是一个只读数据区的符号。注意在cygwin下如果使用gcc直接编译成MZ格式时,源文件中的test对应_test,并且其符号类型为D,即初始化数据段中。但是如果使用m6812-elf-gcc这样的交叉编译工具,源文件中的test对应目标文件的test,即没有添加下划线,并且其符号类型为R。一般而言,位于rodata section。值得注意的是,如果在一个函数中定义const char *test = “abc”, const char test_int = 3。使用nm都不会得到符号信息,但是字符串“abc”分配于只读存储器中,test在rodata section中,大小为4。
S
符号位于非初始化数据区,用于small object。
T
该符号位于代码区text section。
U
该符号在当前文件中是未定义的,即该符号的定义在别的文件中。例如,当前文件调用另一个文件中定义的函数,在这个被调用的函数在当前就是未定义的;但是在定义它的文件中类型是T。但是对于全局变量来说,在定义它的文件中,其符号类型为C,在使用它的文件中,其类型为U。
V
该符号是一个weak object。
W
The symbol is a weak symbol that has not been specifically tagged as a weak object symbol.
-
该符号是a.out格式文件中的stabs symbol。
?
该符号类型没有定义
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

04. 参考示例

4.1 显示二进制目标文件的符号表

[deng@localhost bak]$ nm test
0000000000601024 B __bss_start
0000000000601024 b completed.6355
0000000000601020 D __data_start
0000000000601020 W data_start
0000000000400410 t deregister_tm_clones
0000000000400480 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000400568 R __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601024 D _edata
0000000000601028 B _end
0000000000400554 T _fini
00000000004004a0 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
0000000000400690 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
0000000000400570 r __GNU_EH_FRAME_HDR
0000000000400390 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
0000000000400560 R _IO_stdin_used
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
0000000000400550 T __libc_csu_fini
00000000004004e0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
00000000004004cd T main
0000000000400440 t register_tm_clones
00000000004003e0 T _start
0000000000601028 D __TMC_END__
[deng@localhost bak]$ 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

05. 附录

参考:【Linux】一步一步学Linux系列教程汇总

注:本文转载自blog.csdn.net的沧海一笑-dj的文章"https://blog.csdn.net/dengjin20104042056/article/details/101152714"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top