《深入理解计算机系统》第7章:重定位PC相对引用的理解
在第七章《链接》中的静态链接有对符号进行重定位PC相对引用的处理,书上对应的还有"公式",但不是很好理解。现做实验对"公式"进行理解("公式"内容如有兴趣可以参考原文)
我们的目的是根据.text节起点和目标函数地址(如下面的0x8048420),重新计算引用偏移量
现创建2个文件
//main.c void swap(); int buf[2]={1,2}; int main() { swap(); return 0; } //swap.c extern int buf[]; int *bufp0 = &buf[0]; int *bufp1; void swap() { int temp; bufp1 = &buf[1]; temp = *bufp0; *bufp0 = *bufp1; *bufp1 = temp; }
可以看到main.c引用了swap.c的函数,编译main.c为main.o,反汇编有如下结果
# objdump -d main.o main.o: file format elf32-i386 Disassembly of section .text: 00000000 <main>: 0: 8d 4c 24 04 lea 0x4(%esp),%ecx 4: 83 e4 f0 and $0xfffffff0,%esp 7: ff 71 fc pushl -0x4(%ecx) a: 55 push %ebp b: 89 e5 mov %esp,%ebp d: 51 push %ecx e: 83 ec 04 sub $0x4,%esp 11: e8 fc ff ff ff call 12 <main+0x12> --对swap引用的地址偏移量为12(call命令占一个字节) 16: b8 00 00 00 00 mov $0x0,%eax 1b: 83 c4 04 add $0x4,%esp 1e: 59 pop %ecx 1f: 5d pop %ebp 20: 8d 61 fc lea -0x4(%ecx),%esp 23: c3 ret
将swap.o和main.o编译为可执行文件p,查看p的.text节信息(截取部分如下)
[15] .text PROGBITS 08048330 000330 0001bc 00 AX 0 0 16 --节起始地址为红色部分
反汇编p,(截取部分如下)
080483f0 <main>: 80483f0: 8d 4c 24 04 lea 0x4(%esp),%ecx 80483f4: 83 e4 f0 and $0xfffffff0,%esp 80483f7: ff 71 fc pushl -0x4(%ecx) 80483fa: 55 push %ebp 80483fb: 89 e5 mov %esp,%ebp 80483fd: 51 push %ecx 80483fe: 83 ec 04 sub $0x4,%esp 8048401: e8 1a 00 00 00 call 8048420 <swap> 8048406: 83 c4 04 add $0x4,%esp 8048409: 31 c0 xor %eax,%eax 804840b: 59 pop %ecx 804840c: 5d pop %ebp 804840d: 8d 61 fc lea -0x4(%ecx),%esp
由于不知道swap相对与.text起始地址的偏移量,我们采用main函数的地址,它相对于main函数的偏移量为0x12。
那么新的引用量为0x8048420-(0x080483f0+0x12)-4 = 1A
实际上0x080483f0+0x12+4的地址就是PC的值,0x8048420-PC就是偏移值
可见"公式"害死人。。。
本文来自博客园,作者:charlieroro,转载请注明原文链接:https://www.cnblogs.com/charlieroro/p/8482599.html