重定位条目存储在平面二进制文件中的哪个位置?

时间:2015-09-11 11:55:35

标签: 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>

如您所见,两者都是二进制代码&#34; 48 00 00 01&#34;,但一个调用function,另一个调用myfunction。问题是我们如何找到call target。正如我发现的那样,呼叫目标写在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

我的object-fileelf32-powerpc。输出二进制文件显示在以下块中:

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。但是没有relocation entries。可以请任何人告诉我如何找到relocation entries

先谢谢。

1 个答案:

答案 0 :(得分:1)

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

  

objcopy可用于通过使用输出生成原始二进制文件   二进制的目标(例如,使用-O二进制)。当objcopy生成原始数据时   二进制文件,它基本上会产生内容的内存转储   输入对象文件。 所有符号和重定位信息都将   被丢弃。内存转储将从加载地址开始   最低部分复制到输出文件中。

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

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

或者,您可以生成不需要重定位的目标文件 - 所有地址引用都需要是相对的。查找&#34;与位置无关的代码&#34;了解更多详情。

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

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