System.map内容

System.map是内核符号表文件,位于源码根目录,记录符号(函数名,全局变量…)在内核中的运行地址

System.map中的部分内容如下:

802a2620 t usb_dev_prepare
802a2628 t usb_dev_restore
802a2644 t usb_dev_thaw
802a2660 t usb_dev_resume
802a26b4 t usb_dev_suspend
802a26d8 t usb_release_dev
802a28b8 T usb_find_alt_setting
802a2978 T usb_ifnum_to_if
802a29c4 T usb_altnum_to_altsetting
802a2a04 T usb_find_interface
802a2a5c T usb_alloc_dev
802a2d14 T usb_get_dev
802a2d44 T usb_put_dev
802a2d60 T usb_get_intf
802a2d90 T usb_put_intf

System.map中常用的一些符号如下,小写代表局部,大写代表全局。

符号类型

名称

说明

A

Absolute

符号的值是绝对值,并且在进一步链接过程中不会被改变

B

BSS

符号在未初始化数据区或区(section)中,即在BSS段中

C

Common

符号是公共的。公共符号是未初始化的数据。在链接时,多个公共符号可能具有同一名称。如果该符号定义在其他地方,则公共符号被看作是未定义的引用

D

Data

符号在已初始化数据区中

G

Global

符号是在小对象已初始化数据区中的符号。某些目标文件的格式允许对小数据对象(例如一个全局整型变量)可进行更有效的访问

I

Inderect

符号是对另一个符号的间接引用

N

Debuggging

符号是一个调试符号

R

Read only

符号在一个只读数据区中

S

Small

符号是小对象未初始化数据区中的符号

T

Text

符号是代码区中的符号

U

Undefined

符号是外部的,并且其值为0(未定义)

-

Stabs

符号是a.out目标文件中的一个stab符号,用于保存调试信息

?

Unknown

符号的类型未知,或者与具体文件格式有关


什么时候用到System.map

linux符号表使用到2个文件:
/proc/ksyms(在2.6以后的内核中,对应的文件是/proc/kallsyms)
System.map

vmlinux中的符号表导出后,就得到System.map,kallsyms一方面是System.map在内存中的结果,另一方面还包括动态加载的模块里面的相关符号信息。

当发生oops的时候,linux使用了一个称为klogd(内核日志后台程序)的后台程序,klogd会截取内核oops并且使用syslogd将其记录下来,并将某些像c010b860的地址信息转换成我们可以识别和使用的符号信息。换句话说,klogd使用System.map文件进行名字-地址之间的解析。

对于静态编译进内核的模块,klogd使用System.map文件进行名字-地址之间的解析,而对于动态加载的模块,klogd通过/proc/kallsyms进行名字-地址之间的解析。

另外少数驱动需要System.map来解析符号,没有为你当前运行的特定内核创建的System.map它们就不能正常工作。


如何生成System.map

通过linux-xxx/scripts/mksysmap工具可以将vmlinux.elf中的内核符号表导出得到System.map,
执行mksysmap vmlinux System.map
mksysmap里面的内容是:​​​$NM -n $1 | grep -v '\( [aNUw] \)|\(__crc_\)|\( \$[adt]\)' > $2​