From c430a827216b7c79e5df70ed20a1acd98abc92f2 Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Sat, 13 Nov 2021 09:41:59 +0000 Subject: src: Fix the syscall intrinsic code generation for Linux and Windows The old assembly generated for the syscall intrinsic did not specify clobber constraints. This adds RCX and R11 (that are clobbered by the instruction itself), and memory (that is clobbered by some system calls) to the assembly constraints. Note: This is still incorrect on FreeBSD, which clobbers more registers and uses the carry flag instead of -errno in rax to indicate an error. --- src/llvm_backend_proc.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/llvm_backend_proc.cpp') diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 2b094cfae..8b8559cae 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2002,7 +2002,22 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, constraints = gb_string_appendc(constraints, regs[i]); constraints = gb_string_appendc(constraints, "}"); } - + + // The SYSCALL instruction stores the address of the + // following instruction into RCX, and RFLAGS in R11. + // + // RSP is not saved, but at least on Linux it appears + // that the kernel system-call handler does the right + // thing. + // + // Some but not all system calls will additionally + // clobber memory. + // + // TODO: FreeBSD is different and will also clobber + // R8, R9, and R10. Additionally CF is used to + // indicate an error instead of -errno. + constraints = gb_string_appendc(constraints, ",~{rcx},~{r11},~{memory}"); + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; -- cgit v1.2.3