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-12 06:22:17 +00:00
parent 6c4c9aef61
commit 61c581baeb
6 changed files with 101 additions and 52 deletions

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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()
}

View File

@@ -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()
}

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))
}