aboutsummaryrefslogtreecommitdiff
path: root/stand/kboot/libkboot/arch/amd64
diff options
context:
space:
mode:
Diffstat (limited to 'stand/kboot/libkboot/arch/amd64')
-rw-r--r--stand/kboot/libkboot/arch/amd64/host_syscall.S31
-rw-r--r--stand/kboot/libkboot/arch/amd64/start_arch.h34
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"
+);