abumandour
abumandour

Reputation: 1369

Why are instructions addresses on the top of the memory user space contrary to the linux process memory layout?

#include <stdio.h>
void func() {}

int main() {
    printf("%p", &func);

    return 0;
}

This program outputted 0x55c4cda9464a Supposing that func will be stored in the .text section, and according to this figure, from CS:APP: enter image description here I suppose that the address of func would be somewhere near the starting address of the .text section, but this address is somewhere in the middle. Why is this the case? Local variables stored on the stack have addresses near 2^48 - 1, but I tried to disassemble different C codes and the instructions were always located somewhere around that 0x55... address.

Upvotes: 9

Views: 1083

Answers (1)

P.P
P.P

Reputation: 121407

gcc, when configured with --enable-default-pie1 (which is the default), produces Position Independent Executables(PIE). Which means the load address isn't same as what linker specified at compile-time (0x400000 for x86_64). This is a security mechanism so that Address Space Layout Randomization (ASLR) 2 can be enabled. That is, gcc compiles with -pie option by default.

If you compile with -no-pie option (gcc -no-pie file.c), then you can see the address of func is closer to 0x400000.

On my system, I get:

$ gcc -no-pie t.c
$ ./a.out 
0x401132

You can also check the load address with readelf:

$ readelf -Wl a.out | grep LOAD
 LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x000478 0x000478 R   0x1000
 LOAD           0x001000 0x0000000000401000 0x0000000000401000 0x0001f5 0x0001f5 R E 0x1000
 LOAD           0x002000 0x0000000000402000 0x0000000000402000 0x000158 0x000158 R   0x1000
 LOAD           0x002e10 0x0000000000403e10 0x0000000000403e10 0x000228 0x000230 RW  0x1000

1 you can check this with gcc --verbose.

2 You may also notice that address printed by your program is different in each run. That's because of ASLR. You can disable it with:

$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

ASLR is enabled on Linux by default.

Upvotes: 5

Related Questions