authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-02 12:11:07+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-02 12:11:07+01:00
logdc872a221d8301cfac4b9ead09196c5b18cf63b2
treeccd12100a4a4de5758e5eaf28e31b654e14c0631
parent76e9a4ae8377a9329170b038ce7b393db0402862

std: Fix syscall stubs passing 64bit offsets for BE targets


2 files changed, 46 insertions(+), 25 deletions(-)

lib/std/io/test.zig-3
...@@ -140,9 +140,6 @@ test "File seek ops" {...@@ -140,9 +140,6 @@ test "File seek ops" {
140}140}
141141
142test "setEndPos" {142test "setEndPos" {
143 // https://github.com/ziglang/zig/issues/5127
144 if (std.Target.current.cpu.arch == .mips) return error.SkipZigTest;
145
146 var tmp = tmpDir(.{});143 var tmp = tmpDir(.{});
147 defer tmp.cleanup();144 defer tmp.cleanup();
148145
lib/std/os/linux.zig+46-22
...@@ -48,13 +48,27 @@ pub fn getauxval(index: usize) usize {...@@ -48,13 +48,27 @@ pub fn getauxval(index: usize) usize {
48 return 0;48 return 0;
49}49}
5050
51// Some architectures require 64bit parameters for some syscalls to be passed in51// Some architectures (and some syscalls) require 64bit parameters to be passed
52// even-aligned register pair52// in a even-aligned register pair.
53const require_aligned_register_pair = //53const require_aligned_register_pair = //
54 std.Target.current.cpu.arch.isMIPS() or54 std.Target.current.cpu.arch.isMIPS() or
55 std.Target.current.cpu.arch.isARM() or55 std.Target.current.cpu.arch.isARM() or
56 std.Target.current.cpu.arch.isThumb();56 std.Target.current.cpu.arch.isThumb();
5757
58// Split a 64bit value into a {LSB,MSB} pair.
59fn splitValue64(val: u64) [2]u32 {
60 switch (builtin.endian) {
61 .Little => return [2]u32{
62 @truncate(u32, val),
63 @truncate(u32, val >> 32),
64 },
65 .Big => return [2]u32{
66 @truncate(u32, val >> 32),
67 @truncate(u32, val),
68 },
69 }
70}
71
58/// Get the errno from a syscall return value, or 0 for no error.72/// Get the errno from a syscall return value, or 0 for no error.
59pub fn getErrno(r: usize) u12 {73pub fn getErrno(r: usize) u12 {
60 const signed_r = @bitCast(isize, r);74 const signed_r = @bitCast(isize, r);
...@@ -263,24 +277,26 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {...@@ -263,24 +277,26 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
263}277}
264278
265pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {279pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
280 const offset_halves = splitValue64(offset);
266 return syscall5(281 return syscall5(
267 .preadv,282 .preadv,
268 @bitCast(usize, @as(isize, fd)),283 @bitCast(usize, @as(isize, fd)),
269 @ptrToInt(iov),284 @ptrToInt(iov),
270 count,285 count,
271 @truncate(usize, offset),286 offset_halves[0],
272 @truncate(usize, offset >> 32),287 offset_halves[1],
273 );288 );
274}289}
275290
276pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {291pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {
292 const offset_halves = splitValue64(offset);
277 return syscall6(293 return syscall6(
278 .preadv2,294 .preadv2,
279 @bitCast(usize, @as(isize, fd)),295 @bitCast(usize, @as(isize, fd)),
280 @ptrToInt(iov),296 @ptrToInt(iov),
281 count,297 count,
282 @truncate(usize, offset),298 offset_halves[0],
283 @truncate(usize, offset >> 32),299 offset_halves[1],
284 flags,300 flags,
285 );301 );
286}302}
...@@ -294,24 +310,26 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {...@@ -294,24 +310,26 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
294}310}
295311
296pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {312pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
313 const offset_halves = splitValue64(offset);
297 return syscall5(314 return syscall5(
298 .pwritev,315 .pwritev,
299 @bitCast(usize, @as(isize, fd)),316 @bitCast(usize, @as(isize, fd)),
300 @ptrToInt(iov),317 @ptrToInt(iov),
301 count,318 count,
302 @truncate(usize, offset),319 offset_halves[0],
303 @truncate(usize, offset >> 32),320 offset_halves[1],
304 );321 );
305}322}
306323
307pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {324pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {
325 const offset_halves = splitValue64(offset);
308 return syscall6(326 return syscall6(
309 .pwritev2,327 .pwritev2,
310 @bitCast(usize, @as(isize, fd)),328 @bitCast(usize, @as(isize, fd)),
311 @ptrToInt(iov),329 @ptrToInt(iov),
312 count,330 count,
313 @truncate(usize, offset),331 offset_halves[0],
314 @truncate(usize, offset >> 32),332 offset_halves[1],
315 flags,333 flags,
316 );334 );
317}335}
...@@ -338,6 +356,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us...@@ -338,6 +356,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us
338356
339pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {357pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
340 if (@hasField(SYS, "pread64")) {358 if (@hasField(SYS, "pread64")) {
359 const offset_halves = splitValue64(offset);
341 if (require_aligned_register_pair) {360 if (require_aligned_register_pair) {
342 return syscall6(361 return syscall6(
343 .pread64,362 .pread64,
...@@ -345,8 +364,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {...@@ -345,8 +364,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
345 @ptrToInt(buf),364 @ptrToInt(buf),
346 count,365 count,
347 0,366 0,
348 @truncate(usize, offset),367 offset_halves[0],
349 @truncate(usize, offset >> 32),368 offset_halves[1],
350 );369 );
351 } else {370 } else {
352 return syscall5(371 return syscall5(
...@@ -354,8 +373,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {...@@ -354,8 +373,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
354 @bitCast(usize, @as(isize, fd)),373 @bitCast(usize, @as(isize, fd)),
355 @ptrToInt(buf),374 @ptrToInt(buf),
356 count,375 count,
357 @truncate(usize, offset),376 offset_halves[0],
358 @truncate(usize, offset >> 32),377 offset_halves[1],
359 );378 );
360 }379 }
361 } else {380 } else {
...@@ -401,20 +420,21 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {...@@ -401,20 +420,21 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
401420
402pub fn ftruncate(fd: i32, length: u64) usize {421pub fn ftruncate(fd: i32, length: u64) usize {
403 if (@hasField(SYS, "ftruncate64")) {422 if (@hasField(SYS, "ftruncate64")) {
423 const length_halves = splitValue64(length);
404 if (require_aligned_register_pair) {424 if (require_aligned_register_pair) {
405 return syscall4(425 return syscall4(
406 .ftruncate64,426 .ftruncate64,
407 @bitCast(usize, @as(isize, fd)),427 @bitCast(usize, @as(isize, fd)),
408 0,428 0,
409 @truncate(usize, length),429 length_halves[0],
410 @truncate(usize, length >> 32),430 length_halves[1],
411 );431 );
412 } else {432 } else {
413 return syscall3(433 return syscall3(
414 .ftruncate64,434 .ftruncate64,
415 @bitCast(usize, @as(isize, fd)),435 @bitCast(usize, @as(isize, fd)),
416 @truncate(usize, length),436 length_halves[0],
417 @truncate(usize, length >> 32),437 length_halves[1],
418 );438 );
419 }439 }
420 } else {440 } else {
...@@ -428,6 +448,8 @@ pub fn ftruncate(fd: i32, length: u64) usize {...@@ -428,6 +448,8 @@ pub fn ftruncate(fd: i32, length: u64) usize {
428448
429pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {449pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
430 if (@hasField(SYS, "pwrite64")) {450 if (@hasField(SYS, "pwrite64")) {
451 const offset_halves = splitValue64(offset);
452
431 if (require_aligned_register_pair) {453 if (require_aligned_register_pair) {
432 return syscall6(454 return syscall6(
433 .pwrite64,455 .pwrite64,
...@@ -435,8 +457,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {...@@ -435,8 +457,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
435 @ptrToInt(buf),457 @ptrToInt(buf),
436 count,458 count,
437 0,459 0,
438 @truncate(usize, offset),460 offset_halves[0],
439 @truncate(usize, offset >> 32),461 offset_halves[1],
440 );462 );
441 } else {463 } else {
442 return syscall5(464 return syscall5(
...@@ -444,8 +466,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {...@@ -444,8 +466,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
444 @bitCast(usize, @as(isize, fd)),466 @bitCast(usize, @as(isize, fd)),
445 @ptrToInt(buf),467 @ptrToInt(buf),
446 count,468 count,
447 @truncate(usize, offset),469 offset_halves[0],
448 @truncate(usize, offset >> 32),470 offset_halves[1],
449 );471 );
450 }472 }
451 } else {473 } else {
...@@ -540,6 +562,8 @@ pub fn close(fd: i32) usize {...@@ -540,6 +562,8 @@ pub fn close(fd: i32) usize {
540562
541/// Can only be called on 32 bit systems. For 64 bit see `lseek`.563/// Can only be called on 32 bit systems. For 64 bit see `lseek`.
542pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {564pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {
565 // NOTE: The offset parameter splitting is independent from the target
566 // endianness.
543 return syscall5(567 return syscall5(
544 ._llseek,568 ._llseek,
545 @bitCast(usize, @as(isize, fd)),569 @bitCast(usize, @as(isize, fd)),