Skip to content

Commit 9c1aaeb

Browse files
committed
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. 😃 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.
2 parents 2a6f6f2 + 428bb16 commit 9c1aaeb

File tree

9 files changed

+603
-68
lines changed

9 files changed

+603
-68
lines changed

mk/cfg/x86_64-unknown-netbsd.mk

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# x86_64-unknown-netbsd configuration
2+
CROSS_PREFIX_x86_64-unknown-netbsd=x86_64-unknown-netbsd-
23
CC_x86_64-unknown-netbsd=$(CC)
34
CXX_x86_64-unknown-netbsd=$(CXX)
45
CPP_x86_64-unknown-netbsd=$(CPP)

src/liblibc/lib.rs

+488-50
Large diffs are not rendered by default.

src/libstd/os/netbsd/raw.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! NetBSD/OpenBSD-specific raw type definitions
11+
//! NetBSD-specific raw type definitions
1212
1313
#![stable(feature = "raw_ext", since = "1.1.0")]
1414

@@ -17,7 +17,7 @@ use os::unix::raw::{uid_t, gid_t};
1717

1818
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64;
1919
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u32;
20-
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = i32;
20+
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64;
2121
#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32;
2222
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64;
2323
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32;
@@ -55,6 +55,10 @@ pub struct stat {
5555
#[stable(feature = "raw_ext", since = "1.1.0")]
5656
pub st_ctime_nsec: c_long,
5757
#[stable(feature = "raw_ext", since = "1.1.0")]
58+
pub st_birthtime: time_t,
59+
#[stable(feature = "raw_ext", since = "1.1.0")]
60+
pub st_birthtime_nsec: c_long,
61+
#[stable(feature = "raw_ext", since = "1.1.0")]
5862
pub st_size: off_t,
5963
#[stable(feature = "raw_ext", since = "1.1.0")]
6064
pub st_blocks: blkcnt_t,
@@ -64,8 +68,5 @@ pub struct stat {
6468
pub st_flags: fflags_t,
6569
#[stable(feature = "raw_ext", since = "1.1.0")]
6670
pub st_gen: u32,
67-
#[stable(feature = "raw_ext", since = "1.1.0")]
68-
pub st_birthtime: time_t,
69-
#[stable(feature = "raw_ext", since = "1.1.0")]
70-
pub st_birthtime_nsec: c_long,
71+
st_spare: [u32; 2],
7172
}

src/libstd/sys/unix/c.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@ pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 70;
6161
target_os = "dragonfly"))]
6262
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 71;
6363
#[cfg(any(target_os = "bitrig",
64-
target_os = "netbsd",
6564
target_os = "openbsd"))]
6665
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 101;
66+
#[cfg(target_os = "netbsd")]
67+
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 48;
6768
#[cfg(target_os = "android")]
6869
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 0x0048;
6970

@@ -131,26 +132,31 @@ extern {
131132

132133
pub fn raise(signum: libc::c_int) -> libc::c_int;
133134

135+
#[cfg_attr(target_os = "netbsd", link_name = "__sigaction14")]
134136
pub fn sigaction(signum: libc::c_int,
135137
act: *const sigaction,
136138
oldact: *mut sigaction) -> libc::c_int;
137139

140+
#[cfg_attr(target_os = "netbsd", link_name = "__sigaltstack14")]
138141
pub fn sigaltstack(ss: *const sigaltstack,
139142
oss: *mut sigaltstack) -> libc::c_int;
140143

141144
#[cfg(not(target_os = "android"))]
145+
#[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
142146
pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;
143147

144148
pub fn pthread_sigmask(how: libc::c_int, set: *const sigset_t,
145149
oldset: *mut sigset_t) -> libc::c_int;
146150

147151
#[cfg(not(target_os = "ios"))]
152+
#[cfg_attr(target_os = "netbsd", link_name = "__getpwuid_r50")]
148153
pub fn getpwuid_r(uid: libc::uid_t,
149154
pwd: *mut passwd,
150155
buf: *mut libc::c_char,
151156
buflen: libc::size_t,
152157
result: *mut *mut passwd) -> libc::c_int;
153158

159+
#[cfg_attr(target_os = "netbsd", link_name = "__utimes50")]
154160
pub fn utimes(filename: *const libc::c_char,
155161
times: *const libc::timeval) -> libc::c_int;
156162
pub fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char;
@@ -347,12 +353,12 @@ mod signal_os {
347353
#[cfg(any(target_os = "macos",
348354
target_os = "ios"))]
349355
pub type sigset_t = u32;
350-
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
356+
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))]
351357
#[repr(C)]
352358
pub struct sigset_t {
353359
bits: [u32; 4],
354360
}
355-
#[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))]
361+
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
356362
pub type sigset_t = libc::c_uint;
357363

