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" {
140140}
141141
142142test "setEndPos" {
143 // https://github.com/ziglang/zig/issues/5127
144 if (std.Target.current.cpu.arch == .mips) return error.SkipZigTest;
145
146143 var tmp = tmpDir(.{});
147144 defer tmp.cleanup();
148145
lib/std/os/linux.zig+46-22
......@@ -48,13 +48,27 @@ pub fn getauxval(index: usize) usize {
4848 return 0;
4949}
5050
51// Some architectures require 64bit parameters for some syscalls to be passed in
52// even-aligned register pair
51// Some architectures (and some syscalls) require 64bit parameters to be passed
52// in a even-aligned register pair.
5353const require_aligned_register_pair = //
5454 std.Target.current.cpu.arch.isMIPS() or
5555 std.Target.current.cpu.arch.isARM() or
5656 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
5872/// Get the errno from a syscall return value, or 0 for no error.
5973pub fn getErrno(r: usize) u12 {
6074 const signed_r = @bitCast(isize, r);
......@@ -263,24 +277,26 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
263277}
264278
265279pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
280 const offset_halves = splitValue64(offset);
266281 return syscall5(
267282 .preadv,
268283 @bitCast(usize, @as(isize, fd)),
269284 @ptrToInt(iov),
270285 count,
271 @truncate(usize, offset),
272 @truncate(usize, offset >> 32),
286 offset_halves[0],
287 offset_halves[1],
273288 );
274289}
275290
276291pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {
292 const offset_halves = splitValue64(offset);
277293 return syscall6(
278294 .preadv2,
279295 @bitCast(usize, @as(isize, fd)),
280296 @ptrToInt(iov),
281297 count,
282 @truncate(usize, offset),
283 @truncate(usize, offset >> 32),
298 offset_halves[0],
299 offset_halves[1],
284300 flags,
285301 );
286302}
......@@ -294,24 +310,26 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
294310}
295311
296312pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
313 const offset_halves = splitValue64(offset);
297314 return syscall5(
298315 .pwritev,
299316 @bitCast(usize, @as(isize, fd)),
300317 @ptrToInt(iov),
301318 count,
302 @truncate(usize, offset),
303 @truncate(usize, offset >> 32),
319 offset_halves[0],
320 offset_halves[1],
304321 );
305322}
306323
307324pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {
325 const offset_halves = splitValue64(offset);
308326 return syscall6(
309327 .pwritev2,
310328 @bitCast(usize, @as(isize, fd)),
311329 @ptrToInt(iov),
312330 count,
313 @truncate(usize, offset),
314 @truncate(usize, offset >> 32),
331 offset_halves[0],
332 offset_halves[1],
315333 flags,
316334 );
317335}
......@@ -338,6 +356,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us
338356
339357pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
340358 if (@hasField(SYS, "pread64")) {
359 const offset_halves = splitValue64(offset);
341360 if (require_aligned_register_pair) {
342361 return syscall6(
343362 .pread64,
......@@ -345,8 +364,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
345364 @ptrToInt(buf),
346365 count,
347366 0,
348 @truncate(usize, offset),
349 @truncate(usize, offset >> 32),
367 offset_halves[0],
368 offset_halves[1],
350369 );
351370 } else {
352371 return syscall5(
......@@ -354,8 +373,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
354373 @bitCast(usize, @as(isize, fd)),
355374 @ptrToInt(buf),
356375 count,
357 @truncate(usize, offset),
358 @truncate(usize, offset >> 32),
376 offset_halves[0],
377 offset_halves[1],
359378 );
360379 }
361380 } else {
......@@ -401,20 +420,21 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
401420
402421pub fn ftruncate(fd: i32, length: u64) usize {
403422 if (@hasField(SYS, "ftruncate64")) {
423 const length_halves = splitValue64(length);
404424 if (require_aligned_register_pair) {
405425 return syscall4(
406426 .ftruncate64,
407427 @bitCast(usize, @as(isize, fd)),
408428 0,
409 @truncate(usize, length),
410 @truncate(usize, length >> 32),
429 length_halves[0],
430 length_halves[1],
411431 );
412432 } else {
413433 return syscall3(
414434 .ftruncate64,
415435 @bitCast(usize, @as(isize, fd)),
416 @truncate(usize, length),
417 @truncate(usize, length >> 32),
436 length_halves[0],
437 length_halves[1],
418438 );
419439 }
420440 } else {
......@@ -428,6 +448,8 @@ pub fn ftruncate(fd: i32, length: u64) usize {
428448
429449pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
430450 if (@hasField(SYS, "pwrite64")) {
451 const offset_halves = splitValue64(offset);
452
431453 if (require_aligned_register_pair) {
432454 return syscall6(
433455 .pwrite64,
......@@ -435,8 +457,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
435457 @ptrToInt(buf),
436458 count,
437459 0,
438 @truncate(usize, offset),
439 @truncate(usize, offset >> 32),
460 offset_halves[0],
461 offset_halves[1],
440462 );
441463 } else {
442464 return syscall5(
......@@ -444,8 +466,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
444466 @bitCast(usize, @as(isize, fd)),
445467 @ptrToInt(buf),
446468 count,
447 @truncate(usize, offset),
448 @truncate(usize, offset >> 32),
469 offset_halves[0],
470 offset_halves[1],
449471 );
450472 }
451473 } else {
......@@ -540,6 +562,8 @@ pub fn close(fd: i32) usize {
540562
541563/// Can only be called on 32 bit systems. For 64 bit see `lseek`.
542564pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {
565 // NOTE: The offset parameter splitting is independent from the target
566 // endianness.
543567 return syscall5(
544568 ._llseek,
545569 @bitCast(usize, @as(isize, fd)),