about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-16 00:39:25 +0200
committerGitHub <noreply@github.com>2020-04-16 00:39:25 +0200
commit905a92031371629d28f02bc5eb04415c627c4c9f (patch)
tree3ad9cc08237cbcbe6f678e0ae18df1cb2e1c3f74
parent9433d899a7be210293c88ba3672c699fb00ca725 (diff)
parentdda5c97675b4f5b1f6fdab64606c8a1f21021b0a (diff)
downloadrust-905a92031371629d28f02bc5eb04415c627c4c9f.tar.gz
rust-905a92031371629d28f02bc5eb04415c627c4c9f.zip
Rollup merge of #71145 - pfmooney:illumos-triple, r=nagisa
Add illumos triple

This fixes rust-lang/rust#55553 and adds support for `illumos` as a `target_os` on `x86_64`.  In addition to the compile spec and libstd additions, several library dependencies have been bumped in order to permit working builds of cargo and rustup for the new target.

Work originally started by @jasonbking, with subsequent additions by @pfmooney and @jclulow.
-rw-r--r--Cargo.lock8
-rw-r--r--src/librustc_codegen_ssa/Cargo.toml2
-rw-r--r--src/librustc_codegen_ssa/back/link.rs2
-rw-r--r--src/librustc_target/spec/illumos_base.rs48
-rw-r--r--src/librustc_target/spec/mod.rs3
-rw-r--r--src/librustc_target/spec/x86_64_unknown_illumos.rs24
-rw-r--r--src/librustdoc/clean/cfg.rs1
-rw-r--r--src/libstd/build.rs8
-rw-r--r--src/libstd/f64.rs2
-rw-r--r--src/libstd/os/illumos/fs.rs118
-rw-r--r--src/libstd/os/illumos/mod.rs6
-rw-r--r--src/libstd/os/illumos/raw.rs74
-rw-r--r--src/libstd/os/mod.rs2
-rw-r--r--src/libstd/sys/unix/alloc.rs14
-rw-r--r--src/libstd/sys/unix/args.rs1
-rw-r--r--src/libstd/sys/unix/env.rs11
-rw-r--r--src/libstd/sys/unix/fd.rs2
-rw-r--r--src/libstd/sys/unix/fs.rs34
-rw-r--r--src/libstd/sys/unix/mod.rs2
-rw-r--r--src/libstd/sys/unix/net.rs8
-rw-r--r--src/libstd/sys/unix/os.rs4
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs5
-rw-r--r--src/libstd/sys/unix/thread.rs4
-rw-r--r--src/libstd/sys_common/net.rs4
-rw-r--r--src/libtest/helpers/concurrency.rs1
-rw-r--r--src/libunwind/build.rs2
-rw-r--r--src/tools/build-manifest/src/main.rs1
-rw-r--r--src/tools/compiletest/src/util.rs1
28 files changed, 370 insertions, 22 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e229448df04..55f986b6008 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1786,9 +1786,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.66"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
+checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -4661,9 +4661,9 @@ checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
 
 [[package]]
 name = "socket2"