358364
// This structure has more fields, but we're not all that interested in

src/libstd/sys/unix/os.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,12 @@ pub fn current_exe() -> io::Result<PathBuf> {
213213
::fs::read_link("/proc/curproc/file")
214214
}
215215

216-
#[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))]
216+
#[cfg(target_os = "netbsd")]
217+
pub fn current_exe() -> io::Result<PathBuf> {
218+
::fs::read_link("/proc/curproc/exe")
219+
}
220+
221+
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
217222
pub fn current_exe() -> io::Result<PathBuf> {
218223
use sync::StaticMutex;
219224
static LOCK: StaticMutex = StaticMutex::new();

src/libstd/sys/unix/process.rs

+1
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ mod tests {
452452

453453
#[cfg(not(target_os = "android"))]
454454
extern {
455+
#[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
455456
fn sigaddset(set: *mut c::sigset_t, signum: libc::c_int) -> libc::c_int;
456457
}
457458

src/libstd/sys/unix/sync.rs

+65-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern {
4040
pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> libc::c_int;
4141
pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> libc::c_int;
4242
pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> libc::c_int;
43+
#[cfg_attr(target_os = "netbsd", link_name = "__gettimeofday50")]
4344
pub fn gettimeofday(tp: *mut libc::timeval,
4445
tz: *mut libc::c_void) -> libc::c_int;
4546

@@ -55,7 +56,6 @@ extern {
5556
#[cfg(any(target_os = "freebsd",
5657
target_os = "dragonfly",
5758
target_os = "bitrig",
58-
target_os = "netbsd",
5959
target_os = "openbsd"))]
6060
mod os {
6161
use libc;
@@ -249,3 +249,67 @@ mod os {
249249
};
250250
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
251251
}
252+
253+
#[cfg(target_os = "netbsd")]
254+
mod os {
255+
use libc;
256+
257+
// size of the type minus width of the magic and alignment field
258+
#[cfg(target_arch = "x86_64")]
259+
const __PTHREAD_MUTEX_SIZE__: usize = 48 - 4 - 8;
260+
261+
#[cfg(target_arch = "x86_64")]
262+
const __PTHREAD_MUTEXATTR_SIZE__: usize = 16 - 8; // no magic field
263+
264+
#[cfg(target_arch = "x86_64")]
265+
const __PTHREAD_COND_SIZE__: usize = 40 - 4 - 8;
266+
267+
#[cfg(target_arch = "x86_64")]
268+
const __PTHREAD_RWLOCK_SIZE__: usize = 64 - 4 - 8;
269+
270+
const _PTHREAD_MUTEX_MAGIC_INIT: libc::c_uint = 0x33330003;
271+
const _PTHREAD_COND_MAGIC_INIT: libc::c_uint = 0x55550005;
272+
const _PTHREAD_RWLOCK_MAGIC_INIT: libc::c_uint = 0x99990009;
273+
274+
#[repr(C)]
275+
pub struct pthread_mutex_t {
276+
__magic: libc::c_uint,
277+
__opaque: [u8; __PTHREAD_MUTEX_SIZE__],
278+
__align: libc::c_longlong,
279+
}
280+
#[repr(C)]
281+
pub struct pthread_mutexattr_t {
282+
__opaque: [u8; __PTHREAD_MUTEXATTR_SIZE__],
283+
__align: libc::c_longlong,
284+
}
285+
#[repr(C)]
286+
pub struct pthread_cond_t {
287+
__magic: libc::c_uint,
288+
__opaque: [u8; __PTHREAD_COND_SIZE__],
289+
__align: libc::c_longlong,
290+
}
291+
#[repr(C)]
292+
pub struct pthread_rwlock_t {
293+
__magic: libc::c_uint,
294+
__opaque: [u8; __PTHREAD_RWLOCK_SIZE__],
295+
__align: libc::c_longlong,
296+
}
297+
298+
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
299+
__magic: _PTHREAD_MUTEX_MAGIC_INIT,
300+
__opaque: [0; __PTHREAD_MUTEX_SIZE__],
301+
__align: 0,
302+
};
303+
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
304+
__magic: _PTHREAD_COND_MAGIC_INIT,
305+
__opaque: [0; __PTHREAD_COND_SIZE__],
306+
__align: 0,
307+
};
308+
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
309+
__magic: _PTHREAD_RWLOCK_MAGIC_INIT,
310+
__opaque: [0; __PTHREAD_RWLOCK_SIZE__],
311+
__align: 0,
312+
};
313+
314+
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
315+
}

