I've been reading the ELF specification and cannot figure out where the program entry point and _start address come from.
It seems like they should have to be in a pretty consistent place, but I made a few trivial programs, and _start is always in a different place.
Can anyone clarify?
The
_start
symbol may be defined in any object file. Normally it is generated automatically (it corresponds tomain
in C). You can generate it yourself, for instance in an assembler source file:When the linker has processed all object files it looks for the
_start
symbol and puts its value in thee_entry
field of the elf header. The loader takes the address from this field and makes a call to it after it has finished loading all sections in memory and is ready to execute the file.Take a look at the linker script
ld
is using:The format is documented at: https://sourceware.org/binutils/docs-2.25/ld/Scripts.html
It determines basically everything about how the executable will be generated.
On Binutils 2.24 Ubuntu 14.04 64-bit, it contains the line:
which sets the entry point to the
_start
symbol (goes to the ELF header as mentioned by ctn)And then:
which sets the address of the first headers to
0x400000
+SIZEOF_HEADERS
.I have modified that address to
0x800000
, passed my custom script withld -T
and it worked:readelf -s
says that_start
is at that address.Another way to change it is to use the
-Ttext-segment=0x800000
option.The reason for using
0x400000
= 4Mb =getconf PAGE_SIZE
is to start at the beginning of the second page as asked at: Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0?A question describes how to set
_start
from the command line: Why is the ELF entry point 0x8048000 not changeable with the "ld -e" option?SIZEOF_HEADERS
is the size of the ELF + program headers, which are at the beginning of the ELF file. That data gets loaded into the very beginning of the virtual memory space by Linux (TODO why?) In a minimal Linux x86-64 hello world with 2 program headers it is worth0xb0
, so that the_start
symbol comes at 0x4000b0.I'm not sure but try this link http://www.docstoc.com/docs/23942105/UNIX-ELF-File-Format at page 8 it is shown where the entry point is if it is executable. Basically you need to calculate the offset and you got it. Make sure to remember the little endianness of x86 ( i guess you use it) and reorder if you read bytewise edit: or maybe not i'm not quit sure about this to be honest.