summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-09-22 19:13:39 +0000
committerbors <bors@rust-lang.org>2015-09-22 19:13:39 +0000
commit9c1aaeb7b97e34b6688f31c6921d636d27c02e73 (patch)
tree7382bd6e81a8c1076404039d1665c75e1cb92330 /src/libstd/sys
parent2a6f6f26f4d4a1e22ea5e2b4498d3245d80e8aff (diff)
parent428bb164f33951e561a1eed8e636077ad6ce2506 (diff)
downloadrust-9c1aaeb7b97e34b6688f31c6921d636d27c02e73.tar.gz
rust-9c1aaeb7b97e34b6688f31c6921d636d27c02e73.zip
Auto merge of #28543 - gandro:netbsd, r=alexcrichton
These changes introduce the ability to cross-compile working binaries for NetBSD/amd64. Previous support added in PR #26682 shared all its code with the OpenBSD implementation, and was therefore never functional (e.g. linking against non-existing symbols and using wrong type definitions). Nonetheless, the previous patches were a great starting point and made my work significantly easier. :smiley: 

Because there are no stage0 snapshots for NetBSD (yet), I used a cross-compiler for NetBSD 7.0 RC3 and only tested some toy programs (threading and channels, stack guards, a small TCP/IP echo server and some other platform dependent bits). If someone could point me to documentation on how to generate a stage0 snapshot from a cross-compiler I'm happy to run the full test suite.

A few other notes regarding Rust on NetBSD/amd64:
- To preserve binary compatibility, NetBSD introduces new symbols for system call wrappers on breaking ABI changes and keeps the old (legacy) symbols around, see [this documentation](https://www.netbsd.org/docs/internals/en/chap-processes.html#syscalls_master) for some details. I went ahead and modified the `libc` and `std` crate to use the current (renamed) symbols instead of the legacy ones where I found them, but I might have missed some. Notably using the `sigaction` symbol (deprecated in 1998) instead of `__sigaction14` even triggers SIGSYS (bad syscall) on my amd64 setup. I also changed the type definitions to use the most recent version.
- NetBSD's gdb doesn't really support position independent executables, so you might want to turn that off for debugging, see [NetBSD Problem Report #48250](https://gnats.netbsd.org/48250).
- For binaries invoked using a relative path, NetBSD supports `$ORIGIN` only for short `rpath`s (~64 chars or so, I'm told). If running an executable fails with `execname not specified in AUX vector: No such file or directory`, consider invoking the binary using its full absolute path.
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/unix/c.rs12
-rw-r--r--src/libstd/sys/unix/os.rs7
-rw-r--r--src/libstd/sys/unix/process.rs1
-rw-r--r--src/libstd/sys/unix/sync.rs66
-rw-r--r--src/libstd/sys/unix/thread.rs31
-rw-r--r--src/libstd/sys/unix/time.rs2
6 files changed, 107 insertions, 12 deletions
diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs
index eeecf7f50f7..051b3d8897d 100644
--- a/src/libstd/sys/unix/c.rs
+++ b/src/libstd/sys/unix/c.rs
@@ -61,9 +61,10 @@ pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 70;
           target_os = "dragonfly"))]
 pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 71;
 #[cfg(any(target_os = "bitrig",
-          target_os = "netbsd",
           target_os = "openbsd"))]
 pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 101;
+#[cfg(target_os = "netbsd")]
+pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 48;
 #[cfg(target_os = "android")]
 pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 0x0048;
 
