【问题标题】:Error while relocating binary code (gcc -> objdata -> load binary code -> and execute)重定位二进制代码时出错(gcc -> objdata -> 加载二进制代码 -> 并执行)
【发布时间】:2013-03-04 21:03:00
【问题描述】:

我正在实现一种遗传算法,这些生物是具有三个指针作为输入和输出的函数。 都有以下形式:

// No need for global variables

void _start (float *i, float *o, float *m)
{
    ...
    ...
    ...
}

这些生物应该有几千个,而且非常小,所以我决定不使用共享对象,而是简单地加载原始代码并运行它。

生物被编译

gcc -O3 -c code.c

那我就这样取函数的代码

objcopy -O binary --only-section=.text code.o rawcode

然后将代码加载到内存中并运行

((void(*)(void*,void*,void*)) loaded_code) (i, o, m);

直到在源代码中没有浮点字面量,这才起作用,例如代码:

void _start (int *i, int *o, int *m)
{
    i[0] = m[0] + m[1];
}

编译后产生这个工作代码:

gcc -O3 -c code.c
objdump -d code.o

code.o:     formato del file elf64-x86-64


Disassemblamento della sezione .text:

0000000000000000 <_start>:
   0:   f3 0f 10 02             movss  (%rdx),%xmm0
   4:   f3 0f 58 42 04          addss  0x4(%rdx),%xmm0
   9:   f3 0f 11 07             movss  %xmm0,(%rdi)
   d:   c3                      retq   

但是一个带有浮点字面量的函数为:

void _start (float *i, float *o, float *m)
{
    i[0] = m[0] + 3.0f;
}

生成的代码在执行时不会给出正确的结果

gcc -O3 -c code.c
objdump -d code.o

code.o:     formato del file elf64-x86-64


Disassemblamento della sezione .text:

0000000000000000 <_start>:
   0:   f3 0f 10 05 00 00 00    movss  0x0(%rip),%xmm0        # 8 <_start+0x8>
   7:   00 
   8:   f3 0f 58 02             addss  (%rdx),%xmm0
   c:   f3 0f 11 07             movss  %xmm0,(%rdi)
  10:   c3                      retq

每次使用 %rip 生成指令时都会发生这种情况。 如何将 gcc 设置为不生成此代码?理论上,插入浮点常量可以是here还是不?

您有什么建议可以避免这个问题?

【问题讨论】:

    标签: c gcc assembly shared-objects objcopy


    【解决方案1】:

    编译器将常量放入您甚至不复制的.rodata 部分,因此这不仅仅是一个重定位问题。您可以使用自定义链接器脚本来根据需要合并和重新定位代码,而不是 objcopy,如下所示:

    OUTPUT_FORMAT(binary)
    
    SECTIONS
    {
        merged : {
            *(.text)
            *(.rodata)
        } = 0x90
    
        /DISCARD/ : {
            *(*) /* discard everything else */
        }
    }
    

    不确定为什么要避免共享对象,那将是最简单的解决方案。你可以直接dlopen他们而不用关心细节。

    【讨论】:

    • 感谢它的工作!我想避免共享对象,因为对于如此小的功能来说,加载数千个 .so 似乎很糟糕,而且因为我将其作为一种爱好
    最近更新 更多