| author | |
| committer | |
| log | bd8d6a8342914974ca163fa75db0562d181f6d27 |
| tree | 0c7570d9bbec078ca4910aeff96122582c493e99 |
| parent | e1a535360fb9ed08fc48018571b9702ab12a5876 |
5 files changed, 49 insertions(+), 1 deletions(-)
lib/std/c.zig+1| ... | ... | @@ -123,6 +123,7 @@ pub extern "c" fn write(fd: c.fd_t, buf: [*]const u8, nbyte: usize) isize; |
| 123 | 123 | pub extern "c" fn pwrite(fd: c.fd_t, buf: [*]const u8, nbyte: usize, offset: c.off_t) isize; |
| 124 | 124 | pub extern "c" fn mmap(addr: ?*align(page_size) anyopaque, len: usize, prot: c_uint, flags: c_uint, fd: c.fd_t, offset: c.off_t) *anyopaque; |
| 125 | 125 | pub extern "c" fn munmap(addr: *align(page_size) const anyopaque, len: usize) c_int; |
| 126 | pub extern "c" fn msync(addr: *align(page_size) const anyopaque, len: usize, flags: c_int) c_int; | |
| 126 | 127 | pub extern "c" fn mprotect(addr: *align(page_size) anyopaque, len: usize, prot: c_uint) c_int; |
| 127 | 128 | pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int; |
| 128 | 129 | pub extern "c" fn linkat(oldfd: c.fd_t, oldpath: [*:0]const u8, newfd: c.fd_t, newpath: [*:0]const u8, flags: c_int) c_int; |
lib/std/c/linux.zig+1| ... | ... | @@ -30,6 +30,7 @@ pub const MAP = struct { |
| 30 | 30 | /// Only used by libc to communicate failure. |
| 31 | 31 | pub const FAILED = @intToPtr(*anyopaque, maxInt(usize)); |
| 32 | 32 | }; |
| 33 | pub const MSF = linux.MSF; | |
| 33 | 34 | pub const MMAP2_UNIT = linux.MMAP2_UNIT; |
| 34 | 35 | pub const MSG = linux.MSG; |
| 35 | 36 | pub const NAME_MAX = linux.NAME_MAX; |
lib/std/debug.zig+23-1| ... | ... | @@ -424,6 +424,28 @@ pub const StackIterator = struct { |
| 424 | 424 | return address; |
| 425 | 425 | } |
| 426 | 426 | |
| 427 | fn isValidMemory(address: u64) bool { | |
| 428 | if (native_os != .windows) { | |
| 429 | var res = true; | |
| 430 | const length = 2 * mem.page_size; | |
| 431 | const aligned_address = address & ~@intCast(u64, (mem.page_size - 1)); | |
| 432 | const aligned_memory = @intToPtr([*]align(mem.page_size) u8, aligned_address)[0..length]; | |
| 433 | ||
| 434 | os.msync(aligned_memory, os.MSF.ASYNC) catch |err| { | |
| 435 | switch (err) { | |
| 436 | os.MSyncError.UnmappedMemory => { | |
| 437 | res = false; | |
| 438 | }, | |
| 439 | else => unreachable, | |
| 440 | } | |
| 441 | }; | |
| 442 | return res; | |
| 443 | } else { | |
| 444 | // TODO: Using windows memory API check if a page is mapped | |
| 445 | return true; | |
| 446 | } | |
| 447 | } | |
| 448 | ||
| 427 | 449 | fn next_internal(self: *StackIterator) ?usize { |
| 428 | 450 | const fp = if (comptime native_arch.isSPARC()) |
| 429 | 451 | // On SPARC the offset is positive. (!) |
| ... | ... | @@ -432,7 +454,7 @@ pub const StackIterator = struct { |
| 432 | 454 | math.sub(usize, self.fp, fp_offset) catch return null; |
| 433 | 455 | |
| 434 | 456 | // Sanity check. |
| 435 | if (fp == 0 or !mem.isAligned(fp, @alignOf(usize))) | |
| 457 | if (fp == 0 or !mem.isAligned(fp, @alignOf(usize)) or !isValidMemory(fp)) | |
| 436 | 458 | return null; |
| 437 | 459 | |
| 438 | 460 | const new_fp = math.add(usize, @intToPtr(*const usize, fp).*, fp_bias) catch return null; |
lib/std/os.zig+14| ... | ... | @@ -88,6 +88,7 @@ pub const Kevent = system.Kevent; |
| 88 | 88 | pub const LOCK = system.LOCK; |
| 89 | 89 | pub const MADV = system.MADV; |
| 90 | 90 | pub const MAP = system.MAP; |
| 91 | pub const MSF = system.MSF; | |
| 91 | 92 | pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN; |
| 92 | 93 | pub const MMAP2_UNIT = system.MMAP2_UNIT; |
| 93 | 94 | pub const MSG = system.MSG; |
| ... | ... | @@ -4016,6 +4017,19 @@ pub fn munmap(memory: []align(mem.page_size) const u8) void { |
| 4016 | 4017 | } |
| 4017 | 4018 | } |
| 4018 | 4019 | |
| 4020 | pub const MSyncError = error{ | |
| 4021 | UnmappedMemory, | |
| 4022 | } || UnexpectedError; | |
| 4023 | ||
| 4024 | pub fn msync(memory: []align(mem.page_size) u8, flags: i32) MSyncError!void { | |
| 4025 | switch (errno(system.msync(memory.ptr, memory.len, flags))) { | |
| 4026 | .SUCCESS => return, | |
| 4027 | .NOMEM => return error.UnmappedMemory, // Unsuccessful, provided pointer does not point mapped memory | |
| 4028 | .INVAL => unreachable, // Invalid parameters. | |
| 4029 | else => unreachable, | |
| 4030 | } | |
| 4031 | } | |
| 4032 | ||
| 4019 | 4033 | pub const AccessError = error{ |
| 4020 | 4034 | PermissionDenied, |
| 4021 | 4035 | FileNotFound, |
lib/std/os/linux.zig+10| ... | ... | @@ -406,6 +406,16 @@ pub fn mprotect(address: [*]const u8, length: usize, protection: usize) usize { |
| 406 | 406 | return syscall3(.mprotect, @ptrToInt(address), length, protection); |
| 407 | 407 | } |
| 408 | 408 | |
| 409 | pub const MSF = struct { | |
| 410 | pub const ASYNC = 1; | |
| 411 | pub const INVALIDATE = 2; | |
| 412 | pub const SYNC = 4; | |
| 413 | }; | |
| 414 | ||
| 415 | pub fn msync(address: [*]const u8, length: usize, flags: u32) usize { | |
| 416 | return syscall3(.msync, @ptrToInt(address), length, flags); | |
| 417 | } | |
| 418 | ||
| 409 | 419 | pub fn munmap(address: [*]const u8, length: usize) usize { |
| 410 | 420 | return syscall2(.munmap, @ptrToInt(address), length); |
| 411 | 421 | } |