kallsyms实现原理源码分析

kallsyms是Linux内核用于存储和查询符号信息的关键机制,它将内核和模块的函数及其地址信息保存在/proc/kallsyms文件中。通过kallsyms_addresses数组和kallsyms_names字符串数组存储符号地址和名称,并使用kallsyms_token_table优化查找。在kallsyms_lookup函数中,通过get_symbol_pos获取符号的偏移量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    kallsyms在进行源码调试时具有相当重要的作用。linux内核在编译的过程中,将内核中所有的符号(所有的内核函数以及已经装载的模块)及符号的地址以及符号的类型信息都保存在了/proc/kallsyms文件中。具体格式如下:符号地址,符号类型,符号名

c0100000 T startup_32

c0100000 A _text

c01000c6 t checkCPUtype

c0100147 t is

486c010014e t is

386c010019f t L

6c01001a1 t check_x

87c01001ca t setup_idt

c01001e7 t rp_sidt

c01001f4 t ignore_int

c0100228 T calibrate_delay为了弄清楚内核具体是怎样查询的,我们首先必须知道这些信息在内核中是怎样存储的。

内核为了存储这些信息,定义了如下变量:

extern const unsigned long kallsyms_num_symsextern const u8 kallsyms_token_table[] const u16 kallsyms_token_index[] extern const unsigned long kallsyms_addresses[] extern const unsigned long kallsyms_markers[] 

其中kallsyms_num_syms统计了内核中所有符号的个数;

kallsyms_addresses数组记录了所有内核符号的地址(已经按顺序排列好)

kallsyms_names数组是函数名组成的一个大串,而该串的具体格式为

<lenth><length byte dada>

也就是说对于每个符号而言,都存储的是length+1个字节的内容,其中第一个字节代表了该符号的总长度,而后面length个自己代表了符号的内容。

在这里需要说明一下为了方便符号的查找,linux内核做了两方面的工作:

将常用的串存储在数组kallsyms_token_table数组中,而kallsyms_token_index则代表了该串的索引。其中token就代表了这些常用的字符串,而索引就是一些没有用到的ASCII码值。其中的一些例子入表1所示

190        .asciz        "t.text.lock."

191        .asciz        "text.lock."

192        .asciz        "t.lock."

193        .asciz        "lock."

210        .asciz &n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值