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.
Advertisement
Answer
My assessments (at least on x86_64 Linux with NASM):
- The flags set in
ldMEMORYdefinition are irrelevant in setting the section to executable. The NASM ELF Section extensions are what matter, i.e.section .my_section execwill work even ifMEMORYdoes not havexflag (thanks to @peter-cordes). - If you have specific
ldMEMORYdefinitions that you are using, the origin cannot be0, but must be at least0x10000(see this S.O q&a for more info) Using. = 0x10000;at the start of the section is not sufficient.