Browse Source

core/sys/unix: Add syscalls_linux.odin

Linux is in the unfortunate situation where the system call number is
architecture specific.  This consolidates the system call number
definitions in a single location, adds some wrappers, and hopefully
fixes the existing non-portable invocations of the syscall intrinsic.
Yawning Angel 3 years ago
parent
commit
61c581baeb

+ 34 - 42
core/mem/virtual/virtual_linux.odin

@@ -4,64 +4,56 @@ package mem_virtual
 
 import "core:c"
 import "core:intrinsics"
+import "core:sys/unix"
 
-when ODIN_ARCH == "amd64" {
-	SYS_mmap     :: 9
-	SYS_mprotect :: 10
-	SYS_munmap   :: 11
-	SYS_madvise  :: 28
-	
-	PROT_NONE  :: 0x0
-	PROT_READ  :: 0x1
-	PROT_WRITE :: 0x2
-	PROT_EXEC  :: 0x4
-	PROT_GROWSDOWN :: 0x01000000
-	PROT_GROWSUP :: 0x02000000
+PROT_NONE  :: 0x0
+PROT_READ  :: 0x1
+PROT_WRITE :: 0x2
+PROT_EXEC  :: 0x4
+PROT_GROWSDOWN :: 0x01000000
+PROT_GROWSUP :: 0x02000000
 
-	MAP_FIXED     :: 0x1
-	MAP_PRIVATE   :: 0x2
-	MAP_SHARED    :: 0x4
-	MAP_ANONYMOUS :: 0x20
-	
-	MADV_NORMAL      :: 0
-	MADV_RANDOM      :: 1
-	MADV_SEQUENTIAL  :: 2
-	MADV_WILLNEED    :: 3
-	MADV_DONTNEED    :: 4
-	MADV_FREE        :: 8
-	MADV_REMOVE      :: 9
-	MADV_DONTFORK    :: 10
-	MADV_DOFORK      :: 11
-	MADV_MERGEABLE   :: 12
-	MADV_UNMERGEABLE :: 13
-	MADV_HUGEPAGE    :: 14
-	MADV_NOHUGEPAGE  :: 15
-	MADV_DONTDUMP    :: 16
-	MADV_DODUMP      :: 17
-	MADV_WIPEONFORK  :: 18
-	MADV_KEEPONFORK  :: 19
-	MADV_HWPOISON    :: 100
-} else {
-	#panic("Unsupported architecture")
-}
+MAP_FIXED     :: 0x1
+MAP_PRIVATE   :: 0x2
+MAP_SHARED    :: 0x4
+MAP_ANONYMOUS :: 0x20
+
+MADV_NORMAL      :: 0
+MADV_RANDOM      :: 1
+MADV_SEQUENTIAL  :: 2
+MADV_WILLNEED    :: 3
+MADV_DONTNEED    :: 4
+MADV_FREE        :: 8
+MADV_REMOVE      :: 9
+MADV_DONTFORK    :: 10
+MADV_DOFORK      :: 11
+MADV_MERGEABLE   :: 12
+MADV_UNMERGEABLE :: 13
+MADV_HUGEPAGE    :: 14
+MADV_NOHUGEPAGE  :: 15
+MADV_DONTDUMP    :: 16
+MADV_DODUMP      :: 17
+MADV_WIPEONFORK  :: 18
+MADV_KEEPONFORK  :: 19
+MADV_HWPOISON    :: 100
 
 mmap :: proc "contextless" (addr: rawptr, length: uint, prot: c.int, flags: c.int, fd: c.int, offset: uintptr) -> rawptr {
-	res := intrinsics.syscall(SYS_mmap, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), offset)
+	res := intrinsics.syscall(unix.SYS_mmap, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), offset)
 	return rawptr(res)
 }
 
 munmap :: proc "contextless" (addr: rawptr, length: uint) -> c.int {
-	res := intrinsics.syscall(SYS_munmap, uintptr(addr), uintptr(length))
+	res := intrinsics.syscall(unix.SYS_munmap, uintptr(addr), uintptr(length))
 	return c.int(res)
 }
 
 mprotect :: proc "contextless" (addr: rawptr, length: uint, prot: c.int) -> c.int {
-	res := intrinsics.syscall(SYS_mprotect, uintptr(addr), uintptr(length), uint(prot))
+	res := intrinsics.syscall(unix.SYS_mprotect, uintptr(addr), uintptr(length), uint(prot))
 	return c.int(res)
 }
 
 madvise :: proc "contextless" (addr: rawptr, length: uint, advice: c.int) -> c.int {
-	res := intrinsics.syscall(SYS_madvise, uintptr(addr), uintptr(length), uintptr(advice))
+	res := intrinsics.syscall(unix.SYS_madvise, uintptr(addr), uintptr(length), uintptr(advice))
 	return c.int(res)
 }
 

+ 2 - 3
core/os/os_linux.odin

@@ -8,6 +8,7 @@ import "core:strings"
 import "core:c"
 import "core:strconv"
 import "core:intrinsics"
