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.
This commit is contained in:
Yawning Angel
2021-11-17 14:00:00 +00:00
parent 6c4c9aef61
commit 61c581baeb
6 changed files with 101 additions and 52 deletions
+33 -41
View File
@@ -4,64 +4,56 @@ package mem_virtual
import "core:c" import "core:c"
import "core:intrinsics" import "core:intrinsics"
import "core:sys/unix"
when ODIN_ARCH == "amd64" { PROT_NONE :: 0x0
SYS_mmap :: 9 PROT_READ :: 0x1
SYS_mprotect :: 10 PROT_WRITE :: 0x2
SYS_munmap :: 11 PROT_EXEC :: 0x4
SYS_madvise :: 28 PROT_GROWSDOWN :: 0x01000000
PROT_GROWSUP :: 0x02000000
PROT_NONE :: 0x0 MAP_FIXED :: 0x1
PROT_READ :: 0x1 MAP_PRIVATE :: 0x2
PROT_WRITE :: 0x2 MAP_SHARED :: 0x4
PROT_EXEC :: 0x4 MAP_ANONYMOUS :: 0x20
PROT_GROWSDOWN :: 0x01000000
PROT_GROWSUP :: 0x02000000
MAP_FIXED :: 0x1 MADV_NORMAL :: 0
MAP_PRIVATE :: 0x2 MADV_RANDOM :: 1
MAP_SHARED :: 0x4 MADV_SEQUENTIAL :: 2
MAP_ANONYMOUS :: 0x20 MADV_WILLNEED :: 3
MADV_DONTNEED :: 4
MADV_NORMAL :: 0 MADV_FREE :: 8
MADV_RANDOM :: 1 MADV_REMOVE :: 9
MADV_SEQUENTIAL :: 2 MADV_DONTFORK :: 10
MADV_WILLNEED :: 3 MADV_DOFORK :: 11
MADV_DONTNEED :: 4 MADV_MERGEABLE :: 12
MADV_FREE :: 8 MADV_UNMERGEABLE :: 13
MADV_REMOVE :: 9 MADV_HUGEPAGE :: 14
MADV_DONTFORK :: 10 MADV_NOHUGEPAGE :: 15
MADV_DOFORK :: 11 MADV_DONTDUMP :: 16
MADV_MERGEABLE :: 12 MADV_DODUMP :: 17
MADV_UNMERGEABLE :: 13 MADV_WIPEONFORK :: 18
MADV_HUGEPAGE :: 14 MADV_KEEPONFORK :: 19
MADV_NOHUGEPAGE :: 15 MADV_HWPOISON :: 100
MADV_DONTDUMP :: 16
MADV_DODUMP :: 17
MADV_WIPEONFORK :: 18
MADV_KEEPONFORK :: 19
MADV_HWPOISON :: 100
} else {
#panic("Unsupported architecture")
}
mmap :: proc "contextless" (addr: rawptr, length: uint, prot: c.int, flags: c.int, fd: c.int, offset: uintptr) -> rawptr { 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) return rawptr(res)
} }
munmap :: proc "contextless" (addr: rawptr, length: uint) -> c.int { 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) return c.int(res)
} }
mprotect :: proc "contextless" (addr: rawptr, length: uint, prot: c.int) -> c.int { 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) return c.int(res)
} }
madvise :: proc "contextless" (addr: rawptr, length: uint, advice: c.int) -> c.int { 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) return c.int(res)
} }
+2 -3
View File
@@ -8,6 +8,7 @@ import "core:strings"
import "core:c" import "core:c"
import "core:strconv" import "core:strconv"
import "core:intrinsics" import "core:intrinsics"
import "core:sys/unix"
Handle :: distinct i32 Handle :: distinct i32
File_Time :: distinct u64 File_Time :: distinct u64
@@ -265,8 +266,6 @@ X_OK :: 1 // Test for execute permission
W_OK :: 2 // Test for write permission W_OK :: 2 // Test for write permission
R_OK :: 4 // Test for read permission R_OK :: 4 // Test for read permission
SYS_GETTID :: 186
foreign libc { foreign libc {
@(link_name="__errno_location") __errno_location :: proc() -> ^int --- @(link_name="__errno_location") __errno_location :: proc() -> ^int ---
@@ -594,7 +593,7 @@ exit :: proc "contextless" (code: int) -> ! {
} }
current_thread_id :: proc "contextless" () -> 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 { dlopen :: proc(filename: string, flags: int) -> rawptr {
+2 -1
View File
@@ -5,6 +5,7 @@ package sync2
import "core:c" import "core:c"
import "core:time" import "core:time"
import "core:intrinsics" import "core:intrinsics"
import "core:sys/unix"
FUTEX_WAIT :: 0 FUTEX_WAIT :: 0
FUTEX_WAKE :: 1 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 { 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) return get_errno(code)
} }
+2 -3
View File
@@ -2,9 +2,8 @@
//+private //+private
package sync2 package sync2
import "core:intrinsics" import "core:sys/unix"
_current_thread_id :: proc "contextless" () -> int { _current_thread_id :: proc "contextless" () -> int {
SYS_GETTID :: 186 return unix.sys_gettid()
return int(intrinsics.syscall(SYS_GETTID))
} }
+1 -3
View File
@@ -1,11 +1,9 @@
package sync package sync
import "core:sys/unix" import "core:sys/unix"
import "core:intrinsics"
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
SYS_GETTID :: 186 return unix.sys_gettid()
return int(intrinsics.syscall(SYS_GETTID))
} }
+60
View File
@@ -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))
}