1

I'm implementing a genetic algorithm, the creatures are functions that have three pointers as input and output. All have the form:

// No need for global variables

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

The creatures should be a few thousand, and very small, so I decided not to use shared objects but simply load raw code and run it.

The creatures are compiled

gcc -O3 -c code.c

then I take the code of the function in this way

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

and then load the code into memory and run it

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

This work until in the source code there aren't floating-point literals, for example the code:

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

Compilated produces this working code:

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   

But a function with floating-point literal as:

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

Produces a code that when executed doesn't give the correct result

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

And this happens every time that a instruction is generated using %rip. How do I setting gcc to not generate this code? In theory, to insert a floating-point constant can be done as here or not?

You have any suggestion to avoid this problem?

Community
  • 1
  • 1

1 Answers1

0

The compiler puts the constants into the .rodata section which you don't even copy, so it isn't just a relocation problem. You could use a custom linker script that merges and relocates the code as necessary instead of objcopy, as follows:

OUTPUT_FORMAT(binary)

SECTIONS
{
    merged : {
        *(.text)
        *(.rodata)
    } = 0x90

    /DISCARD/ : {
        *(*) /* discard everything else */
    }
}

Not sure why you wanted to avoid shared objects, that would be the simplest solution. You could just dlopen them and don't bother with the details.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • Thanks it works! I wanted to avoid shared objects because it seems bad load thousands of .so for functions such small, and because I'm doing it as a hobby – Alberto Boldrini Mar 05 '13 at 14:05