System.map内容
System.map是内核符号表文件,位于源码根目录,记录符号(函数名,全局变量…)在内核中的运行地址
System.map中的部分内容如下:
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