src/libstd/sys/unix/thread.rs

+24-7
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ impl Thread {
102102
#[cfg(any(target_os = "freebsd",
103103
target_os = "dragonfly",
104104
target_os = "bitrig",
105-
target_os = "netbsd",
106105
target_os = "openbsd"))]
107106
pub fn set_name(name: &str) {
108107
extern {
@@ -126,6 +125,21 @@ impl Thread {
126125
}
127126
}
128127

128+
#[cfg(target_os = "netbsd")]
129+
pub fn set_name(name: &str) {
130+
extern {
131+
fn pthread_setname_np(thread: libc::pthread_t,
132+
name: *const libc::c_char,
133+
arg: *mut libc::c_void) -> libc::c_int;
134+
}
135+
let cname = CString::new(&b"%s"[..]).unwrap();
136+
let carg = CString::new(name).unwrap();
137+
unsafe {
138+
pthread_setname_np(pthread_self(), cname.as_ptr(),
139+
carg.as_ptr() as *mut libc::c_void);
140+
}
141+
}
142+
129143
pub fn sleep(dur: Duration) {
130144
let mut ts = libc::timespec {
131145
tv_sec: dur.as_secs() as libc::time_t,
@@ -191,13 +205,12 @@ pub mod guard {
191205

192206
#[cfg(any(target_os = "macos",
193207
target_os = "bitrig",
194-
target_os = "netbsd",
195208
target_os = "openbsd"))]
196209
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
197210
current().map(|s| s as *mut libc::c_void)
198211
}
199212

200-
#[cfg(any(target_os = "linux", target_os = "android"))]
213+
#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
201214
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
202215
use super::pthread_attr_init;
203216

@@ -263,7 +276,7 @@ pub mod guard {
263276
pthread_get_stacksize_np(pthread_self())) as usize)
264277
}
265278

266-
#[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "bitrig"))]
279+
#[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
267280
pub unsafe fn current() -> Option<usize> {
268281
#[repr(C)]
269282
struct stack_t {
@@ -290,7 +303,7 @@ pub mod guard {
290303
})
291304
}
292305

293-
#[cfg(any(target_os = "linux", target_os = "android"))]
306+
#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
294307
pub unsafe fn current() -> Option<usize> {
295308
use super::pthread_attr_init;
296309

@@ -307,13 +320,17 @@ pub mod guard {
307320
let mut size = 0;
308321
assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
309322

310-
ret = Some(stackaddr as usize + guardsize as usize);
323+
ret = if cfg!(target_os = "netbsd") {
324+
Some(stackaddr as usize)
325+
} else {
326+
Some(stackaddr as usize + guardsize as usize)
327+
};
311328
}
312329
assert_eq!(pthread_attr_destroy(&mut attr), 0);
313330
ret
314331
}
315332

316-
#[cfg(any(target_os = "linux", target_os = "android"))]
333+
#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
317334
extern {
318335
fn pthread_getattr_np(native: libc::pthread_t,
319336
attr: *mut libc::pthread_attr_t) -> libc::c_int;

src/libstd/sys/unix/time.rs

+2
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ mod inner {
8686
#[link(name = "rt")]
8787
extern {}
8888

89+
8990
extern {
91+
#[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")]
9092
fn clock_gettime(clk_id: libc::c_int, tp: *mut libc::timespec) -> libc::c_int;
9193
}
9294

0 commit comments

Comments
 (0)