Merge pull request #8705 from LemonBoy/libc-fix

32bit glibc fixes
This commit is contained in:
Andrew Kelley 2021-05-11 15:15:00 -04:00 committed by GitHub
commit ace5714551
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 280 additions and 86 deletions

View File

@ -61,7 +61,7 @@ lose: SYSCALL_PIC_SETUP \
# define SETUP_PIC_REG(reg) \
.ifndef GET_PC_THUNK(reg); \
.section .gnu.linkonce.t.GET_PC_THUNK(reg),"ax",@progbits; \
.section .text.GET_PC_THUNK(reg),"axG",@progbits,GET_PC_THUNK(reg),comdat; \
.globl GET_PC_THUNK(reg); \
.hidden GET_PC_THUNK(reg); \
.p2align 4; \
@ -97,8 +97,9 @@ GET_PC_THUNK(reg): \
# define SETUP_PIC_REG_STR(reg) \
".ifndef " GET_PC_THUNK_STR (reg) "\n" \
".section .gnu.linkonce.t." GET_PC_THUNK_STR (reg) ",\"ax\",@progbits\n" \
"section .text." GET_PC_THUNK_STR (reg) ",\"axG\",@progbits," \
".globl " GET_PC_THUNK_STR (reg) "\n" \
GET_PC_THUNK_STR (reg) ",comdat\n" \
".hidden " GET_PC_THUNK_STR (reg) "\n" \
".p2align 4\n" \
".type " GET_PC_THUNK_STR (reg) ",@function\n" \

View File

@ -89,13 +89,13 @@ pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;
pub extern "c" fn raise(sig: c_int) c_int;
pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;
pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;
pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize;
pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize;
pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: off_t) isize;
pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;
pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize;
pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize;
pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;
pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;
pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: u64) *c_void;
pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize;
pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: off_t) *c_void;
pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;
pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;

View File

