As mentioned by Employed, the entry address is not fixed.
Just to verify, I've tried on x86_64:
gcc -Wl,-Ttext-segment=0x800000 hello_world.c
which sets the entry point to 0x800000
(+ the ELF header size, which gets loaded at 0x800000
in memory) instead of the default 0x400000
.
Then both:
readelf -h a.out
and gdb -ex 'b _start'
tell me the entry is at 0x800440
as expected (the header is 0x440
bytes).
This is because that value is an input that tells the Linux kernel where to set the PC when forking a new process.
The default 0x400000
comes from the default linker script used. You can also modify the linker script as mentioned in https://stackoverflow.com/a/31380105/895245 , change 0x400000 there, and use the new script with -T script
If I put it at anything below 0x200000 (2Mb) exactly or other low addresses, the program gets killed. I think this is because ld always loads the sections at multiples of 2Mb, which is the largest page size supported (in huge page), so anything lower starts at 0
, which is bad: Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0?