微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ELF重定位:存在偏移量,但我看不到偏移量的要求

如何解决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,factorial(n));

    return 0;
}

和relafoo.c

int factorial(int n) {
    if (n == 0 || n == 1) {
        return 1;
    }
    return factorial(n-1)*n;
}

现在进入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
  1. 为什么同一个函数(阶乘)有两个偏移量

i objdump -d relamain.o:

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    
  1. 查看生成代码,我发现所有调用均未引用我的阶乘函数的偏移量66或27,这是为什么呢?根据Ryan“ elfmaster” O'Neill的“学习linux二进制分析”,我应该期望至少我会看到call 66call 27,有人可以解释吗?

  2. 如果有人可以将我链接到一本很好的书,该书通过示例(动态链接和重定位除外)详细解释了所有内容,那就太好了

解决方法

1-对于同一功能,您没有两个偏移量。当必须应用重定位时,您有两个位置的两个偏移量。在您的示例中,您两次调用了函数阶乘。一个位于偏移量0x26,另一个位于偏移量0x66,链接到这些调用的重定位偏移量位于偏移量0x27和0x67。偏移量0x27和0x66处的“ 00000000”将由链接器计算的值替换。您可以肯定地看到可执行文件的转储。
2-创建目标文件时。汇编器不知道factorial的地址,因此它放置了“ 00000000”并进行了重定位,以告诉链接器将这些0替换为获取factorial所需的值,因为只有链接器才知道它的确切地址位置。
3-可能是John R. Levine撰写的Linkers&Loaders。但是,我建议您开始阅读http://www.skyfree.org/linux/references/ELF_Format.pdf。也许就足够了,这取决于您寻求的理解水平。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。