Browse Source

Merge pull request #1613 from semarie/linux_arm64

fix Linux arm64 support
gingerBill 3 years ago
parent
commit
633157f4f8
3 changed files with 20 additions and 11 deletions
  1. 3 0
      .github/workflows/ci.yml
  2. 15 11
      core/os/os_linux.odin
  3. 2 0
      core/sys/unix/syscalls_linux.odin

+ 3 - 0
.github/workflows/ci.yml

@@ -90,6 +90,9 @@ jobs:
       - name: Odin check examples/all for Darwin arm64
       - name: Odin check examples/all for Darwin arm64
         run: ./odin check examples/all -vet -strict-style -target:darwin_arm64
         run: ./odin check examples/all -vet -strict-style -target:darwin_arm64
         timeout-minutes: 10
         timeout-minutes: 10
+      - name: Odin check examples/all for Linux arm64
+        run: ./odin check examples/all -vet -strict-style -target:linux_arm64
+        timeout-minutes: 10
   build_windows:
   build_windows:
     runs-on: windows-2019
     runs-on: windows-2019
     steps:
     steps:

+ 15 - 11
core/os/os_linux.odin

@@ -269,7 +269,7 @@ 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
 
 
-AT_FDCWD            :: -100
+AT_FDCWD            :: ~uintptr(99)	/* -100 */
 AT_REMOVEDIR        :: uintptr(0x200)
 AT_REMOVEDIR        :: uintptr(0x200)
 AT_SYMLINK_NOFOLLOW :: uintptr(0x100)
 AT_SYMLINK_NOFOLLOW :: uintptr(0x100)
 
 
@@ -278,7 +278,11 @@ _unix_personality :: proc(persona: u64) -> int {
 }
 }
 
 
 _unix_fork :: proc() -> Pid {
 _unix_fork :: proc() -> Pid {
-	res := int(intrinsics.syscall(unix.SYS_fork))
+	when ODIN_ARCH != .arm64 {
+		res := int(intrinsics.syscall(unix.SYS_fork))
+	} else {
+		res := int(intrinsics.syscall(unix.SYS_clone, unix.SIGCHLD))
+	}
 	return -1 if res < 0 else Pid(res)
 	return -1 if res < 0 else Pid(res)
 }
 }
 
 
@@ -286,7 +290,7 @@ _unix_open :: proc(path: cstring, flags: int, mode: int = 0o000) -> Handle {
 	when ODIN_ARCH != .arm64 {
 	when ODIN_ARCH != .arm64 {
 		res := int(intrinsics.syscall(unix.SYS_open, uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
 		res := int(intrinsics.syscall(unix.SYS_open, uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
 	} else { // NOTE: arm64 does not have open
 	} else { // NOTE: arm64 does not have open
-		res := int(intrinsics.syscall(unix.SYS_openat, uintptr(AT_FDCWD), uintptr(rawptr(path), uintptr(flags), uintptr(mode))))
+		res := int(intrinsics.syscall(unix.SYS_openat, AT_FDCWD, uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
 	}
 	}
 	return -1 if res < 0 else Handle(res)
 	return -1 if res < 0 else Handle(res)
 }
 }
@@ -321,7 +325,7 @@ _unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> int {
 	} else when ODIN_ARCH != .arm64 {
 	} else when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_stat64, uintptr(rawptr(path)), uintptr(stat)))
 		return int(intrinsics.syscall(unix.SYS_stat64, uintptr(rawptr(path)), uintptr(stat)))
 	} else { // NOTE: arm64 does not have stat
 	} else { // NOTE: arm64 does not have stat
-		return int(intrinsics.syscall(unix.SYS_fstatat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(stat), 0))
+		return int(intrinsics.syscall(unix.SYS_fstatat, AT_FDCWD, uintptr(rawptr(path)), uintptr(stat), 0))
 	}
 	}
 }
 }
 
 
@@ -339,7 +343,7 @@ _unix_lstat :: proc(path: cstring, stat: ^OS_Stat) -> int {
 	} else when ODIN_ARCH != .arm64 {
 	} else when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_lstat64, uintptr(rawptr(path)), uintptr(stat)))
 		return int(intrinsics.syscall(unix.SYS_lstat64, uintptr(rawptr(path)), uintptr(stat)))
 	} else { // NOTE: arm64 does not have any lstat
 	} else { // NOTE: arm64 does not have any lstat
-		return int(intrinsics.syscall(unix.SYS_fstatat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(stat), AT_SYMLINK_NOFOLLOW))
+		return int(intrinsics.syscall(unix.SYS_fstatat, AT_FDCWD, uintptr(rawptr(path)), uintptr(stat), AT_SYMLINK_NOFOLLOW))
 	}
 	}
 }
 }
 
 