-version = "0.3.11"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85"
+checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
 dependencies = [
  "cfg-if",
  "libc",
diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
index 717e32d4a0d..d9620a21d37 100644
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ b/src/librustc_codegen_ssa/Cargo.toml
@@ -15,7 +15,7 @@ cc = "1.0.1"
 num_cpus = "1.0"
 memmap = "0.7"
 log = "0.4.5"
-libc = "0.2.44"
+libc = "0.2.50"
 jobserver = "0.1.11"
 tempfile = "3.1"
 
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index d58d9b91c73..4c66d901e7a 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -761,7 +761,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
                         }
                     }
                     LinkerFlavor::Gcc => {
-                        if cfg!(target_os = "solaris") {
+                        if cfg!(any(target_os = "solaris", target_os = "illumos")) {
                             // On historical Solaris systems, "cc" may have
                             // been Sun Studio, which is not flag-compatible
                             // with "gcc".  This history casts a long shadow,
diff --git a/src/librustc_target/spec/illumos_base.rs b/src/librustc_target/spec/illumos_base.rs
new file mode 100644
index 00000000000..35ac346fb3f
--- /dev/null
+++ b/src/librustc_target/spec/illumos_base.rs
@@ -0,0 +1,48 @@
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut late_link_args = LinkArgs::new();
+    late_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec![
+            // LLVM will insert calls to the stack protector functions
+            // "__stack_chk_fail" and "__stack_chk_guard" into code in native
+            // object files.  Some platforms include these symbols directly in
+            // libc, but at least historically these have been provided in
+            // libssp.so on illumos and Solaris systems.
+            "-lssp".to_string(),
+        ],
+    );
+
+    TargetOptions {
+        dynamic_linking: true,
+        executables: true,
+        has_rpath: true,
+        target_family: Some("unix".to_string()),
+        is_like_solaris: true,
+        limit_rdylib_exports: false, // Linker doesn't support this
+        eliminate_frame_pointer: false,
+        late_link_args,
+
+        // While we support ELF TLS, rust requires a way to register
+        // cleanup handlers (in C, this would be something along the lines of:
+        // void register_callback(void (*fn)(void *), void *arg);
+        // (see src/libstd/sys/unix/fast_thread_local.rs) that is currently
+        // missing in illumos.  For now at least, we must fallback to using
+        // pthread_{get,set}specific.
+        //has_elf_tls: true,
+
+        // FIXME: Currently, rust is invoking cc to link, which ends up
+        // causing these to get included twice.  We should eventually transition
+        // to having rustc invoke ld directly, in which case these will need to
+        // be uncommented.
+        //
+        // We want XPG6 behavior from libc and libm.  See standards(5)
+        //pre_link_objects_exe: vec![
+        //    "/usr/lib/amd64/values-Xc.o".to_string(),
+        //    "/usr/lib/amd64/values-xpg6.o".to_string(),
+        //],
+        ..Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 6ff812754aa..8f3097ad423 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -55,6 +55,7 @@ mod fuchsia_base;
 mod haiku_base;
 mod hermit_base;
 mod hermit_kernel_base;
+mod illumos_base;
 mod l4re_base;
 mod linux_base;
 mod linux_kernel_base;
@@ -438,6 +439,8 @@ supported_targets! {
     ("x86_64-sun-solaris", "x86_64-pc-solaris", x86_64_sun_solaris),
     ("sparcv9-sun-solaris", sparcv9_sun_solaris),
 
+    ("x86_64-unknown-illumos", x86_64_unknown_illumos),
+
     ("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu),
     ("i686-pc-windows-gnu", i686_pc_windows_gnu),
     ("i686-uwp-windows-gnu", i686_uwp_windows_gnu),
diff --git a/src/librustc_target/spec/x86_64_unknown_illumos.rs b/src/librustc_target/spec/x86_64_unknown_illumos.rs
new file mode 100644
index 00000000000..8d461f67397
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_unknown_illumos.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::illumos_base::opts();
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]);
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+
+    Ok(Target {
+        // LLVM does not currently have a separate illumos target,
+        // so we still pass Solaris to it
+        llvm_target: "x86_64-pc-solaris".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        arch: "x86_64".to_string(),
+        target_os: "illumos".to_string(),
+        target_env: String::new(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: base,
+    })
+}
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 775d600fc3d..57d499e38a7 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -360,6 +360,7 @@ impl<'a> fmt::Display for Html<'a> {
                         "fuchsia" => "Fuchsia",
                         "haiku" => "Haiku",
                         "hermit" => "HermitCore",
+                        "illumos" => "illumos",
                         "ios" => "iOS",
                         "l4re" => "L4Re",
                         "linux" => "Linux",
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 8db7bc12cd3..743a1778fbd 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -25,6 +25,14 @@ fn main() {
         println!("cargo:rustc-link-lib=posix4");
         println!("cargo:rustc-link-lib=pthread");
         println!("cargo:rustc-link-lib=resolv");
+    } else if target.contains("illumos") {
+        println!("cargo:rustc-link-lib=socket");
+        println!("cargo:rustc-link-lib=posix4");
+        println!("cargo:rustc-link-lib=pthread");
+        println!("cargo:rustc-link-lib=resolv");
+        println!("cargo:rustc-link-lib=nsl");
+        // Use libumem for the (malloc-compatible) allocator
+        println!("cargo:rustc-link-lib=umem");
     } else if target.contains("apple-darwin") {
         println!("cargo:rustc-link-lib=System");
 
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index ff222fc8539..5cf9cb73d4b 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -919,7 +919,7 @@ impl f64 {
     // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
     // of expected NaN).
     fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
-        if !cfg!(target_os = "solaris") {
+        if !cfg!(any(target_os = "solaris", target_os = "illumos")) {
             log_fn(self)
         } else {
             if self.is_finite() {
diff --git a/src/libstd/os/illumos/fs.rs b/src/libstd/os/illumos/fs.rs
new file mode 100644
index 00000000000..2abbf1fa9fa
--- /dev/null
+++ b/src/libstd/os/illumos/fs.rs
@@ -0,0 +1,118 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use libc;
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+#[allow(deprecated)]
+use crate::os::illumos::raw;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Gain a reference to the underlying `stat` structure which contains
+    /// the raw information returned by the OS.
+    ///
+    /// The contents of the returned `stat` are **not** consistent across
+    /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
+    /// cross-Unix abstractions contained within the raw stat.
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    #[rustc_deprecated(
+        since = "1.8.0",
+        reason = "deprecated in favor of the accessor methods of this trait"
+    )]
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat;
+
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat {
+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
+    }
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_atime_nsec as i64
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime_nsec as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime_nsec as i64
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+}
diff --git a/src/libstd/os/illumos/mod.rs b/src/libstd/os/illumos/mod.rs
new file mode 100644
index 00000000000..e61926f8935
--- /dev/null
+++ b/src/libstd/os/illumos/mod.rs
@@ -0,0 +1,6 @@
+//! illumos-specific definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod fs;
+pub mod raw;
diff --git a/src/libstd/os/illumos/raw.rs b/src/libstd/os/illumos/raw.rs
new file mode 100644
index 00000000000..88c832ae7c7
--- /dev/null
+++ b/src/libstd/os/illumos/raw.rs
@@ -0,0 +1,74 @@
+//! illumos-specific raw type definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![rustc_deprecated(
+    since = "1.8.0",
+    reason = "these type aliases are no longer supported by the standard library, the `libc` \
+    crate on crates.io should be used instead for the correct definitions"
+)]
+#![allow(deprecated)]
+
+use crate::os::raw::c_long;
+use crate::os::unix::raw::{gid_t, uid_t};
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blkcnt_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blksize_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type dev_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type fflags_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type ino_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type mode_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type nlink_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type off_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type time_t = i64;
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = u32;
+
+#[repr(C)]
+#[derive(Clone)]
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub struct stat {
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_dev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ino: ino_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mode: mode_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_nlink: nlink_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_uid: uid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gid: gid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_rdev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_size: off_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blksize: blksize_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blocks: blkcnt_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub __unused: [u8; 16],
+}
diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs
index 0fa4a1d2353..fd6ee088e96 100644
--- a/src/libstd/os/mod.rs
+++ b/src/libstd/os/mod.rs
@@ -52,6 +52,8 @@ pub mod freebsd;
 pub mod fuchsia;
 #[cfg(target_os = "haiku")]
 pub mod haiku;
+#[cfg(target_os = "illumos")]
+pub mod illumos;
 #[cfg(target_os = "ios")]
 pub mod ios;
 #[cfg(target_os = "macos")]
diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs
index 77417e41331..8e193935460 100644
--- a/src/libstd/sys/unix/alloc.rs
+++ b/src/libstd/sys/unix/alloc.rs
@@ -52,7 +52,12 @@ unsafe impl GlobalAlloc for System {
     }
 }
 
-#[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))]
+#[cfg(any(
+    target_os = "android",
+    target_os = "illumos",
+    target_os = "redox",
+    target_os = "solaris"
+))]
 #[inline]
 unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     // On android we currently target API level 9 which unfortunately
