Browse Source

Merge pull request #4650 from jasonKercher/arm32-update

Arm32 update for sys/linux
gingerBill 7 months ago
parent
commit
f5e5c9767c

+ 4 - 1
core/os/os2/file_linux.odin

@@ -80,6 +80,9 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err
 	// terminal would be incredibly rare. This has no effect on files while
 	// allowing us to open serial devices.
 	sys_flags: linux.Open_Flags = {.NOCTTY, .CLOEXEC}
+	when size_of(rawptr) == 4 {
+		sys_flags += {.LARGEFILE}
+	}
 	switch flags & (O_RDONLY|O_WRONLY|O_RDWR) {
 	case O_RDONLY:
 	case O_WRONLY: sys_flags += {.WRONLY}
@@ -275,7 +278,7 @@ _remove :: proc(name: string) -> Error {
 	TEMP_ALLOCATOR_GUARD()
 	name_cstr := temp_cstring(name) or_return
 
-	if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS); errno == .NONE {
+	if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS + {.NOFOLLOW}); errno == .NONE {
 		linux.close(fd)
 		return _get_platform_error(linux.rmdir(name_cstr))
 	}

+ 0 - 2
core/os/os2/path_linux.odin

@@ -77,8 +77,6 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 }
 
 _remove_all :: proc(path: string) -> Error {
-	DT_DIR :: 4
-
 	remove_all_dir :: proc(dfd: linux.Fd) -> Error {
 		n := 64
 		buf := make([]u8, n)

+ 2 - 2
core/sys/linux/helpers.odin

@@ -138,8 +138,8 @@ errno_unwrap :: proc {errno_unwrap2, errno_unwrap3}
 when size_of(int) == 4 {
 	// xxx64 system calls take some parameters as pairs of ulongs rather than a single pointer
 	@(private)
-	compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (hi: uint, lo: uint) {
-		no_sign := uint(a)
+	compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (lo: uint, hi: uint) {
+		no_sign := u64(a)
 		hi = uint(no_sign >> 32)
 		lo = uint(no_sign & 0xffff_ffff)
 		return

+ 25 - 15
core/sys/linux/sys.odin

@@ -151,7 +151,8 @@ lseek :: proc "contextless" (fd: Fd, off: i64, whence: Seek_Whence) -> (i64, Err
 		return errno_unwrap(ret, i64)
 	} else {
 		result: i64 = ---
-		ret := syscall(SYS__llseek, fd, compat64_arg_pair(off), &result, whence)
+		lo, hi := compat64_arg_pair(off)
+		ret := syscall(SYS__llseek, fd, hi, lo, &result, whence)
 		return result, Errno(-ret)
 	}
 }
@@ -251,7 +252,11 @@ ioctl :: proc "contextless" (fd: Fd, request: u32, arg: uintptr) -> (uintptr) {
 	Available since Linux 2.2.
 */
 pread :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) {
-	ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset))
+	when ODIN_ARCH == .arm32 {
+		ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), 0, compat64_arg_pair(offset))
+	} else {
+		ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset))
+	}
 	return errno_unwrap(ret, int)
 }
 
@@ -261,7 +266,11 @@ pread :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) {
 	Available since Linux 2.2.
 */
 pwrite :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) {
-	ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset))
+	when ODIN_ARCH == .arm32 {
+		ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), 0, compat64_arg_pair(offset))
+	} else {
+		ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset))
+	}
 	return errno_unwrap(ret, int)
 }
 
