| author | |
| committer | |
| log | ec25b138481e16f2d73d12ed6ffacd8e7ba65e94 |
| tree | 6bced54da3c8843b2906b960923d7593b5e6b2ac |
| parent | 5e242f05510330896db202974570324cf2606c22 |
| parent | 4d6d2922b814d9f6885cfeec7603e73e9a852417 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/3075824 files changed, 312 insertions(+), 272 deletions(-)
build.zig+1-4| ... | @@ -519,10 +519,7 @@ pub fn build(b: *std.Build) !void { | ... | @@ -519,10 +519,7 @@ pub fn build(b: *std.Build) !void { |
| 519 | .skip_libc = true, | 519 | .skip_libc = true, |
| 520 | .no_builtin = true, | 520 | .no_builtin = true, |
| 521 | .max_rss = switch (b.graph.host.result.os.tag) { | 521 | .max_rss = switch (b.graph.host.result.os.tag) { |
| 522 | .freebsd => switch (b.graph.host.result.cpu.arch) { | 522 | .freebsd => 800_000_000, |
| 523 | .x86_64 => 743_802_470, | ||
| 524 | else => 800_000_000, | ||
| 525 | }, | ||
| 526 | .linux => switch (b.graph.host.result.cpu.arch) { | 523 | .linux => switch (b.graph.host.result.cpu.arch) { |
| 527 | .aarch64 => 639_565_414, | 524 | .aarch64 => 639_565_414, |
| 528 | .loongarch64 => 598_884_352, | 525 | .loongarch64 => 598_884_352, |
lib/fuzzer.zig+1-1| ... | @@ -1320,7 +1320,7 @@ pub const MemoryMappedList = struct { | ... | @@ -1320,7 +1320,7 @@ pub const MemoryMappedList = struct { |
| 1320 | const ptr = try std.posix.mmap( | 1320 | const ptr = try std.posix.mmap( |
| 1321 | null, | 1321 | null, |
| 1322 | capacity, | 1322 | capacity, |
| 1323 | std.posix.PROT.READ | std.posix.PROT.WRITE, | 1323 | .{ .READ = true, .WRITE = true }, |
| 1324 | .{ .TYPE = .SHARED }, | 1324 | .{ .TYPE = .SHARED }, |
| 1325 | file.handle, | 1325 | file.handle, |
| 1326 | 0, | 1326 | 0, |
lib/std/Build/Fuzz.zig+1-1| ... | @@ -422,7 +422,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO | ... | @@ -422,7 +422,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO |
| 422 | const mapped_memory = std.posix.mmap( | 422 | const mapped_memory = std.posix.mmap( |
| 423 | null, | 423 | null, |
| 424 | file_size, | 424 | file_size, |
| 425 | std.posix.PROT.READ, | 425 | .{ .READ = true }, |
| 426 | .{ .TYPE = .SHARED }, | 426 | .{ .TYPE = .SHARED }, |
| 427 | coverage_file.handle, | 427 | coverage_file.handle, |
| 428 | 0, | 428 | 0, |
lib/std/Thread.zig+9-9| ... | @@ -1535,7 +1535,7 @@ const LinuxThreadImpl = struct { | ... | @@ -1535,7 +1535,7 @@ const LinuxThreadImpl = struct { |
| 1535 | const mapped = posix.mmap( | 1535 | const mapped = posix.mmap( |
| 1536 | null, | 1536 | null, |
| 1537 | map_bytes, | 1537 | map_bytes, |
| 1538 | posix.PROT.NONE, | 1538 | .{}, |
| 1539 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, | 1539 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, |
| 1540 | -1, | 1540 | -1, |
| 1541 | 0, | 1541 | 0, |
| ... | @@ -1551,14 +1551,14 @@ const LinuxThreadImpl = struct { | ... | @@ -1551,14 +1551,14 @@ const LinuxThreadImpl = struct { |
| 1551 | assert(mapped.len >= map_bytes); | 1551 | assert(mapped.len >= map_bytes); |
| 1552 | errdefer posix.munmap(mapped); | 1552 | errdefer posix.munmap(mapped); |
| 1553 | 1553 | ||
| 1554 | // map everything but the guard page as read/write | 1554 | // Map everything but the guard page as read/write. |
| 1555 | posix.mprotect( | 1555 | const guarded: []align(std.heap.page_size_min) u8 = @alignCast(mapped[guard_offset..]); |
| 1556 | @alignCast(mapped[guard_offset..]), | 1556 | const protection: posix.PROT = .{ .READ = true, .WRITE = true }; |
| 1557 | posix.PROT.READ | posix.PROT.WRITE, | 1557 | switch (posix.errno(posix.system.mprotect(guarded.ptr, guarded.len, protection))) { |
| 1558 | ) catch |err| switch (err) { | 1558 | .SUCCESS => {}, |
| 1559 | error.AccessDenied => unreachable, | 1559 | .NOMEM => return error.OutOfMemory, |
| 1560 | else => |e| return e, | 1560 | else => |err| return posix.unexpectedErrno(err), |
| 1561 | }; | 1561 | } |
| 1562 | 1562 | ||
| 1563 | // Prepare the TLS segment and prepare a user_desc struct when needed on x86 | 1563 | // Prepare the TLS segment and prepare a user_desc struct when needed on x86 |
| 1564 | var tls_ptr = linux.tls.prepareArea(mapped[tls_offset..]); | 1564 | var tls_ptr = linux.tls.prepareArea(mapped[tls_offset..]); |
lib/std/c.zig+14-33| ... | @@ -1672,10 +1672,10 @@ pub const MCL = switch (native_os) { | ... | @@ -1672,10 +1672,10 @@ pub const MCL = switch (native_os) { |
| 1672 | // https://github.com/NetBSD/src/blob/fd2741deca927c18e3ba15acdf78b8b14b2abe36/sys/sys/mman.h#L179 | 1672 | // https://github.com/NetBSD/src/blob/fd2741deca927c18e3ba15acdf78b8b14b2abe36/sys/sys/mman.h#L179 |
| 1673 | // https://github.com/openbsd/src/blob/39404228f6d36c0ca4be5f04ab5385568ebd6aa3/sys/sys/mman.h#L129 | 1673 | // https://github.com/openbsd/src/blob/39404228f6d36c0ca4be5f04ab5385568ebd6aa3/sys/sys/mman.h#L129 |
| 1674 | // https://github.com/illumos/illumos-gate/blob/5280477614f83fea20fc938729df6adb3e44340d/usr/src/uts/common/sys/mman.h#L343 | 1674 | // https://github.com/illumos/illumos-gate/blob/5280477614f83fea20fc938729df6adb3e44340d/usr/src/uts/common/sys/mman.h#L343 |
| 1675 | .freebsd, .dragonfly, .netbsd, .openbsd, .illumos => packed struct(c_int) { | 1675 | .freebsd, .dragonfly, .netbsd, .openbsd, .illumos => packed struct(u32) { |
| 1676 | CURRENT: bool = 0, | 1676 | CURRENT: bool = false, |
| 1677 | FUTURE: bool = 0, | 1677 | FUTURE: bool = false, |
| 1678 | _: std.meta.Int(.unsigned, @bitSizeOf(c_int) - 2) = 0, | 1678 | _: u30 = 0, |
| 1679 | }, | 1679 | }, |
| 1680 | else => void, | 1680 | else => void, |
| 1681 | }; | 1681 | }; |
| ... | @@ -1887,32 +1887,13 @@ pub const PROT = switch (native_os) { | ... | @@ -1887,32 +1887,13 @@ pub const PROT = switch (native_os) { |
| 1887 | .linux => linux.PROT, | 1887 | .linux => linux.PROT, |
| 1888 | .emscripten => emscripten.PROT, | 1888 | .emscripten => emscripten.PROT, |
| 1889 | // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L31 | 1889 | // https://github.com/SerenityOS/serenity/blob/6d59d4d3d9e76e39112842ec487840828f1c9bfe/Kernel/API/POSIX/sys/mman.h#L28-L31 |
| 1890 | .openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .windows, .serenity => struct { | 1890 | .openbsd, .haiku, .dragonfly, .netbsd, .illumos, .freebsd, .windows, .serenity => packed struct(u32) { |
| 1891 | /// page can not be accessed | 1891 | READ: bool = false, |
| 1892 | pub const NONE = 0x0; | 1892 | WRITE: bool = false, |
| 1893 | /// page can be read | 1893 | EXEC: bool = false, |
| 1894 | pub const READ = 0x1; | 1894 | _: u29 = 0, |
| 1895 | /// page can be written | ||
| 1896 | pub const WRITE = 0x2; | ||
| 1897 | /// page can be executed | ||
| 1898 | pub const EXEC = 0x4; | ||
| 1899 | }, | ||
| 1900 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => struct { | ||
| 1901 | /// [MC2] no permissions | ||
| 1902 | pub const NONE: vm_prot_t = 0x00; | ||
| 1903 | /// [MC2] pages can be read | ||
| 1904 | pub const READ: vm_prot_t = 0x01; | ||
| 1905 | /// [MC2] pages can be written | ||
| 1906 | pub const WRITE: vm_prot_t = 0x02; | ||
| 1907 | /// [MC2] pages can be executed | ||
| 1908 | pub const EXEC: vm_prot_t = 0x04; | ||
| 1909 | /// When a caller finds that they cannot obtain write permission on a | ||
| 1910 | /// mapped entry, the following flag can be used. The entry will be | ||
| 1911 | /// made "needs copy" effectively copying the object (using COW), | ||
| 1912 | /// and write permission will be added to the maximum protections for | ||
| 1913 | /// the associated entry. | ||
| 1914 | pub const COPY: vm_prot_t = 0x10; | ||
| 1915 | }, | 1895 | }, |
| 1896 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => vm_prot_t, | ||
| 1916 | else => void, | 1897 | else => void, |
| 1917 | }; | 1898 | }; |
| 1918 | 1899 | ||
| ... | @@ -10349,7 +10330,7 @@ pub extern "c" fn getgrgid(gid: gid_t) ?*group; | ... | @@ -10349,7 +10330,7 @@ pub extern "c" fn getgrgid(gid: gid_t) ?*group; |
| 10349 | pub extern "c" fn getgrgid_r(gid: gid_t, grp: *group, buf: [*]u8, buflen: usize, result: *?*group) c_int; | 10330 | pub extern "c" fn getgrgid_r(gid: gid_t, grp: *group, buf: [*]u8, buflen: usize, result: *?*group) c_int; |
| 10350 | pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int; | 10331 | pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int; |
| 10351 | pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64; | 10332 | pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64; |
| 10352 | pub extern "c" fn mmap64(addr: ?*align(page_size) anyopaque, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: i64) *anyopaque; | 10333 | pub extern "c" fn mmap64(addr: ?*align(page_size) anyopaque, len: usize, prot: PROT, flags: c_uint, fd: fd_t, offset: i64) *anyopaque; |
| 10353 | pub extern "c" fn open64(path: [*:0]const u8, oflag: O, ...) c_int; | 10334 | pub extern "c" fn open64(path: [*:0]const u8, oflag: O, ...) c_int; |
| 10354 | pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: O, ...) c_int; | 10335 | pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: O, ...) c_int; |
| 10355 | pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize; | 10336 | pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize; |
| ... | @@ -10478,7 +10459,7 @@ pub const mlock = switch (native_os) { | ... | @@ -10478,7 +10459,7 @@ pub const mlock = switch (native_os) { |
| 10478 | }; | 10459 | }; |
| 10479 | 10460 | ||
| 10480 | pub const mlock2 = switch (native_os) { | 10461 | pub const mlock2 = switch (native_os) { |
| 10481 | linux => private.mlock2, | 10462 | .linux => private.mlock2, |
| 10482 | else => {}, | 10463 | else => {}, |
| 10483 | }; | 10464 | }; |
| 10484 | 10465 | ||
| ... | @@ -10667,10 +10648,10 @@ pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) i | ... | @@ -10667,10 +10648,10 @@ pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) i |
| 10667 | pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize; | 10648 | pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize; |
| 10668 | pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize; | 10649 | pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize; |
| 10669 | pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize; | 10650 | pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize; |
| 10670 | pub extern "c" fn mmap(addr: ?*align(page_size) anyopaque, len: usize, prot: c_uint, flags: MAP, fd: fd_t, offset: off_t) *anyopaque; | 10651 | pub extern "c" fn mmap(addr: ?*align(page_size) anyopaque, len: usize, prot: PROT, flags: MAP, fd: fd_t, offset: off_t) *anyopaque; |
| 10671 | pub extern "c" fn munmap(addr: *align(page_size) const anyopaque, len: usize) c_int; | 10652 | pub extern "c" fn munmap(addr: *align(page_size) const anyopaque, len: usize) c_int; |
| 10672 | pub extern "c" fn mremap(addr: ?*align(page_size) const anyopaque, old_len: usize, new_len: usize, flags: MREMAP, ...) *anyopaque; | 10653 | pub extern "c" fn mremap(addr: ?*align(page_size) const anyopaque, old_len: usize, new_len: usize, flags: MREMAP, ...) *anyopaque; |
| 10673 | pub extern "c" fn mprotect(addr: *align(page_size) anyopaque, len: usize, prot: c_uint) c_int; | 10654 | pub extern "c" fn mprotect(addr: *align(page_size) anyopaque, len: usize, prot: PROT) c_int; |
| 10674 | pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) c_int; | 10655 | pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) c_int; |
| 10675 | pub extern "c" fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: c_uint) c_int; | 10656 | pub extern "c" fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: c_uint) c_int; |
| 10676 | pub extern "c" fn unlink(path: [*:0]const u8) c_int; | 10657 | pub extern "c" fn unlink(path: [*:0]const u8) c_int; |
lib/std/c/darwin.zig+1-1| ... | @@ -808,7 +808,7 @@ pub const task_vm_info = extern struct { | ... | @@ -808,7 +808,7 @@ pub const task_vm_info = extern struct { |
| 808 | 808 | ||
| 809 | pub const task_vm_info_data_t = task_vm_info; | 809 | pub const task_vm_info_data_t = task_vm_info; |
| 810 | 810 | ||
| 811 | pub const vm_prot_t = c_int; | 811 | pub const vm_prot_t = std.macho.vm_prot_t; |
| 812 | pub const boolean_t = c_int; | 812 | pub const boolean_t = c_int; |
| 813 | 813 | ||
| 814 | pub extern "c" fn mach_vm_protect( | 814 | pub extern "c" fn mach_vm_protect( |
lib/std/debug/ElfFile.zig+1-1| ... | @@ -442,7 +442,7 @@ fn loadInner( | ... | @@ -442,7 +442,7 @@ fn loadInner( |
| 442 | break :mapped std.posix.mmap( | 442 | break :mapped std.posix.mmap( |
| 443 | null, | 443 | null, |
| 444 | file_len, | 444 | file_len, |
| 445 | std.posix.PROT.READ, | 445 | .{ .READ = true }, |
| 446 | .{ .TYPE = .SHARED }, | 446 | .{ .TYPE = .SHARED }, |
| 447 | elf_file.handle, | 447 | elf_file.handle, |
| 448 | 0, | 448 | 0, |
lib/std/debug/MachOFile.zig+1-1| ... | @@ -526,7 +526,7 @@ fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) c | ... | @@ -526,7 +526,7 @@ fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) c |
| 526 | return posix.mmap( | 526 | return posix.mmap( |
| 527 | null, | 527 | null, |
| 528 | file_len, | 528 | file_len, |
| 529 | posix.PROT.READ, | 529 | .{ .READ = true }, |
| 530 | .{ .TYPE = .SHARED }, | 530 | .{ .TYPE = .SHARED }, |
| 531 | file.handle, | 531 | file.handle, |
| 532 | 0, | 532 | 0, |
lib/std/debug/SelfInfo/MachO.zig+1-1| ... | @@ -631,7 +631,7 @@ fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) c | ... | @@ -631,7 +631,7 @@ fn mapDebugInfoFile(io: Io, path: []const u8) ![]align(std.heap.page_size_min) c |
| 631 | return posix.mmap( | 631 | return posix.mmap( |
| 632 | null, | 632 | null, |
| 633 | file_len, | 633 | file_len, |
| 634 | posix.PROT.READ, | 634 | .{ .READ = true }, |
| 635 | .{ .TYPE = .SHARED }, | 635 | .{ .TYPE = .SHARED }, |
| 636 | file.handle, | 636 | file.handle, |
| 637 | 0, | 637 | 0, |
lib/std/dynamic_library.zig+9-9| ... | @@ -238,7 +238,7 @@ pub const ElfDynLib = struct { | ... | @@ -238,7 +238,7 @@ pub const ElfDynLib = struct { |
| 238 | const file_bytes = try posix.mmap( | 238 | const file_bytes = try posix.mmap( |
| 239 | null, | 239 | null, |
| 240 | mem.alignForward(usize, size, page_size), | 240 | mem.alignForward(usize, size, page_size), |
| 241 | posix.PROT.READ, | 241 | .{ .READ = true }, |
| 242 | .{ .TYPE = .PRIVATE }, | 242 | .{ .TYPE = .PRIVATE }, |
| 243 | file.handle, | 243 | file.handle, |
| 244 | 0, | 244 | 0, |
| ... | @@ -276,7 +276,7 @@ pub const ElfDynLib = struct { | ... | @@ -276,7 +276,7 @@ pub const ElfDynLib = struct { |
| 276 | const all_loaded_mem = try posix.mmap( | 276 | const all_loaded_mem = try posix.mmap( |
| 277 | null, | 277 | null, |
| 278 | virt_addr_end, | 278 | virt_addr_end, |
| 279 | posix.PROT.NONE, | 279 | .{}, |
| 280 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, | 280 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, |
| 281 | -1, | 281 | -1, |
| 282 | 0, | 282 | 0, |
| ... | @@ -302,7 +302,7 @@ pub const ElfDynLib = struct { | ... | @@ -302,7 +302,7 @@ pub const ElfDynLib = struct { |
| 302 | const extra_bytes = (base + ph.p_vaddr) - aligned_addr; | 302 | const extra_bytes = (base + ph.p_vaddr) - aligned_addr; |
| 303 | const extended_memsz = mem.alignForward(usize, ph.p_memsz + extra_bytes, page_size); | 303 | const extended_memsz = mem.alignForward(usize, ph.p_memsz + extra_bytes, page_size); |
| 304 | const ptr = @as([*]align(std.heap.page_size_min) u8, @ptrFromInt(aligned_addr)); | 304 | const ptr = @as([*]align(std.heap.page_size_min) u8, @ptrFromInt(aligned_addr)); |
| 305 | const prot = elfToMmapProt(ph.p_flags); | 305 | const prot = elfToProt(ph.p_flags); |
| 306 | if ((ph.p_flags & elf.PF_W) == 0) { | 306 | if ((ph.p_flags & elf.PF_W) == 0) { |
| 307 | // If it does not need write access, it can be mapped from the fd. | 307 | // If it does not need write access, it can be mapped from the fd. |
| 308 | _ = try posix.mmap( | 308 | _ = try posix.mmap( |
| ... | @@ -531,12 +531,12 @@ pub const ElfDynLib = struct { | ... | @@ -531,12 +531,12 @@ pub const ElfDynLib = struct { |
| 531 | return null; | 531 | return null; |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | fn elfToMmapProt(elf_prot: u64) u32 { | 534 | fn elfToProt(elf_prot: u64) posix.PROT { |
| 535 | var result: u32 = posix.PROT.NONE; | 535 | return .{ |
| 536 | if ((elf_prot & elf.PF_R) != 0) result |= posix.PROT.READ; | 536 | .READ = (elf_prot & elf.PF_R) != 0, |
| 537 | if ((elf_prot & elf.PF_W) != 0) result |= posix.PROT.WRITE; | 537 | .WRITE = (elf_prot & elf.PF_W) != 0, |
| 538 | if ((elf_prot & elf.PF_X) != 0) result |= posix.PROT.EXEC; | 538 | .EXEC = (elf_prot & elf.PF_X) != 0, |
| 539 | return result; | 539 | }; |
| 540 | } | 540 | } |
| 541 | }; | 541 | }; |
| 542 | 542 |
lib/std/heap/PageAllocator.zig+1-1| ... | @@ -96,7 +96,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 { | ... | @@ -96,7 +96,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 { |
| 96 | const slice = posix.mmap( | 96 | const slice = posix.mmap( |
| 97 | hint, | 97 | hint, |
| 98 | overalloc_len, | 98 | overalloc_len, |
| 99 | posix.PROT.READ | posix.PROT.WRITE, | 99 | .{ .READ = true, .WRITE = true }, |
| 100 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, | 100 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, |
| 101 | -1, | 101 | -1, |
| 102 | 0, | 102 | 0, |
lib/std/macho.zig+16-4| ... | @@ -9,7 +9,19 @@ const Allocator = mem.Allocator; | ... | @@ -9,7 +9,19 @@ const Allocator = mem.Allocator; |
| 9 | 9 | ||
| 10 | pub const cpu_type_t = c_int; | 10 | pub const cpu_type_t = c_int; |
| 11 | pub const cpu_subtype_t = c_int; | 11 | pub const cpu_subtype_t = c_int; |
| 12 | pub const vm_prot_t = c_int; | 12 | pub const vm_prot_t = packed struct(u32) { |
| 13 | READ: bool = false, | ||
| 14 | WRITE: bool = false, | ||
| 15 | EXEC: bool = false, | ||
| 16 | _: u1 = 0, | ||
| 17 | /// When a caller finds that they cannot obtain write permission on a | ||
| 18 | /// mapped entry, the following flag can be used. The entry will be | ||
| 19 | /// made "needs copy" effectively copying the object (using COW), | ||
| 20 | /// and write permission will be added to the maximum protections for | ||
| 21 | /// the associated entry. | ||
| 22 | COPY: bool = false, | ||
| 23 | __: u27 = 0, | ||
| 24 | }; | ||
| 13 | 25 | ||
| 14 | pub const mach_header = extern struct { | 26 | pub const mach_header = extern struct { |
| 15 | magic: u32, | 27 | magic: u32, |
| ... | @@ -648,10 +660,10 @@ pub const segment_command_64 = extern struct { | ... | @@ -648,10 +660,10 @@ pub const segment_command_64 = extern struct { |
| 648 | filesize: u64 = 0, | 660 | filesize: u64 = 0, |
| 649 | 661 | ||
| 650 | /// maximum VM protection | 662 | /// maximum VM protection |
| 651 | maxprot: vm_prot_t = PROT.NONE, | 663 | maxprot: vm_prot_t = .{}, |
| 652 | 664 | ||
| 653 | /// initial VM protection | 665 | /// initial VM protection |
| 654 | initprot: vm_prot_t = PROT.NONE, | 666 | initprot: vm_prot_t = .{}, |
| 655 | 667 | ||
| 656 | /// number of sections in segment | 668 | /// number of sections in segment |
| 657 | nsects: u32 = 0, | 669 | nsects: u32 = 0, |
| ... | @@ -662,7 +674,7 @@ pub const segment_command_64 = extern struct { | ... | @@ -662,7 +674,7 @@ pub const segment_command_64 = extern struct { |
| 662 | } | 674 | } |
| 663 | 675 | ||
| 664 | pub fn isWriteable(seg: segment_command_64) bool { | 676 | pub fn isWriteable(seg: segment_command_64) bool { |
| 665 | return seg.initprot & PROT.WRITE != 0; | 677 | return seg.initprot.write; |
| 666 | } | 678 | } |
| 667 | }; | 679 | }; |
| 668 | 680 |
lib/std/os/emscripten.zig+8-7| ... | @@ -331,13 +331,14 @@ pub const POLL = struct { | ... | @@ -331,13 +331,14 @@ pub const POLL = struct { |
| 331 | pub const RDBAND = 0x080; | 331 | pub const RDBAND = 0x080; |
| 332 | }; | 332 | }; |
| 333 | 333 | ||
| 334 | pub const PROT = struct { | 334 | pub const PROT = packed struct(u32) { |
| 335 | pub const NONE = 0x0; | 335 | READ: bool = false, |
| 336 | pub const READ = 0x1; | 336 | WRITE: bool = false, |
| 337 | pub const WRITE = 0x2; | 337 | EXEC: bool = false, |
| 338 | pub const EXEC = 0x4; | 338 | _: u21 = 0, |
| 339 | pub const GROWSDOWN = 0x01000000; | 339 | GROWSDOWN: bool = false, |
| 340 | pub const GROWSUP = 0x02000000; | 340 | GROWSUP: bool = false, |
| 341 | __: u6 = 0, | ||
| 341 | }; | 342 | }; |
| 342 | 343 | ||
| 343 | pub const rlim_t = u64; | 344 | pub const rlim_t = u64; |
lib/std/os/linux.zig+30-24| ... | @@ -986,13 +986,13 @@ pub fn pivot_root(new_root: [*:0]const u8, put_old: [*:0]const u8) usize { | ... | @@ -986,13 +986,13 @@ pub fn pivot_root(new_root: [*:0]const u8, put_old: [*:0]const u8) usize { |
| 986 | return syscall2(.pivot_root, @intFromPtr(new_root), @intFromPtr(put_old)); | 986 | return syscall2(.pivot_root, @intFromPtr(new_root), @intFromPtr(put_old)); |
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, offset: i64) usize { | 989 | pub fn mmap(address: ?[*]u8, length: usize, prot: PROT, flags: MAP, fd: i32, offset: i64) usize { |
| 990 | if (@hasField(SYS, "mmap2")) { | 990 | if (@hasField(SYS, "mmap2")) { |
| 991 | return syscall6( | 991 | return syscall6( |
| 992 | .mmap2, | 992 | .mmap2, |
| 993 | @intFromPtr(address), | 993 | @intFromPtr(address), |
| 994 | length, | 994 | length, |
| 995 | prot, | 995 | @as(u32, @bitCast(prot)), |
| 996 | @as(u32, @bitCast(flags)), | 996 | @as(u32, @bitCast(flags)), |
| 997 | @bitCast(@as(isize, fd)), | 997 | @bitCast(@as(isize, fd)), |
| 998 | @truncate(@as(u64, @bitCast(offset)) / std.heap.pageSize()), | 998 | @truncate(@as(u64, @bitCast(offset)) / std.heap.pageSize()), |
| ... | @@ -1005,7 +1005,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, of | ... | @@ -1005,7 +1005,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, of |
| 1005 | @intFromPtr(&[_]usize{ | 1005 | @intFromPtr(&[_]usize{ |
| 1006 | @intFromPtr(address), | 1006 | @intFromPtr(address), |
| 1007 | length, | 1007 | length, |
| 1008 | prot, | 1008 | @as(u32, @bitCast(prot)), |
| 1009 | @as(u32, @bitCast(flags)), | 1009 | @as(u32, @bitCast(flags)), |
| 1010 | @bitCast(@as(isize, fd)), | 1010 | @bitCast(@as(isize, fd)), |
| 1011 | @as(u64, @bitCast(offset)), | 1011 | @as(u64, @bitCast(offset)), |
| ... | @@ -1014,7 +1014,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, of | ... | @@ -1014,7 +1014,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, of |
| 1014 | .mmap, | 1014 | .mmap, |
| 1015 | @intFromPtr(address), | 1015 | @intFromPtr(address), |
| 1016 | length, | 1016 | length, |
| 1017 | prot, | 1017 | @as(u32, @bitCast(prot)), |
| 1018 | @as(u32, @bitCast(flags)), | 1018 | @as(u32, @bitCast(flags)), |
| 1019 | @bitCast(@as(isize, fd)), | 1019 | @bitCast(@as(isize, fd)), |
| 1020 | @as(u64, @bitCast(offset)), | 1020 | @as(u64, @bitCast(offset)), |
| ... | @@ -1022,8 +1022,8 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, of | ... | @@ -1022,8 +1022,8 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: MAP, fd: i32, of |
| 1022 | } | 1022 | } |
| 1023 | } | 1023 | } |
| 1024 | 1024 | ||
| 1025 | pub fn mprotect(address: [*]const u8, length: usize, protection: usize) usize { | 1025 | pub fn mprotect(address: [*]const u8, length: usize, protection: PROT) usize { |
| 1026 | return syscall3(.mprotect, @intFromPtr(address), length, protection); | 1026 | return syscall3(.mprotect, @intFromPtr(address), length, @as(u32, @bitCast(protection))); |
| 1027 | } | 1027 | } |
| 1028 | 1028 | ||
| 1029 | pub fn mremap(old_addr: ?[*]const u8, old_len: usize, new_len: usize, flags: MREMAP, new_addr: ?[*]const u8) usize { | 1029 | pub fn mremap(old_addr: ?[*]const u8, old_len: usize, new_len: usize, flags: MREMAP, new_addr: ?[*]const u8) usize { |
| ... | @@ -3616,24 +3616,30 @@ pub const FUTEX2_FLAGS = packed struct(u32) { | ... | @@ -3616,24 +3616,30 @@ pub const FUTEX2_FLAGS = packed struct(u32) { |
| 3616 | _undefined: u24 = 0, | 3616 | _undefined: u24 = 0, |
| 3617 | }; | 3617 | }; |
| 3618 | 3618 | ||
| 3619 | pub const PROT = struct { | 3619 | pub const PROT = switch (native_arch) { |
| 3620 | /// page can not be accessed | 3620 | .mips, .mipsel, .mips64, .mips64el, .xtensa, .xtensaeb => packed struct(u32) { |
| 3621 | pub const NONE = 0x0; | 3621 | READ: bool = false, |
| 3622 | /// page can be read | 3622 | WRITE: bool = false, |
| 3623 | pub const READ = 0x1; | 3623 | EXEC: bool = false, |
| 3624 | /// page can be written | 3624 | _: u1 = 0, |
| 3625 | pub const WRITE = 0x2; | 3625 | /// Page may be used for atomic ops. |
| 3626 | /// page can be executed | 3626 | SEM: bool = false, |
| 3627 | pub const EXEC = 0x4; | 3627 | __: u19 = 0, |
| 3628 | /// page may be used for atomic ops | 3628 | GROWSDOWN: bool = false, |
| 3629 | pub const SEM = switch (native_arch) { | 3629 | GROWSUP: bool = false, |
| 3630 | .mips, .mipsel, .mips64, .mips64el, .xtensa, .xtensaeb => 0x10, | 3630 | ___: u6 = 0, |
| 3631 | else => 0x8, | 3631 | }, |
| 3632 | }; | 3632 | else => packed struct(u32) { |
| 3633 | /// mprotect flag: extend change to start of growsdown vma | 3633 | READ: bool = false, |
| 3634 | pub const GROWSDOWN = 0x01000000; | 3634 | WRITE: bool = false, |
| 3635 | /// mprotect flag: extend change to end of growsup vma | 3635 | EXEC: bool = false, |
| 3636 | pub const GROWSUP = 0x02000000; | 3636 | /// Page may be used for atomic ops. |
| 3637 | SEM: bool = false, | ||
| 3638 | __: u20 = 0, | ||
| 3639 | GROWSDOWN: bool = false, | ||
| 3640 | GROWSUP: bool = false, | ||
| 3641 | ___: u6 = 0, | ||
| 3642 | }, | ||
| 3637 | }; | 3643 | }; |
| 3638 | 3644 | ||
| 3639 | pub const FD_CLOEXEC = 1; | 3645 | pub const FD_CLOEXEC = 1; |
lib/std/os/linux/IoUring.zig+3-3| ... | @@ -1526,7 +1526,7 @@ pub const SubmissionQueue = struct { | ... | @@ -1526,7 +1526,7 @@ pub const SubmissionQueue = struct { |
| 1526 | const mmap = try posix.mmap( | 1526 | const mmap = try posix.mmap( |
| 1527 | null, | 1527 | null, |
| 1528 | size, | 1528 | size, |
| 1529 | posix.PROT.READ | posix.PROT.WRITE, | 1529 | .{ .READ = true, .WRITE = true }, |
| 1530 | .{ .TYPE = .SHARED, .POPULATE = true }, | 1530 | .{ .TYPE = .SHARED, .POPULATE = true }, |
| 1531 | fd, | 1531 | fd, |
| 1532 | linux.IORING_OFF_SQ_RING, | 1532 | linux.IORING_OFF_SQ_RING, |
| ... | @@ -1540,7 +1540,7 @@ pub const SubmissionQueue = struct { | ... | @@ -1540,7 +1540,7 @@ pub const SubmissionQueue = struct { |
| 1540 | const mmap_sqes = try posix.mmap( | 1540 | const mmap_sqes = try posix.mmap( |
| 1541 | null, | 1541 | null, |
| 1542 | size_sqes, | 1542 | size_sqes, |
| 1543 | posix.PROT.READ | posix.PROT.WRITE, | 1543 | .{ .READ = true, .WRITE = true }, |
| 1544 | .{ .TYPE = .SHARED, .POPULATE = true }, | 1544 | .{ .TYPE = .SHARED, .POPULATE = true }, |
| 1545 | fd, | 1545 | fd, |
| 1546 | linux.IORING_OFF_SQES, | 1546 | linux.IORING_OFF_SQES, |
| ... | @@ -1747,7 +1747,7 @@ pub fn setup_buf_ring( | ... | @@ -1747,7 +1747,7 @@ pub fn setup_buf_ring( |
| 1747 | const mmap = try posix.mmap( | 1747 | const mmap = try posix.mmap( |
| 1748 | null, | 1748 | null, |
| 1749 | mmap_size, | 1749 | mmap_size, |
| 1750 | posix.PROT.READ | posix.PROT.WRITE, | 1750 | .{ .READ = true, .WRITE = true }, |
| 1751 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, | 1751 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, |
| 1752 | -1, | 1752 | -1, |
| 1753 | 0, | 1753 | 0, |
lib/std/os/linux/tls.zig+4-4| ... | @@ -568,7 +568,7 @@ pub fn initStatic(phdrs: []elf.Phdr) void { | ... | @@ -568,7 +568,7 @@ pub fn initStatic(phdrs: []elf.Phdr) void { |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | inline fn mmap_tls(length: usize) usize { | 570 | inline fn mmap_tls(length: usize) usize { |
| 571 | const prot = linux.PROT.READ | linux.PROT.WRITE; | 571 | const prot: linux.PROT = .{ .READ = true, .WRITE = true }; |
| 572 | const flags: linux.MAP = .{ .TYPE = .PRIVATE, .ANONYMOUS = true }; | 572 | const flags: linux.MAP = .{ .TYPE = .PRIVATE, .ANONYMOUS = true }; |
| 573 | 573 | ||
| 574 | if (@hasField(linux.SYS, "mmap2")) { | 574 | if (@hasField(linux.SYS, "mmap2")) { |
| ... | @@ -576,7 +576,7 @@ inline fn mmap_tls(length: usize) usize { | ... | @@ -576,7 +576,7 @@ inline fn mmap_tls(length: usize) usize { |
| 576 | .mmap2, | 576 | .mmap2, |
| 577 | 0, | 577 | 0, |
| 578 | length, | 578 | length, |
| 579 | prot, | 579 | @as(u32, @bitCast(prot)), |
| 580 | @as(u32, @bitCast(flags)), | 580 | @as(u32, @bitCast(flags)), |
| 581 | @as(usize, @bitCast(@as(isize, -1))), | 581 | @as(usize, @bitCast(@as(isize, -1))), |
| 582 | 0, | 582 | 0, |
| ... | @@ -589,7 +589,7 @@ inline fn mmap_tls(length: usize) usize { | ... | @@ -589,7 +589,7 @@ inline fn mmap_tls(length: usize) usize { |
| 589 | @intFromPtr(&[_]usize{ | 589 | @intFromPtr(&[_]usize{ |
| 590 | 0, | 590 | 0, |
| 591 | length, | 591 | length, |
| 592 | prot, | 592 | @as(u32, @bitCast(prot)), |
| 593 | @as(u32, @bitCast(flags)), | 593 | @as(u32, @bitCast(flags)), |
| 594 | @as(usize, @bitCast(@as(isize, -1))), | 594 | @as(usize, @bitCast(@as(isize, -1))), |
| 595 | 0, | 595 | 0, |
| ... | @@ -598,7 +598,7 @@ inline fn mmap_tls(length: usize) usize { | ... | @@ -598,7 +598,7 @@ inline fn mmap_tls(length: usize) usize { |
| 598 | .mmap, | 598 | .mmap, |
| 599 | 0, | 599 | 0, |
| 600 | length, | 600 | length, |
| 601 | prot, | 601 | @as(u32, @bitCast(prot)), |
| 602 | @as(u32, @bitCast(flags)), | 602 | @as(u32, @bitCast(flags)), |
| 603 | @as(usize, @bitCast(@as(isize, -1))), | 603 | @as(usize, @bitCast(@as(isize, -1))), |
| 604 | 0, | 604 | 0, |
lib/std/os/windows.zig-34| ... | @@ -3765,40 +3765,6 @@ pub fn NtFreeVirtualMemory(hProcess: HANDLE, addr: ?*PVOID, size: *SIZE_T, free_ | ... | @@ -3765,40 +3765,6 @@ pub fn NtFreeVirtualMemory(hProcess: HANDLE, addr: ?*PVOID, size: *SIZE_T, free_ |
| 3765 | }; | 3765 | }; |
| 3766 | } | 3766 | } |
| 3767 | 3767 | ||
| 3768 | pub const VirtualProtectError = error{ | ||
| 3769 | InvalidAddress, | ||
| 3770 | Unexpected, | ||
| 3771 | }; | ||
| 3772 | |||
| 3773 | pub fn VirtualProtect(lpAddress: ?LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, lpflOldProtect: *DWORD) VirtualProtectError!void { | ||
| 3774 | // ntdll takes an extra level of indirection here | ||
| 3775 | var addr = lpAddress; | ||
| 3776 | var size = dwSize; | ||
| 3777 | switch (ntdll.NtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, flNewProtect, lpflOldProtect)) { | ||
| 3778 | .SUCCESS => {}, | ||
| 3779 | .INVALID_ADDRESS => return error.InvalidAddress, | ||
| 3780 | else => |st| return unexpectedStatus(st), | ||
| 3781 | } | ||
| 3782 | } | ||
| 3783 | |||
| 3784 | pub fn VirtualProtectEx(handle: HANDLE, addr: ?LPVOID, size: SIZE_T, new_prot: DWORD) VirtualProtectError!DWORD { | ||
| 3785 | var old_prot: DWORD = undefined; | ||
| 3786 | var out_addr = addr; | ||
| 3787 | var out_size = size; | ||
| 3788 | switch (ntdll.NtProtectVirtualMemory( | ||
| 3789 | handle, | ||
| 3790 | &out_addr, | ||
| 3791 | &out_size, | ||
| 3792 | new_prot, | ||
| 3793 | &old_prot, | ||
| 3794 | )) { | ||
| 3795 | .SUCCESS => return old_prot, | ||
| 3796 | .INVALID_ADDRESS => return error.InvalidAddress, | ||
| 3797 | // TODO: map errors | ||
| 3798 | else => |rc| return unexpectedStatus(rc), | ||
| 3799 | } | ||
| 3800 | } | ||
| 3801 | |||
| 3802 | pub const SetConsoleTextAttributeError = error{Unexpected}; | 3768 | pub const SetConsoleTextAttributeError = error{Unexpected}; |
| 3803 | 3769 | ||
| 3804 | pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetConsoleTextAttributeError!void { | 3770 | pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetConsoleTextAttributeError!void { |
lib/std/posix.zig+2-117| ... | @@ -934,128 +934,14 @@ pub fn fanotify_markZ( | ... | @@ -934,128 +934,14 @@ pub fn fanotify_markZ( |
| 934 | } | 934 | } |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | pub const MlockError = error{ | ||
| 938 | PermissionDenied, | ||
| 939 | LockedMemoryLimitExceeded, | ||
| 940 | SystemResources, | ||
| 941 | } || UnexpectedError; | ||
| 942 | |||
| 943 | pub fn mlock(memory: []align(page_size_min) const u8) MlockError!void { | ||
| 944 | if (@TypeOf(system.mlock) == void) | ||
| 945 | @compileError("mlock not supported on this OS"); | ||
| 946 | return switch (errno(system.mlock(memory.ptr, memory.len))) { | ||
| 947 | .SUCCESS => {}, | ||
| 948 | .INVAL => unreachable, // unaligned, negative, runs off end of addrspace | ||
| 949 | .PERM => error.PermissionDenied, | ||
| 950 | .NOMEM => error.LockedMemoryLimitExceeded, | ||
| 951 | .AGAIN => error.SystemResources, | ||
| 952 | else => |err| unexpectedErrno(err), | ||
| 953 | }; | ||
| 954 | } | ||
| 955 | |||
| 956 | pub fn mlock2(memory: []align(page_size_min) const u8, flags: MLOCK) MlockError!void { | ||
| 957 | if (@TypeOf(system.mlock2) == void) | ||
| 958 | @compileError("mlock2 not supported on this OS"); | ||
| 959 | return switch (errno(system.mlock2(memory.ptr, memory.len, flags))) { | ||
| 960 | .SUCCESS => {}, | ||
| 961 | .INVAL => unreachable, // bad memory or bad flags | ||
| 962 | .PERM => error.PermissionDenied, | ||
| 963 | .NOMEM => error.LockedMemoryLimitExceeded, | ||
| 964 | .AGAIN => error.SystemResources, | ||
| 965 | else => |err| unexpectedErrno(err), | ||
| 966 | }; | ||
| 967 | } | ||
| 968 | |||
| 969 | pub fn munlock(memory: []align(page_size_min) const u8) MlockError!void { | ||
| 970 | if (@TypeOf(system.munlock) == void) | ||
| 971 | @compileError("munlock not supported on this OS"); | ||
| 972 | return switch (errno(system.munlock(memory.ptr, memory.len))) { | ||
| 973 | .SUCCESS => {}, | ||
| 974 | .INVAL => unreachable, // unaligned or runs off end of addr space | ||
| 975 | .PERM => return error.PermissionDenied, | ||
| 976 | .NOMEM => return error.LockedMemoryLimitExceeded, | ||
| 977 | .AGAIN => return error.SystemResources, | ||
| 978 | else => |err| unexpectedErrno(err), | ||
| 979 | }; | ||
| 980 | } | ||
| 981 | |||
| 982 | pub fn mlockall(flags: MCL) MlockError!void { | ||
| 983 | if (@TypeOf(system.mlockall) == void) | ||
| 984 | @compileError("mlockall not supported on this OS"); | ||
| 985 | return switch (errno(system.mlockall(flags))) { | ||
| 986 | .SUCCESS => {}, | ||
| 987 | .INVAL => unreachable, // bad flags | ||
| 988 | .PERM => error.PermissionDenied, | ||
| 989 | .NOMEM => error.LockedMemoryLimitExceeded, | ||
| 990 | .AGAIN => error.SystemResources, | ||
| 991 | else => |err| unexpectedErrno(err), | ||
| 992 | }; | ||
| 993 | } | ||
| 994 | |||
| 995 | pub fn munlockall() MlockError!void { | ||
| 996 | if (@TypeOf(system.munlockall) == void) | ||
| 997 | @compileError("munlockall not supported on this OS"); | ||
| 998 | return switch (errno(system.munlockall())) { | ||
| 999 | .SUCCESS => {}, | ||
| 1000 | .PERM => error.PermissionDenied, | ||
| 1001 | .NOMEM => error.LockedMemoryLimitExceeded, | ||
| 1002 | .AGAIN => error.SystemResources, | ||
| 1003 | else => |err| unexpectedErrno(err), | ||
| 1004 | }; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | pub const MProtectError = error{ | ||
| 1008 | /// The memory cannot be given the specified access. This can happen, for example, if you | ||
| 1009 | /// mmap(2) a file to which you have read-only access, then ask mprotect() to mark it | ||
| 1010 | /// PROT_WRITE. | ||
| 1011 | AccessDenied, | ||
| 1012 | |||
| 1013 | /// Changing the protection of a memory region would result in the total number of map‐ | ||
| 1014 | /// pings with distinct attributes (e.g., read versus read/write protection) exceeding the | ||
| 1015 | /// allowed maximum. (For example, making the protection of a range PROT_READ in the mid‐ | ||
| 1016 | /// dle of a region currently protected as PROT_READ|PROT_WRITE would result in three map‐ | ||
| 1017 | /// pings: two read/write mappings at each end and a read-only mapping in the middle.) | ||
| 1018 | OutOfMemory, | ||
| 1019 | } || UnexpectedError; | ||
| 1020 | |||
| 1021 | pub fn mprotect(memory: []align(page_size_min) u8, protection: u32) MProtectError!void { | ||
| 1022 | if (native_os == .windows) { | ||
| 1023 | const win_prot: windows.DWORD = switch (@as(u3, @truncate(protection))) { | ||
| 1024 | 0b000 => windows.PAGE_NOACCESS, | ||
| 1025 | 0b001 => windows.PAGE_READONLY, | ||
| 1026 | 0b010 => unreachable, // +w -r not allowed | ||
| 1027 | 0b011 => windows.PAGE_READWRITE, | ||
| 1028 | 0b100 => windows.PAGE_EXECUTE, | ||
| 1029 | 0b101 => windows.PAGE_EXECUTE_READ, | ||
| 1030 | 0b110 => unreachable, // +w -r not allowed | ||
| 1031 | 0b111 => windows.PAGE_EXECUTE_READWRITE, | ||
| 1032 | }; | ||
| 1033 | var old: windows.DWORD = undefined; | ||
| 1034 | windows.VirtualProtect(memory.ptr, memory.len, win_prot, &old) catch |err| switch (err) { | ||
| 1035 | error.InvalidAddress => return error.AccessDenied, | ||
| 1036 | error.Unexpected => return error.Unexpected, | ||
| 1037 | }; | ||
| 1038 | } else { | ||
| 1039 | switch (errno(system.mprotect(memory.ptr, memory.len, protection))) { | ||
| 1040 | .SUCCESS => return, | ||
| 1041 | .INVAL => unreachable, | ||
| 1042 | .ACCES => return error.AccessDenied, | ||
| 1043 | .NOMEM => return error.OutOfMemory, | ||
| 1044 | else => |err| return unexpectedErrno(err), | ||
| 1045 | } | ||
| 1046 | } | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | pub const MMapError = error{ | 937 | pub const MMapError = error{ |
| 1050 | /// The underlying filesystem of the specified file does not support memory mapping. | 938 | /// The underlying filesystem of the specified file does not support memory mapping. |
| 1051 | MemoryMappingNotSupported, | 939 | MemoryMappingNotSupported, |
| 1052 | |||
| 1053 | /// A file descriptor refers to a non-regular file. Or a file mapping was requested, | 940 | /// A file descriptor refers to a non-regular file. Or a file mapping was requested, |
| 1054 | /// but the file descriptor is not open for reading. Or `MAP.SHARED` was requested | 941 | /// but the file descriptor is not open for reading. Or `MAP.SHARED` was requested |
| 1055 | /// and `PROT_WRITE` is set, but the file descriptor is not open in `RDWR` mode. | 942 | /// and `PROT_WRITE` is set, but the file descriptor is not open in `RDWR` mode. |
| 1056 | /// Or `PROT_WRITE` is set, but the file is append-only. | 943 | /// Or `PROT_WRITE` is set, but the file is append-only. |
| 1057 | AccessDenied, | 944 | AccessDenied, |
| 1058 | |||
| 1059 | /// The `prot` argument asks for `PROT_EXEC` but the mapped area belongs to a file on | 945 | /// The `prot` argument asks for `PROT_EXEC` but the mapped area belongs to a file on |
| 1060 | /// a filesystem that was mounted no-exec. | 946 | /// a filesystem that was mounted no-exec. |
| 1061 | PermissionDenied, | 947 | PermissionDenied, |
| ... | @@ -1063,7 +949,6 @@ pub const MMapError = error{ | ... | @@ -1063,7 +949,6 @@ pub const MMapError = error{ |
| 1063 | ProcessFdQuotaExceeded, | 949 | ProcessFdQuotaExceeded, |
| 1064 | SystemFdQuotaExceeded, | 950 | SystemFdQuotaExceeded, |
| 1065 | OutOfMemory, | 951 | OutOfMemory, |
| 1066 | |||
| 1067 | /// Using FIXED_NOREPLACE flag and the process has already mapped memory at the given address | 952 | /// Using FIXED_NOREPLACE flag and the process has already mapped memory at the given address |
| 1068 | MappingAlreadyExists, | 953 | MappingAlreadyExists, |
| 1069 | } || UnexpectedError; | 954 | } || UnexpectedError; |
| ... | @@ -1076,8 +961,8 @@ pub const MMapError = error{ | ... | @@ -1076,8 +961,8 @@ pub const MMapError = error{ |
| 1076 | pub fn mmap( | 961 | pub fn mmap( |
| 1077 | ptr: ?[*]align(page_size_min) u8, | 962 | ptr: ?[*]align(page_size_min) u8, |
| 1078 | length: usize, | 963 | length: usize, |
| 1079 | prot: u32, | 964 | prot: PROT, |
| 1080 | flags: system.MAP, | 965 | flags: MAP, |
| 1081 | fd: fd_t, | 966 | fd: fd_t, |
| 1082 | offset: u64, | 967 | offset: u64, |
| 1083 | ) MMapError![]align(page_size_min) u8 { | 968 | ) MMapError![]align(page_size_min) u8 { |
lib/std/posix/test.zig+3-3| ... | @@ -172,7 +172,7 @@ test "mmap" { | ... | @@ -172,7 +172,7 @@ test "mmap" { |
| 172 | const data = try posix.mmap( | 172 | const data = try posix.mmap( |
| 173 | null, | 173 | null, |
| 174 | 1234, | 174 | 1234, |
| 175 | posix.PROT.READ | posix.PROT.WRITE, | 175 | .{ .READ = true, .WRITE = true }, |
| 176 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, | 176 | .{ .TYPE = .PRIVATE, .ANONYMOUS = true }, |
| 177 | -1, | 177 | -1, |
| 178 | 0, | 178 | 0, |
| ... | @@ -214,7 +214,7 @@ test "mmap" { | ... | @@ -214,7 +214,7 @@ test "mmap" { |
| 214 | const data = try posix.mmap( | 214 | const data = try posix.mmap( |
| 215 | null, | 215 | null, |
| 216 | alloc_size, | 216 | alloc_size, |
| 217 | posix.PROT.READ, | 217 | .{ .READ = true }, |
| 218 | .{ .TYPE = .PRIVATE }, | 218 | .{ .TYPE = .PRIVATE }, |
| 219 | file.handle, | 219 | file.handle, |
| 220 | 0, | 220 | 0, |
| ... | @@ -239,7 +239,7 @@ test "mmap" { | ... | @@ -239,7 +239,7 @@ test "mmap" { |
| 239 | const data = try posix.mmap( | 239 | const data = try posix.mmap( |
| 240 | null, | 240 | null, |
| 241 | alloc_size / 2, | 241 | alloc_size / 2, |
| 242 | posix.PROT.READ, | 242 | .{ .READ = true }, |
| 243 | .{ .TYPE = .PRIVATE }, | 243 | .{ .TYPE = .PRIVATE }, |
| 244 | file.handle, | 244 | file.handle, |
| 245 | alloc_size / 2, | 245 | alloc_size / 2, |
lib/std/process.zig+192| ... | @@ -886,3 +886,195 @@ pub const SetCurrentDirError = error{ | ... | @@ -886,3 +886,195 @@ pub const SetCurrentDirError = error{ |
| 886 | pub fn setCurrentDir(io: Io, dir: Io.Dir) !void { | 886 | pub fn setCurrentDir(io: Io, dir: Io.Dir) !void { |
| 887 | return io.vtable.processSetCurrentDir(io.userdata, dir); | 887 | return io.vtable.processSetCurrentDir(io.userdata, dir); |
| 888 | } | 888 | } |
| 889 | |||
| 890 | pub const LockMemoryError = error{ | ||
| 891 | UnsupportedOperation, | ||
| 892 | PermissionDenied, | ||
| 893 | LockedMemoryLimitExceeded, | ||
| 894 | SystemResources, | ||
| 895 | } || Io.UnexpectedError; | ||
| 896 | |||
| 897 | pub const LockMemoryOptions = struct { | ||
| 898 | /// Lock pages that are currently resident and mark the entire range so | ||
| 899 | /// that the remaining nonresident pages are locked when they are populated | ||
| 900 | /// by a page fault. | ||
| 901 | on_fault: bool = false, | ||
| 902 | }; | ||
| 903 | |||
| 904 | /// Request part of the calling process's virtual address space to be in RAM, | ||
| 905 | /// preventing that memory from being paged to the swap area. | ||
| 906 | /// | ||
| 907 | /// Corresponds to "mlock" or "mlock2" in libc. | ||
| 908 | /// | ||
| 909 | /// See also: | ||
| 910 | /// * unlockMemory | ||
| 911 | pub fn lockMemory(memory: []align(std.heap.page_size_min) const u8, options: LockMemoryOptions) LockMemoryError!void { | ||
| 912 | if (native_os == .windows) { | ||
| 913 | // TODO call VirtualLock | ||
| 914 | } | ||
| 915 | if (!options.on_fault and @TypeOf(posix.system.mlock) != void) { | ||
| 916 | switch (posix.errno(posix.system.mlock(memory.ptr, memory.len))) { | ||
| 917 | .SUCCESS => return, | ||
| 918 | .INVAL => |err| return std.Io.Threaded.errnoBug(err), // unaligned, negative, runs off end of addrspace | ||
| 919 | .PERM => return error.PermissionDenied, | ||
| 920 | .NOMEM => return error.LockedMemoryLimitExceeded, | ||
| 921 | .AGAIN => return error.SystemResources, | ||
| 922 | else => |err| return posix.unexpectedErrno(err), | ||
| 923 | } | ||
| 924 | } | ||
| 925 | if (@TypeOf(posix.system.mlock2) != void) { | ||
| 926 | const flags: posix.MLOCK = .{ .ONFAULT = options.on_fault }; | ||
| 927 | switch (posix.errno(posix.system.mlock2(memory.ptr, memory.len, flags))) { | ||
| 928 | .SUCCESS => return, | ||
| 929 | .INVAL => |err| return std.Io.Threaded.errnoBug(err), // unaligned, negative, runs off end of addrspace | ||
| 930 | .PERM => return error.PermissionDenied, | ||
| 931 | .NOMEM => return error.LockedMemoryLimitExceeded, | ||
| 932 | .AGAIN => return error.SystemResources, | ||
| 933 | else => |err| return posix.unexpectedErrno(err), | ||
| 934 | } | ||
| 935 | } | ||
| 936 | return error.UnsupportedOperation; | ||
| 937 | } | ||
| 938 | |||
| 939 | pub const UnlockMemoryError = error{ | ||
| 940 | PermissionDenied, | ||
| 941 | OutOfMemory, | ||
| 942 | SystemResources, | ||
| 943 | } || Io.UnexpectedError; | ||
| 944 | |||
| 945 | /// Withdraw request for process's virtual address space to be in RAM. | ||
| 946 | /// | ||
| 947 | /// Corresponds to "munlock" in libc. | ||
| 948 | /// | ||
| 949 | /// See also: | ||
| 950 | /// * `lockMemory` | ||
| 951 | pub fn unlockMemory(memory: []align(std.heap.page_size_min) const u8) UnlockMemoryError!void { | ||
| 952 | if (@TypeOf(posix.system.munlock) == void) return; | ||
| 953 | switch (posix.errno(posix.system.munlock(memory.ptr, memory.len))) { | ||
| 954 | .SUCCESS => return, | ||
| 955 | .INVAL => |err| return std.Io.Threaded.errnoBug(err), // unaligned or runs off end of addr space | ||
| 956 | .PERM => return error.PermissionDenied, | ||
| 957 | .NOMEM => return error.OutOfMemory, | ||
| 958 | .AGAIN => return error.SystemResources, | ||
| 959 | else => |err| return posix.unexpectedErrno(err), | ||
| 960 | } | ||
| 961 | } | ||
| 962 | |||
| 963 | pub const LockMemoryAllOptions = struct { | ||
| 964 | current: bool = false, | ||
| 965 | future: bool = false, | ||
| 966 | /// Asserted to be used together with `current` or `future`, or both. | ||
| 967 | on_fault: bool = false, | ||
| 968 | }; | ||
| 969 | |||
| 970 | pub fn lockMemoryAll(options: LockMemoryAllOptions) LockMemoryError!void { | ||
| 971 | if (@TypeOf(posix.system.mlockall) == void) return error.UnsupportedOperation; | ||
| 972 | var flags: posix.MCL = .{ | ||
| 973 | .CURRENT = options.current, | ||
| 974 | .FUTURE = options.future, | ||
| 975 | }; | ||
| 976 | if (options.on_fault) { | ||
| 977 | assert(options.current or options.future); | ||
| 978 | if (@hasField(posix.MCL, "ONFAULT")) { | ||
| 979 | flags.ONFAULT = true; | ||
| 980 | } else { | ||
| 981 | return error.UnsupportedOperation; | ||
| 982 | } | ||
| 983 | } | ||
| 984 | switch (posix.errno(posix.system.mlockall(flags))) { | ||
| 985 | .SUCCESS => return, | ||
| 986 | .INVAL => |err| return std.Io.Threaded.errnoBug(err), | ||
| 987 | .PERM => return error.PermissionDenied, | ||
| 988 | .NOMEM => return error.LockedMemoryLimitExceeded, | ||
| 989 | .AGAIN => return error.SystemResources, | ||
| 990 | else => |err| return posix.unexpectedErrno(err), | ||
| 991 | } | ||
| 992 | } | ||
| 993 | |||
| 994 | pub fn unlockMemoryAll() UnlockMemoryError!void { | ||
| 995 | if (@TypeOf(posix.system.munlockall) == void) return; | ||
| 996 | switch (posix.errno(posix.system.munlockall())) { | ||
| 997 | .SUCCESS => return, | ||
| 998 | .PERM => return error.PermissionDenied, | ||
| 999 | .NOMEM => return error.OutOfMemory, | ||
| 1000 | .AGAIN => return error.SystemResources, | ||
| 1001 | else => |err| return posix.unexpectedErrno(err), | ||
| 1002 | } | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | pub const ProtectMemoryError = error{ | ||
| 1006 | UnsupportedOperation, | ||
| 1007 | /// The memory cannot be given the specified access. This can happen, for | ||
| 1008 | /// example, if you memory map a file to which you have read-only access, | ||
| 1009 | /// then use `protectMemory` to mark it writable. | ||
| 1010 | AccessDenied, | ||
| 1011 | /// Changing the protection of a memory region would result in the total | ||
| 1012 | /// number of mappings with distinct attributes exceeding the allowed | ||
| 1013 | /// maximum. | ||
| 1014 | OutOfMemory, | ||
| 1015 | } || Io.UnexpectedError; | ||
| 1016 | |||
| 1017 | pub const ProtectMemoryOptions = packed struct(u3) { | ||
| 1018 | read: bool = false, | ||
| 1019 | write: bool = false, | ||
| 1020 | execute: bool = false, | ||
| 1021 | }; | ||
| 1022 | |||
| 1023 | pub fn protectMemory( | ||
| 1024 | memory: []align(std.heap.page_size_min) u8, | ||
| 1025 | options: ProtectMemoryOptions, | ||
| 1026 | ) ProtectMemoryError!void { | ||
| 1027 | if (native_os == .windows) { | ||
| 1028 | var addr = memory.ptr; // ntdll takes an extra level of indirection here | ||
| 1029 | var size = memory.len; // ntdll takes an extra level of indirection here | ||
| 1030 | var old: windows.PAGE = undefined; | ||
| 1031 | const current_process: windows.HANDLE = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1)))); | ||
| 1032 | const new: windows.PAGE = switch (@as(u3, @bitCast(options))) { | ||
| 1033 | 0b000 => .{ .NOACCESS = true }, | ||
| 1034 | 0b001 => .{ .READONLY = true }, | ||
| 1035 | 0b010 => return error.AccessDenied, // +w -r not allowed | ||
| 1036 | 0b011 => .{ .READWRITE = true }, | ||
| 1037 | 0b100 => .{ .EXECUTE = true }, | ||
| 1038 | 0b101 => .{ .EXECUTE_READ = true }, | ||
| 1039 | 0b110 => return error.AccessDenied, // +w -r not allowed | ||
| 1040 | 0b111 => .{ .EXECUTE_READWRITE = true }, | ||
| 1041 | }; | ||
| 1042 | switch (windows.ntdll.NtProtectVirtualMemory(current_process, @ptrCast(&addr), &size, new, &old)) { | ||
| 1043 | .SUCCESS => return, | ||
| 1044 | .INVALID_ADDRESS => return error.AccessDenied, | ||
| 1045 | else => |st| return windows.unexpectedStatus(st), | ||
| 1046 | } | ||
| 1047 | } else if (posix.PROT != void) { | ||
| 1048 | const flags: posix.PROT = .{ | ||
| 1049 | .READ = options.read, | ||
| 1050 | .WRITE = options.write, | ||
| 1051 | .EXEC = options.execute, | ||
| 1052 | }; | ||
| 1053 | switch (posix.errno(posix.system.mprotect(memory.ptr, memory.len, flags))) { | ||
| 1054 | .SUCCESS => return, | ||
| 1055 | .INVAL => |err| return std.Io.Threaded.errnoBug(err), | ||
| 1056 | .ACCES => return error.AccessDenied, | ||
| 1057 | .NOMEM => return error.OutOfMemory, | ||
| 1058 | else => |err| return posix.unexpectedErrno(err), | ||
| 1059 | } | ||
| 1060 | } | ||
| 1061 | return error.UnsupportedOperation; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | test lockMemory { | ||
| 1065 | var page: [std.heap.page_size_min]u8 align(std.heap.page_size_min) = undefined; | ||
| 1066 | lockMemory(&page, .{}) catch return error.SkipZigTest; | ||
| 1067 | unlockMemory(&page) catch return error.SkipZigTest; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | test lockMemoryAll { | ||
| 1071 | lockMemoryAll(.{ .current = true }) catch return error.SkipZigTest; | ||
| 1072 | unlockMemoryAll() catch return error.SkipZigTest; | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | test protectMemory { | ||
| 1076 | if (builtin.cpu.arch == .hexagon) return error.SkipZigTest; // TODO | ||
| 1077 | var page: [std.heap.page_size_min]u8 align(std.heap.page_size_min) = undefined; | ||
| 1078 | protectMemory(&page, .{}) catch return error.SkipZigTest; | ||
| 1079 | protectMemory(&page, .{ .read = true, .write = true }) catch return error.SkipZigTest; | ||
| 1080 | } |
src/link/MachO.zig+10-10| ... | @@ -1758,10 +1758,10 @@ fn initSyntheticSections(self: *MachO) !void { | ... | @@ -1758,10 +1758,10 @@ fn initSyntheticSections(self: *MachO) !void { |
| 1758 | } | 1758 | } |
| 1759 | 1759 | ||
| 1760 | fn getSegmentProt(segname: []const u8) macho.vm_prot_t { | 1760 | fn getSegmentProt(segname: []const u8) macho.vm_prot_t { |
| 1761 | if (mem.eql(u8, segname, "__PAGEZERO")) return macho.PROT.NONE; | 1761 | if (mem.eql(u8, segname, "__PAGEZERO")) return .{}; |
| 1762 | if (mem.eql(u8, segname, "__TEXT")) return macho.PROT.READ | macho.PROT.EXEC; | 1762 | if (mem.eql(u8, segname, "__TEXT")) return .{ .READ = true, .EXEC = true }; |
| 1763 | if (mem.eql(u8, segname, "__LINKEDIT")) return macho.PROT.READ; | 1763 | if (mem.eql(u8, segname, "__LINKEDIT")) return .{ .READ = true }; |
| 1764 | return macho.PROT.READ | macho.PROT.WRITE; | 1764 | return .{ .READ = true, .WRITE = true }; |
| 1765 | } | 1765 | } |
| 1766 | 1766 | ||
| 1767 | fn getSegmentRank(segname: []const u8) u8 { | 1767 | fn getSegmentRank(segname: []const u8) u8 { |
| ... | @@ -3348,7 +3348,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { | ... | @@ -3348,7 +3348,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3348 | .filesize = filesize, | 3348 | .filesize = filesize, |
| 3349 | .vmaddr = base_vmaddr + 0x4000000, | 3349 | .vmaddr = base_vmaddr + 0x4000000, |
| 3350 | .vmsize = filesize, | 3350 | .vmsize = filesize, |
| 3351 | .prot = macho.PROT.READ | macho.PROT.EXEC, | 3351 | .prot = .{ .READ = true, .EXEC = true }, |
| 3352 | }); | 3352 | }); |
| 3353 | } | 3353 | } |
| 3354 | 3354 | ||
| ... | @@ -3360,7 +3360,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { | ... | @@ -3360,7 +3360,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3360 | .filesize = filesize, | 3360 | .filesize = filesize, |
| 3361 | .vmaddr = base_vmaddr + 0xc000000, | 3361 | .vmaddr = base_vmaddr + 0xc000000, |
| 3362 | .vmsize = filesize, | 3362 | .vmsize = filesize, |
| 3363 | .prot = macho.PROT.READ | macho.PROT.WRITE, | 3363 | .prot = .{ .READ = true, .WRITE = true }, |
| 3364 | }); | 3364 | }); |
| 3365 | } | 3365 | } |
| 3366 | 3366 | ||
| ... | @@ -3372,7 +3372,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { | ... | @@ -3372,7 +3372,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3372 | .filesize = filesize, | 3372 | .filesize = filesize, |
| 3373 | .vmaddr = base_vmaddr + 0x10000000, | 3373 | .vmaddr = base_vmaddr + 0x10000000, |
| 3374 | .vmsize = filesize, | 3374 | .vmsize = filesize, |
| 3375 | .prot = macho.PROT.READ | macho.PROT.WRITE, | 3375 | .prot = .{ .READ = true, .WRITE = true }, |
| 3376 | }); | 3376 | }); |
| 3377 | } | 3377 | } |
| 3378 | 3378 | ||
| ... | @@ -3381,7 +3381,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { | ... | @@ -3381,7 +3381,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3381 | self.zig_bss_seg_index = try self.addSegment("__BSS_ZIG", .{ | 3381 | self.zig_bss_seg_index = try self.addSegment("__BSS_ZIG", .{ |
| 3382 | .vmaddr = base_vmaddr + 0x14000000, | 3382 | .vmaddr = base_vmaddr + 0x14000000, |
| 3383 | .vmsize = memsize, | 3383 | .vmsize = memsize, |
| 3384 | .prot = macho.PROT.READ | macho.PROT.WRITE, | 3384 | .prot = .{ .READ = true, .WRITE = true }, |
| 3385 | }); | 3385 | }); |
| 3386 | } | 3386 | } |
| 3387 | 3387 | ||
| ... | @@ -3711,7 +3711,7 @@ pub fn addSegment(self: *MachO, name: []const u8, opts: struct { | ... | @@ -3711,7 +3711,7 @@ pub fn addSegment(self: *MachO, name: []const u8, opts: struct { |
| 3711 | vmsize: u64 = 0, | 3711 | vmsize: u64 = 0, |
| 3712 | fileoff: u64 = 0, | 3712 | fileoff: u64 = 0, |
| 3713 | filesize: u64 = 0, | 3713 | filesize: u64 = 0, |
| 3714 | prot: macho.vm_prot_t = macho.PROT.NONE, | 3714 | prot: macho.vm_prot_t = .{}, |
| 3715 | }) error{OutOfMemory}!u8 { | 3715 | }) error{OutOfMemory}!u8 { |
| 3716 | const gpa = self.base.comp.gpa; | 3716 | const gpa = self.base.comp.gpa; |
| 3717 | const index = @as(u8, @intCast(self.segments.items.len)); | 3717 | const index = @as(u8, @intCast(self.segments.items.len)); |
| ... | @@ -4903,7 +4903,7 @@ pub const MachTask = extern struct { | ... | @@ -4903,7 +4903,7 @@ pub const MachTask = extern struct { |
| 4903 | try task.setCurrProtection( | 4903 | try task.setCurrProtection( |
| 4904 | address, | 4904 | address, |
| 4905 | buf.len, | 4905 | buf.len, |
| 4906 | std.c.PROT.READ | std.c.PROT.WRITE | std.c.PROT.COPY, | 4906 | .{ .READ = true, .WRITE = true, .COPY = true }, |
| 4907 | ); | 4907 | ); |
| 4908 | defer { | 4908 | defer { |
| 4909 | task.setCurrProtection(address, buf.len, curr_prot) catch {}; | 4909 | task.setCurrProtection(address, buf.len, curr_prot) catch {}; |
src/link/MachO/DebugSymbols.zig+2-2| ... | @@ -94,8 +94,8 @@ pub fn initMetadata(self: *DebugSymbols, macho_file: *MachO) !void { | ... | @@ -94,8 +94,8 @@ pub fn initMetadata(self: *DebugSymbols, macho_file: *MachO) !void { |
| 94 | self.linkedit_segment_cmd_index = @intCast(self.segments.items.len); | 94 | self.linkedit_segment_cmd_index = @intCast(self.segments.items.len); |
| 95 | try self.segments.append(self.allocator, .{ | 95 | try self.segments.append(self.allocator, .{ |
| 96 | .segname = makeStaticString("__LINKEDIT"), | 96 | .segname = makeStaticString("__LINKEDIT"), |
| 97 | .maxprot = macho.PROT.READ, | 97 | .maxprot = .{ .READ = true }, |
| 98 | .initprot = macho.PROT.READ, | 98 | .initprot = .{ .READ = true }, |
| 99 | .cmdsize = @sizeOf(macho.segment_command_64), | 99 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 100 | }); | 100 | }); |
| 101 | } | 101 | } |
src/link/MachO/relocatable.zig+1-1| ... | @@ -539,7 +539,7 @@ fn createSegment(macho_file: *MachO) !void { | ... | @@ -539,7 +539,7 @@ fn createSegment(macho_file: *MachO) !void { |
| 539 | const gpa = macho_file.base.comp.gpa; | 539 | const gpa = macho_file.base.comp.gpa; |
| 540 | 540 | ||
| 541 | // For relocatable, we only ever need a single segment so create it now. | 541 | // For relocatable, we only ever need a single segment so create it now. |
| 542 | const prot: macho.vm_prot_t = macho.PROT.READ | macho.PROT.WRITE | macho.PROT.EXEC; | 542 | const prot: macho.vm_prot_t = .{ .READ = true, .WRITE = true, .EXEC = true }; |
| 543 | try macho_file.segments.append(gpa, .{ | 543 | try macho_file.segments.append(gpa, .{ |
| 544 | .cmdsize = @sizeOf(macho.segment_command_64), | 544 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 545 | .segname = MachO.makeStaticString(""), | 545 | .segname = MachO.makeStaticString(""), |
src/link/MappedFile.zig+1-1| ... | @@ -1049,7 +1049,7 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void { | ... | @@ -1049,7 +1049,7 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void { |
| 1049 | } else mf.contents = try std.posix.mmap( | 1049 | } else mf.contents = try std.posix.mmap( |
| 1050 | null, | 1050 | null, |
| 1051 | aligned_capacity, | 1051 | aligned_capacity, |
| 1052 | std.posix.PROT.READ | std.posix.PROT.WRITE, | 1052 | .{ .READ = true, .WRITE = true }, |
| 1053 | .{ .TYPE = if (is_linux) .SHARED_VALIDATE else .SHARED }, | 1053 | .{ .TYPE = if (is_linux) .SHARED_VALIDATE else .SHARED }, |
| 1054 | mf.file.handle, | 1054 | mf.file.handle, |
| 1055 | 0, | 1055 | 0, |