Commit 9f3165540e

Andrew Kelley <andrew@ziglang.org>
2024-02-07 05:12:11
std.os.linux.MAP: use a packed struct
Introduces type safety to this constant. Eliminates one use of `usingnamespace`.
1 parent 3da6043
lib/std/crypto/tlcsprng.zig
@@ -83,7 +83,7 @@ fn tlsCsprngFill(_: *anyopaque, buffer: []u8) void {
                 null,
                 @sizeOf(Context),
                 os.PROT.READ | os.PROT.WRITE,
-                os.MAP.PRIVATE | os.MAP.ANONYMOUS,
+                .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
                 -1,
                 0,
             ) catch {
lib/std/heap/PageAllocator.zig
@@ -35,7 +35,7 @@ fn alloc(_: *anyopaque, n: usize, log2_align: u8, ra: usize) ?[*]u8 {
         hint,
         aligned_len,
         os.PROT.READ | os.PROT.WRITE,
-        os.MAP.PRIVATE | os.MAP.ANONYMOUS,
+        .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
         -1,
         0,
     ) catch return null;
lib/std/os/linux/arm-eabi.zig
@@ -197,19 +197,6 @@ pub const LOCK = struct {
     pub const NB = 4;
 };
 
-pub const MAP = struct {
-    /// stack-like segment
-    pub const GROWSDOWN = 0x0100;
-    /// ETXTBSY
-    pub const DENYWRITE = 0x0800;
-    /// mark it as an executable
-    pub const EXECUTABLE = 0x1000;
-    /// pages are locked
-    pub const LOCKED = 0x2000;
-    /// don't check for reservations
-    pub const NORESERVE = 0x4000;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__vdso_clock_gettime";
     pub const CGT_VER = "LINUX_2.6";
lib/std/os/linux/arm64.zig
@@ -179,19 +179,6 @@ pub const LOCK = struct {
     pub const NB = 4;
 };
 
-pub const MAP = struct {
-    /// stack-like segment
-    pub const GROWSDOWN = 0x0100;
-    /// ETXTBSY
-    pub const DENYWRITE = 0x0800;
-    /// mark it as an executable
-    pub const EXECUTABLE = 0x1000;
-    /// pages are locked
-    pub const LOCKED = 0x2000;
-    /// don't check for reservations
-    pub const NORESERVE = 0x4000;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__kernel_clock_gettime";
     pub const CGT_VER = "LINUX_2.6.39";
lib/std/os/linux/io_uring.zig
@@ -1344,7 +1344,7 @@ pub const SubmissionQueue = struct {
             null,
             size,
             os.PROT.READ | os.PROT.WRITE,
-            os.MAP.SHARED | os.MAP.POPULATE,
+            .{ .TYPE = .SHARED, .POPULATE = true },
             fd,
             linux.IORING_OFF_SQ_RING,
         );
@@ -1358,7 +1358,7 @@ pub const SubmissionQueue = struct {
             null,
             size_sqes,
             os.PROT.READ | os.PROT.WRITE,
-            os.MAP.SHARED | os.MAP.POPULATE,
+            .{ .TYPE = .SHARED, .POPULATE = true },
             fd,
             linux.IORING_OFF_SQES,
         );
lib/std/os/linux/mips.zig
@@ -271,15 +271,6 @@ pub const LOCK = struct {
 
 pub const MMAP2_UNIT = 4096;
 
-pub const MAP = struct {
-    pub const NORESERVE = 0x0400;
-    pub const GROWSDOWN = 0x1000;
-    pub const DENYWRITE = 0x2000;
-    pub const EXECUTABLE = 0x4000;
-    pub const LOCKED = 0x8000;
-    pub const @"32BIT" = 0x40;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__kernel_clock_gettime";
     pub const CGT_VER = "LINUX_2.6.39";
lib/std/os/linux/mips64.zig
@@ -256,15 +256,6 @@ pub const LOCK = struct {
 
 pub const MMAP2_UNIT = 4096;
 
-pub const MAP = struct {
-    pub const NORESERVE = 0x0400;
-    pub const GROWSDOWN = 0x1000;
-    pub const DENYWRITE = 0x2000;
-    pub const EXECUTABLE = 0x4000;
-    pub const LOCKED = 0x8000;
-    pub const @"32BIT" = 0x40;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__kernel_clock_gettime";
     pub const CGT_VER = "LINUX_2.6.39";
lib/std/os/linux/powerpc.zig
@@ -198,19 +198,6 @@ pub const LOCK = struct {
     pub const NB = 4;
 };
 
-pub const MAP = struct {
-    /// stack-like segment
-    pub const GROWSDOWN = 0x0100;
-    /// ETXTBSY
-    pub const DENYWRITE = 0x0800;
-    /// mark it as an executable
-    pub const EXECUTABLE = 0x1000;
-    /// pages are locked
-    pub const LOCKED = 0x0080;
-    /// don't check for reservations
-    pub const NORESERVE = 0x0040;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__kernel_clock_gettime";
     pub const CGT_VER = "LINUX_2.6.15";
lib/std/os/linux/powerpc64.zig
@@ -198,19 +198,6 @@ pub const LOCK = struct {
     pub const NB = 4;
 };
 
-pub const MAP = struct {
-    /// stack-like segment
-    pub const GROWSDOWN = 0x0100;
-    /// ETXTBSY
-    pub const DENYWRITE = 0x0800;
-    /// mark it as an executable
-    pub const EXECUTABLE = 0x1000;
-    /// pages are locked
-    pub const LOCKED = 0x0080;
-    /// don't check for reservations
-    pub const NORESERVE = 0x0040;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__kernel_clock_gettime";
     pub const CGT_VER = "LINUX_2.6.15";
lib/std/os/linux/riscv64.zig
@@ -246,4 +246,3 @@ pub const Stat = extern struct {
 pub const Elf_Symndx = u32;
 
 pub const VDSO = struct {};
-pub const MAP = struct {};
lib/std/os/linux/sparc64.zig
@@ -248,19 +248,6 @@ pub const LOCK = struct {
     pub const UN = 8;
 };
 
-pub const MAP = struct {
-    /// stack-like segment
-    pub const GROWSDOWN = 0x0200;
-    /// ETXTBSY
-    pub const DENYWRITE = 0x0800;
-    /// mark it as an executable
-    pub const EXECUTABLE = 0x1000;
-    /// pages are locked
-    pub const LOCKED = 0x0100;
-    /// don't check for reservations
-    pub const NORESERVE = 0x0040;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__vdso_clock_gettime";
     pub const CGT_VER = "LINUX_2.6";
lib/std/os/linux/tls.zig
@@ -324,7 +324,7 @@ pub fn initStaticTLS(phdrs: []elf.Phdr) void {
             null,
             tls_image.alloc_size + tls_image.alloc_align - 1,
             os.PROT.READ | os.PROT.WRITE,
-            os.MAP.PRIVATE | os.MAP.ANONYMOUS,
+            .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
         ) catch os.abort();
lib/std/os/linux/x86.zig
@@ -211,15 +211,6 @@ pub const LOCK = struct {
     pub const UN = 8;
 };
 
-pub const MAP = struct {
-    pub const NORESERVE = 0x4000;
-    pub const GROWSDOWN = 0x0100;
-    pub const DENYWRITE = 0x0800;
-    pub const EXECUTABLE = 0x1000;
-    pub const LOCKED = 0x2000;
-    pub const @"32BIT" = 0x40;
-};
-
 pub const MMAP2_UNIT = 4096;
 
 pub const VDSO = struct {
lib/std/os/linux/x86_64.zig
@@ -177,21 +177,6 @@ pub const F = struct {
     pub const UNLCK = 2;
 };
 
-pub const MAP = struct {
-    /// only give out 32bit addresses
-    pub const @"32BIT" = 0x40;
-    /// stack-like segment
-    pub const GROWSDOWN = 0x0100;
-    /// ETXTBSY
-    pub const DENYWRITE = 0x0800;
-    /// mark it as an executable
-    pub const EXECUTABLE = 0x1000;
-    /// pages are locked
-    pub const LOCKED = 0x2000;
-    /// don't check for reservations
-    pub const NORESERVE = 0x4000;
-};
-
 pub const VDSO = struct {
     pub const CGT_SYM = "__vdso_clock_gettime";
     pub const CGT_VER = "LINUX_2.6";
lib/std/os/linux.zig
@@ -109,36 +109,136 @@ pub const SYS = switch (@import("builtin").cpu.arch) {
     else => @compileError("The Zig Standard Library is missing syscall definitions for the target CPU architecture"),
 };
 
-pub const MAP = struct {
-    pub usingnamespace arch_bits.MAP;
-
-    /// Share changes
-    pub const SHARED = 0x01;
-    /// Changes are private
-    pub const PRIVATE = 0x02;
-    /// share + validate extension flags
-    pub const SHARED_VALIDATE = 0x03;
-    /// Mask for type of mapping
-    pub const TYPE = 0x0f;
-    /// Interpret addr exactly
-    pub const FIXED = 0x10;
-    /// don't use a file
-    pub const ANONYMOUS = if (is_mips) 0x800 else 0x20;
-    // MAP_ 0x0100 - 0x4000 flags are per architecture
-    /// populate (prefault) pagetables
-    pub const POPULATE = if (is_mips) 0x10000 else 0x8000;
-    /// do not block on IO
-    pub const NONBLOCK = if (is_mips) 0x20000 else 0x10000;
-    /// give out an address that is best suited for process/thread stacks
-    pub const STACK = if (is_mips) 0x40000 else 0x20000;
-    /// create a huge page mapping
-    pub const HUGETLB = if (is_mips) 0x80000 else 0x40000;
-    /// perform synchronous page faults for the mapping
-    pub const SYNC = 0x80000;
-    /// MAP_FIXED which doesn't unmap underlying mapping
-    pub const FIXED_NOREPLACE = 0x100000;
-    /// For anonymous mmap, memory could be uninitialized
-    pub const UNINITIALIZED = 0x4000000;
+pub const MAP_TYPE = enum(u4) {
+    SHARED = 0x01,
+    PRIVATE = 0x02,
+    SHARED_VALIDATE = 0x03,
+};
+
+pub const MAP = switch (native_arch) {
+    .x86_64, .x86 => packed struct(u32) {
+        TYPE: MAP_TYPE,
+        FIXED: bool = false,
+        ANONYMOUS: bool = false,
+        @"32BIT": bool = false,
+        _7: u1 = 0,
+        GROWSDOWN: bool = false,
+        _9: u2 = 0,
+        DENYWRITE: bool = false,
+        EXECUTABLE: bool = false,
+        LOCKED: bool = false,
+        NORESERVE: bool = false,
+        POPULATE: bool = false,
+        NONBLOCK: bool = false,
+        STACK: bool = false,
+        HUGETLB: bool = false,
+        SYNC: bool = false,
+        FIXED_NOREPLACE: bool = false,
+        _21: u5 = 0,
+        UNINITIALIZED: bool = false,
+        _: u5 = 0,
+    },
+    .aarch64, .aarch64_be, .arm, .thumb => packed struct(u32) {
+        TYPE: MAP_TYPE,
+        FIXED: bool = false,
+        ANONYMOUS: bool = false,
+        _6: u2 = 0,
+        GROWSDOWN: bool = false,
+        _9: u2 = 0,
+        DENYWRITE: bool = false,
+        EXECUTABLE: bool = false,
+        LOCKED: bool = false,
+        NORESERVE: bool = false,
+        POPULATE: bool = false,
+        NONBLOCK: bool = false,
+        STACK: bool = false,
+        HUGETLB: bool = false,
+        SYNC: bool = false,
+        FIXED_NOREPLACE: bool = false,
+        _21: u5 = 0,
+        UNINITIALIZED: bool = false,
+        _: u5 = 0,
+    },
+    .riscv64 => packed struct(u32) {
+        TYPE: MAP_TYPE,
+        FIXED: bool = false,
+        ANONYMOUS: bool = false,
+        _6: u9 = 0,
+        POPULATE: bool = false,
+        NONBLOCK: bool = false,
+        STACK: bool = false,
+        HUGETLB: bool = false,
+        SYNC: bool = false,
+        FIXED_NOREPLACE: bool = false,
+        _21: u5 = 0,
+        UNINITIALIZED: bool = false,
+        _: u5 = 0,
+    },
+    .sparc64 => packed struct(u32) {
+        TYPE: MAP_TYPE,
+        FIXED: bool = false,
+        ANONYMOUS: bool = false,
+        NORESERVE: bool = false,
+        _7: u1 = 0,
+        LOCKED: bool = false,
+        GROWSDOWN: bool = false,
+        _10: u1 = 0,
+        DENYWRITE: bool = false,
+        EXECUTABLE: bool = false,
+        _13: u2 = 0,
+        POPULATE: bool = false,
+        NONBLOCK: bool = false,
+        STACK: bool = false,
+        HUGETLB: bool = false,
+        SYNC: bool = false,
+        FIXED_NOREPLACE: bool = false,
+        _21: u5 = 0,
+        UNINITIALIZED: bool = false,
+        _: u5 = 0,
+    },
+    .mips, .mipsel, .mips64, .mips64el => packed struct(u32) {
+        TYPE: MAP_TYPE,
+        FIXED: bool = false,
+        _5: u1 = 0,
+        @"32BIT": bool = false,
+        _7: u3 = 0,
+        NORESERVE: bool = false,
+        ANONYMOUS: bool = false,
+        GROWSDOWN: bool = false,
+        DENYWRITE: bool = false,
+        EXECUTABLE: bool = false,
+        LOCKED: bool = false,
+        POPULATE: bool = false,
+        NONBLOCK: bool = false,
+        STACK: bool = false,
+        HUGETLB: bool = false,
+        FIXED_NOREPLACE: bool = false,
+        _21: u5 = 0,
+        UNINITIALIZED: bool = false,
+        _: u5 = 0,
+    },
+    .powerpc, .powerpcle, .powerpc64, .powerpc64le => packed struct(u32) {
+        TYPE: MAP_TYPE,
+        FIXED: bool = false,
+        ANONYMOUS: bool = false,
+        NORESERVE: bool = false,
+        LOCKED: bool = false,
+        GROWSDOWN: bool = false,
+        _9: u2 = 0,
+        DENYWRITE: bool = false,
+        EXECUTABLE: bool = false,
+        _13: u2 = 0,
+        POPULATE: bool = false,
+        NONBLOCK: bool = false,
+        STACK: bool = false,
+        HUGETLB: bool = false,
+        SYNC: bool = false,
+        FIXED_NOREPLACE: bool = false,
+        _21: u5 = 0,
+        UNINITIALIZED: bool = false,
+        _: u5 = 0,
+    },
+    else => @compileError("missing std.os.linux.MAP constants for this architecture"),
 };
 
 pub const O = struct {
lib/std/os/test.zig
@@ -576,7 +576,7 @@ test "mmap" {
             null,
             1234,
             os.PROT.READ | os.PROT.WRITE,
-            os.MAP.ANONYMOUS | os.MAP.PRIVATE,
+            .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
         );
@@ -618,7 +618,7 @@ test "mmap" {
             null,
             alloc_size,
             os.PROT.READ,
-            os.MAP.PRIVATE,
+            .{ .TYPE = .PRIVATE },
             file.handle,
             0,
         );
@@ -642,7 +642,7 @@ test "mmap" {
             null,
             alloc_size / 2,
             os.PROT.READ,
-            os.MAP.PRIVATE,
+            .{ .TYPE = .PRIVATE },
             file.handle,
             alloc_size / 2,
         );
lib/std/debug.zig
@@ -1652,7 +1652,7 @@ fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
             null,
             file_len,
             os.PROT.READ,
-            os.MAP.SHARED,
+            .{ .TYPE = .SHARED },
             file.handle,
             0,
         );
lib/std/dynamic_library.zig
@@ -127,7 +127,7 @@ pub const ElfDynLib = struct {
             null,
             mem.alignForward(usize, size, mem.page_size),
             os.PROT.READ,
-            os.MAP.PRIVATE,
+            .{ .TYPE = .PRIVATE },
             fd,
             0,
         );
@@ -165,7 +165,7 @@ pub const ElfDynLib = struct {
             null,
             virt_addr_end,
             os.PROT.NONE,
-            os.MAP.PRIVATE | os.MAP.ANONYMOUS,
+            .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
         );
@@ -197,7 +197,7 @@ pub const ElfDynLib = struct {
                                 ptr,
                                 extended_memsz,
                                 prot,
-                                os.MAP.PRIVATE | os.MAP.FIXED,
+                                .{ .TYPE = .PRIVATE, .FIXED = true },
                                 fd,
                                 ph.p_offset - extra_bytes,
                             );
@@ -206,7 +206,7 @@ pub const ElfDynLib = struct {
                                 ptr,
                                 extended_memsz,
                                 prot,
-                                os.MAP.PRIVATE | os.MAP.FIXED | os.MAP.ANONYMOUS,
+                                .{ .TYPE = .PRIVATE, .FIXED = true, .ANONYMOUS = true },
                                 -1,
                                 0,
                             );
lib/std/os.zig
@@ -4657,14 +4657,14 @@ pub fn mmap(
     ptr: ?[*]align(mem.page_size) u8,
     length: usize,
     prot: u32,
-    flags: u32,
+    flags: system.MAP,
     fd: fd_t,
     offset: u64,
 ) MMapError![]align(mem.page_size) u8 {
     const mmap_sym = if (lfs64_abi) system.mmap64 else system.mmap;
 
-    const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
-    const rc = mmap_sym(ptr, length, prot, flags, fd, ioffset);
+    const ioffset: i64 = @bitCast(offset); // the OS treats this as unsigned
+    const rc = mmap_sym(ptr, length, prot, @bitCast(flags), fd, ioffset);
     const err = if (builtin.link_libc) blk: {
         if (rc != std.c.MAP.FAILED) return @as([*]align(mem.page_size) u8, @ptrCast(@alignCast(rc)))[0..length];
         break :blk @as(E, @enumFromInt(system._errno().*));
lib/std/Thread.zig
@@ -1237,7 +1237,7 @@ const LinuxThreadImpl = struct {
             null,
             map_bytes,
             os.PROT.NONE,
-            os.MAP.PRIVATE | os.MAP.ANONYMOUS,
+            .{ .TYPE = .PRIVATE, .ANONYMOUS = true },
             -1,
             0,
         ) catch |err| switch (err) {