| ... | ... | @@ -48,13 +48,27 @@ pub fn getauxval(index: usize) usize { |
| 48 | 48 | return 0; |
| 49 | 49 | } |
| 50 | 50 | |
| 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. |
| 53 | 53 | const require_aligned_register_pair = // |
| 54 | 54 | std.Target.current.cpu.arch.isMIPS() or |
| 55 | 55 | std.Target.current.cpu.arch.isARM() or |
| 56 | 56 | std.Target.current.cpu.arch.isThumb(); |
| 57 | 57 | |
| 58 | // Split a 64bit value into a {LSB,MSB} pair. |
| 59 | fn 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 | 72 | /// Get the errno from a syscall return value, or 0 for no error. |
| 59 | 73 | pub fn getErrno(r: usize) u12 { |
| 60 | 74 | const signed_r = @bitCast(isize, r); |
| ... | ... | @@ -263,24 +277,26 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize { |
| 263 | 277 | } |
| 264 | 278 | |
| 265 | 279 | pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize { |
| 280 | const offset_halves = splitValue64(offset); |
| 266 | 281 | return syscall5( |
| 267 | 282 | .preadv, |
| 268 | 283 | @bitCast(usize, @as(isize, fd)), |
| 269 | 284 | @ptrToInt(iov), |
| 270 | 285 | count, |
| 271 | | @truncate(usize, offset), |
| 272 | | @truncate(usize, offset >> 32), |
| 286 | offset_halves[0], |
| 287 | offset_halves[1], |
| 273 | 288 | ); |
| 274 | 289 | } |
| 275 | 290 | |
| 276 | 291 | pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize { |
| 292 | const offset_halves = splitValue64(offset); |
| 277 | 293 | return syscall6( |
| 278 | 294 | .preadv2, |
| 279 | 295 | @bitCast(usize, @as(isize, fd)), |
| 280 | 296 | @ptrToInt(iov), |
| 281 | 297 | count, |
| 282 | | @truncate(usize, offset), |
| 283 | | @truncate(usize, offset >> 32), |
| 298 | offset_halves[0], |
| 299 | offset_halves[1], |
| 284 | 300 | flags, |
| 285 | 301 | ); |
| 286 | 302 | } |
| ... | ... | @@ -294,24 +310,26 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize { |
| 294 | 310 | } |
| 295 | 311 | |
| 296 | 312 | pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize { |
| 313 | const offset_halves = splitValue64(offset); |
| 297 | 314 | return syscall5( |
| 298 | 315 | .pwritev, |
| 299 | 316 | @bitCast(usize, @as(isize, fd)), |
| 300 | 317 | @ptrToInt(iov), |
| 301 | 318 | count, |
| 302 | | @truncate(usize, offset), |
| 303 | | @truncate(usize, offset >> 32), |
| 319 | offset_halves[0], |
| 320 | offset_halves[1], |
| 304 | 321 | ); |
| 305 | 322 | } |
| 306 | 323 | |
| 307 | 324 | pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize { |
| 325 | const offset_halves = splitValue64(offset); |
| 308 | 326 | return syscall6( |
| 309 | 327 | .pwritev2, |
| 310 | 328 | @bitCast(usize, @as(isize, fd)), |
| 311 | 329 | @ptrToInt(iov), |
| 312 | 330 | count, |
| 313 | | @truncate(usize, offset), |
| 314 | | @truncate(usize, offset >> 32), |
| 331 | offset_halves[0], |
| 332 | offset_halves[1], |
| 315 | 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 | 356 | |
| 339 | 357 | pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize { |
| 340 | 358 | if (@hasField(SYS, "pread64")) { |
| 359 | const offset_halves = splitValue64(offset); |
| 341 | 360 | if (require_aligned_register_pair) { |
| 342 | 361 | return syscall6( |
| 343 | 362 | .pread64, |
| ... | ... | @@ -345,8 +364,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize { |
| 345 | 364 | @ptrToInt(buf), |
| 346 | 365 | count, |
| 347 | 366 | 0, |
| 348 | | @truncate(usize, offset), |
| 349 | | @truncate(usize, offset >> 32), |
| 367 | offset_halves[0], |
| 368 | offset_halves[1], |
| 350 | 369 | ); |
| 351 | 370 | } else { |
| 352 | 371 | return syscall5( |
| ... | ... | @@ -354,8 +373,8 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize { |
| 354 | 373 | @bitCast(usize, @as(isize, fd)), |
| 355 | 374 | @ptrToInt(buf), |
| 356 | 375 | count, |
| 357 | | @truncate(usize, offset), |
| 358 | | @truncate(usize, offset >> 32), |
| 376 | offset_halves[0], |
| 377 | offset_halves[1], |
| 359 | 378 | ); |
| 360 | 379 | } |
| 361 | 380 | } else { |
| ... | ... | @@ -401,20 +420,21 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { |
| 401 | 420 | |
| 402 | 421 | pub fn ftruncate(fd: i32, length: u64) usize { |
| 403 | 422 | if (@hasField(SYS, "ftruncate64")) { |
| 423 | const length_halves = splitValue64(length); |
| 404 | 424 | if (require_aligned_register_pair) { |
| 405 | 425 | return syscall4( |
| 406 | 426 | .ftruncate64, |
| 407 | 427 | @bitCast(usize, @as(isize, fd)), |
| 408 | 428 | 0, |
| 409 | | @truncate(usize, length), |
| 410 | | @truncate(usize, length >> 32), |
| 429 | length_halves[0], |
| 430 | length_halves[1], |
| 411 | 431 | ); |
| 412 | 432 | } else { |
| 413 | 433 | return syscall3( |
| 414 | 434 | .ftruncate64, |
| 415 | 435 | @bitCast(usize, @as(isize, fd)), |
| 416 | | @truncate(usize, length), |
| 417 | | @truncate(usize, length >> 32), |
| 436 | length_halves[0], |
| 437 | length_halves[1], |
| 418 | 438 | ); |
| 419 | 439 | } |
| 420 | 440 | } else { |
| ... | ... | @@ -428,6 +448,8 @@ pub fn ftruncate(fd: i32, length: u64) usize { |
| 428 | 448 | |
| 429 | 449 | pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize { |
| 430 | 450 | if (@hasField(SYS, "pwrite64")) { |
| 451 | const offset_halves = splitValue64(offset); |
| 452 | |
| 431 | 453 | if (require_aligned_register_pair) { |
| 432 | 454 | return syscall6( |
| 433 | 455 | .pwrite64, |
| ... | ... | @@ -435,8 +457,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize { |
| 435 | 457 | @ptrToInt(buf), |
| 436 | 458 | count, |
| 437 | 459 | 0, |
| 438 | | @truncate(usize, offset), |
| 439 | | @truncate(usize, offset >> 32), |
| 460 | offset_halves[0], |
| 461 | offset_halves[1], |
| 440 | 462 | ); |
| 441 | 463 | } else { |
| 442 | 464 | return syscall5( |
| ... | ... | @@ -444,8 +466,8 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize { |
| 444 | 466 | @bitCast(usize, @as(isize, fd)), |
| 445 | 467 | @ptrToInt(buf), |
| 446 | 468 | count, |
| 447 | | @truncate(usize, offset), |
| 448 | | @truncate(usize, offset >> 32), |
| 469 | offset_halves[0], |
| 470 | offset_halves[1], |
| 449 | 471 | ); |
| 450 | 472 | } |
| 451 | 473 | } else { |
| ... | ... | @@ -540,6 +562,8 @@ pub fn close(fd: i32) usize { |
| 540 | 562 | |
| 541 | 563 | /// Can only be called on 32 bit systems. For 64 bit see `lseek`. |
| 542 | 564 | pub 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 | 567 | return syscall5( |
| 544 | 568 | ._llseek, |
| 545 | 569 | @bitCast(usize, @as(isize, fd)), |