c++ - 平面二进制文件中的重定位条目存储在哪里?

标签 c++ powerpc

请注意下面的例子。我有一个 C++ 代码,我想在 powerpc 下编译并生成二进制代码。

#include <stdio.h>

int function(int x);
int myfunction(int x);

int main() 
{
    int x = function(2);
    int y = myfunction(2);

    return x + y;
}

int function(int x)
{
    return x * myfunction(x);
}

int myfunction(int x)
{
    return x;
}

我有两个函数调用:call function(2)call myfunction(2)。我在 powerpc‍‍‍ 下编译此 C++ 代码。所以,现在我使用 objdump 获取目标文件后面的程序集,如下所示:

00000000 <main>:
   0:   94 21 ff e0     stwu    r1,-32(r1)
   4:   7c 08 02 a6     mflr    r0
   8:   93 e1 00 1c     stw r31,28(r1)
   c:   90 01 00 24     stw r0,36(r1)
  10:   7c 3f 0b 78     mr  r31,r1
  14:   38 60 00 02     li  r3,2
  18:   48 00 00 01     bl  18 <main+0x18>
  1c:   7c 60 1b 78     mr  r0,r3
  20:   90 1f 00 08     stw r0,8(r31)
  24:   38 60 00 02     li  r3,2
  28:   48 00 00 01     bl  28 <main+0x28>
  2c:   7c 60 1b 78     mr  r0,r3
  30:   90 1f 00 0c     stw r0,12(r31)
  34:   80 1f 00 08     lwz r0,8(r31)
  38:   81 3f 00 0c     lwz r9,12(r31)
  3c:   7c 00 4a 14     add r0,r0,r9
  40:   7c 03 03 78     mr  r3,r0
  44:   48 00 00 0c     b   50 <main+0x50>
  48:   38 60 00 00     li  r3,0
  4c:   48 00 00 04     b   50 <main+0x50>
  50:   81 61 00 00     lwz r11,0(r1)
  54:   80 0b 00 04     lwz r0,4(r11)
  58:   7c 08 03 a6     mtlr    r0
  5c:   83 eb ff fc     lwz r31,-4(r11)
  60:   7d 61 5b 78     mr  r1,r11
  64:   4e 80 00 20     blr

00000068 <function__Fi>:
  68:   94 21 ff e0     stwu    r1,-32(r1)
  6c:   7c 08 02 a6     mflr    r0
  70:   93 e1 00 1c     stw r31,28(r1)
  74:   90 01 00 24     stw r0,36(r1)
  78:   7c 3f 0b 78     mr  r31,r1
  7c:   90 7f 00 08     stw r3,8(r31)
  80:   80 7f 00 08     lwz r3,8(r31)
  84:   48 00 00 01     bl  84 <function__Fi+0x1c>
  88:   7c 60 1b 78     mr  r0,r3
  8c:   81 3f 00 08     lwz r9,8(r31)
  90:   7c 00 49 d6     mullw   r0,r0,r9
  94:   7c 03 03 78     mr  r3,r0
  98:   48 00 00 0c     b   a4 <function__Fi+0x3c>
  9c:   48 00 00 08     b   a4 <function__Fi+0x3c>
  a0:   48 00 00 04     b   a4 <function__Fi+0x3c>
  a4:   81 61 00 00     lwz r11,0(r1)
  a8:   80 0b 00 04     lwz r0,4(r11)
  ac:   7c 08 03 a6     mtlr    r0
  b0:   83 eb ff fc     lwz r31,-4(r11)
  b4:   7d 61 5b 78     mr  r1,r11
  b8:   4e 80 00 20     blr

000000bc <myfunction__Fi>:
  bc:   94 21 ff e0     stwu    r1,-32(r1)
  c0:   93 e1 00 1c     stw r31,28(r1)
  c4:   7c 3f 0b 78     mr  r31,r1
  c8:   90 7f 00 08     stw r3,8(r31)
  cc:   80 1f 00 08     lwz r0,8(r31)
  d0:   7c 03 03 78     mr  r3,r0
  d4:   48 00 00 04     b   d8 <myfunction__Fi+0x1c>
  d8:   81 61 00 00     lwz r11,0(r1)
  dc:   83 eb ff fc     lwz r31,-4(r11)
  e0:   7d 61 5b 78     mr  r1,r11
  e4:   4e 80 00 20     blr