+import "core:sys/unix"
 
 Handle    :: distinct i32
 File_Time :: distinct u64
@@ -265,8 +266,6 @@ X_OK :: 1 // Test for execute permission
 W_OK :: 2 // Test for write permission
 R_OK :: 4 // Test for read permission
 
-SYS_GETTID :: 186
-
 foreign libc {
 	@(link_name="__errno_location") __errno_location    :: proc() -> ^int ---
 
@@ -594,7 +593,7 @@ exit :: proc "contextless" (code: int) -> ! {
 }
 
 current_thread_id :: proc "contextless" () -> int {
-	return cast(int)intrinsics.syscall(SYS_GETTID)
+	return unix.sys_gettid()
 }
 
 dlopen :: proc(filename: string, flags: int) -> rawptr {

+ 2 - 1
core/sync/sync2/futex_linux.odin

@@ -5,6 +5,7 @@ package sync2
 import "core:c"
 import "core:time"
 import "core:intrinsics"
+import "core:sys/unix"
 
 FUTEX_WAIT :: 0
 FUTEX_WAKE :: 1
@@ -34,7 +35,7 @@ get_errno :: proc(r: int) -> int {
 }
 
 internal_futex :: proc(f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> int {
-	code := int(intrinsics.syscall(202, uintptr(f), uintptr(op), uintptr(val), uintptr(timeout), 0, 0))
+	code := int(intrinsics.syscall(unix.SYS_futex, uintptr(f), uintptr(op), uintptr(val), uintptr(timeout), 0, 0))
 	return get_errno(code)
 }
 

+ 2 - 3
core/sync/sync2/primitives_linux.odin

@@ -2,9 +2,8 @@
 //+private
 package sync2
 
-import "core:intrinsics"
+import "core:sys/unix"
 
 _current_thread_id :: proc "contextless" () -> int {
-	SYS_GETTID :: 186
-	return int(intrinsics.syscall(SYS_GETTID))
+	return unix.sys_gettid()
 }

+ 1 - 3
core/sync/sync_linux.odin

@@ -1,11 +1,9 @@
 package sync
 
 import "core:sys/unix"
-import "core:intrinsics"
 
 current_thread_id :: proc "contextless" () -> int {
-	SYS_GETTID :: 186
-	return int(intrinsics.syscall(SYS_GETTID))
+	return unix.sys_gettid()
 }
 
 

+ 60 - 0
core/sys/unix/syscalls_linux.odin

@@ -0,0 +1,60 @@
+package unix
+
+import "core:intrinsics"
+
+// Linux has inconsistent system call numbering across architectures,
+// for largely historical reasons.  This attempts to provide a unified
+// Odin-side interface for system calls that are required for the core
+// library to work.
+
+// For authorative system call numbers, the following files in the kernel
+// source can be used:
+//
+//  amd64: arch/x86/entry/syscalls/syscall_64.tbl
+//  arm64: include/uapi/asm-generic/unistd.h
+//  386: arch/x86/entry/syscalls/sycall_32.tbl
+//  arm: arch/arm/tools/syscall.tbl
+
+when ODIN_ARCH == "amd64" {
+	SYS_mmap : uintptr : 9
+	SYS_mprotect : uintptr : 10
+	SYS_munmap : uintptr : 11
+	SYS_madvise : uintptr : 28
+	SYS_futex : uintptr : 202
+	SYS_gettid : uintptr : 186
+	SYS_getrandom : uintptr : 318
+} else when ODIN_ARCH == "arm64" {
+	SYS_mmap : uintptr : 222
+	SYS_mprotect : uintptr : 226
+	SYS_munmap : uintptr : 215
+	SYS_madvise : uintptr : 233
+	SYS_futex : uintptr : 98
+	SYS_gettid : uintptr : 178
+	SYS_getrandom : uintptr : 278
+} else when ODIN_ARCH == "386" {
+	SYS_mmap : uintptr : 192 // 90 is "sys_old_mmap", we want mmap2
+	SYS_mprotect : uintptr : 125
+	SYS_munmap : uintptr : 91
+	SYS_madvise : uintptr : 219
+	SYS_futex : uintptr : 240
+	SYS_gettid : uintptr : 224
+	SYS_getrandom : uintptr : 355
+} else when ODIN_ARCH == "arm" {
+	SYS_mmap : uintptr : 192 // 90 is "sys_old_mmap", we want mmap2
+	SYS_mprotect : uintptr : 125
+	SYS_munmap: uintptr : 91
+	SYS_madvise: uintptr : 220
+	SYS_futex : uintptr : 240
+	SYS_gettid : uintptr: 224
+	SYS_getrandom : uintptr : 384
+} else {
+	#panic("Unsupported architecture")
+}
+
+sys_gettid :: proc "contextless" () -> int {
+	return cast(int)intrinsics.syscall(SYS_gettid)
+}
+
+sys_getrandom :: proc "contextless" (buf: ^byte, buflen: int, flags: uint) -> int {
+	return cast(int)intrinsics.syscall(SYS_getrandom, buf, cast(uintptr)(buflen), cast(uintptr)(flags))
+}