Skip to content

Commit 11d7be9

Browse files
committed
Move last_error into memory
1 parent 905c70c commit 11d7be9

File tree

5 files changed

+60
-18
lines changed

5 files changed

+60
-18
lines changed

src/eval.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
183183
"start lang item has more arguments than expected"
184184
);
185185

186+
// Set the last_error to 0
187+
let errno_layout = ecx.layout_of(ecx.tcx.types.u32)?;
188+
let errno_place = ecx.allocate(errno_layout, MiriMemoryKind::Static.into());
189+
ecx.write_scalar(Scalar::from_u32(0), errno_place.into())?;
190+
let errno_ptr = ecx.check_mplace_access(errno_place.into(), Some(Size::from_bits(32)))?;
191+
ecx.machine.last_error = errno_ptr;
192+
186193
Ok(ecx)
187194
}
188195

src/machine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ pub struct Evaluator<'tcx> {
9292
pub(crate) cmd_line: Option<Pointer<Tag>>,
9393

9494
/// Last OS error.
95-
pub(crate) last_error: u32,
95+
pub(crate) last_error: Option<Pointer<Tag>>,
9696

9797
/// TLS state.
9898
pub(crate) tls: TlsData<'tcx>,
@@ -113,7 +113,7 @@ impl<'tcx> Evaluator<'tcx> {
113113
argc: None,
114114
argv: None,
115115
cmd_line: None,
116-
last_error: 0,
116+
last_error: None,
117117
tls: TlsData::default(),
118118
communicate,
119119
file_handler: Default::default(),

src/shims/env.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,18 +137,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
137137
if (bytes.len() as u64) < size {
138138
// We add a `/0` terminator
139139
bytes.push(0);
140-
// This is ok because the buffer is larger than the path with the null terminator.
140+
// This is ok because the buffer is larger than the path with terminatorhe null terminator.
141141
this.memory_mut()
142142
.get_mut(buf.alloc_id)?
143143
.write_bytes(tcx, buf, &bytes)?;
144144
return Ok(Scalar::Ptr(buf));
145145
}
146-
this.machine.last_error = this
147-
.eval_path_scalar(&["libc", "ERANGE"])?
148-
.unwrap()
149-
.to_u32()?;
146+
let erange = this.eval_libc("ERANGE")?;
147+
this.set_last_error(erange)?;
150148
}
151-
Err(e) => this.machine.last_error = e.raw_os_error().unwrap() as u32,
149+
Err(e) => this.set_last_error(Scalar::from_int(
150+
e.raw_os_error().unwrap(),
151+
Size::from_bits(32),
152+
))?,
152153
}
153154
Ok(Scalar::ptr_null(&*this.tcx))
154155
}
@@ -172,7 +173,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
172173
match env::set_current_dir(path) {
173174
Ok(()) => Ok(0),
174175
Err(e) => {
175-
this.machine.last_error = e.raw_os_error().unwrap() as u32;
176+
this.set_last_error(Scalar::from_int(
177+
e.raw_os_error().unwrap(),
178+
Size::from_bits(32),
179+
))?;
176180
Ok(-1)
177181
}
178182
}

src/shims/foreign_items.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
808808
}
809809

810810
"SetLastError" => {
811-
let err = this.read_scalar(args[0])?.to_u32()?;
812-
this.machine.last_error = err;
811+
this.set_last_error(this.read_scalar(args[0])?.not_undef()?)?;
813812
}
814813
"GetLastError" => {
815-
this.write_scalar(Scalar::from_u32(this.machine.last_error), dest)?;
814+
let last_error = this.get_last_error()?;
815+
this.write_scalar(last_error, dest)?;
816816
}
817817

818818
"AddVectoredExceptionHandler" => {
@@ -929,7 +929,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
929929
}
930930
"GetEnvironmentVariableW" => {
931931
// This is not the env var you are looking for.
932-
this.machine.last_error = 203; // ERROR_ENVVAR_NOT_FOUND
932+
this.set_last_error(Scalar::from_u32(203))?; // ERROR_ENVVAR_NOT_FOUND
933933
this.write_null(dest)?;
934934
}
935935
"GetCommandLineW" => {
@@ -971,11 +971,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
971971
return Ok(None);
972972
}
973973

974-
fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
974+
fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
975975
self.eval_context_mut()
976976
.eval_path_scalar(&["libc", name])?
977977
.ok_or_else(|| err_unsup_format!("Path libc::{} cannot be resolved.", name).into())
978-
.and_then(|scalar| scalar.to_i32())
978+
.and_then(|scalar| scalar.not_undef())
979+
}
980+
981+
fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
982+
self.eval_libc(name).and_then(|scalar| scalar.to_i32())
983+
}
984+
985+
fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx, ()> {
986+
let this = self.eval_context_mut();
987+
let tcx = &{ this.tcx.tcx };
988+
let errno_ptr = this.machine.last_error.unwrap();
989+
this.memory_mut().get_mut(errno_ptr.alloc_id)?.write_scalar(
990+
tcx,
991+
errno_ptr,
992+
scalar.into(),
993+
Size::from_bits(32),
994+
)
995+
}
996+
997+
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
998+
let this = self.eval_context_mut();
999+
let tcx = &{ this.tcx.tcx };
1000+
let errno_ptr = this.machine.last_error.unwrap();
1001+
this.memory()
1002+
.get(errno_ptr.alloc_id)?
1003+
.read_scalar(tcx, errno_ptr, Size::from_bits(32))?
1004+
.not_undef()
9791005
}
9801006
}
9811007

src/shims/io.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
221221
if let Some(handle) = this.machine.file_handler.handles.get(&fd) {
222222
f(handle)
223223
} else {
224-
this.machine.last_error = this.eval_libc_i32("EBADF")? as u32;
224+
let ebadf = this.eval_libc("EBADF")?;
225+
this.set_last_error(ebadf)?;
225226
Ok((-1).into())
226227
}
227228
}
@@ -244,7 +245,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
244245
if let Some(handle) = this.machine.file_handler.handles.remove(&fd) {
245246
f(handle, this)
246247
} else {
247-
this.machine.last_error = this.eval_libc_i32("EBADF")? as u32;
248+
let ebadf = this.eval_libc("EBADF")?;
249+
this.set_last_error(ebadf)?;
248250
Ok((-1).into())
249251
}
250252
}
@@ -262,7 +264,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
262264
match result {
263265
Ok(ok) => Ok(ok),
264266
Err(e) => {
265-
self.eval_context_mut().machine.last_error = e.raw_os_error().unwrap() as u32;
267+
self.eval_context_mut().set_last_error(Scalar::from_int(
268+
e.raw_os_error().unwrap(),
269+
Size::from_bits(32),
270+
))?;
266271
Ok((-1).into())
267272
}
268273
}

0 commit comments

Comments
 (0)