@@ -75,7 +80,12 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     libc::memalign(layout.align(), layout.size()) as *mut u8
 }
 
-#[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))]
+#[cfg(not(any(
+    target_os = "android",
+    target_os = "illumos",
+    target_os = "redox",
+    target_os = "solaris"
+)))]
 #[inline]
 unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     let mut out = ptr::null_mut();
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index 09acc3f6e3e..4c3e8542d57 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -65,6 +65,7 @@ impl DoubleEndedIterator for Args {
     target_os = "netbsd",
     target_os = "openbsd",
     target_os = "solaris",
+    target_os = "illumos",
     target_os = "emscripten",
     target_os = "haiku",
     target_os = "l4re",
diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs
index 984bcfa4509..7f5e9b04dba 100644
--- a/src/libstd/sys/unix/env.rs
+++ b/src/libstd/sys/unix/env.rs
@@ -97,6 +97,17 @@ pub mod os {
     pub const EXE_EXTENSION: &str = "";
 }
 
+#[cfg(target_os = "illumos")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "illumos";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
+}
+
 #[cfg(target_os = "haiku")]
 pub mod os {
     pub const FAMILY: &str = "unix";
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index 8a99836912a..1bba56e334a 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -153,6 +153,7 @@ impl FileDesc {
     #[cfg(not(any(
         target_env = "newlib",
         target_os = "solaris",
+        target_os = "illumos",
         target_os = "emscripten",
         target_os = "fuchsia",
         target_os = "l4re",
@@ -169,6 +170,7 @@ impl FileDesc {
     #[cfg(any(
         target_env = "newlib",
         target_os = "solaris",
+        target_os = "illumos",
         target_os = "emscripten",
         target_os = "fuchsia",
         target_os = "l4re",
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index ab2a871b92d..a233aa47dff 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -22,6 +22,7 @@ use libc::fstatat64;
     target_os = "linux",
     target_os = "emscripten",
     target_os = "solaris",
+    target_os = "illumos",
     target_os = "l4re",
     target_os = "fuchsia",
     target_os = "redox"
@@ -200,7 +201,12 @@ pub struct DirEntry {
     // on Solaris and Fuchsia because a) it uses a zero-length
     // array to store the name, b) its lifetime between readdir
     // calls is not guaranteed.
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
+    #[cfg(any(
+        target_os = "solaris",
+        target_os = "illumos",
+        target_os = "fuchsia",
+        target_os = "redox"
+    ))]
     name: Box<[u8]>,
 }
 