@@ -131,26 +132,31 @@ extern {
 
     pub fn raise(signum: libc::c_int) -> libc::c_int;
 
+    #[cfg_attr(target_os = "netbsd", link_name = "__sigaction14")]
     pub fn sigaction(signum: libc::c_int,
                      act: *const sigaction,
                      oldact: *mut sigaction) -> libc::c_int;
 
+    #[cfg_attr(target_os = "netbsd", link_name = "__sigaltstack14")]
     pub fn sigaltstack(ss: *const sigaltstack,
                        oss: *mut sigaltstack) -> libc::c_int;
 
     #[cfg(not(target_os = "android"))]
+    #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
     pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;
 
     pub fn pthread_sigmask(how: libc::c_int, set: *const sigset_t,
                            oldset: *mut sigset_t) -> libc::c_int;
 
     #[cfg(not(target_os = "ios"))]
+    #[cfg_attr(target_os = "netbsd", link_name = "__getpwuid_r50")]
     pub fn getpwuid_r(uid: libc::uid_t,
                       pwd: *mut passwd,
                       buf: *mut libc::c_char,
                       buflen: libc::size_t,
                       result: *mut *mut passwd) -> libc::c_int;
 
+    #[cfg_attr(target_os = "netbsd", link_name = "__utimes50")]
     pub fn utimes(filename: *const libc::c_char,
                   times: *const libc::timeval) -> libc::c_int;
     pub fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char;
@@ -347,12 +353,12 @@ mod signal_os {
     #[cfg(any(target_os = "macos",
               target_os = "ios"))]
     pub type sigset_t = u32;
-    #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+    #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))]
     #[repr(C)]
     pub struct sigset_t {
         bits: [u32; 4],
     }
-    #[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))]
+    #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
     pub type sigset_t = libc::c_uint;
 
     // This structure has more fields, but we're not all that interested in
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 94c4d04ea30..c0e75368f74 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -213,7 +213,12 @@ pub fn current_exe() -> io::Result<PathBuf> {
     ::fs::read_link("/proc/curproc/file")
 }
 
-#[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))]
+#[cfg(target_os = "netbsd")]
+pub fn current_exe() -> io::Result<PathBuf> {
+    ::fs::read_link("/proc/curproc/exe")
+}
+
+#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
 pub fn current_exe() -> io::Result<PathBuf> {
     use sync::StaticMutex;
     static LOCK: StaticMutex = StaticMutex::new();
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index 12ca31ce5e1..ce6e5609ce7 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -452,6 +452,7 @@ mod tests {
 
     #[cfg(not(target_os = "android"))]
     extern {
+        #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
         fn sigaddset(set: *mut c::sigset_t, signum: libc::c_int) -> libc::c_int;
     }
 
diff --git a/src/libstd/sys/unix/sync.rs b/src/libstd/sys/unix/sync.rs
index 4e49b6473c9..954bfbb6b18 100644
--- a/src/libstd/sys/unix/sync.rs
+++ b/src/libstd/sys/unix/sync.rs
@@ -40,6 +40,7 @@ extern {
     pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> libc::c_int;
     pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> libc::c_int;
     pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> libc::c_int;
+    #[cfg_attr(target_os = "netbsd", link_name = "__gettimeofday50")]
     pub fn gettimeofday(tp: *mut libc::timeval,
                         tz: *mut libc::c_void) -> libc::c_int;
 
@@ -55,7 +56,6 @@ extern {
 #[cfg(any(target_os = "freebsd",
           target_os = "dragonfly",
           target_os = "bitrig",
-          target_os = "netbsd",
           target_os = "openbsd"))]
 mod os {
     use libc;
@@ -249,3 +249,67 @@ mod os {
     };
     pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
 }
+
+#[cfg(target_os = "netbsd")]
+mod os {
+    use libc;
+
+    // size of the type minus width of the magic and alignment field
+    #[cfg(target_arch = "x86_64")]
+    const __PTHREAD_MUTEX_SIZE__: usize = 48 - 4 - 8;
+
+    #[cfg(target_arch = "x86_64")]
+    const __PTHREAD_MUTEXATTR_SIZE__: usize = 16 - 8; // no magic field
+
+    #[cfg(target_arch = "x86_64")]
+    const __PTHREAD_COND_SIZE__: usize = 40 - 4 - 8;
+
+    #[cfg(target_arch = "x86_64")]
+    const __PTHREAD_RWLOCK_SIZE__: usize = 64 - 4 - 8;
+
+    const _PTHREAD_MUTEX_MAGIC_INIT: libc::c_uint = 0x33330003;
+    const _PTHREAD_COND_MAGIC_INIT: libc::c_uint = 0x55550005;
+    const _PTHREAD_RWLOCK_MAGIC_INIT: libc::c_uint = 0x99990009;
+
+    #[repr(C)]
+    pub struct pthread_mutex_t {
+        __magic: libc::c_uint,
+        __opaque: [u8; __PTHREAD_MUTEX_SIZE__],
+        __align: libc::c_longlong,
+    }
+    #[repr(C)]
+    pub struct pthread_mutexattr_t {
+        __opaque: [u8; __PTHREAD_MUTEXATTR_SIZE__],
+        __align: libc::c_longlong,
+    }
+    #[repr(C)]
+    pub struct pthread_cond_t {
+        __magic: libc::c_uint,
+        __opaque: [u8; __PTHREAD_COND_SIZE__],
+        __align: libc::c_longlong,
+    }
+    #[repr(C)]
+    pub struct pthread_rwlock_t {
+        __magic: libc::c_uint,
+        __opaque: [u8; __PTHREAD_RWLOCK_SIZE__],
+        __align: libc::c_longlong,
+    }
+
+    pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
+        __magic: _PTHREAD_MUTEX_MAGIC_INIT,
+        __opaque: [0; __PTHREAD_MUTEX_SIZE__],
+        __align: 0,
+    };
+    pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
+        __magic: _PTHREAD_COND_MAGIC_INIT,
+        __opaque: [0; __PTHREAD_COND_SIZE__],
+        __align: 0,
+    };
+    pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
+        __magic: _PTHREAD_RWLOCK_MAGIC_INIT,
+        __opaque: [0; __PTHREAD_RWLOCK_SIZE__],
+        __align: 0,
+    };
+
+    pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
+}
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 268ec7fe356..83e0a03a234 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -102,7 +102,6 @@ impl Thread {
     #[cfg(any(target_os = "freebsd",
               target_os = "dragonfly",
               target_os = "bitrig",
-              target_os = "netbsd",
               target_os = "openbsd"))]
     pub fn set_name(name: &str) {
         extern {
@@ -126,6 +125,21 @@ impl Thread {
         }
     }
 
+    #[cfg(target_os = "netbsd")]
+    pub fn set_name(name: &str) {
+        extern {
+            fn pthread_setname_np(thread: libc::pthread_t,
+                                  name: *const libc::c_char,
+                                  arg: *mut libc::c_void) -> libc::c_int;
+        }
+        let cname = CString::new(&b"%s"[..]).unwrap();
+        let carg = CString::new(name).unwrap();
+        unsafe {
+            pthread_setname_np(pthread_self(), cname.as_ptr(),
+                               carg.as_ptr() as *mut libc::c_void);
+        }
+    }
+
     pub fn sleep(dur: Duration) {
         let mut ts = libc::timespec {
             tv_sec: dur.as_secs() as libc::time_t,
@@ -191,13 +205,12 @@ pub mod guard {
 
     #[cfg(any(target_os = "macos",
               target_os = "bitrig",
-              target_os = "netbsd",
               target_os = "openbsd"))]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         current().map(|s| s as *mut libc::c_void)
     }
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
+    #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         use super::pthread_attr_init;
 
