Following up Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0? and Why do virtual memory addresses for linux binaries start at 0x8048000?, why cannot I make ld
use a different entry point than the default with ld -e
?
If I do so, I either get a segmentation fault
with return code 139, even for addresses close by the default entry point. Why?
EDIT:
I will make the question more specific:
.text
.globl _start
_start:
movl $0x4,%eax # eax = code for 'write' system call
movl $1,%ebx # ebx = file descriptor to standard output
movl $message,%ecx # ecx = pointer to the message
movl $13,%edx # edx = length of the message
int $0x80 # make the system call
movl $0x0,%ebx # the status returned by 'exit'
movl $0x1,%eax # eax = code for 'exit' system call
int $0x80 # make the system call
.data
.globl message
message:
.string "Hello world\n" # The message as data
If I compile this with as program.s -o program.o
and then link it statically with ld -N program.o -o program
, readelf -l program
shows 0x0000000000400078
as the VirtAddr
of the text segment and 0x400078
as entry point. When run, `Hello world" is printed.
However, when I try to link with ld -N -e0x400082 -Ttext=0x400082 program.o -o program
(moving text segment and entry point by 4 bytes), the program will be killed
. Inspecting it with readelf -l
now shows two different headers of type LOAD
, one at 0x0000000000400082
and one at 0x00000000004000b0
.
When I try 0x400086
, it all works, and there is only one LOAD
section.
- What's going on here?
- Which memory addresses may I chose, which ones cannot I chose and why?
Thanks you.