您的位置:

深入系统地了解system.map 文件

一、system.map文件

system.map 文件是Linux系统内核的一个重要文件,该文件记录了系统运行时的大量信息。此文件包含了内核代码符号表,指令地址、数据地址、BSS区地址等等信息。system.map 文件在内核构建时生成,其生成方式有多种。一个典型的system.map 文件包含类似于以下的信息:

c011d684 t reserve_bootmem
c011d68c t free_bootmem
c011d7e0 t pagetable_init
c011d8a8 t copy_kernel
c011d8c8 T copy_user
c011d8e0 T copy_to_user
c011d900 T copy_from_user
c011d920 T strcpy_from_user
c011d940 T strncpy_from_user
c011d960 T strlen_user

上述信息中每个符号的前6个字符是该符号的地址。其中t表示此符号是一个本地代码符号,T表示此符号是一个可导出的代码符号。

二、system.maplibraryname

Linux系统中的库文件也会有对应的system.map 文件,其具有类似的作用。system.maplibraryname 用于指定库文件名。

/lib/modules/2.6.9-55.ELsmp/kernel/fs/gfs/gfs.ko:
00000000 A gfs_lmhosts
00000000 A gfs_lockstate
00000000 A gfs_tune
00000000 A gfs_quota
00000000 A gfs_qrlock
00000000 A gfs_dir
00000000 A gfs_loghead
00000000 A gfs_quota_lock
00000000 A gfs_log_heads
00000000 A gfs_rindex
00000000 A jid_column
00000000 A dqblk_column
00000000 A inode_column
00000000 A timer_mgr

三、system.map在哪

系统默认位置 /boot/System.map-`uname -r`。

四、system.map 符号表

system.map 文件记录了大量与内核代码,内核模块和系统所有符号相关的信息。其中符号表记录每个符号的具体位置。这里是一个示例:

c0008000 T _stext
c0008400 T __exception_table_start
c00084c4 T __exception_table_end
c0008520 T _sinittext
c007fb14 T _etext
c007fc3c T _sdata

表中列出了一些Linux内核的符号,包括起始地址(例如_stext)和结束地址(例如_etext),该地址是可执行文件中对应的代码段的虚拟地址,T表示代码符号,具有全局作用域。

五、system.map和module.symvers

对内核的开发人员而言,使用已经编译的内核模块和在内核源代码中开发新模块都是必要的。这里有两个文件是必备的

module.symvers是内核模块的一个关键文件,如果缺失会导致编译模块时遇到问题。system.map 文件和 module.symvers 文件都包含符号表,它们的唯一区别在于生成方式不同。module.symvers 表示一个开发版本的内核,记录了当前情况下所有可用的地址符号和其对应的版本信息。

六、system.map 查询地址

可以使用符号名来查询某个符号的地址,例如下面的命令查询了符号init的地址:

$ grep '\' /boot/System.map-`uname -r`
c1041630 T init

  

七、system.map 解析地址

system.map 可以被用来查询内核中的符号、函数、变量等等,这样可以方便地进行内核分析、调试、编译以及模块的开发等工作。下面是一个如何解析与显示符号的地址的例子:

#include
#include
   
int main()
{
    printf(“Address of getchar() function: %p\n”, getchar);
    printf(“Address of the read() function: %p\n”, read);
    return 0;
}

   
  

在shell里面运行命令“make test”即可得到Address of getchar() function: xxxxxxxx,其中xxxx表示getchar 函数的地址。可以使用获取到的函数地址进行代码的调试、分析以及二进制文件的反汇编等多种操作。

八、总结

system.map 是Linux中一个很重要的内核文件。在操作系统的编译过程中生成,它记录了Linux内核中大量的相关信息,包括符号表和地址信息。system.map 文件和 module.symvers 文件都包含符号表,而它们的唯一区别在于生成方式不同。开发人员可以使用 system.map 文件来进行内核分析、调试、编译以及模块的开发等工作。了解 system.map 文件将对Linux内核的理解有很大帮助。