Commit 285970982a

Stephen Gregoratto <dev@sgregoratto.me>
2023-10-01 14:09:14
Add illumos OS tag
- Adds `illumos` to the `Target.Os.Tag` enum. A new function, `isSolarish` has been added that returns true if the tag is either Solaris or Illumos. This matches the naming convention found in Rust's `libc` crate[1]. - Add the tag wherever `.solaris` is being checked against. - Check for the C pre-processor macro `__illumos__` in CMake to set the proper target tuple. Illumos distros patch their compilers to have this in the "built-in" set (verified with `echo | cc -dM -E -`). Alternatively you could check the output of `uname -o`. Right now, both Solaris and Illumos import from `c/solaris.zig`. In the future it may be worth putting the shared ABI bits in a base file, and mixing that in with specific `c/solaris.zig`/`c/illumos.zig` files. [1]: https://github.com/rust-lang/libc/tree/6e02a329a2a27f6887ea86952f389ca11e06448c/src/unix/solarish
1 parent 51fa7ef
lib/std/crypto/Certificate/Bundle.zig
@@ -64,7 +64,7 @@ pub fn rescan(cb: *Bundle, gpa: Allocator) RescanError!void {
         .netbsd => return rescanBSD(cb, gpa, "/etc/openssl/certs/ca-certificates.crt"),
         .dragonfly => return rescanBSD(cb, gpa, "/usr/local/etc/ssl/cert.pem"),
         .windows => return rescanWindows(cb, gpa),
-        .solaris => return rescanSolaris(cb, gpa, "/etc/ssl/cacert.pem"),
+        .solaris, .illumos => return rescanSolaris(cb, gpa, "/etc/ssl/cacert.pem"),
         else => {},
     }
 }
lib/std/crypto/tlcsprng.zig
@@ -25,6 +25,7 @@ const os_has_fork = switch (builtin.os.tag) {
     .netbsd,
     .openbsd,
     .solaris,
+    .illumos,
     .tvos,
     .watchos,
     .haiku,
lib/std/dwarf/abi.zig
@@ -6,11 +6,11 @@ const mem = std.mem;
 pub fn supportsUnwinding(target: std.Target) bool {
     return switch (target.cpu.arch) {
         .x86 => switch (target.os.tag) {
-            .linux, .netbsd, .solaris => true,
+            .linux, .netbsd, .solaris, .illumos => true,
             else => false,
         },
         .x86_64 => switch (target.os.tag) {
-            .linux, .netbsd, .freebsd, .openbsd, .macos, .ios, .solaris => true,
+            .linux, .netbsd, .freebsd, .openbsd, .macos, .ios, .solaris, .illumos => true,
             else => false,
         },
         .arm => switch (target.os.tag) {
@@ -194,7 +194,7 @@ pub fn regBytes(
     const ucontext_ptr = thread_context_ptr;
     return switch (builtin.cpu.arch) {
         .x86 => switch (builtin.os.tag) {
-            .linux, .netbsd, .solaris => switch (reg_number) {
+            .linux, .netbsd, .solaris, .illumos => switch (reg_number) {
                 0 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EAX]),
                 1 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.ECX]),
                 2 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.EDX]),
@@ -229,7 +229,7 @@ pub fn regBytes(
             else => error.UnimplementedOs,
         },
         .x86_64 => switch (builtin.os.tag) {
-            .linux, .solaris => switch (reg_number) {
+            .linux, .solaris, .illumos => switch (reg_number) {
                 0 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RAX]),
                 1 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RDX]),
                 2 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RCX]),
@@ -247,7 +247,7 @@ pub fn regBytes(
                 14 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R14]),
                 15 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R15]),
                 16 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RIP]),
-                17...32 => |i| if (builtin.os.tag == .solaris)
+                17...32 => |i| if (builtin.os.tag.isSolarish())
                     mem.asBytes(&ucontext_ptr.mcontext.fpregs.chip_state.xmm[i - 17])
                 else
                     mem.asBytes(&ucontext_ptr.mcontext.fpregs.xmm[i - 17]),
lib/std/fs/file.zig
@@ -359,7 +359,7 @@ pub const File = struct {
                     os.S.IFSOCK => break :blk .unix_domain_socket,
                     else => {},
                 }
