ELF文件.stab段FUN符号范围及内部符号定位技术问询
从.stab段提取FUN符号的范围与内部符号
.stab段的符号条目遵循struct nlist结构(定义在<nlist.h>或<elf.h>中),FUN类型符号的n_type字段会包含N_FUN标记。以下是具体提取方法:
1. 获取函数起止地址
- 起始地址:直接读取FUN符号的
n_value字段,该值就是函数在内存中的起始地址。 - 结束地址:.stab段本身不会直接存储函数结束地址,需要通过相邻符号推断:
- 遍历.stab段的后续符号,找到第一个类型为
N_FUN、N_GLOBAL或N_STATIC的符号,其n_value即为当前函数的结束地址。 - 如果当前FUN是段内最后一个符号,则用对应代码段(如.text)的结束地址作为函数结束地址。
- 遍历.stab段的后续符号,找到第一个类型为
2. 提取内部符号(参数、变量、嵌套作用域)
遍历.stab段的所有条目,筛选出与目标FUN符号关联的条目:
- 参数:符号
n_type包含N_PARAM标记,且n_desc字段指向所属FUN符号的索引,或n_other字段标记其作用域层级属于当前函数。 - 局部变量:符号
n_type包含N_LOCAL标记,作用域关联规则同参数。 - 嵌套作用域/嵌套函数:符号
n_type包含N_FUN标记,且n_other字段的作用域层级高于父函数,或n_desc指向父FUN符号的索引。
解决
objdump -G无法显示FUN起止地址的问题 1. 检查编译调试选项
确保编译时生成了完整的.stab调试信息:
- GCC编译时需指定
-gstab(而非默认的DWARF格式),如果用-g或-g2会生成DWARF调试段(.debug_*),.stab段信息会缺失。 - 确认编译命令中没有添加
-s(strip符号)或-O3等会优化掉调试信息的选项。
2. 调整objdump命令参数
默认的objdump -G输出不会自动计算或显示结束地址,可尝试以下方式:
- 结合
-x选项显示完整符号表,再匹配FUN符号的地址:objdump -G -x obj/kern/kernel - 指定架构解析(针对64位或特殊架构目标):
objdump -G -m i386:x86-64 obj/kern/kernel - 换用
readelf工具,它对.stab段的解析更细致:readelf -wSt obj/kern/kernel,该命令会显示每个.stab符号的n_value(起始地址),你可以手动推断结束地址。
3. 验证.stab段完整性
用readelf -S obj/kern/kernel检查.stab和.stabstr段是否存在且大小非零,如果段缺失或为空,说明编译时未生成对应的调试信息,需重新编译添加-gstab选项。
内容的提问来源于stack exchange,提问作者Er1c Brow0
相关产品推荐
相关产品推荐

