From 2b42e910bf4696032158cc7ae268d3c69d699f70 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 26 May 2019 19:56:37 -0400 Subject: [PATCH] behavior tests passing on Linux --- std/c.zig | 9 +++-- std/debug.zig | 7 ++-- std/fs.zig | 4 +- std/heap.zig | 29 +++++++------- std/io.zig | 6 +-- std/io/c_out_stream.zig | 2 +- std/mem.zig | 73 ++++++++++++++++++++++++----------- std/os.zig | 48 +++++++++++++---------- std/os/bits/linux.zig | 3 +- std/os/linux.zig | 8 ++-- std/os/linux/tls.zig | 4 +- test/stage1/behavior/cast.zig | 2 +- test/stage1/behavior/misc.zig | 5 +-- 13 files changed, 119 insertions(+), 81 deletions(-) diff --git a/std/c.zig b/std/c.zig index c1398bccabab..9171a99ec9a7 100644 --- a/std/c.zig +++ b/std/c.zig @@ -1,4 +1,6 @@ const builtin = @import("builtin"); +const std = @import("std"); +const page_size = std.mem.page_size; pub use @import("os/bits.zig"); @@ -33,7 +35,7 @@ pub extern "c" fn close(fd: fd_t) c_int; pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int; pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int; pub extern "c" fn lseek(fd: fd_t, offset: isize, whence: c_int) isize; -pub extern "c" fn open(path: [*]const u8, oflag: c_int, ...) c_int; +pub extern "c" fn open(path: [*]const u8, oflag: c_uint, ...) c_int; pub extern "c" fn raise(sig: c_int) c_int; pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize; pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize; @@ -42,8 +44,9 @@ pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec, iovcnt: c_int, offset: pub extern "c" fn stat(noalias path: [*]const u8, noalias buf: *Stat) c_int; pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize; pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize; -pub extern "c" fn mmap(addr: ?*c_void, len: usize, prot: c_int, flags: c_int, fd: fd_t, offset: isize) usize; -pub extern "c" fn munmap(addr: ?*c_void, len: usize) c_int; +pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: isize) *c_void; +pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int; +pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int; pub extern "c" fn unlink(path: [*]const u8) c_int; pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8; pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_int, options: c_int) c_int; diff --git a/std/debug.zig b/std/debug.zig index 2c623d42f9f0..0b5136f7cdc3 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -1011,7 +1011,7 @@ fn openSelfDebugInfoPosix(allocator: *mem.Allocator) !DwarfInfo { S.self_exe_file = try fs.openSelfExe(); errdefer S.self_exe_file.close(); - const self_exe_mmap_len = try S.self_exe_file.getEndPos(); + const self_exe_mmap_len = mem.alignForward(try S.self_exe_file.getEndPos(), mem.page_size); const self_exe_mmap = try os.mmap( null, self_exe_mmap_len, @@ -1020,10 +1020,9 @@ fn openSelfDebugInfoPosix(allocator: *mem.Allocator) !DwarfInfo { S.self_exe_file.handle, 0, ); - errdefer os.munmap(self_exe_mmap, self_exe_mmap_len); + errdefer os.munmap(self_exe_mmap); - const file_mmap_slice = @intToPtr([*]const u8, self_exe_mmap)[0..self_exe_mmap_len]; - S.self_exe_mmap_seekable = io.SliceSeekableInStream.init(file_mmap_slice); + S.self_exe_mmap_seekable = io.SliceSeekableInStream.init(self_exe_mmap); return openElfDebugInfo( allocator, diff --git a/std/fs.zig b/std/fs.zig index dcb3143f795e..229f3099c217 100644 --- a/std/fs.zig +++ b/std/fs.zig @@ -595,8 +595,8 @@ pub const Dir = struct { } while (true) { - const rc = os.system.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len); - switch (os.errno(rc)) { + const rc = os.linux.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len); + switch (os.linux.getErrno(rc)) { 0 => {}, os.EBADF => unreachable, os.EFAULT => unreachable, diff --git a/std/heap.zig b/std/heap.zig index 1abe1da4fb1b..198eb2d07348 100644 --- a/std/heap.zig +++ b/std/heap.zig @@ -104,35 +104,36 @@ pub const DirectAllocator = struct { } const alloc_size = if (alignment <= mem.page_size) n else n + alignment; - const addr = os.mmap( + const slice = os.mmap( null, - alloc_size, + mem.alignForward(alloc_size, mem.page_size), os.PROT_READ | os.PROT_WRITE, os.MAP_PRIVATE | os.MAP_ANONYMOUS, -1, 0, ) catch return error.OutOfMemory; - if (alloc_size == n) return @intToPtr([*]u8, addr)[0..n]; + if (alloc_size == n) return slice; - const aligned_addr = mem.alignForward(addr, alignment); + const aligned_addr = mem.alignForward(@ptrToInt(slice.ptr), alignment); // Unmap the extra bytes that were only requested in order to guarantee // that the range of memory we were provided had a proper alignment in // it somewhere. The extra bytes could be at the beginning, or end, or both. - const unused_start_len = aligned_addr - addr; + const unused_start_len = aligned_addr - @ptrToInt(slice.ptr); if (unused_start_len != 0) { - os.munmap(addr, unused_start_len); + os.munmap(slice[0..unused_start_len]); } - const aligned_end_addr = std.mem.alignForward(aligned_addr + n, mem.page_size); - const unused_end_len = addr + alloc_size - aligned_end_addr; + const aligned_end_addr = mem.alignForward(aligned_addr + n, mem.page_size); + const unused_end_len = @ptrToInt(slice.ptr) + slice.len - aligned_end_addr; if (unused_end_len != 0) { - os.munmap(aligned_end_addr, unused_end_len); + os.munmap(@intToPtr([*]align(mem.page_size) u8, aligned_end_addr)[0..unused_end_len]); } return @intToPtr([*]u8, aligned_addr)[0..n]; } - fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { + fn shrink(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { + const old_mem = @alignCast(mem.page_size, old_mem_unaligned); if (os.windows.is_the_target) { const w = os.windows; if (new_size == 0) { @@ -165,12 +166,14 @@ pub const DirectAllocator = struct { const new_addr_end = base_addr + new_size; const new_addr_end_rounded = mem.alignForward(new_addr_end, mem.page_size); if (old_addr_end > new_addr_end_rounded) { - os.munmap(new_addr_end_rounded, old_addr_end - new_addr_end_rounded); + const ptr = @intToPtr([*]align(mem.page_size) u8, new_addr_end_rounded); + os.munmap(ptr[0 .. old_addr_end - new_addr_end_rounded]); } return old_mem[0..new_size]; } - fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { + fn realloc(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { + const old_mem = @alignCast(mem.page_size, old_mem_unaligned); if (os.windows.is_the_target) { if (old_mem.len == 0) { return alloc(allocator, new_size, new_align); @@ -231,7 +234,7 @@ pub const DirectAllocator = struct { const result = try alloc(allocator, new_size, new_align); if (old_mem.len != 0) { @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len)); - os.munmap(@ptrToInt(old_mem.ptr), old_mem.len); + os.munmap(old_mem); } return result; } diff --git a/std/io.zig b/std/io.zig index 41dc38f24574..258961fdfce3 100644 --- a/std/io.zig +++ b/std/io.zig @@ -1,12 +1,12 @@ const std = @import("std.zig"); const builtin = @import("builtin"); -const Os = builtin.Os; const c = std.c; const math = std.math; const debug = std.debug; const assert = debug.assert; const os = std.os; +const fs = std.fs; const mem = std.mem; const meta = std.meta; const trait = meta.trait; @@ -985,7 +985,7 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type { } pub const BufferedAtomicFile = struct { - atomic_file: os.AtomicFile, + atomic_file: fs.AtomicFile, file_stream: File.OutStream, buffered_stream: BufferedOutStream(File.WriteError), allocator: *mem.Allocator, @@ -1001,7 +1001,7 @@ pub const BufferedAtomicFile = struct { }; errdefer allocator.destroy(self); - self.atomic_file = try os.AtomicFile.init(dest_path, File.default_mode); + self.atomic_file = try fs.AtomicFile.init(dest_path, File.default_mode); errdefer self.atomic_file.deinit(); self.file_stream = self.atomic_file.file.outStream(); diff --git a/std/io/c_out_stream.zig b/std/io/c_out_stream.zig index cbc52543825b..8b341e693746 100644 --- a/std/io/c_out_stream.zig +++ b/std/io/c_out_stream.zig @@ -37,7 +37,7 @@ pub const COutStream = struct { os.ENOSPC => return error.NoSpaceLeft, os.EPERM => return error.AccessDenied, os.EPIPE => return error.BrokenPipe, - else => return os.unexpectedErrno(@intCast(usize, errno)), + else => |err| return os.unexpectedErrno(@intCast(usize, err)), } } }; diff --git a/std/mem.zig b/std/mem.zig index 643d297191a0..17dec85a5ba6 100644 --- a/std/mem.zig +++ b/std/mem.zig @@ -585,14 +585,14 @@ pub fn readIntSlice(comptime T: type, bytes: []const u8, endian: builtin.Endian) test "comptime read/write int" { comptime { var bytes: [2]u8 = undefined; - std.mem.writeIntLittle(u16, &bytes, 0x1234); - const result = std.mem.readIntBig(u16, &bytes); + writeIntLittle(u16, &bytes, 0x1234); + const result = readIntBig(u16, &bytes); testing.expect(result == 0x3412); } comptime { var bytes: [2]u8 = undefined; - std.mem.writeIntBig(u16, &bytes, 0x1234); - const result = std.mem.readIntLittle(u16, &bytes); + writeIntBig(u16, &bytes, 0x1234); + const result = readIntLittle(u16, &bytes); testing.expect(result == 0x3412); } } @@ -1053,7 +1053,7 @@ fn testReadIntImpl() void { } } -test "std.mem.writeIntSlice" { +test "writeIntSlice" { testWriteIntImpl(); comptime testWriteIntImpl(); } @@ -1184,7 +1184,7 @@ pub fn reverse(comptime T: type, items: []T) void { } } -test "std.mem.reverse" { +test "reverse" { var arr = []i32{ 5, 3, @@ -1211,7 +1211,7 @@ pub fn rotate(comptime T: type, items: []T, amount: usize) void { reverse(T, items); } -test "std.mem.rotate" { +test "rotate" { var arr = []i32{ 5, 3, @@ -1296,14 +1296,14 @@ pub fn asBytes(ptr: var) AsBytesReturnType(@typeOf(ptr)) { return @ptrCast(AsBytesReturnType(P), ptr); } -test "std.mem.asBytes" { +test "asBytes" { const deadbeef = u32(0xDEADBEEF); const deadbeef_bytes = switch (builtin.endian) { builtin.Endian.Big => "\xDE\xAD\xBE\xEF", builtin.Endian.Little => "\xEF\xBE\xAD\xDE", }; - testing.expect(std.mem.eql(u8, asBytes(&deadbeef), deadbeef_bytes)); + testing.expect(eql(u8, asBytes(&deadbeef), deadbeef_bytes)); var codeface = u32(0xC0DEFACE); for (asBytes(&codeface).*) |*b| @@ -1323,7 +1323,7 @@ test "std.mem.asBytes" { .c = 0xDE, .d = 0xA1, }; - testing.expect(std.mem.eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1")); + testing.expect(eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1")); } ///Given any value, returns a copy of its bytes in an array. @@ -1331,17 +1331,17 @@ pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 { return asBytes(&value).*; } -test "std.mem.toBytes" { +test "toBytes" { var my_bytes = toBytes(u32(0x12345678)); switch (builtin.endian) { - builtin.Endian.Big => testing.expect(std.mem.eql(u8, my_bytes, "\x12\x34\x56\x78")), - builtin.Endian.Little => testing.expect(std.mem.eql(u8, my_bytes, "\x78\x56\x34\x12")), + builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x12\x34\x56\x78")), + builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x78\x56\x34\x12")), } my_bytes[0] = '\x99'; switch (builtin.endian) { - builtin.Endian.Big => testing.expect(std.mem.eql(u8, my_bytes, "\x99\x34\x56\x78")), - builtin.Endian.Little => testing.expect(std.mem.eql(u8, my_bytes, "\x99\x56\x34\x12")), + builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x99\x34\x56\x78")), + builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x99\x56\x34\x12")), } } @@ -1363,7 +1363,7 @@ pub fn bytesAsValue(comptime T: type, bytes: var) BytesAsValueReturnType(T, @typ return @ptrCast(BytesAsValueReturnType(T, @typeOf(bytes)), bytes); } -test "std.mem.bytesAsValue" { +test "bytesAsValue" { const deadbeef = u32(0xDEADBEEF); const deadbeef_bytes = switch (builtin.endian) { builtin.Endian.Big => "\xDE\xAD\xBE\xEF", @@ -1405,7 +1405,7 @@ test "std.mem.bytesAsValue" { pub fn bytesToValue(comptime T: type, bytes: var) T { return bytesAsValue(T, &bytes).*; } -test "std.mem.bytesToValue" { +test "bytesToValue" { const deadbeef_bytes = switch (builtin.endian) { builtin.Endian.Big => "\xDE\xAD\xBE\xEF", builtin.Endian.Little => "\xEF\xBE\xAD\xDE", @@ -1430,25 +1430,25 @@ pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubA return @ptrCast(ReturnType, &ptr[start]); } -test "std.mem.subArrayPtr" { +test "subArrayPtr" { const a1 = "abcdef"; const sub1 = subArrayPtr(&a1, 2, 3); - testing.expect(std.mem.eql(u8, sub1.*, "cde")); + testing.expect(eql(u8, sub1.*, "cde")); var a2 = "abcdef"; var sub2 = subArrayPtr(&a2, 2, 3); - testing.expect(std.mem.eql(u8, sub2, "cde")); + testing.expect(eql(u8, sub2, "cde")); sub2[1] = 'X'; - testing.expect(std.mem.eql(u8, a2, "abcXef")); + testing.expect(eql(u8, a2, "abcXef")); } /// Round an address up to the nearest aligned address pub fn alignForward(addr: usize, alignment: usize) usize { - return (addr + alignment - 1) & ~(alignment - 1); + return alignBackward(addr + (alignment - 1), alignment); } -test "std.mem.alignForward" { +test "alignForward" { testing.expect(alignForward(1, 1) == 1); testing.expect(alignForward(2, 1) == 2); testing.expect(alignForward(1, 2) == 2); @@ -1462,3 +1462,30 @@ test "std.mem.alignForward" { testing.expect(alignForward(16, 8) == 16); testing.expect(alignForward(17, 8) == 24); } + +pub fn alignBackward(addr: usize, alignment: usize) usize { + // 000010000 // example addr + // 000001111 // subtract 1 + // 111110000 // binary not + return addr & ~(alignment - 1); +} + +pub fn isAligned(addr: usize, alignment: usize) bool { + return alignBackward(addr, alignment) == addr; +} + +test "isAligned" { + testing.expect(isAligned(0, 4)); + testing.expect(isAligned(1, 1)); + testing.expect(isAligned(2, 1)); + testing.expect(isAligned(2, 2)); + testing.expect(!isAligned(2, 4)); + testing.expect(isAligned(3, 1)); + testing.expect(!isAligned(3, 2)); + testing.expect(!isAligned(3, 4)); + testing.expect(isAligned(4, 4)); + testing.expect(isAligned(4, 2)); + testing.expect(isAligned(4, 1)); + testing.expect(!isAligned(4, 8)); + testing.expect(!isAligned(4, 16)); +} diff --git a/std/os.zig b/std/os.zig index 0efc2ebca746..1debb1623451 100644 --- a/std/os.zig +++ b/std/os.zig @@ -251,7 +251,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { // Linux can return EINVAL when read amount is > 0x7ffff000 // See https://github.com/ziglang/zig/pull/743#issuecomment-363158274 // TODO audit this. Shawn Landden says that this is not actually true. - // if this logic should stay, move it to std.os.linux.sys + // if this logic should stay, move it to std.os.linux const max_buf_len = 0x7ffff000; var index: usize = 0; @@ -260,8 +260,9 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { const rc = system.read(fd, buf.ptr + index, want_to_read); switch (errno(rc)) { 0 => { - index += rc; - if (rc == want_to_read) continue; + const amt_read = @intCast(usize, rc); + index += amt_read; + if (amt_read == want_to_read) continue; // Read returned less than buf.len. return index; }, @@ -374,7 +375,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void { // Linux can return EINVAL when write amount is > 0x7ffff000 // See https://github.com/ziglang/zig/pull/743#issuecomment-363165856 // TODO audit this. Shawn Landden says that this is not actually true. - // if this logic should stay, move it to std.os.linux.sys + // if this logic should stay, move it to std.os.linux const max_bytes_len = 0x7ffff000; var index: usize = 0; @@ -383,7 +384,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void { const rc = system.write(fd, bytes.ptr + index, amt_to_write); switch (errno(rc)) { 0 => { - index += rc; + index += @intCast(usize, rc); continue; }, EINTR => continue, @@ -1863,14 +1864,10 @@ pub const MProtectError = error{ Unexpected, }; -/// address and length must be page-aligned -pub fn mprotect(address: usize, length: usize, protection: u32) MProtectError!void { - const negative_page_size = @bitCast(usize, -isize(mem.page_size)); - const aligned_address = address & negative_page_size; - const aligned_end = (address + length + mem.page_size - 1) & negative_page_size; - assert(address == aligned_address); - assert(length == aligned_end - aligned_address); - switch (errno(system.mprotect(address, length, protection))) { +/// `memory.len` must be page-aligned. +pub fn mprotect(memory: [*]align(mem.page_size) u8, protection: u32) MProtectError!void { + assert(mem.isAligned(memory.len, mem.page_size)); + switch (errno(system.mprotect(memory.ptr, memory.len, protection))) { 0 => return, EINVAL => unreachable, EACCES => return error.AccessDenied, @@ -1906,17 +1903,26 @@ pub const MMapError = error{ /// Map files or devices into memory. /// Use of a mapped region can result in these signals: +/// `length` must be page-aligned. /// * SIGSEGV - Attempted write into a region mapped as read-only. /// * SIGBUS - Attempted access to a portion of the buffer that does not correspond to the file -pub fn mmap(address: ?[*]u8, length: usize, prot: u32, flags: u32, fd: fd_t, offset: isize) MMapError!usize { +pub fn mmap( + ptr: ?[*]align(mem.page_size) u8, + length: usize, + prot: u32, + flags: u32, + fd: fd_t, + offset: isize, +) MMapError![]align(mem.page_size) u8 { + assert(mem.isAligned(length, mem.page_size)); const err = if (builtin.link_libc) blk: { - const rc = system.mmap(address, length, prot, flags, fd, offset); - if (rc != system.MMAP_FAILED) return rc; - break :blk system._errno().*; + const rc = std.c.mmap(ptr, length, prot, flags, fd, offset); + if (rc != MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length]; + break :blk @intCast(usize, system._errno().*); } else blk: { - const rc = system.mmap(address, length, prot, flags, fd, offset); + const rc = system.mmap(ptr, length, prot, flags, fd, offset); const err = errno(rc); - if (err == 0) return rc; + if (err == 0) return @intToPtr([*]align(mem.page_size) u8, rc)[0..length]; break :blk err; }; switch (err) { @@ -1940,8 +1946,8 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: u32, flags: u32, fd: fd_t, off /// Zig's munmap function does not, for two reasons: /// * It violates the Zig principle that resource deallocation must succeed. /// * The Windows function, VirtualFree, has this restriction. -pub fn munmap(address: usize, length: usize) void { - switch (errno(system.munmap(address, length))) { +pub fn munmap(memory: []align(mem.page_size) u8) void { + switch (errno(system.munmap(memory.ptr, memory.len))) { 0 => return, EINVAL => unreachable, // Invalid parameters. ENOMEM => unreachable, // Attempted to unmap a region in the middle of an existing mapping. diff --git a/std/os/bits/linux.zig b/std/os/bits/linux.zig index b4f51f3518a5..5473299488eb 100644 --- a/std/os/bits/linux.zig +++ b/std/os/bits/linux.zig @@ -1,4 +1,5 @@ const std = @import("../../std.zig"); +const maxInt = std.math.maxInt; pub use @import("linux/errno.zig"); pub use switch (builtin.arch) { @@ -39,7 +40,7 @@ pub const PROT_EXEC = 4; pub const PROT_GROWSDOWN = 0x01000000; pub const PROT_GROWSUP = 0x02000000; -pub const MAP_FAILED = maxInt(usize); +pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize)); pub const MAP_SHARED = 0x01; pub const MAP_PRIVATE = 0x02; pub const MAP_TYPE = 0x0f; diff --git a/std/os/linux.zig b/std/os/linux.zig index 4b00433b6c7e..4b3739907928 100644 --- a/std/os/linux.zig +++ b/std/os/linux.zig @@ -173,12 +173,12 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @bitCast(usize, isize(fd)), @bitCast(usize, offset)); } -pub fn mprotect(address: usize, length: usize, protection: usize) usize { - return syscall3(SYS_mprotect, address, length, protection); +pub fn mprotect(address: [*]const u8, length: usize, protection: usize) usize { + return syscall3(SYS_mprotect, @ptrToInt(address), length, protection); } -pub fn munmap(address: usize, length: usize) usize { - return syscall2(SYS_munmap, address, length); +pub fn munmap(address: [*]const u8, length: usize) usize { + return syscall2(SYS_munmap, @ptrToInt(address), length); } pub fn read(fd: i32, buf: [*]u8, count: usize) usize { diff --git a/std/os/linux/tls.zig b/std/os/linux/tls.zig index f06ed144b9e6..a10d68663b9d 100644 --- a/std/os/linux/tls.zig +++ b/std/os/linux/tls.zig @@ -237,7 +237,7 @@ pub fn allocateTLS(size: usize) usize { return @ptrToInt(&main_thread_tls_buffer); } - const addr = os.mmap( + const slice = os.mmap( null, size, os.PROT_READ | os.PROT_WRITE, @@ -246,5 +246,5 @@ pub fn allocateTLS(size: usize) usize { 0, ) catch @panic("out of memory"); - return addr; + return @ptrToInt(slice.ptr); } diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index 8ed03f493671..57de1e2eeb90 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -318,7 +318,7 @@ fn testCastPtrOfArrayToSliceAndPtr() void { test "cast *[1][*]const u8 to [*]const ?[*]const u8" { const window_name = [1][*]const u8{c"window name"}; const x: [*]const ?[*]const u8 = &window_name; - expect(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name")); + expect(mem.eql(u8, std.mem.toSliceConst(u8, x[0].?), "window name")); } test "@intCast comptime_int" { diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index 4cc401a008e5..2ef3e02348a4 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -2,7 +2,6 @@ const std = @import("std"); const expect = std.testing.expect; const expectEqualSlices = std.testing.expectEqualSlices; const mem = std.mem; -const cstr = std.cstr; const builtin = @import("builtin"); const maxInt = std.math.maxInt; @@ -210,7 +209,7 @@ test "multiline C string" { c\\three ; const s2 = c"one\ntwo)\nthree"; - expect(cstr.cmp(s1, s2) == 0); + expect(std.cstr.cmp(s1, s2) == 0); } test "type equality" { @@ -363,7 +362,7 @@ test "C string concatenation" { const a = c"OK" ++ c" IT " ++ c"WORKED"; const b = c"OK IT WORKED"; - const len = cstr.len(b); + const len = mem.len(u8, b); const len_with_null = len + 1; { var i: u32 = 0;