@@ -263,7 +276,7 @@ pub mod guard {
               pthread_get_stacksize_np(pthread_self())) as usize)
     }
 
-    #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "bitrig"))]
+    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
     pub unsafe fn current() -> Option<usize> {
         #[repr(C)]
         struct stack_t {
@@ -290,7 +303,7 @@ pub mod guard {
         })
     }
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
+    #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
     pub unsafe fn current() -> Option<usize> {
         use super::pthread_attr_init;
 
@@ -307,13 +320,17 @@ pub mod guard {
             let mut size = 0;
             assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
 
-            ret = Some(stackaddr as usize + guardsize as usize);
+            ret = if cfg!(target_os = "netbsd") {
+                Some(stackaddr as usize)
+            } else {
+                Some(stackaddr as usize + guardsize as usize)
+            };
         }
         assert_eq!(pthread_attr_destroy(&mut attr), 0);
         ret
     }
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
+    #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
     extern {
         fn pthread_getattr_np(native: libc::pthread_t,
                               attr: *mut libc::pthread_attr_t) -> libc::c_int;
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index db0d0f15061..73b66877588 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -86,7 +86,9 @@ mod inner {
     #[link(name = "rt")]
     extern {}
 
+
     extern {
+        #[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")]
         fn clock_gettime(clk_id: libc::c_int, tp: *mut libc::timespec) -> libc::c_int;
     }