@@ -403,7 +409,12 @@ impl fmt::Debug for ReadDir {
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
 
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
+    #[cfg(any(
+        target_os = "solaris",
+        target_os = "fuchsia",
+        target_os = "redox",
+        target_os = "illumos"
+    ))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         use crate::slice;
 
@@ -441,7 +452,12 @@ impl Iterator for ReadDir {
         }
     }
 
-    #[cfg(not(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox")))]
+    #[cfg(not(any(
+        target_os = "solaris",
+        target_os = "fuchsia",
+        target_os = "redox",
+        target_os = "illumos"
+    )))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         if self.end_of_stream {
             return None;
@@ -514,12 +530,12 @@ impl DirEntry {
         lstat(&self.path())
     }
 
-    #[cfg(any(target_os = "solaris", target_os = "haiku"))]
+    #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "haiku"))]
     pub fn file_type(&self) -> io::Result<FileType> {
         lstat(&self.path()).map(|m| m.file_type())
     }
 
-    #[cfg(not(any(target_os = "solaris", target_os = "haiku")))]
+    #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "haiku")))]
     pub fn file_type(&self) -> io::Result<FileType> {
         match self.entry.d_type {
             libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }),
@@ -540,6 +556,7 @@ impl DirEntry {
         target_os = "emscripten",
         target_os = "android",
         target_os = "solaris",
+        target_os = "illumos",
         target_os = "haiku",
         target_os = "l4re",
         target_os = "fuchsia",
@@ -586,7 +603,12 @@ impl DirEntry {
     fn name_bytes(&self) -> &[u8] {
         unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() }
     }
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
+    #[cfg(any(
+        target_os = "solaris",
+        target_os = "illumos",
+        target_os = "fuchsia",
+        target_os = "redox"
+    ))]
     fn name_bytes(&self) -> &[u8] {
         &*self.name
     }
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index fbcb006ecdf..0154609d939 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -17,6 +17,8 @@ pub use crate::os::freebsd as platform;
 pub use crate::os::fuchsia as platform;
 #[cfg(all(not(doc), target_os = "haiku"))]
 pub use crate::os::haiku as platform;
+#[cfg(all(not(doc), target_os = "illumos"))]
+pub use crate::os::illumos as platform;
 #[cfg(all(not(doc), target_os = "ios"))]
 pub use crate::os::ios as platform;
 #[cfg(all(not(doc), target_os = "l4re"))]
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index b37675e0a0a..d18c22b0573 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -322,11 +322,19 @@ impl Socket {
         Ok(raw != 0)
     }
 
+    #[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         let mut nonblocking = nonblocking as libc::c_int;
         cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(drop)
     }
 
+    #[cfg(any(target_os = "solaris", target_os = "illumos"))]
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        // FIONBIO is inadequate for sockets on illumos/Solaris, so use the
+        // fcntl(F_[GS]ETFL)-based method provided by FileDesc instead.
+        self.0.set_nonblocking(nonblocking)
+    }
+
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
         if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 91f7d1524cc..a9cd5094997 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -54,7 +54,7 @@ extern "C" {
         ),
         link_name = "__errno"
     )]
-    #[cfg_attr(target_os = "solaris", link_name = "___errno")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
     #[cfg_attr(
         any(target_os = "macos", target_os = "ios", target_os = "freebsd"),
         link_name = "__error"
@@ -357,7 +357,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     }
 }
 