@ -61,6 +61,23 @@ pub const EAI = extern enum(c_int) {
_,
};
pub extern "c" fn fallocate64(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int;
pub extern "c" fn fopen64(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE;
pub extern "c" fn fstat64(fd: fd_t, buf: *libc_stat) c_int;
pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;
pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;
pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;
pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64;
pub extern "c" fn mmap64(addr: ?*align(std.mem.page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: i64) *c_void;
pub extern "c" fn open64(path: [*:0]const u8, oflag: c_uint, ...) c_int;
pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;
pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize;
pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: i64) isize;
pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: i64) isize;
pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: i64) isize;
pub extern "c" fn sendfile64(out_fd: fd_t, in_fd: fd_t, offset: ?*i64, count: usize) isize;
pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_int;
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
@ -90,8 +107,6 @@ pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
pub extern "c" fn fallocate(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int;
pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;
pub extern "c" fn sendfile(
out_fd: fd_t,
in_fd: fd_t,

View File

@ -482,7 +482,7 @@ pub const File = struct {
/// order to handle partial reads from the underlying OS layer.
/// See https://github.com/ziglang/zig/issues/7699
pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize {
if (iovecs.len == 0) return;
if (iovecs.len == 0) return 0;
var i: usize = 0;
var off: usize = 0;
@ -524,8 +524,8 @@ pub const File = struct {
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
/// order to handle partial reads from the underlying OS layer.
/// See https://github.com/ziglang/zig/issues/7699
pub fn preadvAll(self: File, iovecs: []const os.iovec, offset: u64) PReadError!void {
if (iovecs.len == 0) return;
pub fn preadvAll(self: File, iovecs: []os.iovec, offset: u64) PReadError!usize {
if (iovecs.len == 0) return 0;
var i: usize = 0;
var off: usize = 0;

View File

@ -520,6 +520,89 @@ test "makePath, put some files in it, deleteTree" {
}
}
test "writev, readv" {
var tmp = tmpDir(.{});
defer tmp.cleanup();
const line1 = "line1\n";
const line2 = "line2\n";
var buf1: [line1.len]u8 = undefined;
var buf2: [line2.len]u8 = undefined;
var write_vecs = [_]std.os.iovec_const{
.{
.iov_base = line1,
.iov_len = line1.len,
},
.{
.iov_base = line2,
.iov_len = line2.len,
},
};
var read_vecs = [_]std.os.iovec{
.{
.iov_base = &buf2,
.iov_len = buf2.len,
},
.{
.iov_base = &buf1,
.iov_len = buf1.len,
},
};
var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
defer src_file.close();
try src_file.writevAll(&write_vecs);
try testing.expectEqual(@as(u64, line1.len + line2.len), try src_file.getEndPos());
try src_file.seekTo(0);
const read = try src_file.readvAll(&read_vecs);
try testing.expectEqual(@as(usize, line1.len + line2.len), read);
try testing.expectEqualStrings(&buf1, "line2\n");
try testing.expectEqualStrings(&buf2, "line1\n");
}
test "pwritev, preadv" {
var tmp = tmpDir(.{});
defer tmp.cleanup();
const line1 = "line1\n";
const line2 = "line2\n";
var buf1: [line1.len]u8 = undefined;
var buf2: [line2.len]u8 = undefined;
var write_vecs = [_]std.os.iovec_const{
.{
.iov_base = line1,
.iov_len = line1.len,
},
.{
.iov_base = line2,
.iov_len = line2.len,
},
};
var read_vecs = [_]std.os.iovec{
.{
.iov_base = &buf2,
.iov_len = buf2.len,
},
.{
.iov_base = &buf1,
.iov_len = buf1.len,
},
};
var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
defer src_file.close();
try src_file.pwritevAll(&write_vecs, 16);
try testing.expectEqual(@as(u64, 16 + line1.len + line2.len), try src_file.getEndPos());
const read = try src_file.preadvAll(&read_vecs, 16);
try testing.expectEqual(@as(usize, line1.len + line2.len), read);
try testing.expectEqualStrings(&buf1, "line2\n");
try testing.expectEqualStrings(&buf2, "line1\n");
}
test "access file" {
if (builtin.os.tag == .wasi) return error.SkipZigTest;

View File

@ -497,8 +497,14 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
};
const adjusted_len = math.min(max_count, buf.len);
const pread_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.pread64
else
system.pread;
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
while (true) {
const rc = system.pread(fd, buf.ptr, adjusted_len, offset);
const rc = pread_sym(fd, buf.ptr, adjusted_len, ioffset);
switch (errno(rc)) {
0 => return @intCast(usize, rc),
EINTR => continue,
@ -567,15 +573,13 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
}
while (true) {
const rc = if (builtin.link_libc)
if (std.Target.current.os.tag == .linux)
system.ftruncate64(fd, @bitCast(off_t, length))
else
system.ftruncate(fd, @bitCast(off_t, length))
const ftruncate_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.ftruncate64
else
system.ftruncate(fd, length);
system.ftruncate;
switch (errno(rc)) {
const ilen = @bitCast(i64, length); // the OS treats this as unsigned
switch (errno(ftruncate_sym(fd, ilen))) {
0 => return,
EINTR => continue,
EFBIG => return error.FileTooBig,
@ -637,8 +641,14 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);
const preadv_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.preadv64
else
system.preadv;
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
while (true) {
const rc = system.preadv(fd, iov.ptr, iov_count, offset);
const rc = preadv_sym(fd, iov.ptr, iov_count, ioffset);
switch (errno(rc)) {
0 => return @bitCast(usize, rc),
EINTR => continue,
@ -895,8 +905,14 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
};
const adjusted_len = math.min(max_count, bytes.len);
const pwrite_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.pwrite64
else
system.pwrite;
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
while (true) {
const rc = system.pwrite(fd, bytes.ptr, adjusted_len, offset);
const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, ioffset);
switch (errno(rc)) {
0 => return @intCast(usize, rc),
EINTR => continue,
@ -977,9 +993,15 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
}
}
const pwritev_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.pwritev64
else
system.pwritev;
const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
while (true) {
const rc = system.pwritev(fd, iov.ptr, iov_count, offset);
const rc = pwritev_sym(fd, iov.ptr, iov_count, ioffset);
switch (errno(rc)) {
0 => return @intCast(usize, rc),
EINTR => continue,
@ -1068,8 +1090,14 @@ pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t
const file_path_w = try windows.cStrToPrefixedFileW(file_path);
return openW(file_path_w.span(), flags, perm);
}
const open_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.open64
else
system.open;
while (true) {
const rc = system.open(file_path, flags, perm);
const rc = open_sym(file_path, flags, perm);
switch (errno(rc)) {
0 => return @intCast(fd_t, rc),
EINTR => continue,
@ -1202,8 +1230,14 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: mode_t)
const file_path_w = try windows.cStrToPrefixedFileW(file_path);
return openatW(dir_fd, file_path_w.span(), flags, mode);
}
const openat_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.openat64
else
system.openat;
while (true) {
const rc = system.openat(dir_fd, file_path, flags, mode);
const rc = openat_sym(dir_fd, file_path, flags, mode);
switch (errno(rc)) {
0 => return @intCast(fd_t, rc),
EINTR => continue,
@ -3437,8 +3471,13 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
@compileError("fstat is not yet implemented on Windows");
}
const fstat_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.fstat64
else
system.fstat;
var stat = mem.zeroes(Stat);
switch (errno(system.fstat(fd, &stat))) {
switch (errno(fstat_sym(fd, &stat))) {
0 => return stat,
EINVAL => unreachable,
EBADF => unreachable, // Always a race condition.
@ -3488,8 +3527,13 @@ pub fn fstatatWasi(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!S
/// Same as `fstatat` but `pathname` is null-terminated.
/// See also `fstatat`.
pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {
const fstatat_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.fstatat64
else
system.fstatat;
var stat = mem.zeroes(Stat);
switch (errno(system.fstatat(dirfd, pathname, &stat, flags))) {
switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {
0 => return stat,
EINVAL => unreachable,
EBADF => unreachable, // Always a race condition.
@ -3701,12 +3745,17 @@ pub fn mmap(
fd: fd_t,
offset: u64,
) MMapError![]align(mem.page_size) u8 {
const mmap_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.mmap64
else
system.mmap;
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
const rc = mmap_sym(ptr, length, prot, flags, fd, ioffset);
const err = if (builtin.link_libc) blk: {
const rc = std.c.mmap(ptr, length, prot, flags, fd, offset);
if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];
break :blk system._errno().*;
} else blk: {
const rc = system.mmap(ptr, length, prot, flags, fd, offset);
const err = errno(rc);
if (err == 0) return @intToPtr([*]align(mem.page_size) u8, rc)[0..length];
break :blk err;
@ -4056,8 +4105,14 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
else => |err| return unexpectedErrno(err),
}
}
const ipos = @bitCast(i64, offset); // the OS treats this as unsigned
switch (errno(system.lseek(fd, ipos, SEEK_SET))) {
const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.lseek64
else
system.lseek;
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
switch (errno(lseek_sym(fd, ioffset, SEEK_SET))) {
0 => return,
EBADF => unreachable, // always a race condition
EINVAL => return error.Unseekable,
@ -4098,7 +4153,13 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
else => |err| return unexpectedErrno(err),
}
}
switch (errno(system.lseek(fd, offset, SEEK_CUR))) {
const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.lseek64
else
system.lseek;
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
switch (errno(lseek_sym(fd, ioffset, SEEK_CUR))) {
0 => return,
EBADF => unreachable, // always a race condition
EINVAL => return error.Unseekable,
@ -4139,7 +4200,13 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
else => |err| return unexpectedErrno(err),
}
}
switch (errno(system.lseek(fd, offset, SEEK_END))) {
const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.lseek64
else
system.lseek;
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
switch (errno(lseek_sym(fd, ioffset, SEEK_END))) {
0 => return,
EBADF => unreachable, // always a race condition
EINVAL => return error.Unseekable,
@ -4180,7 +4247,12 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
else => |err| return unexpectedErrno(err),
}
}
const rc = system.lseek(fd, 0, SEEK_CUR);
const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.lseek64
else
system.lseek;
const rc = lseek_sym(fd, 0, SEEK_CUR);
switch (errno(rc)) {
0 => return @bitCast(u64, rc),
EBADF => unreachable, // always a race condition
@ -5198,9 +5270,14 @@ pub fn sendfile(
// Here we match BSD behavior, making a zero count value send as many bytes as possible.
const adjusted_count = if (in_len == 0) max_count else math.min(in_len, @as(size_t, max_count));
const sendfile_sym = if (builtin.link_libc)
system.sendfile64
else
system.sendfile;
while (true) {
var offset: off_t = @bitCast(off_t, in_offset);
const rc = system.sendfile(out_fd, in_fd, &offset, adjusted_count);
const rc = sendfile_sym(out_fd, in_fd, &offset, adjusted_count);
switch (errno(rc)) {
0 => {
const amt = @bitCast(usize, rc);
@ -6018,9 +6095,13 @@ pub fn prctl(option: PR, args: anytype) PrctlError!u31 {
pub const GetrlimitError = UnexpectedError;
pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
const getrlimit_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.getrlimit64
else
system.getrlimit;
var limits: rlimit = undefined;
const rc = system.getrlimit(resource, &limits);
switch (errno(rc)) {
switch (errno(getrlimit_sym(resource, &limits))) {
0 => return limits,
EFAULT => unreachable, // bogus pointer
EINVAL => unreachable,
@ -6031,8 +6112,12 @@ pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
pub const SetrlimitError = error{PermissionDenied} || UnexpectedError;
pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void {
const rc = system.setrlimit(resource, &limits);
switch (errno(rc)) {
const setrlimit_sym = if (builtin.os.tag == .linux and builtin.link_libc)
system.setrlimit64
else
system.setrlimit;
switch (errno(setrlimit_sym(resource, &limits))) {
0 => return,
EFAULT => unreachable, // bogus pointer
EINVAL => unreachable,

View File

@ -59,15 +59,30 @@ const require_aligned_register_pair =
std.Target.current.cpu.arch.isThumb();
// Split a 64bit value into a {LSB,MSB} pair.
fn splitValue64(val: u64) [2]u32 {
// The LE/BE variants specify the endianness to assume.
fn splitValueLE64(val: i64) [2]u32 {
const u = @bitCast(u64, val);
return [2]u32{
@truncate(u32, u),
@truncate(u32, u >> 32),
};
}
fn splitValueBE64(val: i64) [2]u32 {
return [2]u32{
@truncate(u32, u >> 32),
@truncate(u32, u),
};
}
fn splitValue64(val: i64) [2]u32 {
const u = @bitCast(u64, val);
switch (builtin.endian) {
.Little => return [2]u32{
@truncate(u32, val),
@truncate(u32, val >> 32),
@truncate(u32, u),
@truncate(u32, u >> 32),
},
.Big => return [2]u32{
@truncate(u32, val >> 32),
@truncate(u32, val),
@truncate(u32, u >> 32),
@truncate(u32, u),
},
}
}
@ -141,8 +156,8 @@ pub fn utimensat(dirfd: i32, path: ?[*:0]const u8, times: *const [2]timespec, fl
return syscall4(.utimensat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(times), flags);
}
pub fn fallocate(fd: i32, mode: i32, offset: u64, length: u64) usize {
if (@sizeOf(usize) == 4) {
pub fn fallocate(fd: i32, mode: i32, offset: i64, length: i64) usize {
if (usize_bits < 64) {
const offset_halves = splitValue64(offset);
const length_halves = splitValue64(length);
return syscall6(
@ -159,8 +174,8 @@ pub fn fallocate(fd: i32, mode: i32, offset: u64, length: u64) usize {
.fallocate,
@bitCast(usize, @as(isize, fd)),
@bitCast(usize, @as(isize, mode)),
offset,
length,
@bitCast(u64, offset),
@bitCast(u64, length),
);
}
}
@ -243,7 +258,7 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {
return syscall2(.umount2, @ptrToInt(special), flags);
}
pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: u64) usize {
pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: i64) usize {
if (@hasField(SYS, "mmap2")) {
// Make sure the offset is also specified in multiples of page size
if ((offset & (MMAP2_UNIT - 1)) != 0)
@ -256,7 +271,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
prot,
flags,
@bitCast(usize, @as(isize, fd)),
@truncate(usize, offset / MMAP2_UNIT),
@truncate(usize, @bitCast(u64, offset) / MMAP2_UNIT),
);
} else {
return syscall6(
@ -266,7 +281,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
prot,
flags,
@bitCast(usize, @as(isize, fd)),
offset,
@bitCast(u64, offset),
);
}
}
@ -308,8 +323,8 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
}
pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
const offset_halves = splitValue64(offset);
pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {
const offset_halves = splitValueLE64(offset);
return syscall5(
.preadv,
@bitCast(usize, @as(isize, fd)),
@ -320,7 +335,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
);
}
pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {
pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {
const offset_halves = splitValue64(offset);
return syscall6(
.preadv2,
@ -341,8 +356,8 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
return syscall3(.writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
}
pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
const offset_halves = splitValue64(offset);
pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {
const offset_halves = splitValueLE64(offset);
return syscall5(
.pwritev,
@bitCast(usize, @as(isize, fd)),
@ -353,7 +368,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us
);
}
pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {
pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {
const offset_halves = splitValue64(offset);
return syscall6(
.pwritev2,
@ -386,7 +401,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us
return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));
}
pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: i64) usize {
if (@hasField(SYS, "pread64") and usize_bits < 64) {
const offset_halves = splitValue64(offset);
if (require_aligned_register_pair) {
@ -417,7 +432,7 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
@bitCast(usize, @as(isize, fd)),
@ptrToInt(buf),
count,
offset,
@bitCast(u64, offset),
);
}
}
@ -452,7 +467,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
}
pub fn ftruncate(fd: i32, length: u64) usize {
pub fn ftruncate(fd: i32, length: i64) usize {
if (@hasField(SYS, "ftruncate64") and usize_bits < 64) {
const length_halves = splitValue64(length);
if (require_aligned_register_pair) {
@ -475,12 +490,12 @@ pub fn ftruncate(fd: i32, length: u64) usize {
return syscall2(
.ftruncate,
@bitCast(usize, @as(isize, fd)),
@truncate(usize, length),
@bitCast(usize, length),
);
}
}
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: i64) usize {
if (@hasField(SYS, "pwrite64") and usize_bits < 64) {
const offset_halves = splitValue64(offset);
@ -512,7 +527,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
@bitCast(usize, @as(isize, fd)),
@ptrToInt(buf),
count,
offset,
@bitCast(u64, offset),
);
}
}

View File

@ -20,7 +20,7 @@ test "fallocate" {
try expect((try file.stat()).size == 0);
const len: u64 = 65536;
const len: i64 = 65536;
switch (linux.getErrno(linux.fallocate(file.handle, 0, 0, len))) {
0 => {},
linux.ENOSYS => return error.SkipZigTest,

View File

@ -225,7 +225,7 @@ export fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8
return dest;
}
export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) isize {
export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) c_int {
@setRuntimeSafety(false);
var index: usize = 0;
@ -250,7 +250,7 @@ test "memcmp" {
try std.testing.expect(memcmp(base_arr[0..], arr3[0..], base_arr.len) < 0);
}
export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.C) isize {
export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.C) c_int {
@setRuntimeSafety(false);
var index: usize = 0;

View File

@ -40,10 +40,11 @@ pub const ABI = struct {
}
};
// The order of the elements in this array defines the linking order.
pub const libs = [_]Lib{
.{ .name = "c", .sover = 6 },
.{ .name = "m", .sover = 6 },
.{ .name = "pthread", .sover = 0 },
.{ .name = "c", .sover = 6 },
.{ .name = "dl", .sover = 2 },
.{ .name = "rt", .sover = 1 },
.{ .name = "ld", .sover = 2 },

View File

@ -1648,17 +1648,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
// libc dep
if (self.base.options.link_libc) {
if (self.base.options.libc_installation != null) {
if (self.base.options.link_mode == .Static) {
try argv.append("--start-group");
try argv.append("-lc");
try argv.append("-lm");
try argv.append("--end-group");
} else {
try argv.append("-lc");
try argv.append("-lm");
}
const needs_grouping = self.base.options.link_mode == .Static;
if (needs_grouping) try argv.append("--start-group");
try argv.append("-lm");
try argv.append("-lpthread");
try argv.append("-lc");
if (needs_grouping) try argv.append("--end-group");
} else if (target.isGnuLibC()) {
try argv.append(comp.libunwind_static_lib.?.full_object_path);
for (glibc.libs) |lib| {

View File

@ -98,15 +98,14 @@ const test_targets = blk: {
},
.link_libc = true,
},
// https://github.com/ziglang/zig/issues/4926
//TestTarget{
// .target = .{
// .cpu_arch = .i386,
// .os_tag = .linux,
// .abi = .gnu,
// },
// .link_libc = true,
//},
TestTarget{
.target = .{
.cpu_arch = .i386,
.os_tag = .linux,
.abi = .gnu,
},
.link_libc = true,
},
TestTarget{
.target = .{