我为我的英语不好而道歉,真的很难理解重定位部分包含 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真正包含的内容吗?
答案 0 :(得分: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
包含虚拟地址。为了使这些文件的重定位条目对动态链接器更有用,段偏移(文件解释)让位于虚拟地址(内存解释)。
只是为了在Linux上使用x86的Here are(search page)重定位类型:
#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 */