From 92b24f5f632b16aec24a62944b33fc384afbc584 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 2 Mar 2019 13:29:16 +0100 Subject: [PATCH 1/8] add HermitCore support even if it doesn't have a UNIX interface --- src/hermit/aarch64.rs | 2 + src/hermit/mod.rs | 85 +++++++++++++++++++++++++++++++++++++++++++ src/hermit/x86_64.rs | 2 + src/lib.rs | 3 ++ 4 files changed, 92 insertions(+) create mode 100644 src/hermit/aarch64.rs create mode 100644 src/hermit/mod.rs create mode 100644 src/hermit/x86_64.rs diff --git a/src/hermit/aarch64.rs b/src/hermit/aarch64.rs new file mode 100644 index 0000000000000..1a92e3b4fa341 --- /dev/null +++ b/src/hermit/aarch64.rs @@ -0,0 +1,2 @@ +pub type c_char = u8; +pub type wchar_t = u32; diff --git a/src/hermit/mod.rs b/src/hermit/mod.rs new file mode 100644 index 0000000000000..3e28ef50c0f8b --- /dev/null +++ b/src/hermit/mod.rs @@ -0,0 +1,85 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// libc port for HermitCore (https://hermitcore.org) +// +// Ported by Colin Fink +// and Stefan Lankes + +pub type int8_t = i8; +pub type int16_t = i16; +pub type int32_t = i32; +pub type int64_t = i64; +pub type uint8_t = u8; +pub type uint16_t = u16; +pub type uint32_t = u32; +pub type uint64_t = u64; + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; + +pub type wchar_t = i32; +pub type wint_t = u32; +pub type wctype_t = i64; + +pub type regoff_t = size_t; +pub type off_t = c_long; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else { + // Unknown target_arch + } +} + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} diff --git a/src/hermit/x86_64.rs b/src/hermit/x86_64.rs new file mode 100644 index 0000000000000..76ec3ce823e8f --- /dev/null +++ b/src/hermit/x86_64.rs @@ -0,0 +1,2 @@ +pub type c_char = i8; +pub type wchar_t = i32; diff --git a/src/lib.rs b/src/lib.rs index 72e93aaf62def..b2e8eb0dc9103 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -232,6 +232,9 @@ cfg_if! { } else if #[cfg(unix)] { mod unix; pub use unix::*; + } else if #[cfg(target_os = "hermit")] { + mod redox; + pub use hermit::*; } else if #[cfg(target_env = "sgx")] { mod sgx; pub use sgx::*; From 585d45a1f315818d6c4fae985e5ce732525f8f71 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 2 Mar 2019 20:18:52 +0100 Subject: [PATCH 2/8] remove redefinition of c_char and w_char, remove typo --- src/hermit/mod.rs | 2 -- src/lib.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hermit/mod.rs b/src/hermit/mod.rs index 3e28ef50c0f8b..3e15175a585c5 100644 --- a/src/hermit/mod.rs +++ b/src/hermit/mod.rs @@ -41,11 +41,9 @@ pub type intptr_t = isize; pub type uintptr_t = usize; pub type ssize_t = isize; -pub type c_char = i8; pub type c_long = i64; pub type c_ulong = u64; -pub type wchar_t = i32; pub type wint_t = u32; pub type wctype_t = i64; diff --git a/src/lib.rs b/src/lib.rs index 6969d350d7235..019f072e1784a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -107,7 +107,7 @@ cfg_if! { mod unix; pub use unix::*; } else if #[cfg(target_os = "hermit")] { - mod redox; + mod hermit; pub use hermit::*; } else if #[cfg(target_env = "sgx")] { mod sgx; From 682b8af2867288f27f181dd20720419b537ef502 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 3 Mar 2019 00:39:31 +0100 Subject: [PATCH 3/8] add target "hermit" to build.sh --- ci/build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/build.sh b/ci/build.sh index 74727a3313a1f..b830ceb0f22b4 100644 --- a/ci/build.sh +++ b/ci/build.sh @@ -167,7 +167,9 @@ done # FIXME: https://github.com/rust-lang/rust/issues/58564 # sparc-unknown-linux-gnu RUST_LINUX_NO_CORE_TARGETS="\ +x86_64-unknown-hermit \ x86_64-unknown-dragonfly \ +aarch64-unknown-hermit \ aarch64-pc-windows-msvc \ aarch64-unknown-cloudabi \ armebv7r-none-eabi \ From 52bb1524443f7fe7152b86b9ef85284a586bd600 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 3 Mar 2019 01:34:02 +0100 Subject: [PATCH 4/8] allowd unused types ggid_t and uuid_t --- src/unix/hermit/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs index 0c372f12128e6..f19bba4aa02ec 100644 --- a/src/unix/hermit/mod.rs +++ b/src/unix/hermit/mod.rs @@ -19,7 +19,9 @@ pub type c_long = i64; pub type c_ulong = u64; +#[allow(unused)] pub type uid_t = u16; +#[allow(unused)] pub type gid_t = u16; pub type speed_t = ::c_uint; pub type mode_t = u32; From cab10b479076fa588c5ceb0085ace51ff62d1a39 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 3 Mar 2019 10:02:12 +0100 Subject: [PATCH 5/8] add missing traits like Debug --- src/unix/hermit/mod.rs | 339 ++++++++++++++++++++++++++++++++++------- 1 file changed, 280 insertions(+), 59 deletions(-) diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs index f19bba4aa02ec..20d10411ffb55 100644 --- a/src/unix/hermit/mod.rs +++ b/src/unix/hermit/mod.rs @@ -51,6 +51,286 @@ pub type pthread_mutexattr_t = usize; pub type pthread_rwlock_t = usize; pub type pthread_rwlockattr_t = usize; +s_no_extra_traits! { + pub struct dirent { + pub d_ino: ::c_long, + pub d_off: off_t, + pub d_reclen: u16, + pub d_name: [::c_char; 256], + } + + // Dummy + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108], + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8], + } + + pub struct fd_set { + fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], + } + + pub struct sockaddr_storage { + pub s2_len: u8, + pub ss_family: sa_family_t, + pub s2_data1: [::c_char; 2], + pub s2_data2: [u32; 3], + pub s2_data3: [u32; 3], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_atime: time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_spare4: [::c_long; 2], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr { + fn eq(&self, other: &sockaddr) -> bool { + self.sa_len == other.sa_len + && self.sa_family == other.sa_family + && self + .sa_data + .iter() + .zip(other.sa_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr {} + impl ::fmt::Debug for sockaddr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr") + .field("sa_len", &self.sa_len) + .field("sa_family", &self.sa_family) + // FIXME: .field("sa_data", &self.sa_data) + .finish() + } + } + impl ::hash::Hash for sockaddr { + fn hash(&self, state: &mut H) { + self.sa_len.hash(state); + self.sa_family.hash(state); + self.sa_data.hash(state); + } + } + + impl PartialEq for sockaddr_in { + fn eq(&self, other: &sockaddr_in) -> bool { + self.sin_len == other.sin_len + && self.sin_family == other.sin_family + && self.sin_port == other.sin_port + && self.sin_addr == other.sin_addr + && self + .sin_zero + .iter() + .zip(other.sin_zero.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_in {} + impl ::fmt::Debug for sockaddr_in { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_in") + .field("sin_len", &self.sin_len) + .field("sin_family", &self.sin_family) + .field("sin_port", &self.sin_port) + .field("sin_addr", &self.sin_addr) + // FIXME: .field("sin_zero", &self.sin_zero) + .finish() + } + } + impl ::hash::Hash for sockaddr_in { + fn hash(&self, state: &mut H) { + self.sin_len.hash(state); + self.sin_family.hash(state); + self.sin_port.hash(state); + self.sin_addr.hash(state); + self.sin_zero.hash(state); + } + } + + impl PartialEq for fd_set { + fn eq(&self, other: &fd_set) -> bool { + self.fds_bits + .iter() + .zip(other.fds_bits.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for fd_set {} + impl ::fmt::Debug for fd_set { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fd_set") + // FIXME: .field("fds_bits", &self.fds_bits) + .finish() + } + } + impl ::hash::Hash for fd_set { + fn hash(&self, state: &mut H) { + self.fds_bits.hash(state); + } + } + + impl PartialEq for stat { + fn eq(&self, other: &stat) -> bool { + self.st_dev == other.st_dev + && self.st_ino == other.st_ino + && self.st_mode == other.st_mode + && self.st_nlink == other.st_nlink + && self.st_uid == other.st_uid + && self.st_gid == other.st_gid + && self.st_rdev == other.st_rdev + && self.st_size == other.st_size + && self.st_atime == other.st_atime + && self.st_atime_nsec == other.st_atime_nsec + && self.st_mtime == other.st_mtime + && self.st_mtime_nsec == other.st_mtime_nsec + && self.st_ctime == other.st_ctime + && self.st_ctime_nsec == other.st_ctime_nsec + && self.st_blksize == other.st_blksize + && self.st_blocks == other.st_blocks + && self + .st_spare4 + .iter() + .zip(other.st_spare4.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for stat {} + impl ::fmt::Debug for stat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("stat") + .field("st_dev", &self.st_dev) + .field("st_ino", &self.st_ino) + .field("st_mode", &self.st_mode) + .field("st_nlink", &self.st_nlink) + .field("st_uid", &self.st_uid) + .field("st_gid", &self.st_gid) + .field("st_rdev", &self.st_rdev) + .field("st_size", &self.st_size) + .field("st_atime", &self.st_atime) + .field("st_atime_nsec", &self.st_atime_nsec) + .field("st_mtime", &self.st_mtime) + .field("st_mtime_nsec", &self.st_mtime_nsec) + .field("st_ctime", &self.st_ctime) + .field("st_ctime_nsec", &self.st_ctime_nsec) + .field("st_blksize", &self.st_blksize) + .field("st_blocks", &self.st_blocks) + // FIXME: .field("st_spare4", &self.st_spare4) + .finish() + } + } + impl ::hash::Hash for stat { + fn hash(&self, state: &mut H) { + self.st_dev.hash(state); + self.st_ino.hash(state); + self.st_mode.hash(state); + self.st_nlink.hash(state); + self.st_uid.hash(state); + self.st_gid.hash(state); + self.st_rdev.hash(state); + self.st_size.hash(state); + self.st_atime.hash(state); + self.st_atime_nsec.hash(state); + self.st_mtime.hash(state); + self.st_mtime_nsec.hash(state); + self.st_ctime.hash(state); + self.st_ctime_nsec.hash(state); + self.st_blksize.hash(state); + self.st_blocks.hash(state); + self.st_spare4.hash(state); + } + } + } +} + s! { pub struct in_addr { pub s_addr: ::in_addr_t, @@ -72,19 +352,8 @@ s! { pub ai_next: *mut addrinfo, } - pub struct dirent { - pub d_ino: ::c_long, - pub d_off: off_t, - pub d_reclen: u16, - pub d_name: [::c_char; 256], - } - pub struct Dl_info {} - pub struct fd_set { - fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], - } - pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -143,20 +412,6 @@ s! { pub sa_handler: usize, } - pub struct sockaddr { - pub sa_len: u8, - pub sa_family: sa_family_t, - pub sa_data: [::c_char; 14], - } - - pub struct sockaddr_in { - pub sin_len: u8, - pub sin_family: sa_family_t, - pub sin_port: ::in_port_t, - pub sin_addr: ::in_addr, - pub sin_zero: [::c_char; 8], - } - pub struct sockaddr_in6 { pub sin6_len: u8, pub sin6_family: sa_family_t, @@ -166,40 +421,6 @@ s! { pub sin6_scope_id: u32, } - pub struct sockaddr_storage { - pub s2_len: u8, - pub ss_family: sa_family_t, - pub s2_data1: [::c_char; 2], - pub s2_data2: [u32; 3], - pub s2_data3: [u32; 3], - } - - // Dummy - pub struct sockaddr_un { - pub sun_family: sa_family_t, - pub sun_path: [::c_char; 108], - } - - pub struct stat { - pub st_dev: ::dev_t, - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: dev_t, - pub st_size: off_t, - pub st_atime: time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: blksize_t, - pub st_blocks: blkcnt_t, - pub st_spare4: [::c_long; 2], - } - pub struct statvfs {} pub struct tm { From be35992bb5e4343e9c634d99bbb7665ca14d2d4f Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 3 Mar 2019 14:23:37 +0100 Subject: [PATCH 6/8] add missing debug trait for sockaddr_storage --- src/unix/hermit/mod.rs | 46 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs index 20d10411ffb55..56555e847cb18 100644 --- a/src/unix/hermit/mod.rs +++ b/src/unix/hermit/mod.rs @@ -52,20 +52,20 @@ pub type pthread_rwlock_t = usize; pub type pthread_rwlockattr_t = usize; s_no_extra_traits! { - pub struct dirent { + pub struct dirent { pub d_ino: ::c_long, pub d_off: off_t, pub d_reclen: u16, pub d_name: [::c_char; 256], } - // Dummy + // Dummy pub struct sockaddr_un { pub sun_family: sa_family_t, pub sun_path: [::c_char; 108], } - pub struct sockaddr { + pub struct sockaddr { pub sa_len: u8, pub sa_family: sa_family_t, pub sa_data: [::c_char; 14], @@ -258,6 +258,46 @@ cfg_if! { } } + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.s2_len == other.s2_len + && self.ss_family == other.ss_family + && self.s2_data1 + .iter() + .zip(other.s2_data1.iter()) + .all(|(a,b)| a == b) + && self.s2_data2 + .iter() + .zip(other.s2_data2.iter()) + .all(|(a,b)| a == b) + && self.s2_data3 + .iter() + .zip(other.s2_data3.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("s2_len", &self.s2_len) + .field("ss_family", &self.ss_family) + // FIXME: .field("s2_data1", &self.s2_data1) + // FIXME: .field("s2_data2", &self.s2_data2) + // FIXME: .field("s2_data3", &self.s2_data3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.s2_len.hash(state); + self.ss_family.hash(state); + self.s2_data1.hash(state); + self.s2_data2.hash(state); + self.s2_data3.hash(state); + } + } + impl PartialEq for stat { fn eq(&self, other: &stat) -> bool { self.st_dev == other.st_dev From 5d185569ac75019d1ab015173c77eaf64ec30ee7 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 3 Mar 2019 15:15:06 +0100 Subject: [PATCH 7/8] remove unused variables --- src/unix/hermit/mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs index 56555e847cb18..aafd56eff8b85 100644 --- a/src/unix/hermit/mod.rs +++ b/src/unix/hermit/mod.rs @@ -19,10 +19,8 @@ pub type c_long = i64; pub type c_ulong = u64; -#[allow(unused)] -pub type uid_t = u16; -#[allow(unused)] -pub type gid_t = u16; +//pub type uid_t = u16; +//pub type gid_t = u16; pub type speed_t = ::c_uint; pub type mode_t = u32; pub type dev_t = i16; From 14353e8101484aa1ed9a269854469669abbf4e30 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 3 Mar 2019 16:24:54 +0100 Subject: [PATCH 8/8] remove obsolete definition of gid_t and uid_t --- src/unix/hermit/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/unix/hermit/mod.rs b/src/unix/hermit/mod.rs index aafd56eff8b85..288cc46a50693 100644 --- a/src/unix/hermit/mod.rs +++ b/src/unix/hermit/mod.rs @@ -19,8 +19,6 @@ pub type c_long = i64; pub type c_ulong = u64; -//pub type uid_t = u16; -//pub type gid_t = u16; pub type speed_t = ::c_uint; pub type mode_t = u32; pub type dev_t = i16;