让我感到奇怪的有趣的事情是执行函数调用的行:

  18:   48 00 00 01     bl  18 <main+0x18>
  ...
  28:   48 00 00 01     bl  28 <main+0x28>

如您所见,两者都是二进制代码“48 00 00 01”,但一个调用function,另一个调用myfunction。问题是我们如何找到调用目标。正如我所发现的,调用目标写在 RELOCATION ENTRIES 上。哦,一切正常,我使用下面的命令生成重定位条目,如下:

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE 
00000018 R_PPC_REL24       function__Fi
00000028 R_PPC_REL24       myfunction__Fi
00000084 R_PPC_REL24       myfunction__Fi

此条目对于查找调用目标很有用。现在,我使用 objcopy -O binary 命令生成原始二进制文件(平面二进制文件)。

objcopy -O binary object-file

我的目标文件elf32-powerpc。以下 block 中显示的输出二进制文件:

2564 0000 2564 0a00 93e1 001c 9001 0024
7c3f 0b78 3860 0002 4800 0001 7c60 1b78
901f 0008 3860 0002 4800 0001 7c60 1b78
901f 000c 801f 0008 2c00 0002 4182 003c
2c00 0002 4181 0010 2c00 0001 4182 0014
4800 0058 2c00 0003 4182 0038 4800 004c
3d20 0000 3869 0000 389f 0008 4cc6 3182
4800 0001 4800 004c 3d20 0000 3869 0004
3880 0014 4cc6 3182 4800 0001 4800 0034
3d20 0000 3869 0004 3880 001e 4cc6 3182
4800 0001 4800 001c 3d20 0000 3869 0004
3880 0028 4cc6 3182 4800 0001 4800 0004
3860 0000 4800 0004 8161 0000 800b 0004
7c08 03a6 83eb fffc 7d61 5b78 4e80 0020
9421 ffe0 7c08 02a6 93e1 001c 9001 0024
7c3f 0b78 907f 0008 807f 0008 4800 0001
7c60 1b78 813f 0008 7c00 49d6 7c03 0378
4800 000c 4800 0008 4800 0004 8161 0000
800b 0004 7c08 03a6 83eb fffc 7d61 5b78
4e80 0020 9421 ffe0 93e1 001c 7c3f 0b78
907f 0008 801f 0008 7c03 0378 4800 0004
8161 0000 83eb fffc 7d61 5b78 4e80 0020

我们可以在上面找到4800 0001。但是没有重定位条目。谁能告诉我如何找到重定位条目

提前致谢。

最佳答案

当您执行 objcopy 时,您的重定位条目将被丢弃。来自手册:

objcopy can be used to generate a raw binary file by using an output target of binary (e.g., use -O binary). When objcopy generates a raw binary file, it will essentially produce a memory dump of the contents of the input object file. All symbols and relocation information will be discarded. The memory dump will start at the load address of the lowest section copied into the output file.

为了使您的原始二进制文件有用,您可以在此处进行一些选择:

您可以在构建过程中执行重定位,这样您的原始二进制文件就可以运行了。但是,这意味着二进制文件需要在内存中的固定地址运行。

或者,您可以生成一个不需要重定位的目标文件——所有地址引用都需要是相对的。查找“与位置无关的代码”以获取更多详细信息。

最后,您还可以使用其他方式生成原始二进制文件(代替或补充 objcopy 阶段),它在输出文件中包含重定位表,然后让您的代码在运行时手动处理这些重定位。

此处的选择将取决于您尝试做什么,以及您的运行时环境有哪些限制。

关于c++ - 平面二进制文件中的重定位条目存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32522938/

相关文章:

c++ - WM_NCHITTEST 和主监视器左侧的辅助监视器

linux - 大内存页和碎片

macos - Mac OS X 10.5 App "not supported on this architecture"通过复制修复?

c++ - 图像处理库

c++ - 如果 char 可以在 C++ 中存储数字,为什么我们需要 int?

linux - __copy_tofrom_user 在哪里定义? (Linux 2.6.33 PowerPC 弧线)

PowerPC 440EP 和 PowerPC E300C3 上的 Node.js "Illegal instruction"

c - 什么会导致程序计数器的地址无效?

c++ - 由于编译器优化,代码运行缓慢

c++ - 双线性插值,我的实现有问题