diff options
| author | bors <bors@rust-lang.org> | 2015-09-22 19:13:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-09-22 19:13:39 +0000 |
| commit | 9c1aaeb7b97e34b6688f31c6921d636d27c02e73 (patch) | |
| tree | 7382bd6e81a8c1076404039d1665c75e1cb92330 /src/libstd/sys | |
| parent | 2a6f6f26f4d4a1e22ea5e2b4498d3245d80e8aff (diff) | |
| parent | 428bb164f33951e561a1eed8e636077ad6ce2506 (diff) | |
| download | rust-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.rs | 12 | ||||
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 7 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/unix/sync.rs | 66 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 31 | ||||
| -rw-r--r-- | src/libstd/sys/unix/time.rs | 2 |
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; } |
