Can I make clang generate absolute addresses for f

2019-07-23 13:40发布

问题:

Here's a simplified version of some code I'm working with right now:

int Do_A_Thing(void)
{
    return(42);
}

void Some_Function(void)
{
    int (*fn_do_thing)(void) = Do_A_Thing;

    fn_do_thing();
}

When I compile this in xcode 4.1, the assembler it generates sets the fn_do_thing variable like so:

0x2006: calll  0x200b              ;
0x200b: popl   %eax                ; get EIP
0x200c: movl   1333(%eax), %eax

I.e. it generates a relative address for the place to find the Do_A_Thing function - "current instruction plus 1333", which according to the map file is a "non-lazy pointer" to the function.

When I compile similar code on Windows with Visual Studio, windows generates a fixed address instead of doing it relatively like this. If Do_A_Thing lives at, for example, 0x40050914, it just sets fn_do_thing to 0x40050914. By contrast, xcode sets it to "where I am + some offset".

Is there any way to make xcode generate an absolute address to set the function pointer to, like visual studio does? Or is there some reason that wouldn't work? I have noticed that every time I run the program, the Do_A_Thing function (and all other functions) seem to load at a different address.

回答1:

You're looking at position independent code (more specifically Position Independent Executable) in action. This, as you noticed, allows the OS to load the binary anywhere in memory, which provides numerous security improvements for potentially insecure code.

You can disable it via removing a linker option in XCode (-Wl,-pie).

Note that on x86_64 (amd64), instructions can operate relative to the instruction pointer, which improves the efficiency of this technique (and makes it basically "free" in performance cost).