7

Mac平台下使用nm命令查看文件的符号表

 3 years ago
source link: http://yuanfentiank789.github.io/2018/11/05/Mac%E5%B9%B3%E5%8F%B0%E4%B8%8B%E4%BD%BF%E7%94%A8nm%E5%91%BD%E4%BB%A4%E6%9F%A5%E7%9C%8B%E6%96%87%E4%BB%B6%E7%9A%84%E7%AC%A6%E5%8F%B7%E8%A1%A8/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Mac平台下使用nm命令查看文件的符号表 - JackPeng博客

在Mac平台下,可以使用nm命令来查看一个文件的符号表信息。nm命令行工具是附带在Xcode中的,因此在使用之前请事先安装好Xcode。

nm命令的格式大致如下:

nm  [ -agnoprumxjlfPA [ s segname sectname ] ] [ - ] [ -t format ] [ [ -arch arch_flag ]... ] [ file ... ]

如果不带任何可选参数的话,使用nm命令将会列出指定文件中的所有符号,符号出现的次序默认按照字符排序。如果符号代表的是一个由Object C语言编写的函数,那么其名字将是+-[Class_name(category_name) method:name:]。

对于每一个符号,其格式是“符号值 符号类型 符号名”:

Center 不过可以看到,nm命令也有许多的参数可选,这些参数的大致作用如下:

-a,显示所有符号,包括那些专门用来调试的符号。

-g,只显示全局符号,不显示局部符号。

-n,按照数字而不是默认的字符排序。

-p,不排序,按照符号在符号表中出现的次序显示。

-r,符号按照反序显示(默认就是按照符号名字字符排序的反序,如果带上-p参数就是按照在符号表中出现次序的反序,如果带上-n参数就是按照符号名数字排序的反序)。

-u,只显示未定义的符号。

-U,不显示未定义的符号,与-u的作用刚好相反。

-j,只显示符号的名字,而不显示符号对应的数值和类型。

-s segname sectname

只解析位于文件中segname段里sectname节内的符号。

-arch archtype OS X和iOS系统都是支持所谓的肥(Fat)文件的,也就是一个大文件中包含了分别对不同平台支持的文件。

默认情况下,nm会将其中每一个平台文件中所包含的符号都列出来。如果你只想看某一个平台文件中的符号,可以用这个选项指定。

例如,对于包含了32位armv7指令集和64位armv8指令集的iOS可执行文件来说,如果只想看表示32位armv7指令集部分的符号,可以加上-arch arm参数;而如果想看表示64位armv8指令集部分的符号,可以加上-arch arm64参数。

-x,将以16进制的形式显示符号表中所有符号每一项的值,格式如下: Center -A,在每一行符号的前面加上文件名。

-P,以简单格式显示每一个符号,格式如下: Center -t format,如果使用前面的-P参数,则符号的数值将使用16进制表示,但是可以再加上-t参数来指定用别的格式显示符号的值。主要有下面几种:

d:以10进制显示;

o:以8进制显示;

x:以16进制显示(默认)。

一般来说,在每个符号的前面,都有一个字母来表示这个符号的类型。对于每一个符号来说,其类型如果是小写字母表示的的,则说明该符号是本地(Local)的或者说是内部(Internal)的,而如果是大写字母表示的,则说明该符号是全局的,也就是可供外部(External)访问的。

一共主要有以下几种类型:

1)U,未定义符号

表示这个符号没有在本文件中定义,需要解析别的文件从而找出对应符号的定义。

例如,当前文件调用另一个文件中定义的函数或者全局变量,这个被调用的函数或全局变量在当前文件中就是未定义的。(但是,在定义它的文件中,如果是函数则对应的类型是T,而如果是全局变量则其符号类型为C)。

2)A,绝对符号

表示该符号的值是绝对的,在以后的链接过程中,不允许进行改变。这种类型的符号常常出现在中断向量表中,例如用符号来表示各个中断向量函数在中断向量表中的位置。

3)T,定义在__TEXT段__text区(代码区)中的符号

表示该符号位于代码区中,其值表示该符号在整个文件当中的所处的位置。

有点奇怪的是符号“__mh_execute_header”竟然类型也为T,算作在代码区定义的符号。

4)D,定义在__DATA段__data区中的符号

表明该符号位于初始化数据区中,其值表示该符号在整个文件当中的所处的位置。

5)B,定义在__DATA段__bss区中的符号

表明该符号位于非初始化数据区中,其值表示该符号在bss段中的偏移。

6)C,所谓的普通(Common)符号,定义在__DATA段__common区中的符号

普通符号是定义在一个未初始化数据段内的符号。该符号没有包含于一个普通的区中,只有在链接过程中才进行分配,符号的值表示该符号需要的字节数。例如在一个C文件中,定义int test,并且该符号在别的地方会被引用,则该符号类型即为C,否则其类型为B。

7)I,间接符号

说明这个符号是仅仅是对另一个符号的间接引用。

8)S,其它符号

定义在除前所述其它地方的符号,例如出现在__TEXT段__const区中的符号。

莽莽乾坤起纷争,江湖色变任浮沉,神魔乱舞惊天地,英雄儿女显奇能!小彭飞刀,例无虚发,快准狠;



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK