// Package syscall provides the syscall primitives required for the runtime.
package syscall
+import (
+ _ "unsafe" // for go:linkname
+)
+
// TODO(https://go.dev/issue/51087): This package is incomplete and currently
// only contains very minimal support for Linux.
// Syscall6 calls system call number 'num' with arguments a1-6.
func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr)
+
+// syscall_RawSyscall6 is a push linkname to export Syscall6 as
+// syscall.RawSyscall6.
+//
+// //go:uintptrkeepalive because the uintptr argument may be converted pointers
+// that need to be kept alive in the caller (this is implied for Syscall6 since
+// it has no body).
+//
+// //go:nosplit because stack copying does not account for uintptrkeepalive, so
+// the stack must not grow. Stack copying cannot blindly assume that all
+// uintptr arguments are pointers, because some values may look like pointers,
+// but not really be pointers, and adjusting their value would break the call.
+//
+// This is a separate wrapper because we can't export one function as two
+// names. The assembly implementations name themselves Syscall6 would not be
+// affected by a linkname.
+//
+//go:uintptrkeepalive
+//go:nosplit
+//go:linkname syscall_RawSyscall6 syscall.RawSyscall6
+func syscall_RawSyscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) {
+ return Syscall6(num, a1, a2, a3, a4, a5, a6)
+}
MOVL $0, err+24(FP)
RET
-// func RawSyscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- MOVL trap+0(FP), AX // syscall entry
- MOVL a1+4(FP), BX
- MOVL a2+8(FP), CX
- MOVL a3+12(FP), DX
- MOVL a4+16(FP), SI
- MOVL a5+20(FP), DI
- MOVL a6+24(FP), BP
- INVOKE_SYSCALL
- CMPL AX, $0xfffff001
- JLS ok2
- MOVL $-1, r1+28(FP)
- MOVL $0, r2+32(FP)
- NEGL AX
- MOVL AX, err+36(FP)
- RET
-ok2:
- MOVL AX, r1+28(FP)
- MOVL DX, r2+32(FP)
- MOVL $0, err+36(FP)
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
MOVL trap+0(FP), AX // syscall entry
MOVQ $0, err+48(FP)
RET
-// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- MOVQ a1+8(FP), DI
- MOVQ a2+16(FP), SI
- MOVQ a3+24(FP), DX
- MOVQ a4+32(FP), R10
- MOVQ a5+40(FP), R8
- MOVQ a6+48(FP), R9
- MOVQ trap+0(FP), AX // syscall entry
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS ok2
- MOVQ $-1, r1+56(FP)
- MOVQ $0, r2+64(FP)
- NEGQ AX
- MOVQ AX, err+72(FP)
- RET
-ok2:
- MOVQ AX, r1+56(FP)
- MOVQ DX, r2+64(FP)
- MOVQ $0, err+72(FP)
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOVQ a1+8(FP), DI
BL runtime·exitsyscall(SB)
RET
-// func RawSyscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
-// Actually RawSyscall5 but the rest of the code expects it to be named RawSyscall6.
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
- MOVW trap+0(FP), R7 // syscall entry
- MOVW a1+4(FP), R0
- MOVW a2+8(FP), R1
- MOVW a3+12(FP), R2
- MOVW a4+16(FP), R3
- MOVW a5+20(FP), R4
- MOVW a6+24(FP), R5
- SWI $0
- MOVW $0xfffff001, R6
- CMP R6, R0
- BLS ok2
- MOVW $-1, R1
- MOVW R1, r1+28(FP)
- MOVW $0, R2
- MOVW R2, r2+32(FP)
- RSB $0, R0, R0
- MOVW R0, err+36(FP)
- RET
-ok2:
- MOVW R0, r1+28(FP)
- MOVW R1, r2+32(FP)
- MOVW $0, R0
- MOVW R0, err+36(FP)
- RET
-
#define SYS__LLSEEK 140 /* from zsysnum_linux_arm.go */
// func seek(fd int, offset int64, whence int) (newoffset int64, errno int)
// Implemented in assembly to avoid allocation when
MOVD ZR, err+48(FP) // errno
RET
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- MOVD a1+8(FP), R0
- MOVD a2+16(FP), R1
- MOVD a3+24(FP), R2
- MOVD a4+32(FP), R3
- MOVD a5+40(FP), R4
- MOVD a6+48(FP), R5
- MOVD trap+0(FP), R8 // syscall entry
- SVC
- CMN $4095, R0
- BCC ok
- MOVD $-1, R4
- MOVD R4, r1+56(FP) // r1
- MOVD ZR, r2+64(FP) // r2
- NEG R0, R0
- MOVD R0, err+72(FP) // errno
- RET
-ok:
- MOVD R0, r1+56(FP) // r1
- MOVD R1, r2+64(FP) // r2
- MOVD ZR, err+72(FP) // errno
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
MOVD a1+8(FP), R0
MOVV R0, err+48(FP) // errno
RET
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- MOVV a1+8(FP), R4
- MOVV a2+16(FP), R5
- MOVV a3+24(FP), R6
- MOVV a4+32(FP), R7
- MOVV a5+40(FP), R8
- MOVV a6+48(FP), R9
- MOVV trap+0(FP), R2 // syscall entry
- SYSCALL
- BEQ R7, ok2
- MOVV $-1, R1
- MOVV R1, r1+56(FP) // r1
- MOVV R0, r2+64(FP) // r2
- MOVV R2, err+72(FP) // errno
- RET
-ok2:
- MOVV R2, r1+56(FP) // r1
- MOVV R3, r2+64(FP) // r2
- MOVV R0, err+72(FP) // errno
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOVV a1+8(FP), R4
MOVW R0, err+24(FP) // errno
RET
-TEXT ·RawSyscall6(SB),NOSPLIT,$20-40
- MOVW a1+4(FP), R4
- MOVW a2+8(FP), R5
- MOVW a3+12(FP), R6
- MOVW a4+16(FP), R7
- MOVW a5+20(FP), R8
- MOVW a6+24(FP), R9
- MOVW R8, 16(R29)
- MOVW R9, 20(R29)
- MOVW trap+0(FP), R2 // syscall entry
- SYSCALL
- BEQ R7, ok2
- MOVW $-1, R1
- MOVW R1, r1+28(FP) // r1
- MOVW R0, r2+32(FP) // r2
- MOVW R2, err+36(FP) // errno
- RET
-ok2:
- MOVW R2, r1+28(FP) // r1
- MOVW R3, r2+32(FP) // r2
- MOVW R0, err+36(FP) // errno
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
MOVW a1+4(FP), R4
MOVD R0, err+48(FP) // errno
RET
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- MOVD a1+8(FP), R3
- MOVD a2+16(FP), R4
- MOVD a3+24(FP), R5
- MOVD a4+32(FP), R6
- MOVD a5+40(FP), R7
- MOVD a6+48(FP), R8
- MOVD trap+0(FP), R9 // syscall entry
- SYSCALL R9
- BVC ok2
- MOVD $-1, R4
- MOVD R4, r1+56(FP) // r1
- MOVD R0, r2+64(FP) // r2
- MOVD R3, err+72(FP) // errno
- RET
-ok2:
- MOVD R3, r1+56(FP) // r1
- MOVD R0, r2+64(FP) // r2
- MOVD R0, err+72(FP) // errno
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOVD a1+8(FP), R3
MOV A0, err+48(FP) // errno
RET
-// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- MOV a1+8(FP), A0
- MOV a2+16(FP), A1
- MOV a3+24(FP), A2
- MOV a4+32(FP), A3
- MOV a5+40(FP), A4
- MOV a6+48(FP), A5
- MOV trap+0(FP), A7 // syscall entry
- ECALL
- MOV $-4096, T0
- BLTU T0, A0, err
- MOV A0, r1+56(FP) // r1
- MOV A1, r2+64(FP) // r2
- MOV ZERO, err+72(FP) // errno
- RET
-err:
- MOV $-1, T0
- MOV T0, r1+56(FP) // r1
- MOV ZERO, r2+64(FP) // r2
- SUB A0, ZERO, A0
- MOV A0, err+72(FP) // errno
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOV a1+8(FP), A0
MOVD $0, err+48(FP) // errno
RET
-// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
- MOVD a1+8(FP), R2
- MOVD a2+16(FP), R3
- MOVD a3+24(FP), R4
- MOVD a4+32(FP), R5
- MOVD a5+40(FP), R6
- MOVD a6+48(FP), R7
- MOVD trap+0(FP), R1 // syscall entry
- SYSCALL
- MOVD $0xfffffffffffff001, R8
- CMPUBLT R2, R8, ok2
- MOVD $-1, r1+56(FP)
- MOVD $0, r2+64(FP)
- NEG R2, R2
- MOVD R2, err+72(FP) // errno
- RET
-ok2:
- MOVD R2, r1+56(FP)
- MOVD R3, r2+64(FP)
- MOVD $0, err+72(FP) // errno
- RET
-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
MOVD $0, R2
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+
+// N.B. RawSyscall6 is provided via linkname by runtime/internal/syscall.
+//
+// Errno is uintptr and thus compatible with the runtime/internal/syscall
+// definition.
+
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)