authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-08-16 11:09:52+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-08-18 07:27:23+02:00
logd4973c992203ed6fb761d3f3b871dd9849541b5a
tree8dc1a3f1b684ca5526ea78615fdd5f2c77a09ec5
parentbcf41c859430301fe8117514b90e2610ae107276

std.os.linux: Fix syscall errno value handling for mips.

The kernel sets r7 to 0 (success) or -1 (error), and stores the result in r2. When r7 is -1 and the result is positive, it needs to be negated to get the errno value that higher-level code, such as errnoFromSyscall(), expects to see. The old code was missing the check that r2 is positive, but was also doing the r7 check incorrectly; since it can only be set to 0 or -1, the blez instruction would always branch. In practice, this fix is necessary for e.g. the ENOSYS error to be interpreted correctly. This manifested as hitting an unreachable branch when calling process_vm_readv() in std.debug.MemoryAccessor.

2 files changed, 35 insertions(+), 18 deletions(-)

lib/std/os/linux/mips.zig+17-9
...@@ -14,7 +14,8 @@ const timespec = linux.timespec;...@@ -14,7 +14,8 @@ const timespec = linux.timespec;
14pub fn syscall0(number: SYS) usize {14pub fn syscall0(number: SYS) usize {
15 return asm volatile (15 return asm volatile (
16 \\ syscall16 \\ syscall
17 \\ blez $7, 1f17 \\ beq $7, $zero, 1f
18 \\ blez $2, 1f
18 \\ subu $2, $0, $219 \\ subu $2, $0, $2
19 \\ 1:20 \\ 1:
20 : [ret] "={$2}" (-> usize),21 : [ret] "={$2}" (-> usize),
...@@ -28,7 +29,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {...@@ -28,7 +29,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
28 \\ .set noat29 \\ .set noat
29 \\ .set noreorder30 \\ .set noreorder
30 \\ syscall31 \\ syscall
31 \\ blez $7, 1f32 \\ beq $7, $zero, 1f
32 \\ nop33 \\ nop
33 \\ b 2f34 \\ b 2f
34 \\ subu $2, $0, $235 \\ subu $2, $0, $2
...@@ -46,7 +47,8 @@ pub fn syscall_pipe(fd: *[2]i32) usize {...@@ -46,7 +47,8 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
46pub fn syscall1(number: SYS, arg1: usize) usize {47pub fn syscall1(number: SYS, arg1: usize) usize {
47 return asm volatile (48 return asm volatile (
48 \\ syscall49 \\ syscall
49 \\ blez $7, 1f50 \\ beq $7, $zero, 1f
51 \\ blez $2, 1f
50 \\ subu $2, $0, $252 \\ subu $2, $0, $2
51 \\ 1:53 \\ 1:
52 : [ret] "={$2}" (-> usize),54 : [ret] "={$2}" (-> usize),
...@@ -59,7 +61,8 @@ pub fn syscall1(number: SYS, arg1: usize) usize {...@@ -59,7 +61,8 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
59pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {61pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
60 return asm volatile (62 return asm volatile (
61 \\ syscall63 \\ syscall
62 \\ blez $7, 1f64 \\ beq $7, $zero, 1f
65 \\ blez $2, 1f
63 \\ subu $2, $0, $266 \\ subu $2, $0, $2
64 \\ 1:67 \\ 1:
65 : [ret] "={$2}" (-> usize),68 : [ret] "={$2}" (-> usize),
...@@ -73,7 +76,8 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {...@@ -73,7 +76,8 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
73pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {76pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
74 return asm volatile (77 return asm volatile (
75 \\ syscall78 \\ syscall
76 \\ blez $7, 1f79 \\ beq $7, $zero, 1f
80 \\ blez $2, 1f
77 \\ subu $2, $0, $281 \\ subu $2, $0, $2
78 \\ 1:82 \\ 1:
79 : [ret] "={$2}" (-> usize),83 : [ret] "={$2}" (-> usize),
...@@ -88,7 +92,8 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {...@@ -88,7 +92,8 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
88pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {92pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
89 return asm volatile (93 return asm volatile (
90 \\ syscall94 \\ syscall
91 \\ blez $7, 1f95 \\ beq $7, $zero, 1f
96 \\ blez $2, 1f
92 \\ subu $2, $0, $297 \\ subu $2, $0, $2
93 \\ 1:98 \\ 1:
94 : [ret] "={$2}" (-> usize),99 : [ret] "={$2}" (-> usize),
...@@ -108,7 +113,8 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,...@@ -108,7 +113,8 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
108 \\ sw %[arg5], 16($sp)113 \\ sw %[arg5], 16($sp)
109 \\ syscall114 \\ syscall
110 \\ addu $sp, $sp, 24115 \\ addu $sp, $sp, 24
111 \\ blez $7, 1f116 \\ beq $7, $zero, 1f
117 \\ blez $2, 1f
112 \\ subu $2, $0, $2118 \\ subu $2, $0, $2
113 \\ 1:119 \\ 1:
114 : [ret] "={$2}" (-> usize),120 : [ret] "={$2}" (-> usize),
...@@ -141,7 +147,8 @@ pub fn syscall6(...@@ -141,7 +147,8 @@ pub fn syscall6(
141 \\ sw %[arg6], 20($sp)147 \\ sw %[arg6], 20($sp)
142 \\ syscall148 \\ syscall
143 \\ addu $sp, $sp, 24149 \\ addu $sp, $sp, 24
144 \\ blez $7, 1f150 \\ beq $7, $zero, 1f
151 \\ blez $2, 1f
145 \\ subu $2, $0, $2152 \\ subu $2, $0, $2
146 \\ 1:153 \\ 1:
147 : [ret] "={$2}" (-> usize),154 : [ret] "={$2}" (-> usize),
...@@ -174,7 +181,8 @@ pub fn syscall7(...@@ -174,7 +181,8 @@ pub fn syscall7(
174 \\ sw %[arg7], 24($sp)181 \\ sw %[arg7], 24($sp)
175 \\ syscall182 \\ syscall
176 \\ addu $sp, $sp, 32183 \\ addu $sp, $sp, 32
177 \\ blez $7, 1f184 \\ beq $7, $zero, 1f
185 \\ blez $2, 1f
178 \\ subu $2, $0, $2186 \\ subu $2, $0, $2
179 \\ 1:187 \\ 1:
180 : [ret] "={$2}" (-> usize),188 : [ret] "={$2}" (-> usize),
lib/std/os/linux/mips64.zig+18-9
...@@ -14,7 +14,8 @@ const timespec = linux.timespec;...@@ -14,7 +14,8 @@ const timespec = linux.timespec;
14pub fn syscall0(number: SYS) usize {14pub fn syscall0(number: SYS) usize {
15 return asm volatile (15 return asm volatile (
16 \\ syscall16 \\ syscall
17 \\ blez $7, 1f17 \\ beq $7, $zero, 1f
18 \\ blez $2, 1f
18 \\ dsubu $2, $0, $219 \\ dsubu $2, $0, $2
19 \\ 1:20 \\ 1:
20 : [ret] "={$2}" (-> usize),21 : [ret] "={$2}" (-> usize),
...@@ -28,7 +29,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {...@@ -28,7 +29,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
28 \\ .set noat29 \\ .set noat
29 \\ .set noreorder30 \\ .set noreorder
30 \\ syscall31 \\ syscall
31 \\ blez $7, 1f32 \\ beq $7, $zero, 1f
32 \\ nop33 \\ nop
33 \\ b 2f34 \\ b 2f
34 \\ subu $2, $0, $235 \\ subu $2, $0, $2
...@@ -46,7 +47,9 @@ pub fn syscall_pipe(fd: *[2]i32) usize {...@@ -46,7 +47,9 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
46pub fn syscall1(number: SYS, arg1: usize) usize {47pub fn syscall1(number: SYS, arg1: usize) usize {
47 return asm volatile (48 return asm volatile (
48 \\ syscall49 \\ syscall
49 \\ blez $7, 1f50 \\ beq $7, $zero, 1f
51 \\ blez $2, 1f
52 \\ nop
50 \\ dsubu $2, $0, $253 \\ dsubu $2, $0, $2
51 \\ 1:54 \\ 1:
52 : [ret] "={$2}" (-> usize),55 : [ret] "={$2}" (-> usize),
...@@ -59,7 +62,8 @@ pub fn syscall1(number: SYS, arg1: usize) usize {...@@ -59,7 +62,8 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
59pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {62pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
60 return asm volatile (63 return asm volatile (
61 \\ syscall64 \\ syscall
62 \\ blez $7, 1f65 \\ beq $7, $zero, 1f
66 \\ blez $2, 1f
63 \\ dsubu $2, $0, $267 \\ dsubu $2, $0, $2
64 \\ 1:68 \\ 1:
65 : [ret] "={$2}" (-> usize),69 : [ret] "={$2}" (-> usize),
...@@ -73,7 +77,8 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {...@@ -73,7 +77,8 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
73pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {77pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
74 return asm volatile (78 return asm volatile (
75 \\ syscall79 \\ syscall
76 \\ blez $7, 1f80 \\ beq $7, $zero, 1f
81 \\ blez $2, 1f
77 \\ dsubu $2, $0, $282 \\ dsubu $2, $0, $2
78 \\ 1:83 \\ 1:
79 : [ret] "={$2}" (-> usize),84 : [ret] "={$2}" (-> usize),
...@@ -88,7 +93,8 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {...@@ -88,7 +93,8 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
88pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {93pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
89 return asm volatile (94 return asm volatile (
90 \\ syscall95 \\ syscall
91 \\ blez $7, 1f96 \\ beq $7, $zero, 1f
97 \\ blez $2, 1f
92 \\ dsubu $2, $0, $298 \\ dsubu $2, $0, $2
93 \\ 1:99 \\ 1:
94 : [ret] "={$2}" (-> usize),100 : [ret] "={$2}" (-> usize),
...@@ -104,7 +110,8 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)...@@ -104,7 +110,8 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)
104pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {110pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
105 return asm volatile (111 return asm volatile (
106 \\ syscall112 \\ syscall
107 \\ blez $7, 1f113 \\ beq $7, $zero, 1f
114 \\ blez $2, 1f
108 \\ dsubu $2, $0, $2115 \\ dsubu $2, $0, $2
109 \\ 1:116 \\ 1:
110 : [ret] "={$2}" (-> usize),117 : [ret] "={$2}" (-> usize),
...@@ -129,7 +136,8 @@ pub fn syscall6(...@@ -129,7 +136,8 @@ pub fn syscall6(
129) usize {136) usize {
130 return asm volatile (137 return asm volatile (
131 \\ syscall138 \\ syscall
132 \\ blez $7, 1f139 \\ beq $7, $zero, 1f
140 \\ blez $2, 1f
133 \\ dsubu $2, $0, $2141 \\ dsubu $2, $0, $2
134 \\ 1:142 \\ 1:
135 : [ret] "={$2}" (-> usize),143 : [ret] "={$2}" (-> usize),
...@@ -156,7 +164,8 @@ pub fn syscall7(...@@ -156,7 +164,8 @@ pub fn syscall7(
156) usize {164) usize {
157 return asm volatile (165 return asm volatile (
158 \\ syscall166 \\ syscall
159 \\ blez $7, 1f167 \\ beq $7, $zero, 1f
168 \\ blez $2, 1f
160 \\ dsubu $2, $0, $2169 \\ dsubu $2, $0, $2
161 \\ 1:170 \\ 1:
162 : [ret] "={$2}" (-> usize),171 : [ret] "={$2}" (-> usize),