| author | |
| committer | |
| log | d4973c992203ed6fb761d3f3b871dd9849541b5a |
| tree | 8dc1a3f1b684ca5526ea78615fdd5f2c77a09ec5 |
| parent | bcf41c859430301fe8117514b90e2610ae107276 |
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; |
| 14 | pub fn syscall0(number: SYS) usize { | 14 | pub fn syscall0(number: SYS) usize { |
| 15 | return asm volatile ( | 15 | return asm volatile ( |
| 16 | \\ syscall | 16 | \\ syscall |
| 17 | \\ blez $7, 1f | 17 | \\ beq $7, $zero, 1f |
| 18 | \\ blez $2, 1f | ||
| 18 | \\ subu $2, $0, $2 | 19 | \\ 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 noat | 29 | \\ .set noat |
| 29 | \\ .set noreorder | 30 | \\ .set noreorder |
| 30 | \\ syscall | 31 | \\ syscall |
| 31 | \\ blez $7, 1f | 32 | \\ beq $7, $zero, 1f |
| 32 | \\ nop | 33 | \\ nop |
| 33 | \\ b 2f | 34 | \\ b 2f |
| 34 | \\ subu $2, $0, $2 | 35 | \\ 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 { |
| 46 | pub fn syscall1(number: SYS, arg1: usize) usize { | 47 | pub fn syscall1(number: SYS, arg1: usize) usize { |
| 47 | return asm volatile ( | 48 | return asm volatile ( |
| 48 | \\ syscall | 49 | \\ syscall |
| 49 | \\ blez $7, 1f | 50 | \\ beq $7, $zero, 1f |
| 51 | \\ blez $2, 1f | ||
| 50 | \\ subu $2, $0, $2 | 52 | \\ 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 { |
| 59 | pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { | 61 | pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { |
| 60 | return asm volatile ( | 62 | return asm volatile ( |
| 61 | \\ syscall | 63 | \\ syscall |
| 62 | \\ blez $7, 1f | 64 | \\ beq $7, $zero, 1f |
| 65 | \\ blez $2, 1f | ||
| 63 | \\ subu $2, $0, $2 | 66 | \\ 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 { |
| 73 | pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { | 76 | pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { |
| 74 | return asm volatile ( | 77 | return asm volatile ( |
| 75 | \\ syscall | 78 | \\ syscall |
| 76 | \\ blez $7, 1f | 79 | \\ beq $7, $zero, 1f |
| 80 | \\ blez $2, 1f | ||
| 77 | \\ subu $2, $0, $2 | 81 | \\ 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 { |
| 88 | pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { | 92 | pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { |
| 89 | return asm volatile ( | 93 | return asm volatile ( |
| 90 | \\ syscall | 94 | \\ syscall |
| 91 | \\ blez $7, 1f | 95 | \\ beq $7, $zero, 1f |
| 96 | \\ blez $2, 1f | ||
| 92 | \\ subu $2, $0, $2 | 97 | \\ 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 | \\ syscall | 114 | \\ syscall |
| 110 | \\ addu $sp, $sp, 24 | 115 | \\ addu $sp, $sp, 24 |
| 111 | \\ blez $7, 1f | 116 | \\ beq $7, $zero, 1f |
| 117 | \\ blez $2, 1f | ||
| 112 | \\ subu $2, $0, $2 | 118 | \\ 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 | \\ syscall | 148 | \\ syscall |
| 143 | \\ addu $sp, $sp, 24 | 149 | \\ addu $sp, $sp, 24 |
| 144 | \\ blez $7, 1f | 150 | \\ beq $7, $zero, 1f |
| 151 | \\ blez $2, 1f | ||
| 145 | \\ subu $2, $0, $2 | 152 | \\ 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 | \\ syscall | 182 | \\ syscall |
| 176 | \\ addu $sp, $sp, 32 | 183 | \\ addu $sp, $sp, 32 |
| 177 | \\ blez $7, 1f | 184 | \\ beq $7, $zero, 1f |
| 185 | \\ blez $2, 1f | ||
| 178 | \\ subu $2, $0, $2 | 186 | \\ 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; |
| 14 | pub fn syscall0(number: SYS) usize { | 14 | pub fn syscall0(number: SYS) usize { |
| 15 | return asm volatile ( | 15 | return asm volatile ( |
| 16 | \\ syscall | 16 | \\ syscall |
| 17 | \\ blez $7, 1f | 17 | \\ beq $7, $zero, 1f |
| 18 | \\ blez $2, 1f | ||
| 18 | \\ dsubu $2, $0, $2 | 19 | \\ 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 noat | 29 | \\ .set noat |
| 29 | \\ .set noreorder | 30 | \\ .set noreorder |
| 30 | \\ syscall | 31 | \\ syscall |
| 31 | \\ blez $7, 1f | 32 | \\ beq $7, $zero, 1f |
| 32 | \\ nop | 33 | \\ nop |
| 33 | \\ b 2f | 34 | \\ b 2f |
| 34 | \\ subu $2, $0, $2 | 35 | \\ 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 { |
| 46 | pub fn syscall1(number: SYS, arg1: usize) usize { | 47 | pub fn syscall1(number: SYS, arg1: usize) usize { |
| 47 | return asm volatile ( | 48 | return asm volatile ( |
| 48 | \\ syscall | 49 | \\ syscall |
| 49 | \\ blez $7, 1f | 50 | \\ beq $7, $zero, 1f |
| 51 | \\ blez $2, 1f | ||
| 52 | \\ nop | ||
| 50 | \\ dsubu $2, $0, $2 | 53 | \\ 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 { |
| 59 | pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { | 62 | pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize { |
| 60 | return asm volatile ( | 63 | return asm volatile ( |
| 61 | \\ syscall | 64 | \\ syscall |
| 62 | \\ blez $7, 1f | 65 | \\ beq $7, $zero, 1f |
| 66 | \\ blez $2, 1f | ||
| 63 | \\ dsubu $2, $0, $2 | 67 | \\ 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 { |
| 73 | pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { | 77 | pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize { |
| 74 | return asm volatile ( | 78 | return asm volatile ( |
| 75 | \\ syscall | 79 | \\ syscall |
| 76 | \\ blez $7, 1f | 80 | \\ beq $7, $zero, 1f |
| 81 | \\ blez $2, 1f | ||
| 77 | \\ dsubu $2, $0, $2 | 82 | \\ 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 { |
| 88 | pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { | 93 | pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { |
| 89 | return asm volatile ( | 94 | return asm volatile ( |
| 90 | \\ syscall | 95 | \\ syscall |
| 91 | \\ blez $7, 1f | 96 | \\ beq $7, $zero, 1f |
| 97 | \\ blez $2, 1f | ||
| 92 | \\ dsubu $2, $0, $2 | 98 | \\ 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) |
| 104 | pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { | 110 | pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { |
| 105 | return asm volatile ( | 111 | return asm volatile ( |
| 106 | \\ syscall | 112 | \\ syscall |
| 107 | \\ blez $7, 1f | 113 | \\ beq $7, $zero, 1f |
| 114 | \\ blez $2, 1f | ||
| 108 | \\ dsubu $2, $0, $2 | 115 | \\ 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 | \\ syscall | 138 | \\ syscall |
| 132 | \\ blez $7, 1f | 139 | \\ beq $7, $zero, 1f |
| 140 | \\ blez $2, 1f | ||
| 133 | \\ dsubu $2, $0, $2 | 141 | \\ 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 | \\ syscall | 166 | \\ syscall |
| 159 | \\ blez $7, 1f | 167 | \\ beq $7, $zero, 1f |
| 168 | \\ blez $2, 1f | ||
| 160 | \\ dsubu $2, $0, $2 | 169 | \\ dsubu $2, $0, $2 |
| 161 | \\ 1: | 170 | \\ 1: |
| 162 | : [ret] "={$2}" (-> usize), | 171 | : [ret] "={$2}" (-> usize), |