为了理解重定位的概念,我编写了一个简单的 chk.c 程序,如下所示:
1 #include<stdio.h>
2 main(){
3 int x,y,sum;
4 x = 3;
5 y = 4;
6 sum = x + y;
7 printf("sum = %d\n",sum);
8 }
使用“objdump -d chk.o”的等效汇编代码是:
00000000 <main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 e4 f0 and $0xfffffff0,%esp
6: 83 ec 20 sub $0x20,%esp
9: c7 44 24 1c 03 00 00 movl $0x3,0x1c(%esp)
10: 00
11: c7 44 24 18 04 00 00 movl $0x4,0x18(%esp)
18: 00
19: 8b 44 24 18 mov 0x18(%esp),%eax
1d: 8b 54 24 1c mov 0x1c(%esp),%edx
21: 8d 04 02 lea (%edx,%eax,1),%eax
24: 89 44 24 14 mov %eax,0x14(%esp)
28: b8 00 00 00 00 mov $0x0,%eax
2d: 8b 54 24 14 mov 0x14(%esp),%edx
31: 89 54 24 04 mov %edx,0x4(%esp)
35: 89 04 24 mov %eax,(%esp)
38: e8 fc ff ff ff call 39 <main+0x39>
3d: c9 leave
3e: c3 ret
使用 readelf 看到的 .rel.text 部分如下:
Relocation section '.rel.text' at offset 0x360 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000029 00000501 R_386_32 00000000 .rodata
00000039 00000902 R_386_PC32 00000000 printf
据此我有以下问题:
1)从 .rel.text 部分中的第二个条目,我能够理解 .text 部分中偏移量 0x39 处的值(此处为 0xfcffffff)必须替换为与符号表索引 9 关联的符号的地址(&结果是 printf)。但我在这里无法清楚地理解 0x02 (ELF32_R_TYPE) 的含义。 R_386_PC32 在这里指定了什么?谁能清楚地解释一下它的含义。
2)我也无法理解第一个条目。 .text 部分中 0x29 偏移处需要替换什么以及为什么这里不清楚。我再次想知道这里 R_386_32 的含义。我找到了一份 pdf elf_format.pdf,但我无法从中清楚地理解 .rel.text 部分中“Type”的含义。
3)我还想知道汇编inst“lea(%edx,%eax,1),%eax”的含义。虽然我找到了一个非常好的链接(LEA 指令的目的是什么? https://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction)描述了lea的含义,但是lea的格式(括号内的3个arg是什么)不清楚。
如果有人能清楚地解释上述问题的答案,将不胜感激。尽管我已经通过谷歌进行了很多尝试,但我仍然在努力寻找这些问题的答案。
还有一个问题。我在下面显示了偏移量 5 和 9 的符号表条目。
Num: Value Size Type Bind Vis Ndx Name
5: 00000000 0 SECTION LOCAL DEFAULT 5
9: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf'
.rel.text 表中第一个条目的信息字段是 0x05,表示符号表的索引。我已经显示了上面索引 5 的符号表条目,但无法理解它如何告诉我们它是针对 .rodata 的。