@@ -347,7 +351,7 @@ _unix_readlink :: proc(path: cstring, buf: rawptr, bufsiz: uint) -> int {
 	when ODIN_ARCH != .arm64 {
 	when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_readlink, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
 		return int(intrinsics.syscall(unix.SYS_readlink, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
 	} else { // NOTE: arm64 does not have readlink
 	} else { // NOTE: arm64 does not have readlink
-		return int(intrinsics.syscall(unix.SYS_readlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
+		return int(intrinsics.syscall(unix.SYS_readlinkat, AT_FDCWD, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
 	}
 	}
 }
 }
 
 
@@ -355,7 +359,7 @@ _unix_access :: proc(path: cstring, mask: int) -> int {
 	when ODIN_ARCH != .arm64 {
 	when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_access, uintptr(rawptr(path)), uintptr(mask)))
 		return int(intrinsics.syscall(unix.SYS_access, uintptr(rawptr(path)), uintptr(mask)))
 	} else { // NOTE: arm64 does not have access
 	} else { // NOTE: arm64 does not have access
-		return int(intrinsics.syscall(unix.SYS_faccessat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(mask)))
+		return int(intrinsics.syscall(unix.SYS_faccessat, AT_FDCWD, uintptr(rawptr(path)), uintptr(mask)))
 	}
 	}
 }
 }
 
 
@@ -371,7 +375,7 @@ _unix_rename :: proc(old, new: cstring) -> int {
 	when ODIN_ARCH != .arm64 {
 	when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_rename, uintptr(rawptr(old)), uintptr(rawptr(new))))
 		return int(intrinsics.syscall(unix.SYS_rename, uintptr(rawptr(old)), uintptr(rawptr(new))))
 	} else { // NOTE: arm64 does not have rename
 	} else { // NOTE: arm64 does not have rename
-		return int(intrinsics.syscall(unix.SYS_renameat, uintptr(AT_FDCWD), uintptr(rawptr(old)), uintptr(rawptr(new))))
+		return int(intrinsics.syscall(unix.SYS_renameat, AT_FDCWD, uintptr(rawptr(old)), uintptr(rawptr(new))))
 	}
 	}
 }
 }
 
 
@@ -379,7 +383,7 @@ _unix_unlink :: proc(path: cstring) -> int {
 	when ODIN_ARCH != .arm64 {
 	when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_unlink, uintptr(rawptr(path))))
 		return int(intrinsics.syscall(unix.SYS_unlink, uintptr(rawptr(path))))
 	} else { // NOTE: arm64 does not have unlink
 	} else { // NOTE: arm64 does not have unlink
-		return int(intrinsics.syscall(unix.SYS_unlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path), 0)))
+		return int(intrinsics.syscall(unix.SYS_unlinkat, AT_FDCWD, uintptr(rawptr(path)), 0))
 	}
 	}
 }
 }
 
 
@@ -387,7 +391,7 @@ _unix_rmdir :: proc(path: cstring) -> int {
 	when ODIN_ARCH != .arm64 {
 	when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_rmdir, uintptr(rawptr(path))))
 		return int(intrinsics.syscall(unix.SYS_rmdir, uintptr(rawptr(path))))
 	} else { // NOTE: arm64 does not have rmdir
 	} else { // NOTE: arm64 does not have rmdir
-		return int(intrinsics.syscall(unix.SYS_unlinkat, uintptr(AT_FDCWD), uintptr(rawptr(path)), AT_REMOVEDIR))
+		return int(intrinsics.syscall(unix.SYS_unlinkat, AT_FDCWD, uintptr(rawptr(path)), AT_REMOVEDIR))
 	}
 	}
 }
 }
 
 
@@ -395,7 +399,7 @@ _unix_mkdir :: proc(path: cstring, mode: u32) -> int {
 	when ODIN_ARCH != .arm64 {
 	when ODIN_ARCH != .arm64 {
 		return int(intrinsics.syscall(unix.SYS_mkdir, uintptr(rawptr(path)), uintptr(mode)))
 		return int(intrinsics.syscall(unix.SYS_mkdir, uintptr(rawptr(path)), uintptr(mode)))
 	} else { // NOTE: arm64 does not have mkdir
 	} else { // NOTE: arm64 does not have mkdir
-		return int(intrinsics.syscall(unix.SYS_mkdirat, uintptr(AT_FDCWD), uintptr(rawptr(path)), uintptr(mode)))
+		return int(intrinsics.syscall(unix.SYS_mkdirat, AT_FDCWD, uintptr(rawptr(path)), uintptr(mode)))
 	}
 	}
 }
 }
 
 

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

@@ -675,6 +675,8 @@ when ODIN_ARCH == .amd64 {
 	SYS_landlock_create_ruleset : uintptr : 444
 	SYS_landlock_create_ruleset : uintptr : 444
 	SYS_landlock_add_rule : uintptr : 445
 	SYS_landlock_add_rule : uintptr : 445
 	SYS_landlock_restrict_self : uintptr : 446
 	SYS_landlock_restrict_self : uintptr : 446
+	
+	SIGCHLD :: 17
 } else when ODIN_ARCH == .i386 {
 } else when ODIN_ARCH == .i386 {
 	SYS_restart_syscall : uintptr : 0
 	SYS_restart_syscall : uintptr : 0
 	SYS_exit : uintptr : 1
 	SYS_exit : uintptr : 1