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;
1414pub fn syscall0(number: SYS) usize {
1515 return asm volatile (
1616 \\ syscall
17 \\ blez $7, 1f
17 \\ beq $7, $zero, 1f
18 \\ blez $2, 1f
1819 \\ subu $2, $0, $2
1920 \\ 1:
2021 : [ret] "={$2}" (-> usize),
......@@ -28,7 +29,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
2829 \\ .set noat
2930 \\ .set noreorder
3031 \\ syscall
31 \\ blez $7, 1f
32 \\ beq $7, $zero, 1f
3233 \\ nop
3334 \\ b 2f
3435 \\ subu $2, $0, $2
......@@ -46,7 +47,8 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
4647pub fn syscall1(number: SYS, arg1: usize) usize {
4748 return asm volatile (
4849 \\ syscall
49 \\ blez $7, 1f
50 \\ beq $7, $zero, 1f
51 \\ blez $2, 1f
5052 \\ subu $2, $0, $2
5153 \\ 1:
5254 : [ret] "={$2}" (-> usize),
......@@ -59,7 +61,8 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
5961pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
6062 return asm volatile (
6163 \\ syscall
62 \\ blez $7, 1f
64 \\ beq $7, $zero, 1f
65 \\ blez $2, 1f
6366 \\ subu $2, $0, $2
6467 \\ 1:
6568 : [ret] "={$2}" (-> usize),
......@@ -73,7 +76,8 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
7376pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
7477 return asm volatile (
7578 \\ syscall
76 \\ blez $7, 1f
79 \\ beq $7, $zero, 1f
80 \\ blez $2, 1f
7781 \\ subu $2, $0, $2
7882 \\ 1:
7983 : [ret] "={$2}" (-> usize),
......@@ -88,7 +92,8 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
8892pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
8993 return asm volatile (
9094 \\ syscall
91 \\ blez $7, 1f
95 \\ beq $7, $zero, 1f
96 \\ blez $2, 1f
9297 \\ subu $2, $0, $2
9398 \\ 1:
9499 : [ret] "={$2}" (-> usize),
......@@ -108,7 +113,8 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
108113 \\ sw %[arg5], 16($sp)
109114 \\ syscall
110115 \\ addu $sp, $sp, 24
111 \\ blez $7, 1f
116 \\ beq $7, $zero, 1f
117 \\ blez $2, 1f
112118 \\ subu $2, $0, $2
113119 \\ 1:
114120 : [ret] "={$2}" (-> usize),
......@@ -141,7 +147,8 @@ pub fn syscall6(
141147 \\ sw %[arg6], 20($sp)
142148 \\ syscall
143149 \\ addu $sp, $sp, 24
144 \\ blez $7, 1f
150 \\ beq $7, $zero, 1f
151 \\ blez $2, 1f
145152 \\ subu $2, $0, $2
146153 \\ 1:
147154 : [ret] "={$2}" (-> usize),
......@@ -174,7 +181,8 @@ pub fn syscall7(
174181 \\ sw %[arg7], 24($sp)
175182 \\ syscall
176183 \\ addu $sp, $sp, 32
177 \\ blez $7, 1f
184 \\ beq $7, $zero, 1f
185 \\ blez $2, 1f
178186 \\ subu $2, $0, $2
179187 \\ 1:
180188 : [ret] "={$2}" (-> usize),
lib/std/os/linux/mips64.zig+18-9
......@@ -14,7 +14,8 @@ const timespec = linux.timespec;
1414pub fn syscall0(number: SYS) usize {
1515 return asm volatile (
1616 \\ syscall
17 \\ blez $7, 1f
17 \\ beq $7, $zero, 1f
18 \\ blez $2, 1f
1819 \\ dsubu $2, $0, $2
1920 \\ 1:
2021 : [ret] "={$2}" (-> usize),
......@@ -28,7 +29,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
2829 \\ .set noat
2930 \\ .set noreorder
3031 \\ syscall
31 \\ blez $7, 1f
32 \\ beq $7, $zero, 1f
3233 \\ nop
3334 \\ b 2f
3435 \\ subu $2, $0, $2
......@@ -46,7 +47,9 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
4647pub fn syscall1(number: SYS, arg1: usize) usize {
4748 return asm volatile (
4849 \\ syscall
49 \\ blez $7, 1f
50 \\ beq $7, $zero, 1f
51 \\ blez $2, 1f
52 \\ nop
5053 \\ dsubu $2, $0, $2
5154 \\ 1:
5255 : [ret] "={$2}" (-> usize),
......@@ -59,7 +62,8 @@ pub fn syscall1(number: SYS, arg1: usize) usize {
5962pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
6063 return asm volatile (
6164 \\ syscall
62 \\ blez $7, 1f
65 \\ beq $7, $zero, 1f
66 \\ blez $2, 1f
6367 \\ dsubu $2, $0, $2
6468 \\ 1:
6569 : [ret] "={$2}" (-> usize),
......@@ -73,7 +77,8 @@ pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
7377pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
7478 return asm volatile (
7579 \\ syscall
76 \\ blez $7, 1f
80 \\ beq $7, $zero, 1f
81 \\ blez $2, 1f
7782 \\ dsubu $2, $0, $2
7883 \\ 1:
7984 : [ret] "={$2}" (-> usize),
......@@ -88,7 +93,8 @@ pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
8893pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
8994 return asm volatile (
9095 \\ syscall
91 \\ blez $7, 1f
96 \\ beq $7, $zero, 1f
97 \\ blez $2, 1f
9298 \\ dsubu $2, $0, $2
9399 \\ 1:
94100 : [ret] "={$2}" (-> usize),
......@@ -104,7 +110,8 @@ pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize)
104110pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
105111 return asm volatile (
106112 \\ syscall
107 \\ blez $7, 1f
113 \\ beq $7, $zero, 1f
114 \\ blez $2, 1f
108115 \\ dsubu $2, $0, $2
109116 \\ 1:
110117 : [ret] "={$2}" (-> usize),
......@@ -129,7 +136,8 @@ pub fn syscall6(
129136) usize {
130137 return asm volatile (
131138 \\ syscall
132 \\ blez $7, 1f
139 \\ beq $7, $zero, 1f
140 \\ blez $2, 1f
133141 \\ dsubu $2, $0, $2
134142 \\ 1:
135143 : [ret] "={$2}" (-> usize),
......@@ -156,7 +164,8 @@ pub fn syscall7(
156164) usize {
157165 return asm volatile (
158166 \\ syscall
159 \\ blez $7, 1f
167 \\ beq $7, $zero, 1f
168 \\ blez $2, 1f
160169 \\ dsubu $2, $0, $2
161170 \\ 1:
162171 : [ret] "={$2}" (-> usize),