【问题标题】:relocation section header information in .elf file.elf 文件中的重定位节头信息
【发布时间】:2014-12-21 09:34:56
【问题描述】:

我很抱歉我的英语不好,真的很难理解 sh_info 字段包含的重定位部分是什么,以下是我从 ELF 文档中得到的信息:

它说

sh_info:包含应用重定位的节的节标题索引

sh_link:包含相关符号表的节头索引。

很明显:sh_info 与重定位段所关联的符号表段无关,其信息存储在 sh_link 中。

根据我的理解:重定位符号时,三个部分相关:重定位部分、符号表部分和包含符号表中符号定义的部分。

假设 1:所以我假设 sh_info 是关于前面提到的第三部分

-----但是,当我查看重定位示例代码时,我的假设似乎不匹配

static int elf_do_reloc(Elf32_Ehdr *hdr, Elf32_Rel *rel, Elf32_Shdr *reltab) {
Elf32_Shdr *target = elf_section(hdr, reltab->sh_info);
int addr = (int)hdr + target->sh_offset;
int *ref = (int *)(addr + rel->r_offset);

// Symbol value
int symval = 0;
if(ELF32_R_SYM(rel->r_info) != SHN_UNDEF) {
    symval = elf_get_symval(hdr, reltab->sh_link, ELF32_R_SYM(rel->r_info));
    if(symval == ELF_RELOC_ERR) return ELF_RELOC_ERR;
}

-----Sicce r_info 是重定位部分中仅包含的字段

这意味着 sh_info 是重定位节本身的索引。 假设 2

更让我困惑的是别人发的一个例子,reading elf file example

似乎 sh_info 字段信息与我之前的 2 个假设无关

谁能帮忙解释一下 sh_info 真正包含什么?

【问题讨论】:

    标签: elf relocation


    【解决方案1】:

    关于"confusing example",可能重定位部分已被删除,但仅提及sh_info 与解析(动态)符号名称有关,并且(如您问题中的图像所示)该字段对SHT_SYMTAB 具有不同的含义和SHT_DYNSYM(部分中的项目数 + 1)。

    Section #0A        OFF: 0x000015F8
        Name:      .rela.plt (0x00000084)
        Type:      SHT_RELA (0x00000004)
        Flags:     -a-
        Addr:      0x004003E8
        Offset:    0x000003E8
        Size:      0x00000090
        Link:      0x00000005
        Info       0x0000000C
        
    Section #05        OFF: 0x000014B8
        Name:      .dynsym (0x0000004E)
        Type:      SHT_DYNSYM (0x0000000B)
        Flags:     -a-
        Addr:      0x00400280
        Offset:    0x00000280
        Size:      0x000000A8
        Link:      0x00000006
        Info       0x00000001
        
    Section #0C        OFF: 0x00001678
        Name:      .plt (0x00000089)
        Type:      SHT_PROGBITS (0x00000001)
        Flags:     -ax
        Addr:      0x004004A0
        Offset:    0x000004A0
        Size:      0x00000070
        Link:      0x00000000
        Info       0x00000000
    

    您可以看到sh_link 指向.dynsym 部分,sh_info 指向.plt 部分(其中包含可执行内存)。

    所以sh_link 是 符号表和sh_info 是 被修改的可执行部分。

    基本上您的文档已经说明了一切,但这里还有一些参考资料。

    Chapter on Sections[图4-12:sh_link和sh_info解读]:

    sh_link - 关联符号表的节头索引。

    sh_info - 应用重定位的节的节头索引。

    还有一章关于relocation:

    重定位节引用另外两个节:符号表和要修改的节。节头的sh_info 和sh_link 成员,在上面的“节”中描述,指定了这些关系。不同目标文件的重定位条目对r_offset 成员的解释略有不同。

    • 在可重定位文件中,r_offset 保存一个节偏移量。重定位部分本身描述了如何修改文件中的另一个部分;重定位偏移量指定第二部分内的存储单元。
    • 在可执行文件和共享对象文件中,r_offset 拥有一个虚拟地址。为了使这些文件的重定位条目对动态链接器更有用,节偏移(文件解释)让位于虚拟地址(内存解释)。

    只是为了好玩...Here are (search page) Linux 上 x86 的重定位类型:

    #define R_X86_64_NONE           0       /* No reloc */
    #define R_X86_64_64             1       /* Direct 64 bit  */
    #define R_X86_64_PC32           2       /* PC relative 32 bit signed */
    #define R_X86_64_GOT32          3       /* 32 bit GOT entry */
    #define R_X86_64_PLT32          4       /* 32 bit PLT address */
    #define R_X86_64_COPY           5       /* Copy symbol at runtime */
    #define R_X86_64_GLOB_DAT       6       /* Create GOT entry */
    #define R_X86_64_JUMP_SLOT      7       /* Create PLT entry */
    #define R_X86_64_RELATIVE       8       /* Adjust by program base */
    #define R_X86_64_GOTPCREL       9       /* 32 bit signed pc relative
                                                offset to GOT */
    #define R_X86_64_32             10      /* Direct 32 bit zero extended */
    #define R_X86_64_32S            11      /* Direct 32 bit sign extended */
    #define R_X86_64_16             12      /* Direct 16 bit zero extended */
    #define R_X86_64_PC16           13      /* 16 bit sign extended pc relative */
    #define R_X86_64_8              14      /* Direct 8 bit sign extended  */
    #define R_X86_64_PC8            15      /* 8 bit sign extended pc relative */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多