-                if (builtin.os.tag == .solaris) switch (m) {
+                if (builtin.os.tag.isSolarish()) switch (m) {
                     os.S.IFDOOR => break :blk .door,
                     os.S.IFPORT => break :blk .event_port,
                     else => {},
@@ -685,7 +685,7 @@ pub const File = struct {
                 else => {},
             }
 
-            if (builtin.os.tag == .solaris) switch (m) {
+            if (builtin.os.tag.isSolarish()) switch (m) {
                 os.S.IFDOOR => return .door,
                 os.S.IFPORT => return .event_port,
                 else => {},
lib/std/fs/get_app_data_dir.zig
@@ -44,7 +44,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
             };
             return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
         },
-        .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
+        .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => {
             if (os.getenv("XDG_DATA_HOME")) |xdg| {
                 return fs.path.join(allocator, &[_][]const u8{ xdg, appname });
             }
lib/std/os/test.zig
@@ -234,7 +234,7 @@ test "link with relative paths" {
     if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
 
     switch (native_os) {
-        .wasi, .linux, .solaris => {},
+        .wasi, .linux, .solaris, .illumos => {},
         else => return error.SkipZigTest,
     }
     if (true) {
@@ -277,7 +277,7 @@ test "linkat with different directories" {
     if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
 
     switch (native_os) {
-        .wasi, .linux, .solaris => {},
+        .wasi, .linux, .solaris, .illumos => {},
         else => return error.SkipZigTest,
     }
     if (true) {
@@ -706,7 +706,7 @@ test "fcntl" {
 
 test "signalfd" {
     switch (native_os) {
-        .linux, .solaris => {},
+        .linux, .solaris, .illumos => {},
         else => return error.SkipZigTest,
     }
     _ = &os.signalfd;
@@ -732,7 +732,7 @@ test "sync" {
 
 test "fsync" {
     switch (native_os) {
-        .linux, .windows, .solaris => {},
+        .linux, .windows, .solaris, .illumos => {},
         else => return error.SkipZigTest,
     }
 
@@ -870,7 +870,7 @@ test "sigaction" {
 
 test "dup & dup2" {
     switch (native_os) {
-        .linux, .solaris => {},
+        .linux, .solaris, .illumos => {},
         else => return error.SkipZigTest,
     }
 
lib/std/zig/system/NativePaths.zig
@@ -89,7 +89,7 @@ pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths {
         return self;
     }
 
-    if (builtin.os.tag == .solaris) {
+    if (builtin.os.tag.isSolarish()) {
         try self.addLibDir("/usr/lib/64");
         try self.addLibDir("/usr/local/lib/64");
         try self.addLibDir("/lib/64");
lib/std/zig/system/NativeTargetInfo.zig
@@ -51,7 +51,7 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {
                     error.InvalidVersion => {},
                 }
             },
-            .solaris => {
+            .solaris, .illumos => {
                 const uts = std.os.uname();
                 const release = mem.sliceTo(&uts.release, 0);
                 if (std.SemanticVersion.parse(release)) |ver| {
@@ -257,12 +257,12 @@ fn detectAbiAndDynamicLinker(
 ) DetectError!NativeTargetInfo {
     const native_target_has_ld = comptime builtin.target.hasDynamicLinker();
     const is_linux = builtin.target.os.tag == .linux;
-    const is_solaris = builtin.target.os.tag == .solaris;
+    const is_solarish = builtin.target.os.tag.isSolarish();
     const have_all_info = cross_target.dynamic_linker.get() != null and
         cross_target.abi != null and (!is_linux or cross_target.abi.?.isGnu());
     const os_is_non_native = cross_target.os_tag != null;
     // The Solaris/illumos environment is always the same.
-    if (!native_target_has_ld or have_all_info or os_is_non_native or is_solaris) {
+    if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) {
         return defaultAbiAndDynamicLinker(cpu, os, cross_target);
     }
     if (cross_target.abi) |abi| {
lib/std/zig/CrossTarget.zig
@@ -111,6 +111,7 @@ fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void {
         .kfreebsd,
         .lv2,
         .solaris,
+        .illumos,
         .zos,
         .haiku,
         .minix,
@@ -709,6 +710,7 @@ fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const
         .kfreebsd,
         .lv2,
         .solaris,
+        .illumos,
         .zos,
         .haiku,
         .minix,
lib/std/c.zig
@@ -49,7 +49,7 @@ pub usingnamespace switch (builtin.os.tag) {
     .openbsd => @import("c/openbsd.zig"),
     .haiku => @import("c/haiku.zig"),
     .hermit => @import("c/hermit.zig"),
-    .solaris => @import("c/solaris.zig"),
+    .solaris, .illumos => @import("c/solaris.zig"),
     .fuchsia => @import("c/fuchsia.zig"),
     .minix => @import("c/minix.zig"),
     .emscripten => @import("c/emscripten.zig"),
lib/std/debug.zig
@@ -990,6 +990,7 @@ pub fn openSelfDebugInfo(allocator: mem.Allocator) OpenSelfDebugInfoError!DebugI
             .openbsd,
             .macos,
             .solaris,
+            .illumos,
             .windows,
             => return try DebugInfo.init(allocator),
             else => return error.UnsupportedOperatingSystem,
@@ -2228,7 +2229,7 @@ pub const ModuleDebugInfo = switch (native_os) {
             };
         }
     },
-    .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku, .solaris => struct {
+    .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku, .solaris, .illumos => struct {
         base_address: usize,
         dwarf: DW.DwarfInfo,
         mapped_memory: []align(mem.page_size) const u8,
@@ -2313,6 +2314,7 @@ pub const have_segfault_handling_support = switch (native_os) {
     .macos,
     .netbsd,
     .solaris,
+    .illumos,
     .windows,
     => true,
 
@@ -2386,7 +2388,7 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
         .freebsd, .macos => @intFromPtr(info.addr),
         .netbsd => @intFromPtr(info.info.reason.fault.addr),
         .openbsd => @intFromPtr(info.data.fault.addr),
-        .solaris => @intFromPtr(info.reason.fault.addr),
+        .solaris, .illumos => @intFromPtr(info.reason.fault.addr),
         else => unreachable,
     };
 
lib/std/dynamic_library.zig
@@ -10,7 +10,7 @@ const system = std.os.system;
 pub const DynLib = switch (builtin.os.tag) {
     .linux => if (builtin.link_libc) DlDynlib else ElfDynLib,
     .windows => WindowsDynLib,
-    .macos, .tvos, .watchos, .ios, .freebsd, .netbsd, .openbsd, .dragonfly, .solaris => DlDynlib,
+    .macos, .tvos, .watchos, .ios, .freebsd, .netbsd, .openbsd, .dragonfly, .solaris, .illumos => DlDynlib,
     else => void,
 };
 
@@ -388,7 +388,7 @@ pub const DlDynlib = struct {
 
 test "dynamic_library" {
     const libname = switch (builtin.os.tag) {
-        .linux, .freebsd, .openbsd => "invalid_so.so",
+        .linux, .freebsd, .openbsd, .solaris, .illumos => "invalid_so.so",
         .windows => "invalid_dll.dll",
         .macos, .tvos, .watchos, .ios => "invalid_dylib.dylib",
         else => return error.SkipZigTest,
lib/std/fs.zig
@@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
 /// fit into a UTF-8 encoded array of this length.
 /// The byte count includes room for a null sentinel byte.
 pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
-    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .plan9 => os.PATH_MAX,
+    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9 => os.PATH_MAX,
     // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
     // If it would require 4 UTF-8 bytes, then there would be a surrogate
     // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
@@ -59,7 +59,7 @@ pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
 /// (depending on the platform) this assumption may not hold for every configuration.
 /// The byte count does not include a null sentinel byte.
 pub const MAX_NAME_BYTES = switch (builtin.os.tag) {
-    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris => os.NAME_MAX,
+    .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .illumos => os.NAME_MAX,
     // Haiku's NAME_MAX includes the null terminator, so subtract one.
     .haiku => os.NAME_MAX - 1,
     // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
@@ -325,7 +325,7 @@ pub const IterableDir = struct {
     const IteratorError = error{ AccessDenied, SystemResources } || os.UnexpectedError;
 
     pub const Iterator = switch (builtin.os.tag) {
-        .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => struct {
+        .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => struct {
             dir: Dir,
             seek: i64,
             buf: [1024]u8, // TODO align(@alignOf(os.system.dirent)),
@@ -343,7 +343,7 @@ pub const IterableDir = struct {
                 switch (builtin.os.tag) {
                     .macos, .ios => return self.nextDarwin(),
                     .freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
-                    .solaris => return self.nextSolaris(),
+                    .solaris, .illumos => return self.nextSolaris(),
                     else => @compileError("unimplemented"),
                 }
             }
@@ -897,6 +897,7 @@ pub const IterableDir = struct {
             .dragonfly,
             .openbsd,
             .solaris,
+            .illumos,
             => return Iterator{
                 .dir = self.dir,
                 .seek = 0,
@@ -1840,7 +1841,7 @@ pub const Dir = struct {
             error.AccessDenied => |e| switch (builtin.os.tag) {
                 // non-Linux POSIX systems return EPERM when trying to delete a directory, so
                 // we need to handle that case specifically and translate the error
-                .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris => {
+                .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => {
                     // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
                     const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT.SYMLINK_NOFOLLOW) catch return e;
                     const is_dir = fstat.mode & os.S.IFMT == os.S.IFDIR;
@@ -3004,7 +3005,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
     }
     switch (builtin.os.tag) {
         .linux => return os.readlinkZ("/proc/self/exe", out_buffer),
-        .solaris => return os.readlinkZ("/proc/self/path/a.out", out_buffer),
+        .solaris, .illumos => return os.readlinkZ("/proc/self/path/a.out", out_buffer),
         .freebsd, .dragonfly => {
             var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC, os.KERN.PROC_PATHNAME, -1 };
             var out_len: usize = out_buffer.len;
lib/std/os.zig
@@ -33,6 +33,7 @@ pub const haiku = std.c;
 pub const netbsd = std.c;
 pub const openbsd = std.c;
 pub const solaris = std.c;
+pub const illumos = std.c;
 pub const linux = @import("os/linux.zig");
 pub const plan9 = @import("os/plan9.zig");
 pub const uefi = @import("os/uefi.zig");
@@ -1821,7 +1822,7 @@ pub fn execveZ(
                 .BADARCH => return error.InvalidExe,
                 else => return unexpectedErrno(err),
             },
-            .linux, .solaris => switch (err) {
+            .linux => switch (err) {
                 .LIBBAD => return error.InvalidExe,
                 else => return unexpectedErrno(err),
             },
@@ -5226,6 +5227,7 @@ pub fn isGetFdPathSupportedOnTarget(os: std.Target.Os) bool {
         .macos, .ios, .watchos, .tvos,
         .linux,
         .solaris,
+        .illumos,
         .freebsd,
         => true,
         // zig fmt: on
@@ -5280,7 +5282,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
             };
             return target;
         },
-        .solaris => {
+        .solaris, .illumos => {
             var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined;
             const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/path/{d}", .{fd}) catch unreachable;
 
lib/std/process.zig
@@ -959,7 +959,18 @@ pub const UserInfo = struct {
 /// POSIX function which gets a uid from username.
 pub fn getUserInfo(name: []const u8) !UserInfo {
     return switch (builtin.os.tag) {
-        .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd, .haiku, .solaris => posixGetUserInfo(name),
+        .linux,
+        .macos,
+        .watchos,
+        .tvos,
+        .ios,
+        .freebsd,
+        .netbsd,
+        .openbsd,
+        .haiku,
+        .solaris,
+        .illumos,
+        => posixGetUserInfo(name),
         else => @compileError("Unsupported OS"),
     };
 }
lib/std/target.zig
@@ -58,6 +58,7 @@ pub const Target = struct {
             glsl450,
             vulkan,
             plan9,
+            illumos,
             other,
 
             pub inline fn isDarwin(tag: Tag) bool {
@@ -74,6 +75,10 @@ pub const Target = struct {
                 };
             }
 
+            pub inline fn isSolarish(tag: Tag) bool {
+                return tag == .solaris or tag == .illumos;
+            }
+
             pub fn dynamicLibSuffix(tag: Tag) [:0]const u8 {
                 if (tag.isDarwin()) {
                     return ".dylib";
@@ -326,7 +331,7 @@ pub const Target = struct {
                             .max = .{ .major = 6, .minor = 4, .patch = 0 },
                         },
                     },
-                    .solaris => return .{
+                    .solaris, .illumos => return .{
                         .semver = .{
                             .min = .{ .major = 5, .minor = 11, .patch = 0 },
                             .max = .{ .major = 5, .minor = 11, .patch = 0 },
@@ -376,6 +381,7 @@ pub const Target = struct {
                 .openbsd,
                 .dragonfly,
                 .solaris,
+                .illumos,
                 => return TaggedVersionRange{ .semver = self.version_range.semver },
 
                 else => return .none,
@@ -409,6 +415,7 @@ pub const Target = struct {
                 .openbsd,
                 .haiku,
                 .solaris,
+                .illumos,
                 => true,
 
                 .linux,
@@ -569,6 +576,7 @@ pub const Target = struct {
                 .shadermodel,
                 .liteos, // TODO: audit this
                 .solaris,
+                .illumos,
                 => return .none,
             }
         }
@@ -1575,7 +1583,7 @@ pub const Target = struct {
             .netbsd => return copy(&result, "/libexec/ld.elf_so"),
             .openbsd => return copy(&result, "/usr/libexec/ld.so"),
             .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
-            .solaris => return copy(&result, "/usr/lib/amd64/ld.so.1"),
+            .solaris, .illumos => return copy(&result, "/usr/lib/64/ld.so.1"),
             .linux => switch (self.cpu.arch) {
                 .x86,
                 .sparc,
@@ -2115,6 +2123,7 @@ pub const Target = struct {
             .emscripten,
             .plan9,
             .solaris,
+            .illumos,
             .haiku,
             .ananas,
             .fuchsia,
lib/std/Thread.zig
@@ -43,7 +43,7 @@ pub const max_name_len = switch (target.os.tag) {
     .freebsd => 15,
     .openbsd => 23,
     .dragonfly => 1023,
-    .solaris => 31,
+    .solaris, .illumos => 31,
     else => 0,
 };
 
@@ -123,7 +123,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
                 else => |e| return os.unexpectedErrno(e),
             }
         },
-        .netbsd, .solaris => if (use_pthreads) {
+        .netbsd, .solaris, .illumos => if (use_pthreads) {
             const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr, null);
             switch (err) {
                 .SUCCESS => return,
@@ -229,7 +229,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
                 else => |e| return os.unexpectedErrno(e),
             }
         },
-        .netbsd, .solaris => if (use_pthreads) {
+        .netbsd, .solaris, .illumos => if (use_pthreads) {
             const err = std.c.pthread_getname_np(self.getHandle(), buffer.ptr, max_name_len + 1);
             switch (err) {
                 .SUCCESS => return std.mem.sliceTo(buffer, 0),
@@ -636,7 +636,7 @@ const PosixThreadImpl = struct {
                 };
                 return @as(usize, @intCast(count));
             },
-            .solaris => {
+            .solaris, .illumos => {
                 // The "proper" way to get the cpu count would be to query
                 // /dev/kstat via ioctls, and traverse a linked list for each
                 // cpu.
src/codegen/llvm.zig
@@ -120,7 +120,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
         .lv2 => "lv2",
         .netbsd => "netbsd",
         .openbsd => "openbsd",
-        .solaris => "solaris",
+        .solaris, .illumos => "solaris",
         .windows => "windows",
         .zos => "zos",
         .haiku => "haiku",
@@ -231,7 +231,7 @@ pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType {
         .macos => .MacOSX,
         .netbsd => .NetBSD,
         .openbsd => .OpenBSD,
-        .solaris => .Solaris,
+        .solaris, .illumos => .Solaris,
         .zos => .ZOS,
         .haiku => .Haiku,
         .minix => .Minix,
src/link/Elf.zig
@@ -3818,7 +3818,7 @@ const CsuObjects = struct {
                     .static_pie  => result.set( "start_dyn.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ),
                     // zig fmt: on
                 },
-                .solaris => switch (mode) {
+                .solaris, .illumos => switch (mode) {
                     // zig fmt: off
                     .dynamic_lib => result.set( null,     "crti.o", null, null, "crtn.o" ),
                     .dynamic_exe,
src/crash_report.zig
@@ -190,7 +190,7 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
         .freebsd, .macos => @intFromPtr(info.addr),
         .netbsd => @intFromPtr(info.info.reason.fault.addr),
         .openbsd => @intFromPtr(info.data.fault.addr),
-        .solaris => @intFromPtr(info.reason.fault.addr),
+        .solaris, .illumos => @intFromPtr(info.reason.fault.addr),
         else => @compileError("TODO implement handleSegfaultPosix for new POSIX OS"),
     };
 
src/libc_installation.zig
@@ -213,9 +213,8 @@ pub const LibCInstallation = struct {
             try self.findNativeIncludeDirPosix(args);
             try self.findNativeCrtBeginDirHaiku(args);
             self.crt_dir = try args.allocator.dupeZ(u8, "/system/develop/lib");
-        } else if (builtin.target.os.tag == .solaris) {
-            // There is only one libc in illumos, and its headers and
-            // libraries are always in the same spot.
+        } else if (builtin.target.os.tag.isSolarish()) {
+            // There is only one libc, and its headers/libraries are always in the same spot.
             self.include_dir = try args.allocator.dupeZ(u8, "/usr/include");
             self.sys_include_dir = try args.allocator.dupeZ(u8, "/usr/include");
             self.crt_dir = try args.allocator.dupeZ(u8, "/usr/lib/64");
src/libcxx.zig
@@ -150,7 +150,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
 
         if (std.mem.startsWith(u8, cxx_src, "src/support/win32/") and target.os.tag != .windows)
             continue;
-        if (std.mem.startsWith(u8, cxx_src, "src/support/solaris/") and target.os.tag != .solaris)
+        if (std.mem.startsWith(u8, cxx_src, "src/support/solaris/") and !target.os.tag.isSolarish())
             continue;
         if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos)
             continue;
src/target.zig
@@ -218,7 +218,7 @@ pub fn hasValgrindSupport(target: std.Target) bool {
         .aarch64_32,
         .aarch64_be,
         => {
-            return target.os.tag == .linux or target.os.tag == .solaris or
+            return target.os.tag == .linux or target.os.tag == .solaris or target.os.tag == .illumos or
                 (target.os.tag == .windows and target.abi != .msvc);
         },
         else => return false,
@@ -493,7 +493,7 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
             "-lc",
             "-lutil",
         },
-        .solaris => &[_][]const u8{
+        .solaris, .illumos => &[_][]const u8{
             "-lm",
             "-lsocket",
             "-lnsl",
build.zig
@@ -670,9 +670,9 @@ fn addCmakeCfgOptionsToExe(
                     try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
                 }
             },
-            .solaris => {
-                    try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
-                    try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
+            .solaris, .illumos => {
+                try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes);
+                try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes);
             },
             else => {},
         }
CMakeLists.txt
@@ -1,4 +1,5 @@
 cmake_minimum_required(VERSION 3.5)
+include(CheckSymbolExists)
 
 if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
@@ -709,12 +710,17 @@ string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" ZIG_HOST_TARGET_OS)
 if(ZIG_HOST_TARGET_OS STREQUAL "darwin")
   set(ZIG_HOST_TARGET_OS "macos")
 elseif(ZIG_HOST_TARGET_OS STREQUAL "sunos")
-  set(ZIG_HOST_TARGET_OS "solaris")
+  check_symbol_exists(__illumos__ "" ZIG_HOST_TARGET_HAS_ILLUMOS_MACRO)
+  if (ZIG_HOST_TARGET_HAS_ILLUMOS_MACRO)
+    set(ZIG_HOST_TARGET_OS "illumos")
+  else()
+    set(ZIG_HOST_TARGET_OS "solaris")
+  endif()
 endif()
 
 string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" ZIG_HOST_TARGET_ARCH)
 if(ZIG_HOST_TARGET_ARCH MATCHES "^i[3-9]86$")
-  if (ZIG_HOST_TARGET_OS STREQUAL "solaris")
+  if (ZIG_HOST_TARGET_OS MATCHES "(solaris|illumos)")
     set(ZIG_HOST_TARGET_ARCH "x86_64")
   else()
     set(ZIG_HOST_TARGET_ARCH "x86")
@@ -730,7 +736,6 @@ elseif(ZIG_HOST_TARGET_ARCH STREQUAL "armv7b")
 endif()
 string(REGEX REPLACE "^((arm|thumb)(hf?)?)el$" "\\1" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")
 if(ZIG_HOST_TARGET_ARCH MATCHES "^arm(hf?)?(eb)?$")
-  include(CheckSymbolExists)
   check_symbol_exists(__thumb__ "" ZIG_HOST_TARGET_DEFAULTS_TO_THUMB)
   if(ZIG_HOST_TARGET_DEFAULTS_TO_THUMB)
     string(REGEX REPLACE "^arm" "thumb" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")