When linking a program with GNU ld, the text segment in the resulting ELF file should start at 0x0400000
as suggested by the output of:
$> ld -verbose | grep -i text-segment
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
However, take this simple hello world program:
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
and compile it with gcc -no-pie
, then the resulting ELF file has the following LOAD segments:
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0005a8 0x0005a8 R 0x1000
LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x00014d 0x00014d R E 0x1000
LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x0000cc 0x0000cc R 0x1000
LOAD 0x002e00 0x0000000000403e00 0x0000000000403e00 0x000230 0x000238 RW 0x1000
Now it looks like the segment starting at 0x401000
is the text segment since it is marked as executable, but then what is the purpose of the two segments immediately before and after it?