-#[cfg(any(target_os = "solaris"))]
+#[cfg(any(target_os = "solaris", target_os = "illumos"))]
 pub fn current_exe() -> io::Result<PathBuf> {
     extern "C" {
         fn getexecname() -> *const c_char;
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 2626ca37cf8..5e103578350 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -33,6 +33,7 @@ impl Drop for Handler {
     target_os = "dragonfly",
     target_os = "freebsd",
     target_os = "solaris",
+    target_os = "illumos",
     all(target_os = "netbsd", not(target_vendor = "rumprun")),
     target_os = "openbsd"
 ))]
@@ -162,7 +163,8 @@ mod imp {
         target_os = "freebsd",
         target_os = "netbsd",
         target_os = "openbsd",
-        target_os = "solaris"
+        target_os = "solaris",
+        target_os = "illumos"
     ))]
     unsafe fn get_stack() -> libc::stack_t {
         libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
@@ -214,6 +216,7 @@ mod imp {
     target_os = "dragonfly",
     target_os = "freebsd",
     target_os = "solaris",
+    target_os = "illumos",
     all(target_os = "netbsd", not(target_vendor = "rumprun")),
     target_os = "openbsd"
 )))]
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index aab5a92a7ad..895ea48e2b4 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -132,7 +132,7 @@ impl Thread {
         }
     }
 
-    #[cfg(target_os = "solaris")]
+    #[cfg(any(target_os = "solaris", target_os = "illumos"))]
     pub fn set_name(name: &CStr) {
         weak! {
             fn pthread_setname_np(
@@ -155,7 +155,7 @@ impl Thread {
         target_os = "redox"
     ))]
     pub fn set_name(_name: &CStr) {
-        // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
+        // Newlib, Haiku, and Emscripten have no way to set a thread name.
     }
     #[cfg(target_os = "fuchsia")]
     pub fn set_name(_name: &CStr) {
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index 135e8308afa..cdd3d2edf1f 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -17,7 +17,7 @@ cfg_if::cfg_if! {
     if #[cfg(any(
         target_os = "dragonfly", target_os = "freebsd",
         target_os = "ios", target_os = "macos",
-        target_os = "openbsd", target_os = "netbsd",
+        target_os = "openbsd", target_os = "netbsd", target_os = "illumos",
         target_os = "solaris", target_os = "haiku", target_os = "l4re"))] {
         use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
         use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
@@ -43,7 +43,7 @@ cfg_if::cfg_if! {
     if #[cfg(any(
         target_os = "dragonfly", target_os = "freebsd",
         target_os = "openbsd", target_os = "netbsd",
-        target_os = "solaris"))] {
+        target_os = "solaris", target_os = "illumos"))] {
         use libc::c_uchar;
         type IpV4MultiCastType = c_uchar;
     } else {
diff --git a/src/libtest/helpers/concurrency.rs b/src/libtest/helpers/concurrency.rs
index 6b0c8a8af32..e8f3820558a 100644
--- a/src/libtest/helpers/concurrency.rs
+++ b/src/libtest/helpers/concurrency.rs
@@ -77,6 +77,7 @@ pub fn get_concurrency() -> usize {
         target_os = "linux",
         target_os = "macos",
         target_os = "solaris",
+        target_os = "illumos",
     ))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs
index 0628e5d2fc0..c8d2419ab45 100644
--- a/src/libunwind/build.rs
+++ b/src/libunwind/build.rs
@@ -30,6 +30,8 @@ fn main() {
         }
     } else if target.contains("solaris") {
         println!("cargo:rustc-link-lib=gcc_s");
+    } else if target.contains("illumos") {
+        println!("cargo:rustc-link-lib=gcc_s");
     } else if target.contains("dragonfly") {
         println!("cargo:rustc-link-lib=gcc_pic");
     } else if target.contains("pc-windows-gnu") {
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index f075d3e22d6..6de07d3e5cf 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -139,6 +139,7 @@ static TARGETS: &[&str] = &[
     "x86_64-pc-solaris",
     "x86_64-unknown-cloudabi",
     "x86_64-unknown-freebsd",
+    "x86_64-unknown-illumos",
     "x86_64-unknown-linux-gnu",
     "x86_64-unknown-linux-gnux32",
     "x86_64-unknown-linux-musl",
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 2663b3d160a..c61bee0f8d9 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -21,6 +21,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[
     ("fuchsia", "fuchsia"),
     ("haiku", "haiku"),
     ("hermit", "hermit"),
+    ("illumos", "illumos"),
     ("ios", "ios"),
     ("l4re", "l4re"),
     ("linux", "linux"),