Skip to content

Commit 6e74aa0

Browse files
committed
rustc_target: introduce Os
Improve type safety by using an enum rather than strings.
1 parent 64bc206 commit 6e74aa0

File tree

21 files changed

+142
-123
lines changed

21 files changed

+142
-123
lines changed

src/concurrency/thread.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_index::{Idx, IndexVec};
1515
use rustc_middle::mir::Mutability;
1616
use rustc_middle::ty::layout::TyAndLayout;
1717
use rustc_span::Span;
18+
use rustc_target::spec::Os;
1819

1920
use crate::concurrency::GlobalDataRaceHandler;
2021
use crate::shims::tls;
@@ -471,7 +472,7 @@ impl<'tcx> ThreadManager<'tcx> {
471472
) {
472473
ecx.machine.threads.threads[ThreadId::MAIN_THREAD].on_stack_empty =
473474
Some(on_main_stack_empty);
474-
if ecx.tcx.sess.target.os.as_ref() != "windows" {
475+
if ecx.tcx.sess.target.os != Os::Windows {
475476
// The main thread can *not* be joined on except on windows.
476477
ecx.machine.threads.threads[ThreadId::MAIN_THREAD].join_status =
477478
ThreadJoinStatus::Detached;

src/eval.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_hir::def_id::DefId;
1414
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutCx};
1515
use rustc_middle::ty::{self, Ty, TyCtxt};
1616
use rustc_session::config::EntryFnType;
17+
use rustc_target::spec::Os;
1718

1819
use crate::concurrency::GenmcCtx;
1920
use crate::concurrency::thread::TlsAllocAction;
@@ -341,7 +342,7 @@ pub fn create_ecx<'tcx>(
341342
ecx.machine.argv = Some(argv_place.ptr());
342343
}
343344
// Store command line as UTF-16 for Windows `GetCommandLineW`.
344-
if tcx.sess.target.os == "windows" {
345+
if tcx.sess.target.os == Os::Windows {
345346
// Construct a command string with all the arguments.
346347
let cmd_utf16: Vec<u16> = args_to_utf16_command_string(config.args.iter());
347348

src/helpers.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_middle::ty::{self, IntTy, Ty, TyCtxt, UintTy};
1919
use rustc_session::config::CrateType;
2020
use rustc_span::{Span, Symbol};
2121
use rustc_symbol_mangling::mangle_internal_symbol;
22+
use rustc_target::spec::Os;
2223

2324
use crate::*;
2425

@@ -234,7 +235,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
234235

235236
/// Helper function to get a `libc` constant as a `Scalar`.
236237
fn eval_libc(&self, name: &str) -> Scalar {
237-
if self.eval_context_ref().tcx.sess.target.os == "windows" {
238+
if self.eval_context_ref().tcx.sess.target.os == Os::Windows {
238239
panic!(
239240
"`libc` crate is not reliably available on Windows targets; Miri should not use it there"
240241
);
@@ -290,7 +291,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
290291
/// Helper function to get the `TyAndLayout` of a `libc` type
291292
fn libc_ty_layout(&self, name: &str) -> TyAndLayout<'tcx> {
292293
let this = self.eval_context_ref();
293-
if this.tcx.sess.target.os == "windows" {
294+
if this.tcx.sess.target.os == Os::Windows {
294295
panic!(
295296
"`libc` crate is not reliably available on Windows targets; Miri should not use it there"
296297
);
@@ -669,7 +670,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
669670
/// Helper function used inside the shims of foreign functions to assert that the target OS
670671
/// is `target_os`. It panics showing a message with the `name` of the foreign function
671672
/// if this is not the case.
672-
fn assert_target_os(&self, target_os: &str, name: &str) {
673+
fn assert_target_os(&self, target_os: Os, name: &str) {
673674
assert_eq!(
674675
self.eval_context_ref().tcx.sess.target.os,
675676
target_os,
@@ -680,9 +681,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
680681
/// Helper function used inside shims of foreign functions to check that the target OS
681682
/// is one of `target_oses`. It returns an error containing the `name` of the foreign function
682683
/// in a message if this is not the case.
683-
fn check_target_os(&self, target_oses: &[&str], name: Symbol) -> InterpResult<'tcx> {
684-
let target_os = self.eval_context_ref().tcx.sess.target.os.as_ref();
685-
if !target_oses.contains(&target_os) {
684+
fn check_target_os(&self, target_oses: &[Os], name: Symbol) -> InterpResult<'tcx> {
685+
let target_os = &self.eval_context_ref().tcx.sess.target.os;
686+
if !target_oses.contains(target_os) {
686687
throw_unsup_format!("`{name}` is not supported on {target_os}");
687688
}
688689
interp_ok(())
@@ -918,7 +919,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
918919
/// Always returns a `Vec<u32>` no matter the size of `wchar_t`.
919920
fn read_wchar_t_str(&self, ptr: Pointer) -> InterpResult<'tcx, Vec<u32>> {
920921
let this = self.eval_context_ref();
921-
let wchar_t = if this.tcx.sess.target.os == "windows" {
922+
let wchar_t = if this.tcx.sess.target.os == Os::Windows {
922923
// We don't have libc on Windows so we have to hard-code the type ourselves.
923924
this.machine.layouts.u16
924925
} else {

src/machine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_span::def_id::{CrateNum, DefId};
3131
use rustc_span::{Span, SpanData, Symbol};
3232
use rustc_symbol_mangling::mangle_internal_symbol;
3333
use rustc_target::callconv::FnAbi;
34-
use rustc_target::spec::Arch;
34+
use rustc_target::spec::{Arch, Os};
3535

3636
use crate::alloc_addresses::EvalContextExt;
3737
use crate::concurrency::cpu_affinity::{self, CpuAffinityMask};
@@ -739,7 +739,7 @@ impl<'tcx> MiriMachine<'tcx> {
739739
);
740740
let threads = ThreadManager::new(config);
741741
let mut thread_cpu_affinity = FxHashMap::default();
742-
if matches!(&*tcx.sess.target.os, "linux" | "freebsd" | "android") {
742+
if matches!(&tcx.sess.target.os, Os::Linux | Os::FreeBsd | Os::Android) {
743743
thread_cpu_affinity
744744
.insert(threads.active_thread(), CpuAffinityMask::new(&layout_cx, config.num_cpus));
745745
}

src/shims/alloc.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_ast::expand::allocator::SpecialAllocatorMethod;
33
use rustc_middle::ty::Ty;
44
use rustc_span::Symbol;
55
use rustc_target::callconv::FnAbi;
6-
use rustc_target::spec::Arch;
6+
use rustc_target::spec::{Arch, Os};
77

88
use crate::*;
99

@@ -19,10 +19,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
1919
// This is given by `alignof(max_align_t)`. The following list is taken from
2020
// `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should
2121
// be kept in sync.
22-
let os = this.tcx.sess.target.os.as_ref();
22+
let os = &this.tcx.sess.target.os;
2323
let max_fundamental_align = match &this.tcx.sess.target.arch {
24-
Arch::RiscV32 if matches!(os, "espidf" | "zkvm") => 4,
25-
Arch::Xtensa if matches!(os, "espidf") => 4,
24+
Arch::RiscV32 if matches!(os, Os::EspIdf | Os::Zkvm) => 4,
25+
Arch::Xtensa if matches!(os, Os::EspIdf) => 4,
2626
Arch::X86
2727
| Arch::Arm
2828
| Arch::M68k

src/shims/env.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::ffi::{OsStr, OsString};
22

33
use rustc_data_structures::fx::FxHashMap;
4+
use rustc_target::spec::Os;
45

56
use self::shims::unix::UnixEnvVars;
67
use self::shims::windows::WindowsEnvVars;
@@ -48,7 +49,7 @@ impl<'tcx> EnvVars<'tcx> {
4849

4950
let env_vars = if ecx.target_os_is_unix() {
5051
EnvVars::Unix(UnixEnvVars::new(ecx, env_vars)?)
51-
} else if ecx.tcx.sess.target.os == "windows" {
52+
} else if ecx.tcx.sess.target.os == Os::Windows {
5253
EnvVars::Windows(WindowsEnvVars::new(ecx, env_vars)?)
5354
} else {
5455
// For "none" targets (i.e., without an OS).
@@ -118,7 +119,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
118119
let this = self.eval_context_ref();
119120
let index = thread.to_u32();
120121
let target_os = &this.tcx.sess.target.os;
121-
if target_os == "linux" || target_os == "netbsd" {
122+
if matches!(target_os, Os::Linux | Os::NetBsd) {
122123
// On Linux, the main thread has PID == TID so we uphold this. NetBSD also appears
123124
// to exhibit the same behavior, though I can't find a citation.
124125
this.get_pid().strict_add(index)

src/shims/extern_static.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Provides the `extern static` that this platform expects.
22
3+
use rustc_target::spec::Os;
4+
35
use crate::*;
46

57
impl<'tcx> MiriMachine<'tcx> {
@@ -49,28 +51,28 @@ impl<'tcx> MiriMachine<'tcx> {
4951
Self::add_extern_static(ecx, "environ", environ);
5052
}
5153

52-
match ecx.tcx.sess.target.os.as_ref() {
53-
"linux" => {
54+
match &ecx.tcx.sess.target.os {
55+
Os::Linux => {
5456
Self::null_ptr_extern_statics(
5557
ecx,
5658
&["__cxa_thread_atexit_impl", "__clock_gettime64"],
5759
)?;
5860
Self::weak_symbol_extern_statics(ecx, &["getrandom", "gettid", "statx"])?;
5961
}
60-
"freebsd" => {
62+
Os::FreeBsd => {
6163
Self::null_ptr_extern_statics(ecx, &["__cxa_thread_atexit_impl"])?;
6264
}
63-
"android" => {
65+
Os::Android => {
6466
Self::null_ptr_extern_statics(ecx, &["bsd_signal"])?;
6567
Self::weak_symbol_extern_statics(ecx, &["signal", "getrandom", "gettid"])?;
6668
}
67-
"windows" => {
69+
Os::Windows => {
6870
// "_tls_used"
6971
// This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
7072
let val = ImmTy::from_int(0, ecx.machine.layouts.u8);
7173
Self::alloc_extern_static(ecx, "_tls_used", val)?;
7274
}
73-
"illumos" | "solaris" => {
75+
Os::Illumos | Os::Solaris => {
7476
Self::weak_symbol_extern_statics(ecx, &["pthread_setname_np"])?;
7577
}
7678
_ => {} // No "extern statics" supported on this target

src/shims/foreign_items.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_middle::{mir, ty};
1515
use rustc_session::config::OomStrategy;
1616
use rustc_span::Symbol;
1717
use rustc_target::callconv::FnAbi;
18-
use rustc_target::spec::Arch;
18+
use rustc_target::spec::{Os, Arch};
1919

2020
use super::alloc::EvalContextExt as _;
2121
use super::backtrace::EvalContextExt as _;
@@ -101,9 +101,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
101101

102102
fn is_dyn_sym(&self, name: &str) -> bool {
103103
let this = self.eval_context_ref();
104-
match this.tcx.sess.target.os.as_ref() {
104+
match &this.tcx.sess.target.os {
105105
os if this.target_os_is_unix() => shims::unix::foreign_items::is_dyn_sym(name, os),
106-
"windows" => shims::windows::foreign_items::is_dyn_sym(name),
106+
Os::Windows => shims::windows::foreign_items::is_dyn_sym(name),
107107
_ => false,
108108
}
109109
}
@@ -842,12 +842,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
842842
}
843843

844844
// Platform-specific shims
845-
return match this.tcx.sess.target.os.as_ref() {
845+
return match &this.tcx.sess.target.os {
846846
_ if this.target_os_is_unix() =>
847847
shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner(
848848
this, link_name, abi, args, dest,
849849
),
850-
"windows" =>
850+
Os::Windows =>
851851
shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner(
852852
this, link_name, abi, args, dest,
853853
),

src/shims/os_str.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::os::windows::ffi::{OsStrExt, OsStringExt};
77
use std::path::{Path, PathBuf};
88

99
use rustc_middle::ty::Ty;
10+
use rustc_target::spec::Os;
1011

1112
use crate::*;
1213

@@ -329,7 +330,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
329330
// Below we assume that everything non-Windows works like Unix, at least
330331
// when it comes to file system path conventions.
331332
#[cfg(windows)]
332-
return if target_os == "windows" {
333+
return if *target_os == Os::Windows {
333334
// Windows-on-Windows, all fine.
334335
os_str
335336
} else {
@@ -346,7 +347,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
346347
Cow::Owned(OsString::from_wide(&path))
347348
};
348349
#[cfg(unix)]
349-
return if target_os == "windows" {
350+
return if *target_os == Os::Windows {
350351
// Windows target, Unix host.
351352
let mut path: Vec<u8> = os_str.into_owned().into_encoded_bytes();
352353
match direction {

src/shims/time.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::time::{Duration, SystemTime};
55

66
use chrono::{DateTime, Datelike, Offset, Timelike, Utc};
77
use chrono_tz::Tz;
8+
use rustc_target::spec::Os;
89

910
use crate::*;
1011

@@ -31,8 +32,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3132
}
3233

3334
// Some further platform-specific names we support.
34-
match this.tcx.sess.target.os.as_ref() {
35-
"linux" | "freebsd" | "android" => {
35+
match &this.tcx.sess.target.os {
36+
Os::Linux | Os::FreeBsd | Os::Android => {
3637
// Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
3738
// is just specified to be "faster and less precise", so we treat it like normal
3839
// clocks.
@@ -42,7 +43,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
4243
return Some(TimeoutClock::Monotonic);
4344
}
4445
}
45-
"macos" => {
46+
Os::MacOs => {
4647
// `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but
4748
// that's not really something a program running inside Miri can tell, anyway.
4849
// We need to support it because std uses it.
@@ -176,7 +177,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
176177
// solaris/illumos system tm struct does not have
177178
// the additional tm_zone/tm_gmtoff fields.
178179
// https://docs.oracle.com/cd/E36784_01/html/E36874/localtime-r-3c.html
179-
if !matches!(&*this.tcx.sess.target.os, "solaris" | "illumos") {
180+
if !matches!(&this.tcx.sess.target.os, Os::Solaris | Os::Illumos) {
180181
// tm_zone represents the timezone value in the form of: +0730, +08, -0730 or -08.
181182
// This may not be consistent with libc::localtime_r's result.
182183

@@ -215,7 +216,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
215216
) -> InterpResult<'tcx> {
216217
let this = self.eval_context_mut();
217218

218-
this.assert_target_os("windows", shim_name);
219+
this.assert_target_os(Os::Windows, shim_name);
219220
this.check_no_isolation(shim_name)?;
220221

221222
let filetime = this.deref_pointer_as(LPFILETIME_op, this.windows_ty_layout("FILETIME"))?;
@@ -237,7 +238,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
237238
) -> InterpResult<'tcx, Scalar> {
238239
let this = self.eval_context_mut();
239240

240-
this.assert_target_os("windows", "QueryPerformanceCounter");
241+
this.assert_target_os(Os::Windows, "QueryPerformanceCounter");
241242

242243
// QueryPerformanceCounter uses a hardware counter as its basis.
243244
// Miri will emulate a counter with a resolution of 1 nanosecond.
@@ -260,7 +261,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
260261
) -> InterpResult<'tcx, Scalar> {
261262
let this = self.eval_context_mut();
262263

263-
this.assert_target_os("windows", "QueryPerformanceFrequency");
264+
this.assert_target_os(Os::Windows, "QueryPerformanceFrequency");
264265

265266
// Retrieves the frequency of the hardware performance counter.
266267
// The frequency of the performance counter is fixed at system boot and
@@ -301,7 +302,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
301302
fn mach_absolute_time(&self) -> InterpResult<'tcx, Scalar> {
302303
let this = self.eval_context_ref();
303304

304-
this.assert_target_os("macos", "mach_absolute_time");
305+
this.assert_target_os(Os::MacOs, "mach_absolute_time");
305306

306307
// This returns a u64, with time units determined dynamically by `mach_timebase_info`.
307308
// We return plain nanoseconds.
@@ -316,7 +317,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
316317
fn mach_timebase_info(&mut self, info_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
317318
let this = self.eval_context_mut();
318319

319-
this.assert_target_os("macos", "mach_timebase_info");
320+
this.assert_target_os(Os::MacOs, "mach_timebase_info");
320321

321322
let info = this.deref_pointer_as(info_op, this.libc_ty_layout("mach_timebase_info"))?;
322323

@@ -418,7 +419,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
418419
fn Sleep(&mut self, timeout: &OpTy<'tcx>) -> InterpResult<'tcx> {
419420
let this = self.eval_context_mut();
420421

421-
this.assert_target_os("windows", "Sleep");
422+
this.assert_target_os(Os::Windows, "Sleep");
422423

423424
let timeout_ms = this.read_scalar(timeout)?.to_u32()?;
424425

0 commit comments

Comments
 (0)