1

我为我糟糕的英语道歉,真的很难理解重定位部分的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

更让我困惑的是别人发的一个例子,阅读elf文件的例子

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

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

4

1 回答 1

1

关于“令人困惑的示例”,可能重定位部分已被删除,但仅提及sh_info与解析(动态)符号名称和(如您的问题中的图像所示)该字段具有不同的含义SHT_SYMTABSHT_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 修改的可执行部分。

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

章节章节 [图4-12:sh_linksh_info解释]

sh_link- 相关符号表的节标题索引。

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

还有一章关于搬迁

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

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

只是为了好玩......这里是搜索页面)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 */
于 2014-11-08T18:57:32.987 回答