@@ -1127,7 +1136,10 @@ fdatasync :: proc "contextless" (fd: Fd) -> (Errno) {
 	On 32-bit architectures available since Linux 2.4.
 */
 truncate :: proc "contextless" (name: cstring, length: i64) -> (Errno) {
-	when size_of(int) == 4 {
+	when ODIN_ARCH == .arm32 {
+		ret := syscall(SYS_truncate64, cast(rawptr) name, 0, compat64_arg_pair(length))
+		return Errno(-ret)
+	} else when size_of(int) == 4 {
 		ret := syscall(SYS_truncate64, cast(rawptr) name, compat64_arg_pair(length))
 		return Errno(-ret)
 	} else {
@@ -1141,7 +1153,10 @@ truncate :: proc "contextless" (name: cstring, length: i64) -> (Errno) {
 	On 32-bit architectures available since 2.4.
 */
 ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) {
-	when size_of(int) == 4 {
+	when ODIN_ARCH == .arm32 {
+		ret := syscall(SYS_ftruncate64, fd, 0, compat64_arg_pair(length))
+		return Errno(-ret)
+	} else when size_of(int) == 4 {
 		ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length))
 		return Errno(-ret)
 	} else {
@@ -1952,10 +1967,10 @@ sigaltstack :: proc "contextless" (stack: ^Sig_Stack, old_stack: ^Sig_Stack) ->
 */
 mknod :: proc "contextless" (name: cstring, mode: Mode, dev: Dev) -> (Errno) {
 	when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
-		ret := syscall(SYS_mknodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode, dev)
+		ret := syscall(SYS_mknodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode, cast(uint) dev)
 		return Errno(-ret)
 	} else {
-		ret := syscall(SYS_mknod, cast(rawptr) name, transmute(u32) mode, dev)
+		ret := syscall(SYS_mknod, cast(rawptr) name, transmute(u32) mode, cast(uint) dev)
 		return Errno(-ret)
 	}
 }
@@ -2586,7 +2601,7 @@ mkdirat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode) -> (Errno)
 	Available since Linux 2.6.16.
 */
 mknodat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode, dev: Dev) -> (Errno) {
-	ret := syscall(SYS_mknodat, dirfd, cast(rawptr) name, transmute(u32) mode, dev)
+	ret := syscall(SYS_mknodat, dirfd, cast(rawptr) name, transmute(u32) mode, cast(uint) dev)
 	return Errno(-ret)
 }
 
@@ -2684,13 +2699,8 @@ faccessat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK) ->
 	Available since Linux 2.6.16.
 */
 ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) {
-	when size_of(int) == 8 {
-		ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
-		return errno_unwrap(ret, i32)
-	} else {
-		ret := syscall(SYS_ppoll_time64, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
-		return errno_unwrap(ret, i32)
-	}
+	ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
+	return errno_unwrap(ret, i32)
 }
 
 // TODO(flysand): unshare

+ 156 - 66
core/sys/linux/types.odin

@@ -3,7 +3,7 @@ package linux
 /*
 	Type for storage device handle.
 */
-Dev :: distinct int
+Dev :: distinct u64
 
 /*
 	Type for 32-bit User IDs.
@@ -153,6 +153,7 @@ when ODIN_ARCH == .amd64 {
 		uid:        Uid,
 		gid:        Gid,
 		rdev:       Dev,
+		_:          [4]u8,
 		size:       i64,
 		blksize:    uint,
 		blocks:     u64,
@@ -516,79 +517,79 @@ Pid_FD_Flags :: bit_set[Pid_FD_Flags_Bits; i32]
 Sig_Set :: [_SIGSET_NWORDS]uint
 
 @private SI_MAX_SIZE       :: 128
-@private SI_ARCH_PREAMBLE  :: 4 * size_of(i32)
+@private SI_ARCH_PREAMBLE  :: 4 * size_of(i32) when size_of(rawptr) == 8 else 3 * size_of(i32)
 @private SI_PAD_SIZE       :: SI_MAX_SIZE - SI_ARCH_PREAMBLE
 
 Sig_Handler_Fn :: #type proc "c" (sig: Signal)
 Sig_Restore_Fn :: #type proc "c" () -> !
 
-Sig_Info :: struct #packed {
-	signo: Signal,
-	errno: Errno,
-	code: i32,
-	_pad0: i32,
-	using _union: struct #raw_union {
-		_pad1: [SI_PAD_SIZE]u8,
-		using _kill: struct {
-			pid: Pid, /* sender's pid */
-			uid: Uid, /* sender's uid */
-		},
-		using _timer: struct {
-			timerid: i32,   /* timer id */
-			overrun: i32,   /* overrun count */
-			value: Sig_Val, /* timer value */
-		},
-		/* POSIX.1b signals */
-		using _rt: struct {
-			_pid0: Pid, /* sender's pid */
-			_uid0: Uid, /* sender's uid */
-		},
-		/* SIGCHLD */
-		using _sigchld: struct {
-			_pid1: Pid,  /* which child */
-			_uid1: Uid,  /* sender's uid */
-			status: i32, /* exit code */
-			utime: uint,
-			stime: uint, //clock_t
-		},
-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-		using _sigfault: struct {
-			addr: rawptr, /* faulting insn/memory ref. */
-			using _: struct #raw_union {
-				trapno: i32,   /* Trap number that caused signal */
-				addr_lsb: i16, /* LSB of the reported address */
-				using _addr_bnd: struct {
-					_pad2: u64,
-					lower: rawptr, /* lower bound during fault */
-					upper: rawptr, /* upper bound during fault */
-				},
-				using _addr_pkey: struct {
-					_pad3: u64,
-					pkey: u32, /* protection key on PTE that faulted */
-				},
-				using _perf: struct {
-					perf_data: u64,
-					perf_type: u32,
-					perf_flags: u32,
+when size_of(rawptr) == 8 {
+	Sig_Info :: struct #packed {
+		signo: Signal,
+		errno: Errno,
+		code: i32,
+		_pad0: i32,
+		using _union: struct #raw_union {
+			_pad1: [SI_PAD_SIZE]u8,
+			using _kill: struct {
+				pid: Pid, /* sender's pid */
+				uid: Uid, /* sender's uid */
+			},
+			using _timer: struct {
+				timerid: i32,   /* timer id */
+				overrun: i32,   /* overrun count */
+				value: Sig_Val, /* timer value */
+			},
+			/* POSIX.1b signals */
+			using _rt: struct {
+				_pid0: Pid, /* sender's pid */
+				_uid0: Uid, /* sender's uid */
+			},
+			/* SIGCHLD */
+			using _sigchld: struct {
+				_pid1: Pid,  /* which child */
+				_uid1: Uid,  /* sender's uid */
+				status: i32, /* exit code */
+				utime: uint,
+				stime: uint, //clock_t
+			},
+			/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+			using _sigfault: struct {
+				addr: rawptr, /* faulting insn/memory ref. */
+				using _: struct #raw_union {
+					trapno: i32,   /* Trap number that caused signal */
+					addr_lsb: i16, /* LSB of the reported address */
+					using _addr_bnd: struct {
+						_pad2: u64,
+						lower: rawptr, /* lower bound during fault */
+						upper: rawptr, /* upper bound during fault */
+					},
+					using _addr_pkey: struct {
+						_pad3: u64,
+						pkey: u32, /* protection key on PTE that faulted */
+					},
+					using _perf: struct {
+						perf_data: u64,
+						perf_type: u32,
+						perf_flags: u32,
+					},
 				},
 			},
+			/* SIGPOLL */
+			using _sigpoll: struct {
+				band: int, /* POLL_IN, POLL_OUT, POLL_MSG */
+				fd: Fd,
+			},
+			/* SIGSYS */
+			using _sigsys: struct {
+				call_addr: rawptr, /* calling user insn */
+				syscall: i32,      /* triggering system call number */
+				arch: u32,         /* AUDIT_ARCH_* of syscall */
+			},
 		},
-		/* SIGPOLL */
-		using _sigpoll: struct {
-			band: int, /* POLL_IN, POLL_OUT, POLL_MSG */
-			fd: Fd,
-		},
-		/* SIGSYS */
-		using _sigsys: struct {
-			call_addr: rawptr, /* calling user insn */
-			syscall: i32,      /* triggering system call number */
-			arch: u32,         /* AUDIT_ARCH_* of syscall */
-		},
-	},
-}
+	}
 
