authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-11 15:15:00-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-05-11 15:15:00-04:00
logace5714551da16b541d8015e97a2fe32a7a1cf76
tree115b330897cc048f554cae530ba23b6d8bce1256
parentc3d4733a00880e2c757b61b66ba18d9b6753aa11
parent8bb58fb4286ad03a243e32e31d67dd2bb5c117ef
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8705 from LemonBoy/libc-fix

32bit glibc fixes

12 files changed, 280 insertions(+), 86 deletions(-)

lib/libc/glibc/sysdeps/i386/sysdep.h+3-2
...@@ -61,7 +61,7 @@ lose: SYSCALL_PIC_SETUP \...@@ -61,7 +61,7 @@ lose: SYSCALL_PIC_SETUP \
6161
62# define SETUP_PIC_REG(reg) \62# define SETUP_PIC_REG(reg) \
63 .ifndef GET_PC_THUNK(reg); \63 .ifndef GET_PC_THUNK(reg); \
64 .section .gnu.linkonce.t.GET_PC_THUNK(reg),"ax",@progbits; \64 .section .text.GET_PC_THUNK(reg),"axG",@progbits,GET_PC_THUNK(reg),comdat; \
65 .globl GET_PC_THUNK(reg); \65 .globl GET_PC_THUNK(reg); \
66 .hidden GET_PC_THUNK(reg); \66 .hidden GET_PC_THUNK(reg); \
67 .p2align 4; \67 .p2align 4; \
...@@ -97,8 +97,9 @@ GET_PC_THUNK(reg): \...@@ -97,8 +97,9 @@ GET_PC_THUNK(reg): \
9797
98# define SETUP_PIC_REG_STR(reg) \98# define SETUP_PIC_REG_STR(reg) \
99 ".ifndef " GET_PC_THUNK_STR (reg) "\n" \99 ".ifndef " GET_PC_THUNK_STR (reg) "\n" \
100 ".section .gnu.linkonce.t." GET_PC_THUNK_STR (reg) ",\"ax\",@progbits\n" \100 "section .text." GET_PC_THUNK_STR (reg) ",\"axG\",@progbits," \
101 ".globl " GET_PC_THUNK_STR (reg) "\n" \101 ".globl " GET_PC_THUNK_STR (reg) "\n" \
102 GET_PC_THUNK_STR (reg) ",comdat\n" \
102 ".hidden " GET_PC_THUNK_STR (reg) "\n" \103 ".hidden " GET_PC_THUNK_STR (reg) "\n" \
103 ".p2align 4\n" \104 ".p2align 4\n" \
104 ".type " GET_PC_THUNK_STR (reg) ",@function\n" \105 ".type " GET_PC_THUNK_STR (reg) ",@function\n" \
lib/std/c.zig+5-5
...@@ -89,13 +89,13 @@ pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;...@@ -89,13 +89,13 @@ pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;
89pub extern "c" fn raise(sig: c_int) c_int;89pub extern "c" fn raise(sig: c_int) c_int;
90pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;90pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
91pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;91pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;
92pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;92pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize;
93pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize;93pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: off_t) isize;
94pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;94pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;
95pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize;95pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize;
96pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;96pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;
97pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;97pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize;
98pub 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;98pub 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;
99pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;99pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;
100pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;100pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
101pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;101pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;
lib/std/c/linux.zig+17-2
...@@ -61,6 +61,23 @@ pub const EAI = extern enum(c_int) {...@@ -61,6 +61,23 @@ pub const EAI = extern enum(c_int) {
61 _,61 _,
62};62};
6363
64pub extern "c" fn fallocate64(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int;
65pub extern "c" fn fopen64(noalias filename: [*:0]const u8, noalias modes: [*:0]const u8) ?*FILE;
66pub extern "c" fn fstat64(fd: fd_t, buf: *libc_stat) c_int;
67pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;
68pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;
69pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;
70pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64;
71pub 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;
72pub extern "c" fn open64(path: [*:0]const u8, oflag: c_uint, ...) c_int;
73pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;
74pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize;
75pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: i64) isize;
76pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: i64) isize;
77pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: i64) isize;
78pub extern "c" fn sendfile64(out_fd: fd_t, in_fd: fd_t, offset: ?*i64, count: usize) isize;
79pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_int;
80
64pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;81pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
65pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;82pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
66pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;83pub 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;...@@ -90,8 +107,6 @@ pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
90107
91pub extern "c" fn fallocate(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int;108pub extern "c" fn fallocate(fd: fd_t, mode: c_int, offset: off_t, len: off_t) c_int;
92109
93pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;
94
95pub extern "c" fn sendfile(110pub extern "c" fn sendfile(
96 out_fd: fd_t,111 out_fd: fd_t,
97 in_fd: fd_t,112 in_fd: fd_t,
lib/std/fs/file.zig+3-3
...@@ -482,7 +482,7 @@ pub const File = struct {...@@ -482,7 +482,7 @@ pub const File = struct {
482 /// order to handle partial reads from the underlying OS layer.482 /// order to handle partial reads from the underlying OS layer.
483 /// See https://github.com/ziglang/zig/issues/7699483 /// See https://github.com/ziglang/zig/issues/7699
484 pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize {484 pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize {
485 if (iovecs.len == 0) return;485 if (iovecs.len == 0) return 0;
486486
487 var i: usize = 0;487 var i: usize = 0;
488 var off: usize = 0;488 var off: usize = 0;
...@@ -524,8 +524,8 @@ pub const File = struct {...@@ -524,8 +524,8 @@ pub const File = struct {
524 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in524 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
525 /// order to handle partial reads from the underlying OS layer.525 /// order to handle partial reads from the underlying OS layer.
526 /// See https://github.com/ziglang/zig/issues/7699526 /// See https://github.com/ziglang/zig/issues/7699
527 pub fn preadvAll(self: File, iovecs: []const os.iovec, offset: u64) PReadError!void {527 pub fn preadvAll(self: File, iovecs: []os.iovec, offset: u64) PReadError!usize {
528 if (iovecs.len == 0) return;528 if (iovecs.len == 0) return 0;
529529
530 var i: usize = 0;530 var i: usize = 0;
531 var off: usize = 0;531 var off: usize = 0;
lib/std/fs/test.zig+83
...@@ -520,6 +520,89 @@ test "makePath, put some files in it, deleteTree" {...@@ -520,6 +520,89 @@ test "makePath, put some files in it, deleteTree" {
520 }520 }
521}521}
522522
523test "writev, readv" {
524 var tmp = tmpDir(.{});
525 defer tmp.cleanup();
526
527 const line1 = "line1\n";
528 const line2 = "line2\n";
529
530 var buf1: [line1.len]u8 = undefined;
531 var buf2: [line2.len]u8 = undefined;
532 var write_vecs = [_]std.os.iovec_const{
533 .{
534 .iov_base = line1,
535 .iov_len = line1.len,
536 },
537 .{
538 .iov_base = line2,
539 .iov_len = line2.len,
540 },
541 };
542 var read_vecs = [_]std.os.iovec{
543 .{
544 .iov_base = &buf2,
545 .iov_len = buf2.len,
546 },
547 .{
548 .iov_base = &buf1,
549 .iov_len = buf1.len,
550 },
551 };
552
553 var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
554 defer src_file.close();
555
556 try src_file.writevAll(&write_vecs);
557 try testing.expectEqual(@as(u64, line1.len + line2.len), try src_file.getEndPos());
558 try src_file.seekTo(0);
559 const read = try src_file.readvAll(&read_vecs);
560 try testing.expectEqual(@as(usize, line1.len + line2.len), read);
561 try testing.expectEqualStrings(&buf1, "line2\n");
562 try testing.expectEqualStrings(&buf2, "line1\n");
563}
564
565test "pwritev, preadv" {
566 var tmp = tmpDir(.{});
567 defer tmp.cleanup();
568
569 const line1 = "line1\n";
570 const line2 = "line2\n";
571
572 var buf1: [line1.len]u8 = undefined;
573 var buf2: [line2.len]u8 = undefined;
574 var write_vecs = [_]std.os.iovec_const{
575 .{
576 .iov_base = line1,
577 .iov_len = line1.len,
578 },
579 .{
580 .iov_base = line2,
581 .iov_len = line2.len,
582 },
583 };
584 var read_vecs = [_]std.os.iovec{
585 .{
586 .iov_base = &buf2,
587 .iov_len = buf2.len,
588 },
589 .{
590 .iov_base = &buf1,
591 .iov_len = buf1.len,
592 },
593 };
594
595 var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
596 defer src_file.close();
597
598 try src_file.pwritevAll(&write_vecs, 16);
599 try testing.expectEqual(@as(u64, 16 + line1.len + line2.len), try src_file.getEndPos());
600 const read = try src_file.preadvAll(&read_vecs, 16);
601 try testing.expectEqual(@as(usize, line1.len + line2.len), read);
602 try testing.expectEqualStrings(&buf1, "line2\n");
603 try testing.expectEqualStrings(&buf2, "line1\n");
604}
605
523test "access file" {606test "access file" {
524 if (builtin.os.tag == .wasi) return error.SkipZigTest;607 if (builtin.os.tag == .wasi) return error.SkipZigTest;
525608
lib/std/os.zig+112-27
...@@ -497,8 +497,14 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {...@@ -497,8 +497,14 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
497 };497 };
498 const adjusted_len = math.min(max_count, buf.len);498 const adjusted_len = math.min(max_count, buf.len);
499499
500 const pread_sym = if (builtin.os.tag == .linux and builtin.link_libc)
501 system.pread64
502 else
503 system.pread;
504
505 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
500 while (true) {506 while (true) {
501 const rc = system.pread(fd, buf.ptr, adjusted_len, offset);507 const rc = pread_sym(fd, buf.ptr, adjusted_len, ioffset);
502 switch (errno(rc)) {508 switch (errno(rc)) {
503 0 => return @intCast(usize, rc),509 0 => return @intCast(usize, rc),
504 EINTR => continue,510 EINTR => continue,
...@@ -567,15 +573,13 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {...@@ -567,15 +573,13 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
567 }573 }
568574
569 while (true) {575 while (true) {
570 const rc = if (builtin.link_libc)576 const ftruncate_sym = if (builtin.os.tag == .linux and builtin.link_libc)
571 if (std.Target.current.os.tag == .linux)577 system.ftruncate64
572 system.ftruncate64(fd, @bitCast(off_t, length))
573 else
574 system.ftruncate(fd, @bitCast(off_t, length))
575 else578 else
576 system.ftruncate(fd, length);579 system.ftruncate;
577580
578 switch (errno(rc)) {581 const ilen = @bitCast(i64, length); // the OS treats this as unsigned
582 switch (errno(ftruncate_sym(fd, ilen))) {
579 0 => return,583 0 => return,
580 EINTR => continue,584 EINTR => continue,
581 EFBIG => return error.FileTooBig,585 EFBIG => return error.FileTooBig,
...@@ -637,8 +641,14 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {...@@ -637,8 +641,14 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
637641
638 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);642 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);
639643
644 const preadv_sym = if (builtin.os.tag == .linux and builtin.link_libc)
645 system.preadv64
646 else
647 system.preadv;
648
649 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
640 while (true) {650 while (true) {
641 const rc = system.preadv(fd, iov.ptr, iov_count, offset);651 const rc = preadv_sym(fd, iov.ptr, iov_count, ioffset);
642 switch (errno(rc)) {652 switch (errno(rc)) {
643 0 => return @bitCast(usize, rc),653 0 => return @bitCast(usize, rc),
644 EINTR => continue,654 EINTR => continue,
...@@ -895,8 +905,14 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {...@@ -895,8 +905,14 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
895 };905 };
896 const adjusted_len = math.min(max_count, bytes.len);906 const adjusted_len = math.min(max_count, bytes.len);
897907
908 const pwrite_sym = if (builtin.os.tag == .linux and builtin.link_libc)
909 system.pwrite64
910 else
911 system.pwrite;
912
913 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
898 while (true) {914 while (true) {
899 const rc = system.pwrite(fd, bytes.ptr, adjusted_len, offset);915 const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, ioffset);
900 switch (errno(rc)) {916 switch (errno(rc)) {
901 0 => return @intCast(usize, rc),917 0 => return @intCast(usize, rc),
902 EINTR => continue,918 EINTR => continue,
...@@ -977,9 +993,15 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz...@@ -977,9 +993,15 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
977 }993 }
978 }994 }
979995
996 const pwritev_sym = if (builtin.os.tag == .linux and builtin.link_libc)
997 system.pwritev64
998 else
999 system.pwritev;
1000
980 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);1001 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);
1002 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
981 while (true) {1003 while (true) {
982 const rc = system.pwritev(fd, iov.ptr, iov_count, offset);1004 const rc = pwritev_sym(fd, iov.ptr, iov_count, ioffset);
983 switch (errno(rc)) {1005 switch (errno(rc)) {
984 0 => return @intCast(usize, rc),1006 0 => return @intCast(usize, rc),
985 EINTR => continue,1007 EINTR => continue,
...@@ -1068,8 +1090,14 @@ pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t...@@ -1068,8 +1090,14 @@ pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: mode_t) OpenError!fd_t
1068 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1090 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1069 return openW(file_path_w.span(), flags, perm);1091 return openW(file_path_w.span(), flags, perm);
1070 }1092 }
1093
1094 const open_sym = if (builtin.os.tag == .linux and builtin.link_libc)
1095 system.open64
1096 else
1097 system.open;
1098
1071 while (true) {1099 while (true) {
1072 const rc = system.open(file_path, flags, perm);1100 const rc = open_sym(file_path, flags, perm);
1073 switch (errno(rc)) {1101 switch (errno(rc)) {
1074 0 => return @intCast(fd_t, rc),1102 0 => return @intCast(fd_t, rc),
1075 EINTR => continue,1103 EINTR => continue,
...@@ -1202,8 +1230,14 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: mode_t)...@@ -1202,8 +1230,14 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: mode_t)
1202 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1230 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1203 return openatW(dir_fd, file_path_w.span(), flags, mode);1231 return openatW(dir_fd, file_path_w.span(), flags, mode);
1204 }1232 }
1233
1234 const openat_sym = if (builtin.os.tag == .linux and builtin.link_libc)
1235 system.openat64
1236 else
1237 system.openat;
1238
1205 while (true) {1239 while (true) {
1206 const rc = system.openat(dir_fd, file_path, flags, mode);1240 const rc = openat_sym(dir_fd, file_path, flags, mode);
1207 switch (errno(rc)) {1241 switch (errno(rc)) {
1208 0 => return @intCast(fd_t, rc),1242 0 => return @intCast(fd_t, rc),
1209 EINTR => continue,1243 EINTR => continue,
...@@ -3437,8 +3471,13 @@ pub fn fstat(fd: fd_t) FStatError!Stat {...@@ -3437,8 +3471,13 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
3437 @compileError("fstat is not yet implemented on Windows");3471 @compileError("fstat is not yet implemented on Windows");
3438 }3472 }
34393473
3474 const fstat_sym = if (builtin.os.tag == .linux and builtin.link_libc)
3475 system.fstat64
3476 else
3477 system.fstat;
3478
3440 var stat = mem.zeroes(Stat);3479 var stat = mem.zeroes(Stat);
3441 switch (errno(system.fstat(fd, &stat))) {3480 switch (errno(fstat_sym(fd, &stat))) {
3442 0 => return stat,3481 0 => return stat,
3443 EINVAL => unreachable,3482 EINVAL => unreachable,
3444 EBADF => unreachable, // Always a race condition.3483 EBADF => unreachable, // Always a race condition.
...@@ -3488,8 +3527,13 @@ pub fn fstatatWasi(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!S...@@ -3488,8 +3527,13 @@ pub fn fstatatWasi(dirfd: fd_t, pathname: []const u8, flags: u32) FStatAtError!S
3488/// Same as `fstatat` but `pathname` is null-terminated.3527/// Same as `fstatat` but `pathname` is null-terminated.
3489/// See also `fstatat`.3528/// See also `fstatat`.
3490pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {3529pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!Stat {
3530 const fstatat_sym = if (builtin.os.tag == .linux and builtin.link_libc)
3531 system.fstatat64
3532 else
3533 system.fstatat;
3534
3491 var stat = mem.zeroes(Stat);3535 var stat = mem.zeroes(Stat);
3492 switch (errno(system.fstatat(dirfd, pathname, &stat, flags))) {3536 switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {
3493 0 => return stat,3537 0 => return stat,
3494 EINVAL => unreachable,3538 EINVAL => unreachable,
3495 EBADF => unreachable, // Always a race condition.3539 EBADF => unreachable, // Always a race condition.
...@@ -3701,12 +3745,17 @@ pub fn mmap(...@@ -3701,12 +3745,17 @@ pub fn mmap(
3701 fd: fd_t,3745 fd: fd_t,
3702 offset: u64,3746 offset: u64,
3703) MMapError![]align(mem.page_size) u8 {3747) MMapError![]align(mem.page_size) u8 {
3748 const mmap_sym = if (builtin.os.tag == .linux and builtin.link_libc)
3749 system.mmap64
3750 else
3751 system.mmap;
3752
3753 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
3754 const rc = mmap_sym(ptr, length, prot, flags, fd, ioffset);
3704 const err = if (builtin.link_libc) blk: {3755 const err = if (builtin.link_libc) blk: {
3705 const rc = std.c.mmap(ptr, length, prot, flags, fd, offset);
3706 if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];3756 if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];
3707 break :blk system._errno().*;3757 break :blk system._errno().*;
3708 } else blk: {3758 } else blk: {
3709 const rc = system.mmap(ptr, length, prot, flags, fd, offset);
3710 const err = errno(rc);3759 const err = errno(rc);
3711 if (err == 0) return @intToPtr([*]align(mem.page_size) u8, rc)[0..length];3760 if (err == 0) return @intToPtr([*]align(mem.page_size) u8, rc)[0..length];
3712 break :blk err;3761 break :blk err;
...@@ -4056,8 +4105,14 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -4056,8 +4105,14 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
4056 else => |err| return unexpectedErrno(err),4105 else => |err| return unexpectedErrno(err),
4057 }4106 }
4058 }4107 }
4059 const ipos = @bitCast(i64, offset); // the OS treats this as unsigned4108
4060 switch (errno(system.lseek(fd, ipos, SEEK_SET))) {4109 const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
4110 system.lseek64
4111 else
4112 system.lseek;
4113
4114 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4115 switch (errno(lseek_sym(fd, ioffset, SEEK_SET))) {
4061 0 => return,4116 0 => return,
4062 EBADF => unreachable, // always a race condition4117 EBADF => unreachable, // always a race condition
4063 EINVAL => return error.Unseekable,4118 EINVAL => return error.Unseekable,
...@@ -4098,7 +4153,13 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -4098,7 +4153,13 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
4098 else => |err| return unexpectedErrno(err),4153 else => |err| return unexpectedErrno(err),
4099 }4154 }
4100 }4155 }
4101 switch (errno(system.lseek(fd, offset, SEEK_CUR))) {4156 const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
4157 system.lseek64
4158 else
4159 system.lseek;
4160
4161 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4162 switch (errno(lseek_sym(fd, ioffset, SEEK_CUR))) {
4102 0 => return,4163 0 => return,
4103 EBADF => unreachable, // always a race condition4164 EBADF => unreachable, // always a race condition
4104 EINVAL => return error.Unseekable,4165 EINVAL => return error.Unseekable,
...@@ -4139,7 +4200,13 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -4139,7 +4200,13 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
4139 else => |err| return unexpectedErrno(err),4200 else => |err| return unexpectedErrno(err),
4140 }4201 }
4141 }4202 }
4142 switch (errno(system.lseek(fd, offset, SEEK_END))) {4203 const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
4204 system.lseek64
4205 else
4206 system.lseek;
4207
4208 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4209 switch (errno(lseek_sym(fd, ioffset, SEEK_END))) {
4143 0 => return,4210 0 => return,
4144 EBADF => unreachable, // always a race condition4211 EBADF => unreachable, // always a race condition
4145 EINVAL => return error.Unseekable,4212 EINVAL => return error.Unseekable,
...@@ -4180,7 +4247,12 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {...@@ -4180,7 +4247,12 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
4180 else => |err| return unexpectedErrno(err),4247 else => |err| return unexpectedErrno(err),
4181 }4248 }
4182 }4249 }
4183 const rc = system.lseek(fd, 0, SEEK_CUR);4250 const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
4251 system.lseek64
4252 else
4253 system.lseek;
4254
4255 const rc = lseek_sym(fd, 0, SEEK_CUR);
4184 switch (errno(rc)) {4256 switch (errno(rc)) {
4185 0 => return @bitCast(u64, rc),4257 0 => return @bitCast(u64, rc),
4186 EBADF => unreachable, // always a race condition4258 EBADF => unreachable, // always a race condition
...@@ -5198,9 +5270,14 @@ pub fn sendfile(...@@ -5198,9 +5270,14 @@ pub fn sendfile(
5198 // Here we match BSD behavior, making a zero count value send as many bytes as possible.5270 // Here we match BSD behavior, making a zero count value send as many bytes as possible.
5199 const adjusted_count = if (in_len == 0) max_count else math.min(in_len, @as(size_t, max_count));5271 const adjusted_count = if (in_len == 0) max_count else math.min(in_len, @as(size_t, max_count));
52005272
5273 const sendfile_sym = if (builtin.link_libc)
5274 system.sendfile64
5275 else
5276 system.sendfile;
5277
5201 while (true) {5278 while (true) {
5202 var offset: off_t = @bitCast(off_t, in_offset);5279 var offset: off_t = @bitCast(off_t, in_offset);
5203 const rc = system.sendfile(out_fd, in_fd, &offset, adjusted_count);5280 const rc = sendfile_sym(out_fd, in_fd, &offset, adjusted_count);
5204 switch (errno(rc)) {5281 switch (errno(rc)) {
5205 0 => {5282 0 => {
5206 const amt = @bitCast(usize, rc);5283 const amt = @bitCast(usize, rc);
...@@ -6018,9 +6095,13 @@ pub fn prctl(option: PR, args: anytype) PrctlError!u31 {...@@ -6018,9 +6095,13 @@ pub fn prctl(option: PR, args: anytype) PrctlError!u31 {
6018pub const GetrlimitError = UnexpectedError;6095pub const GetrlimitError = UnexpectedError;
60196096
6020pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {6097pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
6098 const getrlimit_sym = if (builtin.os.tag == .linux and builtin.link_libc)
6099 system.getrlimit64
6100 else
6101 system.getrlimit;
6102
6021 var limits: rlimit = undefined;6103 var limits: rlimit = undefined;
6022 const rc = system.getrlimit(resource, &limits);6104 switch (errno(getrlimit_sym(resource, &limits))) {
6023 switch (errno(rc)) {
6024 0 => return limits,6105 0 => return limits,
6025 EFAULT => unreachable, // bogus pointer6106 EFAULT => unreachable, // bogus pointer
6026 EINVAL => unreachable,6107 EINVAL => unreachable,
...@@ -6031,8 +6112,12 @@ pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {...@@ -6031,8 +6112,12 @@ pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit {
6031pub const SetrlimitError = error{PermissionDenied} || UnexpectedError;6112pub const SetrlimitError = error{PermissionDenied} || UnexpectedError;
60326113
6033pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void {6114pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void {
6034 const rc = system.setrlimit(resource, &limits);6115 const setrlimit_sym = if (builtin.os.tag == .linux and builtin.link_libc)
6035 switch (errno(rc)) {6116 system.setrlimit64
6117 else
6118 system.setrlimit;
6119
6120 switch (errno(setrlimit_sym(resource, &limits))) {
6036 0 => return,6121 0 => return,
6037 EFAULT => unreachable, // bogus pointer6122 EFAULT => unreachable, // bogus pointer
6038 EINVAL => unreachable,6123 EINVAL => unreachable,
lib/std/os/linux.zig+39-24
...@@ -59,15 +59,30 @@ const require_aligned_register_pair =...@@ -59,15 +59,30 @@ const require_aligned_register_pair =
59 std.Target.current.cpu.arch.isThumb();59 std.Target.current.cpu.arch.isThumb();
6060
61// Split a 64bit value into a {LSB,MSB} pair.61// Split a 64bit value into a {LSB,MSB} pair.
62fn splitValue64(val: u64) [2]u32 {62// The LE/BE variants specify the endianness to assume.
63fn splitValueLE64(val: i64) [2]u32 {
64 const u = @bitCast(u64, val);
65 return [2]u32{
66 @truncate(u32, u),
67 @truncate(u32, u >> 32),
68 };
69}
70fn splitValueBE64(val: i64) [2]u32 {
71 return [2]u32{
72 @truncate(u32, u >> 32),
73 @truncate(u32, u),
74 };
75}
76fn splitValue64(val: i64) [2]u32 {
77 const u = @bitCast(u64, val);
63 switch (builtin.endian) {78 switch (builtin.endian) {
64 .Little => return [2]u32{79 .Little => return [2]u32{
65 @truncate(u32, val),80 @truncate(u32, u),
66 @truncate(u32, val >> 32),81 @truncate(u32, u >> 32),
67 },82 },
68 .Big => return [2]u32{83 .Big => return [2]u32{
69 @truncate(u32, val >> 32),84 @truncate(u32, u >> 32),
70 @truncate(u32, val),85 @truncate(u32, u),
71 },86 },
72 }87 }
73}88}
...@@ -141,8 +156,8 @@ pub fn utimensat(dirfd: i32, path: ?[*:0]const u8, times: *const [2]timespec, fl...@@ -141,8 +156,8 @@ pub fn utimensat(dirfd: i32, path: ?[*:0]const u8, times: *const [2]timespec, fl
141 return syscall4(.utimensat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(times), flags);156 return syscall4(.utimensat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(times), flags);
142}157}
143158
144pub fn fallocate(fd: i32, mode: i32, offset: u64, length: u64) usize {159pub fn fallocate(fd: i32, mode: i32, offset: i64, length: i64) usize {
145 if (@sizeOf(usize) == 4) {160 if (usize_bits < 64) {
146 const offset_halves = splitValue64(offset);161 const offset_halves = splitValue64(offset);
147 const length_halves = splitValue64(length);162 const length_halves = splitValue64(length);
148 return syscall6(163 return syscall6(
...@@ -159,8 +174,8 @@ pub fn fallocate(fd: i32, mode: i32, offset: u64, length: u64) usize {...@@ -159,8 +174,8 @@ pub fn fallocate(fd: i32, mode: i32, offset: u64, length: u64) usize {
159 .fallocate,174 .fallocate,
160 @bitCast(usize, @as(isize, fd)),175 @bitCast(usize, @as(isize, fd)),
161 @bitCast(usize, @as(isize, mode)),176 @bitCast(usize, @as(isize, mode)),
162 offset,177 @bitCast(u64, offset),
163 length,178 @bitCast(u64, length),
164 );179 );
165 }180 }
166}181}
...@@ -243,7 +258,7 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {...@@ -243,7 +258,7 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {
243 return syscall2(.umount2, @ptrToInt(special), flags);258 return syscall2(.umount2, @ptrToInt(special), flags);
244}259}
245260
246pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: u64) usize {261pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: i64) usize {
247 if (@hasField(SYS, "mmap2")) {262 if (@hasField(SYS, "mmap2")) {
248 // Make sure the offset is also specified in multiples of page size263 // Make sure the offset is also specified in multiples of page size
249 if ((offset & (MMAP2_UNIT - 1)) != 0)264 if ((offset & (MMAP2_UNIT - 1)) != 0)
...@@ -256,7 +271,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -256,7 +271,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
256 prot,271 prot,
257 flags,272 flags,
258 @bitCast(usize, @as(isize, fd)),273 @bitCast(usize, @as(isize, fd)),
259 @truncate(usize, offset / MMAP2_UNIT),274 @truncate(usize, @bitCast(u64, offset) / MMAP2_UNIT),
260 );275 );
261 } else {276 } else {
262 return syscall6(277 return syscall6(
...@@ -266,7 +281,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -266,7 +281,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
266 prot,281 prot,
267 flags,282 flags,
268 @bitCast(usize, @as(isize, fd)),283 @bitCast(usize, @as(isize, fd)),
269 offset,284 @bitCast(u64, offset),
270 );285 );
271 }286 }
272}287}
...@@ -308,8 +323,8 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {...@@ -308,8 +323,8 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
308 return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);323 return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
309}324}
310325
311pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {326pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {
312 const offset_halves = splitValue64(offset);327 const offset_halves = splitValueLE64(offset);
313 return syscall5(328 return syscall5(
314 .preadv,329 .preadv,
315 @bitCast(usize, @as(isize, fd)),330 @bitCast(usize, @as(isize, fd)),
...@@ -320,7 +335,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {...@@ -320,7 +335,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
320 );335 );
321}336}
322337
323pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {338pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {
324 const offset_halves = splitValue64(offset);339 const offset_halves = splitValue64(offset);
325 return syscall6(340 return syscall6(
326 .preadv2,341 .preadv2,
...@@ -341,8 +356,8 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {...@@ -341,8 +356,8 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
341 return syscall3(.writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);356 return syscall3(.writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
342}357}
343358
344pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {359pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {
345 const offset_halves = splitValue64(offset);360 const offset_halves = splitValueLE64(offset);
346 return syscall5(361 return syscall5(
347 .pwritev,362 .pwritev,
348 @bitCast(usize, @as(isize, fd)),363 @bitCast(usize, @as(isize, fd)),
...@@ -353,7 +368,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us...@@ -353,7 +368,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us
353 );368 );
354}369}
355370
356pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {371pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {
357 const offset_halves = splitValue64(offset);372 const offset_halves = splitValue64(offset);
358 return syscall6(373 return syscall6(
359 .pwritev2,374 .pwritev2,
...@@ -386,7 +401,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us...@@ -386,7 +401,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us
386 return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));401 return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));
387}402}
388403
389pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {404pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: i64) usize {
390 if (@hasField(SYS, "pread64") and usize_bits < 64) {405 if (@hasField(SYS, "pread64") and usize_bits < 64) {
391 const offset_halves = splitValue64(offset);406 const offset_halves = splitValue64(offset);
392 if (require_aligned_register_pair) {407 if (require_aligned_register_pair) {
...@@ -417,7 +432,7 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {...@@ -417,7 +432,7 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
417 @bitCast(usize, @as(isize, fd)),432 @bitCast(usize, @as(isize, fd)),
418 @ptrToInt(buf),433 @ptrToInt(buf),
419 count,434 count,
420 offset,435 @bitCast(u64, offset),
421 );436 );
422 }437 }
423}438}
...@@ -452,7 +467,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {...@@ -452,7 +467,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
452 return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);467 return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
453}468}
454469
455pub fn ftruncate(fd: i32, length: u64) usize {470pub fn ftruncate(fd: i32, length: i64) usize {
456 if (@hasField(SYS, "ftruncate64") and usize_bits < 64) {471 if (@hasField(SYS, "ftruncate64") and usize_bits < 64) {
457 const length_halves = splitValue64(length);472 const length_halves = splitValue64(length);
458 if (require_aligned_register_pair) {473 if (require_aligned_register_pair) {
...@@ -475,12 +490,12 @@ pub fn ftruncate(fd: i32, length: u64) usize {...@@ -475,12 +490,12 @@ pub fn ftruncate(fd: i32, length: u64) usize {
475 return syscall2(490 return syscall2(
476 .ftruncate,491 .ftruncate,
477 @bitCast(usize, @as(isize, fd)),492 @bitCast(usize, @as(isize, fd)),
478 @truncate(usize, length),493 @bitCast(usize, length),
479 );494 );
480 }495 }
481}496}
482497
483pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {498pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: i64) usize {
484 if (@hasField(SYS, "pwrite64") and usize_bits < 64) {499 if (@hasField(SYS, "pwrite64") and usize_bits < 64) {
485 const offset_halves = splitValue64(offset);500 const offset_halves = splitValue64(offset);
486501
...@@ -512,7 +527,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {...@@ -512,7 +527,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
512 @bitCast(usize, @as(isize, fd)),527 @bitCast(usize, @as(isize, fd)),
513 @ptrToInt(buf),528 @ptrToInt(buf),
514 count,529 count,
515 offset,530 @bitCast(u64, offset),
516 );531 );
517 }532 }
518}533}
lib/std/os/linux/test.zig+1-1
...@@ -20,7 +20,7 @@ test "fallocate" {...@@ -20,7 +20,7 @@ test "fallocate" {
2020
21 try expect((try file.stat()).size == 0);21 try expect((try file.stat()).size == 0);
2222
23 const len: u64 = 65536;23 const len: i64 = 65536;
24 switch (linux.getErrno(linux.fallocate(file.handle, 0, 0, len))) {24 switch (linux.getErrno(linux.fallocate(file.handle, 0, 0, len))) {
25 0 => {},25 0 => {},
26 linux.ENOSYS => return error.SkipZigTest,26 linux.ENOSYS => return error.SkipZigTest,
lib/std/special/c.zig+2-2
...@@ -225,7 +225,7 @@ export fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8...@@ -225,7 +225,7 @@ export fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) callconv(.C) ?[*]u8
225 return dest;225 return dest;
226}226}
227227
228export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) isize {228export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) c_int {
229 @setRuntimeSafety(false);229 @setRuntimeSafety(false);
230230
231 var index: usize = 0;231 var index: usize = 0;
...@@ -250,7 +250,7 @@ test "memcmp" {...@@ -250,7 +250,7 @@ test "memcmp" {
250 try std.testing.expect(memcmp(base_arr[0..], arr3[0..], base_arr.len) < 0);250 try std.testing.expect(memcmp(base_arr[0..], arr3[0..], base_arr.len) < 0);
251}251}
252252
253export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.C) isize {253export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) callconv(.C) c_int {
254 @setRuntimeSafety(false);254 @setRuntimeSafety(false);
255255
256 var index: usize = 0;256 var index: usize = 0;
src/glibc.zig+2-1
...@@ -40,10 +40,11 @@ pub const ABI = struct {...@@ -40,10 +40,11 @@ pub const ABI = struct {
40 }40 }
41};41};
4242
43// The order of the elements in this array defines the linking order.
43pub const libs = [_]Lib{44pub const libs = [_]Lib{
44 .{ .name = "c", .sover = 6 },
45 .{ .name = "m", .sover = 6 },45 .{ .name = "m", .sover = 6 },
46 .{ .name = "pthread", .sover = 0 },46 .{ .name = "pthread", .sover = 0 },
47 .{ .name = "c", .sover = 6 },
47 .{ .name = "dl", .sover = 2 },48 .{ .name = "dl", .sover = 2 },
48 .{ .name = "rt", .sover = 1 },49 .{ .name = "rt", .sover = 1 },
49 .{ .name = "ld", .sover = 2 },50 .{ .name = "ld", .sover = 2 },
src/link/Elf.zig+5-10
...@@ -1648,17 +1648,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1648,17 +1648,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1648 // libc dep1648 // libc dep
1649 if (self.base.options.link_libc) {1649 if (self.base.options.link_libc) {
1650 if (self.base.options.libc_installation != null) {1650 if (self.base.options.libc_installation != null) {
1651 if (self.base.options.link_mode == .Static) {1651 const needs_grouping = self.base.options.link_mode == .Static;
1652 try argv.append("--start-group");1652 if (needs_grouping) try argv.append("--start-group");
1653 try argv.append("-lc");1653 try argv.append("-lm");
1654 try argv.append("-lm");
1655 try argv.append("--end-group");
1656 } else {
1657 try argv.append("-lc");
1658 try argv.append("-lm");
1659 }
1660
1661 try argv.append("-lpthread");1654 try argv.append("-lpthread");
1655 try argv.append("-lc");
1656 if (needs_grouping) try argv.append("--end-group");
1662 } else if (target.isGnuLibC()) {1657 } else if (target.isGnuLibC()) {
1663 try argv.append(comp.libunwind_static_lib.?.full_object_path);1658 try argv.append(comp.libunwind_static_lib.?.full_object_path);
1664 for (glibc.libs) |lib| {1659 for (glibc.libs) |lib| {
test/tests.zig+8-9
...@@ -98,15 +98,14 @@ const test_targets = blk: {...@@ -98,15 +98,14 @@ const test_targets = blk: {
98 },98 },
99 .link_libc = true,99 .link_libc = true,
100 },100 },
101 // https://github.com/ziglang/zig/issues/4926101 TestTarget{
102 //TestTarget{102 .target = .{
103 // .target = .{103 .cpu_arch = .i386,
104 // .cpu_arch = .i386,104 .os_tag = .linux,
105 // .os_tag = .linux,105 .abi = .gnu,
106 // .abi = .gnu,106 },
107 // },107 .link_libc = true,
108 // .link_libc = true,108 },
109 //},
110109
111 TestTarget{110 TestTarget{
112 .target = .{111 .target = .{