You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何像nm工具一样打印ELF文件的符号名?相关技术疑问

嗨,我来帮你理清这个问题~

实现类似nm工具打印ELF符号名的正确姿势

首先得先纠正一个小误区:你提到的shstrtab和符号名其实没啥直接关系,不用把它转换成Elf64_Sym结构体来获取符号名。下面我给你拆解清楚各个表的作用和正确的实现步骤:

1. 先搞懂几个关键ELF表的分工

  • shstrtab(段头字符串表):它存储的是ELF文件中各个段(section)的名称,比如.text、.symtab、.strtab这些段的名字,和符号本身的名字无关。
  • symtab(符号表段):这才是存储符号信息的地方,里面是一个个Elf64_Sym结构体,每个结构体记录了符号的地址、类型、名字偏移等信息。
  • strtab(符号字符串表):真正存储符号名称的地方,Elf64_Sym里的st_name字段是一个偏移量,指向这个表中的具体字符串。

2. 正确获取符号名的步骤

要实现类似nm的功能,核心是处理symtab和strtab,步骤大概是这样:

  • 读取ELF文件的文件头(Elf64_Ehdr),通过它找到段头表(section header table)的位置。
  • 遍历段头表(每个元素是Elf64_Shdr),定位两个关键段:
    • 找到类型为SHT_SYMTAB的段(也就是symtab),它的内容是Elf64_Sym数组。
    • 通过symtab段头的sh_link字段,找到对应的strtab段(这个字段是段头表中strtab的索引)。
  • 遍历symtab里的每个Elf64_Sym:
    • 用st_name的值作为偏移量,到strtab的起始地址处读取对应的字符串,这就是符号的名字。
    • 还可以通过st_info、st_shndx等字段判断符号类型(比如全局函数、局部变量),像nm那样输出对应的标记。

3. shstrtab的正确用法

虽然shstrtab不直接参与符号名获取,但它能帮你更直观地定位段:遍历段头表时,每个段头的sh_name是shstrtab里的偏移,通过它可以拿到段的名称(比如判断某个段是不是.symtab或.strtab),方便调试或灵活定位。

简单代码片段示意

// 假设已将ELF文件读取到内存,ehdr是Elf64_Ehdr指针,shdrs是段头表数组
Elf64_Shdr *symtab_shdr = NULL;
Elf64_Shdr *strtab_shdr = NULL;
char *strtab = NULL;
Elf64_Sym *symtab = NULL;

// 遍历段头表,定位symtab和对应的strtab
for (int i = 0; i < ehdr->e_shnum; i++) {
    // 用shstrtab获取当前段的名称
    char *sec_name = (char *)((uint8_t *)ehdr + shdrs[ehdr->e_shstrndx].sh_offset) + shdrs[i].sh_name;
    if (shdrs[i].sh_type == SHT_SYMTAB) {
        symtab_shdr = &shdrs[i];
        // symtab的sh_link字段指向strtab的段索引
        strtab_shdr = &shdrs[symtab_shdr->sh_link];
        strtab = (char *)((uint8_t *)ehdr + strtab_shdr->sh_offset);
        symtab = (Elf64_Sym *)((uint8_t *)ehdr + symtab_shdr->sh_offset);
        break;
    }
}

// 遍历符号表打印符号名
if (symtab && strtab) {
    int sym_count = symtab_shdr->sh_size / symtab_shdr->sh_entsize;
    for (int i = 0; i < sym_count; i++) {
        if (symtab[i].st_name != 0) { // 跳过无名符号
            char *sym_name = strtab + symtab[i].st_name;
            printf("%s\n", sym_name);
            // 这里还可以添加符号地址、类型等信息的打印
        }
    }
}

这样就能正确获取并打印ELF文件里的符号名啦,核心是别把shstrtab和strtab搞混哦~

内容的提问来源于stack exchange,提问作者SJS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:35:55