diff options
Diffstat (limited to 'stand/kboot/libkboot/arch/amd64')
-rw-r--r-- | stand/kboot/libkboot/arch/amd64/host_syscall.S | 31 | ||||
-rw-r--r-- | stand/kboot/libkboot/arch/amd64/start_arch.h | 34 |
2 files changed, 65 insertions, 0 deletions
diff --git a/stand/kboot/libkboot/arch/amd64/host_syscall.S b/stand/kboot/libkboot/arch/amd64/host_syscall.S new file mode 100644 index 000000000000..0869bfe245f6 --- /dev/null +++ b/stand/kboot/libkboot/arch/amd64/host_syscall.S @@ -0,0 +1,31 @@ +#include <machine/asm.h> + +/* + * Emulate the Linux system call interface. The system call number is set in + * %rax, and %rdi, %rsi, %rdx, %r10, %r8, %r9 have the 6 system call + * arguments. errno is returned as a negative value, but we use it more as a + * flag something went wrong rather than using its value. + * + * Note: For system calls, we use %r10 instead of %rcx for the 4th argument. + * See section A.2.1 for the Linux calling conventions of the ABI spec + * https://web.archive.org/web/20160801075146/http://www.x86-64.org/documentation/abi.pdf + * In addition to the below, %r11 and %rcx are destroyed, negative + * values are ERRNO for %rax between -1 and -4095 otherwise the system + * call is successful. Unlike other Unix systems, carry isn't used to + * signal an error in the system call. We expose the raw system call + * result, rather than do the POSIX converion to -1 and setting errno. + */ +ENTRY(host_syscall) + movq %rdi, %rax /* SYS_ number in %rax */ + movq %rsi, %rdi /* arg2 -> 1 */ + movq %rdx, %rsi /* arg3 -> 2 */ + movq %rcx, %rdx /* arg4 -> 3 */ + movq %r8, %r10 /* arg5 -> 4 */ + movq %r9, %r8 /* arg6 -> 5 */ + movq 8(%rsp),%r9 /* arg7 -> 6 from stack. */ + syscall + ret +/* Note: We're exposing the raw return value to the caller */ +END(host_syscall) + + .section .note.GNU-stack,"",%progbits diff --git a/stand/kboot/libkboot/arch/amd64/start_arch.h b/stand/kboot/libkboot/arch/amd64/start_arch.h new file mode 100644 index 000000000000..818a5b277c10 --- /dev/null +++ b/stand/kboot/libkboot/arch/amd64/start_arch.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* + * Provides a _start routine that calls a _start_c routine that takes a pointer + * to the stack as documented in crt1.c. We skip the pointer to _DYNAMIC since + * we don't support dynamic libraries, at all. And while _start_c is our own + * thing, we comport to the calling conventions that glibc and musl have and + * make sure the second argument (%esi) is 0 for _DYNAMIC placeholder. We + * likely could call main directly with only a few more lines of code, but this + * is simple enough and concentrates all the expressable in C stuff there. We + * also generate eh_frames should we need to debug things (it doesn't change the + * genreated code, but leaves enough breadcrumbs to keep gdb happy). + */ + +__asm__( +".text\n" /* ENTRY(_start) */ +".p2align 4,0x90\n" +".global _start\n" +".type _start, @function\n" +"_start:\n" +".cfi_startproc\n" +" xor %rbp, %rbp\n" /* Clear out the stack frame pointer */ +" mov %rsp, %rdi\n" /* Pass pointer to current stack with argc, argv and envp on it */ +" xor %rsi, %rsi\n" /* No dynamic pointer for us, to keep it simple */ +" andq $-16, %rsp\n" /* Align stack to 16-byte boundary */ +" call _start_c\n" /* Our MI code takes it from here and won't return */ +/* NORETURN */ +".size _start, . - _start\n" /* END(_start) */ +".cfi_endproc" +); |