Skip to content

Commit fd8f9a6

Browse files
committed
Auto merge of #3198 - devnexen:solarish_support, r=RalfJung
illumos support
2 parents e3fe30d + b4011a0 commit fd8f9a6

File tree

9 files changed

+102
-24
lines changed

9 files changed

+102
-24
lines changed

src/tools/miri/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ degree documented below):
227227
- We have unofficial support (not maintained by the Miri team itself) for some further operating systems.
228228
- `freebsd`: **maintainer wanted**. Supports `std::env` and parts of `std::{thread, fs}`, but not `std::sync`.
229229
- `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works.
230+
- `illumos`: maintained by @devnexen. Support very incomplete, but a basic "hello world" works.
230231
- `wasm`: **maintainer wanted**. Support very incomplete, not even standard output works, but an empty `main` function works.
231232
- For targets on other operating systems, Miri might fail before even reaching the `main` function.
232233

src/tools/miri/ci/ci.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ case $HOST_TARGET in
146146
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus
147147
MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-getentropy libc-getrandom libc-misc fs env num_cpus
148148
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic
149+
MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic pthread-sync
150+
# TODO fix solaris stack guard
151+
# MIRI_TEST_TARGET=x86_64-pc-solaris run_tests_minimal $VERY_BASIC hello panic/panic pthread-sync
149152
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm
150153
MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm
151154
MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std

src/tools/miri/src/concurrency/thread.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ impl TryFrom<u64> for ThreadId {
7878
}
7979
}
8080

81+
impl TryFrom<i128> for ThreadId {
82+
type Error = TryFromIntError;
83+
fn try_from(id: i128) -> Result<Self, Self::Error> {
84+
u32::try_from(id).map(Self)
85+
}
86+
}
87+
8188
impl From<u32> for ThreadId {
8289
fn from(id: u32) -> Self {
8390
Self(id)

src/tools/miri/src/shims/unix/foreign_items.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::*;
1313
use shims::unix::freebsd::foreign_items as freebsd;
1414
use shims::unix::linux::foreign_items as linux;
1515
use shims::unix::macos::foreign_items as macos;
16+
use shims::unix::solarish::foreign_items as solarish;
1617

1718
pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
1819
match name {
@@ -29,6 +30,7 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
2930
"freebsd" => freebsd::is_dyn_sym(name),
3031
"linux" => linux::is_dyn_sym(name),
3132
"macos" => macos::is_dyn_sym(name),
33+
"solaris" | "illumos" => solarish::is_dyn_sym(name),
3234
_ => false,
3335
},
3436
}
@@ -591,8 +593,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
591593
}
592594
"getentropy" => {
593595
// This function is non-standard but exists with the same signature and behavior on
594-
// Linux, macOS, and FreeBSD.
595-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd") {
596+
// Linux, macOS, FreeBSD and Solaris/Illumos.
597+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd" | "illumos" | "solaris") {
596598
throw_unsup_format!(
597599
"`getentropy` is not supported on {}",
598600
this.tcx.sess.target.os
@@ -608,6 +610,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
608610
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=getentropy&sektion=3&format=html
609611
// Linux: https://man7.org/linux/man-pages/man3/getentropy.3.html
610612
// macOS: https://keith.github.io/xcode-man-pages/getentropy.2.html
613+
// Solaris/Illumos: https://illumos.org/man/3C/getentropy
611614
if bufsize > 256 {
612615
let err = this.eval_libc("EIO");
613616
this.set_last_error(err)?;
@@ -730,6 +733,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
730733
"freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
731734
"linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
732735
"macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
736+
"solaris" | "illumos" => solarish::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
733737
_ => Ok(EmulateItemResult::NotSupported),
734738
};
735739
}

src/tools/miri/src/shims/unix/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod thread;
1111
mod freebsd;
1212
mod linux;
1313
mod macos;
14+
mod solarish;
1415

1516
pub use env::UnixEnvVars;
1617
pub use fd::{FdTable, FileDescription};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use rustc_span::Symbol;
2+
use rustc_target::spec::abi::Abi;
3+
4+
use crate::shims::unix::*;
5+
use crate::*;
6+
use shims::EmulateItemResult;
7+
8+
pub fn is_dyn_sym(_name: &str) -> bool {
9+
false
10+
}
11+
12+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
13+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
14+
fn emulate_foreign_item_inner(
15+
&mut self,
16+
link_name: Symbol,
17+
abi: Abi,
18+
args: &[OpTy<'tcx, Provenance>],
19+
dest: &MPlaceTy<'tcx, Provenance>,
20+
) -> InterpResult<'tcx, EmulateItemResult> {
21+
let this = self.eval_context_mut();
22+
match link_name.as_str() {
23+
// Threading
24+
"pthread_condattr_setclock" => {
25+
let [attr, clock_id] =
26+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
27+
let result = this.pthread_condattr_setclock(attr, clock_id)?;
28+
this.write_scalar(result, dest)?;
29+
}
30+
"pthread_condattr_getclock" => {
31+
let [attr, clock_id] =
32+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
33+
let result = this.pthread_condattr_getclock(attr, clock_id)?;
34+
this.write_scalar(result, dest)?;
35+
}
36+
37+
_ => return Ok(EmulateItemResult::NotSupported),
38+
}
39+
Ok(EmulateItemResult::NeedsJumping)
40+
}
41+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod foreign_items;

src/tools/miri/src/shims/unix/sync.rs

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,20 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
6868
// (the kind has to be at this particular offset for compatibility with Linux's static initializer
6969
// macros, e.g. PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.)
7070

71+
#[inline]
72+
fn mutex_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
73+
if matches!(&*ecx.tcx.sess.target.os, "macos") { 4 } else { 0 }
74+
}
75+
7176
fn mutex_get_id<'mir, 'tcx: 'mir>(
7277
ecx: &mut MiriInterpCx<'mir, 'tcx>,
7378
mutex_op: &OpTy<'tcx, Provenance>,
7479
) -> InterpResult<'tcx, MutexId> {
75-
ecx.mutex_get_or_create_id(mutex_op, ecx.libc_ty_layout("pthread_mutex_t"), 4)
80+
ecx.mutex_get_or_create_id(
81+
mutex_op,
82+
ecx.libc_ty_layout("pthread_mutex_t"),
83+
mutex_id_offset(ecx),
84+
)
7685
}
7786

7887
fn mutex_reset_id<'mir, 'tcx: 'mir>(
@@ -81,7 +90,7 @@ fn mutex_reset_id<'mir, 'tcx: 'mir>(
8190
) -> InterpResult<'tcx, ()> {
8291
ecx.deref_pointer_and_write(
8392
mutex_op,
84-
4,
93+
mutex_id_offset(ecx),
8594
Scalar::from_i32(0),
8695
ecx.libc_ty_layout("pthread_mutex_t"),
8796
ecx.machine.layouts.u32,
@@ -124,13 +133,20 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
124133
// (need to avoid this because it is set by static initializer macros)
125134
// bytes 4-7: rwlock id as u32 or 0 if id is not assigned yet.
126135

127-
const RWLOCK_ID_OFFSET: u64 = 4;
136+
#[inline]
137+
fn rwlock_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
138+
if matches!(&*ecx.tcx.sess.target.os, "macos") { 4 } else { 0 }
139+
}
128140

129141
fn rwlock_get_id<'mir, 'tcx: 'mir>(
130142
ecx: &mut MiriInterpCx<'mir, 'tcx>,
131143
rwlock_op: &OpTy<'tcx, Provenance>,
132144
) -> InterpResult<'tcx, RwLockId> {
133-
ecx.rwlock_get_or_create_id(rwlock_op, ecx.libc_ty_layout("pthread_rwlock_t"), RWLOCK_ID_OFFSET)
145+
ecx.rwlock_get_or_create_id(
146+
rwlock_op,
147+
ecx.libc_ty_layout("pthread_rwlock_t"),
148+
rwlock_id_offset(ecx),
149+
)
134150
}
135151

136152
// pthread_condattr_t
@@ -177,14 +193,18 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
177193
// bytes 4-7: the conditional variable id as u32 or 0 if id is not assigned yet.
178194
// bytes 8-11: the clock id constant as i32
179195

180-
const CONDVAR_ID_OFFSET: u64 = 4;
181196
const CONDVAR_CLOCK_OFFSET: u64 = 8;
182197

198+
#[inline]
199+
fn cond_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
200+
if matches!(&*ecx.tcx.sess.target.os, "macos") { 4 } else { 0 }
201+
}
202+
183203
fn cond_get_id<'mir, 'tcx: 'mir>(
184204
ecx: &mut MiriInterpCx<'mir, 'tcx>,
185205
cond_op: &OpTy<'tcx, Provenance>,
186206
) -> InterpResult<'tcx, CondvarId> {
187-
ecx.condvar_get_or_create_id(cond_op, ecx.libc_ty_layout("pthread_cond_t"), CONDVAR_ID_OFFSET)
207+
ecx.condvar_get_or_create_id(cond_op, ecx.libc_ty_layout("pthread_cond_t"), cond_id_offset(ecx))
188208
}
189209

190210
fn cond_reset_id<'mir, 'tcx: 'mir>(
@@ -193,7 +213,7 @@ fn cond_reset_id<'mir, 'tcx: 'mir>(
193213
) -> InterpResult<'tcx, ()> {
194214
ecx.deref_pointer_and_write(
195215
cond_op,
196-
CONDVAR_ID_OFFSET,
216+
cond_id_offset(ecx),
197217
Scalar::from_i32(0),
198218
ecx.libc_ty_layout("pthread_cond_t"),
199219
ecx.machine.layouts.u32,
@@ -287,7 +307,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
287307
) -> InterpResult<'tcx, i32> {
288308
let this = self.eval_context_mut();
289309

290-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
310+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
291311
throw_unsup_format!(
292312
"`pthread_mutexattr_init` is not supported on {}",
293313
this.tcx.sess.target.os
@@ -376,7 +396,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
376396
) -> InterpResult<'tcx, i32> {
377397
let this = self.eval_context_mut();
378398

379-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
399+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
380400
throw_unsup_format!(
381401
"`pthread_mutex_init` is not supported on {}",
382402
this.tcx.sess.target.os
@@ -537,7 +557,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
537557
) -> InterpResult<'tcx, i32> {
538558
let this = self.eval_context_mut();
539559

540-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
560+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
541561
throw_unsup_format!(
542562
"`pthread_rwlock_rdlock` is not supported on {}",
543563
this.tcx.sess.target.os
@@ -562,7 +582,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
562582
) -> InterpResult<'tcx, i32> {
563583
let this = self.eval_context_mut();
564584

565-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
585+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
566586
throw_unsup_format!(
567587
"`pthread_rwlock_tryrdlock` is not supported on {}",
568588
this.tcx.sess.target.os
@@ -586,7 +606,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
586606
) -> InterpResult<'tcx, i32> {
587607
let this = self.eval_context_mut();
588608

589-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
609+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
590610
throw_unsup_format!(
591611
"`pthread_rwlock_wrlock` is not supported on {}",
592612
this.tcx.sess.target.os
@@ -623,7 +643,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
623643
) -> InterpResult<'tcx, i32> {
624644
let this = self.eval_context_mut();
625645

626-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
646+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
627647
throw_unsup_format!(
628648
"`pthread_rwlock_trywrlock` is not supported on {}",
629649
this.tcx.sess.target.os
@@ -647,7 +667,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
647667
) -> InterpResult<'tcx, i32> {
648668
let this = self.eval_context_mut();
649669

650-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
670+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
651671
throw_unsup_format!(
652672
"`pthread_rwlock_unlock` is not supported on {}",
653673
this.tcx.sess.target.os
@@ -673,7 +693,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
673693
) -> InterpResult<'tcx, i32> {
674694
let this = self.eval_context_mut();
675695

676-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
696+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
677697
throw_unsup_format!(
678698
"`pthread_rwlock_destroy` is not supported on {}",
679699
this.tcx.sess.target.os
@@ -704,7 +724,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
704724
) -> InterpResult<'tcx, i32> {
705725
let this = self.eval_context_mut();
706726

707-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
727+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
708728
throw_unsup_format!(
709729
"`pthread_condattr_init` is not supported on {}",
710730
this.tcx.sess.target.os
@@ -728,9 +748,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
728748
let this = self.eval_context_mut();
729749

730750
// Does not exist on macOS!
731-
if !matches!(&*this.tcx.sess.target.os, "linux") {
751+
if !matches!(&*this.tcx.sess.target.os, "linux" | "solaris" | "illumos") {
732752
throw_unsup_format!(
733-
"`pthread_condattr_init` is not supported on {}",
753+
"`pthread_condattr_setclock` is not supported on {}",
734754
this.tcx.sess.target.os
735755
);
736756
}
@@ -756,9 +776,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
756776
let this = self.eval_context_mut();
757777

758778
// Does not exist on macOS!
759-
if !matches!(&*this.tcx.sess.target.os, "linux") {
779+
if !matches!(&*this.tcx.sess.target.os, "linux" | "solaris" | "illumos") {
760780
throw_unsup_format!(
761-
"`pthread_condattr_init` is not supported on {}",
781+
"`pthread_condattr_getclock` is not supported on {}",
762782
this.tcx.sess.target.os
763783
);
764784
}
@@ -793,7 +813,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
793813
) -> InterpResult<'tcx, i32> {
794814
let this = self.eval_context_mut();
795815

796-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos") {
816+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "solaris" | "illumos") {
797817
throw_unsup_format!(
798818
"`pthread_cond_init` is not supported on {}",
799819
this.tcx.sess.target.os

src/tools/miri/src/shims/unix/thread.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
4242
throw_unsup_format!("Miri supports pthread_join only with retval==NULL");
4343
}
4444

45-
let thread_id = this.read_target_usize(thread)?;
45+
let thread_id = this.read_scalar(thread)?.to_int(this.libc_ty_layout("pthread_t").size)?;
4646
this.join_thread_exclusive(thread_id.try_into().expect("thread ID should fit in u32"))?;
4747

4848
Ok(0)

0 commit comments

Comments
 (0)