Basic Hello World as seen many times before on x86_64 Linux:
global my_start_symbol
section .my_section
my_start_symbol:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msg_len
syscall
mov rax, 60
xor rdi, rdi
syscall
section .rodata:
msg: db "Hello, world!", 10
msg_len: equ $ - msg
My current ld
linker script:
__linux_mmap_min_addr = 0x10000;
ENTRY(my_start_symbol)
MEMORY
{
rom (rx) : ORIGIN = 0, LENGTH = 512K
}
SECTIONS
{
. = __linux_mmap_min_addr;
.my_section :
{
*(.my_section*)
} > rom
.rodata :
{
*(.rodata*)
} > rom
}
Invoked with:
nasm -f elf64 assembly.asm -o assembly.o
ld -T linker.ld assembly.o -o assembly
I'm currently getting a segfault. Inspecting the output of readelf -a
I can see that my_section
does not have executable permissions. I believe this is causing the segfault. If I replace it with .text : { *(.my_section*) } > rom
it still does not get set as executable. Only if I revert to using .text
everywhere as is convention, does it set it as executable.
My assessments (at least on x86_64 Linux with NASM):
ld
MEMORY
definition are irrelevant in setting the section to executable. The NASM ELF Section extensions are what matter, i.e. section .my_section exec
will work even if MEMORY
does not have x
flag (thanks to @peter-cordes).ld
MEMORY
definitions that you are using, the origin cannot be 0
, but must be at least 0x10000
(see this S.O q&a for more info) Using . = 0x10000;
at the start of the section is not sufficient.