Linux ELF重新定位:有偏移量,但我看不到需要偏移量
我试图理解elf的迁移,但有两件事我并不真正理解: 说我有: relamain.cLinux ELF重新定位:有偏移量,但我看不到需要偏移量,linux,elf,dynamic-linking,Linux,Elf,Dynamic Linking,我试图理解elf的迁移,但有两件事我并不真正理解: 说我有: relamain.c #include <stdio.h> #include <stdlib.h> #include "relafoo.c" int main() { int n; scanf("%d",&n); printf("\ngot %d, %d!=%d",n,n,factorial(n)); ret
#include <stdio.h>
#include <stdlib.h>
#include "relafoo.c"
int main() {
int n;
scanf("%d",&n);
printf("\ngot %d, %d!=%d",n,n,factorial(n));
return 0;
}
现在在relamain.o readelf-r中,我看到:
000000000027 000900000002 R_X86_64_PC32 0000000000000000 factorial - 4
000000000052 000500000002 R_X86_64_PC32 0000000000000000 .rodata - 4
00000000005c 000c00000004 R_X86_64_PLT32 0000000000000000 __isoc99_scanf - 4
000000000066 000900000002 R_X86_64_PC32 0000000000000000 factorial - 4
0000000000000031 <main>:
31: 55 push rbp
32: 48 89 e5 mov rbp,rsp
35: 48 83 ec 10 sub rsp,0x10
39: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
40: 00 00
42: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
46: 31 c0 xor eax,eax
48: 48 8d 45 f4 lea rax,[rbp-0xc]
4c: 48 89 c6 mov rsi,rax
4f: 48 8d 3d 00 00 00 00 lea rdi,[rip+0x0] # 56 <main+0x25>
56: b8 00 00 00 00 mov eax,0x0
5b: e8 00 00 00 00 call 60 <main+0x2f>
60: 8b 45 f4 mov eax,DWORD PTR [rbp-0xc]
63: 89 c7 mov edi,eax
65: e8 00 00 00 00 call 6a <main+0x39>
6a: 89 c1 mov ecx,eax
6c: 8b 55 f4 mov edx,DWORD PTR [rbp-0xc]
6f: 8b 45 f4 mov eax,DWORD PTR [rbp-0xc]
72: 89 c6 mov esi,eax
74: 48 8d 3d 00 00 00 00 lea rdi,[rip+0x0] # 7b <main+0x4a>
7b: b8 00 00 00 00 mov eax,0x0
80: e8 00 00 00 00 call 85 <main+0x54>
85: b8 00 00 00 00 mov eax,0x0
8a: 48 8b 75 f8 mov rsi,QWORD PTR [rbp-0x8]
8e: 64 48 33 34 25 28 00 xor rsi,QWORD PTR fs:0x28
95: 00 00
97: 74 05 je 9e <main+0x6d>
99: e8 00 00 00 00 call 9e <main+0x6d>
9e: c9 leave
9f: c3 ret
00000000000000 31:
31:55推动rbp
32:48 89 e5 mov rbp,rsp
35:48 83 ec 10子rsp,0x10
39:64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
40: 00 00
42:48 89 45 f8 mov QWORD PTR[rbp-0x8],rax
46:31 c0 xor eax,eax
48:48 8d 45 f4 lea rax[rbp-0xc]
4c:48 89 c6移动rsi,rax
4f:48 8d 3d 00 lea rdi,[rip+0x0]#56
56:B800 mov eax,0x0
5b:e8 00 00呼叫60
60:8b 45 f4 mov eax,DWORD PTR[rbp-0xc]
63:89 c7移动电子数据交换,eax
65:e8 00呼叫6a
6a:89 c1 mov ecx,eax
6c:8b 55 f4 mov edx,DWORD PTR[rbp-0xc]
6f:8b 45 f4 mov eax,DWORD PTR[rbp-0xc]
72:89 c6电影esi,eax
74:48 8d 3d 00 lea rdi,[rip+0x0]#7b
7b:b800 mov eax,0x0
80:E800呼叫85
85:B800 mov eax,0x0
8a:48 8b 75 f8移动rsi,QWORD PTR[rbp-0x8]
8e:64 48 33 34 25 28 00异或rsi,QWORD PTR fs:0x28
95: 00 00
97:74 05日本脑炎9e
99:e8 00呼叫9e
9e:c9离开
9f:c3 ret
call 66
或call 27
,有人能解释一下吗
1-同一函数没有两个偏移量。当必须应用重定位时,有两个偏移到两个位置。在您的示例中,有两个对factorial函数的调用。一个位于偏移量0x26,另一个位于偏移量0x66,与这些调用链接的重定位的偏移量位于偏移量0x27和0x67。偏移量0x27和0x66处的“00000000”将由链接器计算的值替换。您可以肯定地看到可执行文件的转储。
2-创建对象文件时。汇编程序不知道
factorial
地址,因此它会放置“00000000”并放置一个重新定位,以告诉链接器用获取factorial
所需的值替换这些0,因为只有链接器才知道它的确切位置。3-可能是John R.Levine的链接器和加载程序。然而,我建议你,开始阅读。也许这就足够了,这取决于你所寻求的理解水平
0000000000000031 <main>:
31: 55 push rbp
32: 48 89 e5 mov rbp,rsp
35: 48 83 ec 10 sub rsp,0x10
39: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
40: 00 00
42: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
46: 31 c0 xor eax,eax
48: 48 8d 45 f4 lea rax,[rbp-0xc]
4c: 48 89 c6 mov rsi,rax
4f: 48 8d 3d 00 00 00 00 lea rdi,[rip+0x0] # 56 <main+0x25>
56: b8 00 00 00 00 mov eax,0x0
5b: e8 00 00 00 00 call 60 <main+0x2f>
60: 8b 45 f4 mov eax,DWORD PTR [rbp-0xc]
63: 89 c7 mov edi,eax
65: e8 00 00 00 00 call 6a <main+0x39>
6a: 89 c1 mov ecx,eax
6c: 8b 55 f4 mov edx,DWORD PTR [rbp-0xc]
6f: 8b 45 f4 mov eax,DWORD PTR [rbp-0xc]
72: 89 c6 mov esi,eax
74: 48 8d 3d 00 00 00 00 lea rdi,[rip+0x0] # 7b <main+0x4a>
7b: b8 00 00 00 00 mov eax,0x0
80: e8 00 00 00 00 call 85 <main+0x54>
85: b8 00 00 00 00 mov eax,0x0
8a: 48 8b 75 f8 mov rsi,QWORD PTR [rbp-0x8]
8e: 64 48 33 34 25 28 00 xor rsi,QWORD PTR fs:0x28
95: 00 00
97: 74 05 je 9e <main+0x6d>
99: e8 00 00 00 00 call 9e <main+0x6d>
9e: c9 leave
9f: c3 ret