-#assert(size_of(Sig_Info) == 128)
-when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
+	#assert(size_of(Sig_Info) == 128)
 	#assert(offset_of(Sig_Info, signo)      == 0x00)
 	#assert(offset_of(Sig_Info, errno)      == 0x04)
 	#assert(offset_of(Sig_Info, code)       == 0x08)
@@ -615,7 +616,96 @@ when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
 	#assert(offset_of(Sig_Info, syscall)    == 0x18)
 	#assert(offset_of(Sig_Info, arch)       == 0x1C)
 } else {
-	// TODO
+	Sig_Info :: struct {
+		signo: Signal,
+		errno: Errno,
+		code: i32,
+		using _union: struct #raw_union {
+			_pad1: [SI_PAD_SIZE]u8,
+			using _kill: struct {
+				pid: Pid, /* sender's pid */
+				uid: Uid, /* sender's uid */
+			},
+			using _timer: struct {
+				timerid: i32,   /* timer id */
+				overrun: i32,   /* overrun count */
+				value: Sig_Val, /* timer value */
+			},
+			/* POSIX.1b signals */
+			using _rt: struct {
+				_pid0: Pid, /* sender's pid */
+				_uid0: Uid, /* sender's uid */
+			},
+			/* SIGCHLD */
+			using _sigchld: struct {
+				_pid1: Pid,  /* which child */
+				_uid1: Uid,  /* sender's uid */
+				status: i32, /* exit code */
+				utime: uint,
+				stime: uint, //clock_t
+			},
+			/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+			using _sigfault: struct {
+				addr: rawptr, /* faulting insn/memory ref. */
+				using _: struct #raw_union {
+					trapno: i32,   /* Trap number that caused signal */
+					addr_lsb: i16, /* LSB of the reported address */
+					using _addr_bnd: struct {
+						_pad2: u32,
+						lower: rawptr, /* lower bound during fault */
+						upper: rawptr, /* upper bound during fault */
+					},
+					using _addr_pkey: struct {
+						_pad3: u32,
+						pkey: u32, /* protection key on PTE that faulted */
+					},
+					using _perf: struct {
+						perf_data: u32,
+						perf_type: u32,
+						perf_flags: u32,
+					},
+				},
+			},
+			/* SIGPOLL */
+			using _sigpoll: struct {
+				band: int, /* POLL_IN, POLL_OUT, POLL_MSG */
+				fd: Fd,
+			},
+			/* SIGSYS */
+			using _sigsys: struct {
+				call_addr: rawptr, /* calling user insn */
+				syscall: i32,      /* triggering system call number */
+				arch: u32,         /* AUDIT_ARCH_* of syscall */
+			},
+		},
+	}
+
+	#assert(size_of(Sig_Info) == 128)
+	#assert(offset_of(Sig_Info, signo)      == 0x00)
+	#assert(offset_of(Sig_Info, errno)      == 0x04)
+	#assert(offset_of(Sig_Info, code)       == 0x08)
+	#assert(offset_of(Sig_Info, pid)        == 0x0c)
+	#assert(offset_of(Sig_Info, uid)        == 0x10)
+	#assert(offset_of(Sig_Info, timerid)    == 0x0c)
+	#assert(offset_of(Sig_Info, overrun)    == 0x10)
+	#assert(offset_of(Sig_Info, value)      == 0x14)
+	#assert(offset_of(Sig_Info, status)     == 0x14)
+	#assert(offset_of(Sig_Info, utime)      == 0x18)
+	#assert(offset_of(Sig_Info, stime)      == 0x1c)
+	#assert(offset_of(Sig_Info, addr)       == 0x0c)
+	#assert(offset_of(Sig_Info, addr_lsb)   == 0x10)
+	#assert(offset_of(Sig_Info, trapno)     == 0x10)
+	#assert(offset_of(Sig_Info, lower)      == 0x14)
+	#assert(offset_of(Sig_Info, upper)      == 0x18)
+	#assert(offset_of(Sig_Info, pkey)       == 0x14)
+	#assert(offset_of(Sig_Info, perf_data)  == 0x10)
+	#assert(offset_of(Sig_Info, perf_type)  == 0x14)
+	#assert(offset_of(Sig_Info, perf_flags) == 0x18)
+	#assert(offset_of(Sig_Info, band)       == 0x0c)
+	#assert(offset_of(Sig_Info, fd)         == 0x10)
+	#assert(offset_of(Sig_Info, call_addr)  == 0x0c)
+	#assert(offset_of(Sig_Info, syscall)    == 0x10)
+	#assert(offset_of(Sig_Info, arch)       == 0x14)
 }
 
 SIGEV_MAX_SIZE :: 64