'How do assembly system calls in FreeBSD on ARM64 machines work?
I would like to port some assembly code from macOS (M1) to FreeBSD on a Raspberry Pi 4. Since they are both based on ARM64 processors, this should not be too difficult in theory, but I cannot find anything on how to properly execute syscalls in FreeBSD on ARM64 architectures.
Here is my sample HelloWorld program that works fine on macOS,
.global _main
.align 4
_main:
mov X0, #1 // arg[0] = 1 = STDOUT
adr X1, helloworld // arg[1] = string to print
mov X2, #16 // arg[2] = length of our string
mov X16, #4 // Unix write system call
svc #0x80 // call kernel to output the string
mov X0, #0 // use 0 return code
mov X16, #1 // Unix exit system call
svc #0x80 // call kernel to end program
helloworld: .ascii "Hello M1-World!\n"
So far, I found out the following changes I need to make to have it run on FreeBSD:
- Change
_mainto_start - Change register X16 to X8 (the register that holds the syscall number)
Also, the system call numbers seem to be correct (same as on macOS), judging from the content of /usr/include/sys/syscall.h. So that would make it:
.global _start
.align 4
_start:
mov X0, #1 // arg[0] = 1 = STDOUT
adr X1, helloworld // arg[1] = string to print
mov X2, #16 // arg[2] = length of our string
mov X8, #4 // Unix write system call
svc #0x80 // call kernel to output the string
mov X0, #0 // use 0 return code
mov X8, #1 // Unix exit system call
svc #0x80 // call kernel to end program
helloworld: .ascii "Hello M1-World!\n"
Then I can assemble and link the program with
cc -g -c hello.asm
ld hello.o -o hello
and running it in the debugger gdb shows that it works until it hits the first svc instruction, when it terminates with
Program received signal SIGILL, Illegal instruction.
Illegal operand.
So my question is, how do I make this work? More precisely,
- Is
svcthe correct instruction for a syscall? - If so, does it matter what argument we pass for
svc? (My choice of 0x80 here was arbitrary, as it in fact does not matter on macOS.) - What is the calling convention for FreeBSD ARM64 syscalls? (Here, I assumed it is passing the arguments in register X0, X1, X2,... as this is the conventions on macOS or ARM64 Linux.)
Thanks.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
