Skip to content

Commit d193769

Browse files
committed
Make work after mir-alloc-oom
1 parent 6a18683 commit d193769

11 files changed

+44
-34
lines changed

rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
46ae6ee65df19c6a3fb683499c1203e749975e60
1+
39e20f1ae5f13451eb35247808d6a2527cb7d060

src/eval.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,16 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
169169
// Make space for `0` terminator.
170170
let size = u64::try_from(arg.len()).unwrap().checked_add(1).unwrap();
171171
let arg_type = tcx.mk_array(tcx.types.u8, size);
172-
let arg_place = ecx.allocate(ecx.layout_of(arg_type)?, MiriMemoryKind::Machine.into());
172+
let arg_place =
173+
ecx.allocate(ecx.layout_of(arg_type)?, MiriMemoryKind::Machine.into())?;
173174
ecx.write_os_str_to_c_str(OsStr::new(arg), arg_place.ptr, size)?;
174175
argvs.push(arg_place.ptr);
175176
}
176177
// Make an array with all these pointers, in the Miri memory.
177178
let argvs_layout = ecx.layout_of(
178179
tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), u64::try_from(argvs.len()).unwrap()),
179180
)?;
180-
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into());
181+
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into())?;
181182
for (idx, arg) in argvs.into_iter().enumerate() {
182183
let place = ecx.mplace_field(&argvs_place, idx)?;
183184
ecx.write_scalar(arg, &place.into())?;
@@ -188,14 +189,14 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
188189
// Store `argc` and `argv` for macOS `_NSGetArg{c,v}`.
189190
{
190191
let argc_place =
191-
ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into());
192+
ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?;
192193
ecx.write_scalar(argc, &argc_place.into())?;
193194
ecx.machine.argc = Some(argc_place.ptr);
194195

195196
let argv_place = ecx.allocate(
196197
ecx.layout_of(tcx.mk_imm_ptr(tcx.types.unit))?,
197198
MiriMemoryKind::Machine.into(),
198-
);
199+
)?;
199200
ecx.write_scalar(argv, &argv_place.into())?;
200201
ecx.machine.argv = Some(argv_place.ptr);
201202
}
@@ -214,7 +215,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
214215

215216
let cmd_utf16: Vec<u16> = cmd.encode_utf16().collect();
216217
let cmd_type = tcx.mk_array(tcx.types.u16, u64::try_from(cmd_utf16.len()).unwrap());
217-
let cmd_place = ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into());
218+
let cmd_place =
219+
ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into())?;
218220
ecx.machine.cmd_line = Some(cmd_place.ptr);
219221
// Store the UTF-16 string. We just allocated so we know the bounds are fine.
220222
for (idx, &c) in cmd_utf16.iter().enumerate() {
@@ -226,7 +228,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
226228
};
227229

228230
// Return place (in static memory so that it does not count as leak).
229-
let ret_place = ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into());
231+
let ret_place = ecx.allocate(ecx.machine.layouts.isize, MiriMemoryKind::Machine.into())?;
230232
// Call start function.
231233
ecx.call_function(
232234
start_instance,

src/helpers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
440440
} else {
441441
// Allocate new place, set initial value to 0.
442442
let errno_layout = this.machine.layouts.u32;
443-
let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into());
443+
let errno_place = this.allocate(errno_layout, MiriMemoryKind::Machine.into())?;
444444
this.write_scalar(Scalar::from_u32(0), &errno_place.into())?;
445445
this.active_thread_mut().last_error = Some(errno_place);
446446
Ok(errno_place)

src/machine.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ impl MemoryExtra {
199199
// "__cxa_thread_atexit_impl"
200200
// This should be all-zero, pointer-sized.
201201
let layout = this.machine.layouts.usize;
202-
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into());
202+
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
203203
this.write_scalar(Scalar::from_machine_usize(0, this), &place.into())?;
204204
Self::add_extern_static(this, "__cxa_thread_atexit_impl", place.ptr);
205205
// "environ"
@@ -213,7 +213,7 @@ impl MemoryExtra {
213213
// "_tls_used"
214214
// This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
215215
let layout = this.machine.layouts.u8;
216-
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into());
216+
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
217217
this.write_scalar(Scalar::from_u8(0), &place.into())?;
218218
Self::add_extern_static(this, "_tls_used", place.ptr);
219219
}
@@ -377,6 +377,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
377377

378378
const GLOBAL_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Global);
379379

380+
const PANIC_ON_ALLOC_FAIL: bool = false;
381+
380382
#[inline(always)]
381383
fn enforce_alignment(memory_extra: &MemoryExtra) -> bool {
382384
memory_extra.check_alignment != AlignmentCheck::None

src/shims/backtrace.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5757
let array_ty = tcx.mk_array(ptr_ty, ptrs.len().try_into().unwrap());
5858

5959
// Write pointers into array
60-
let alloc = this.allocate(this.layout_of(array_ty).unwrap(), MiriMemoryKind::Rust.into());
60+
let alloc =
61+
this.allocate(this.layout_of(array_ty).unwrap(), MiriMemoryKind::Rust.into())?;
6162
for (i, ptr) in ptrs.into_iter().enumerate() {
6263
let place = this.mplace_index(&alloc, i as u64)?;
6364
this.write_immediate_to_mplace(ptr.into(), &place)?;

src/shims/env.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ fn alloc_env_var_as_c_str<'mir, 'tcx>(
8888
let mut name_osstring = name.to_os_string();
8989
name_osstring.push("=");
9090
name_osstring.push(value);
91-
Ok(ecx.alloc_os_str_as_c_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into()))
91+
ecx.alloc_os_str_as_c_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into())
9292
}
9393

9494
fn alloc_env_var_as_wide_str<'mir, 'tcx>(
@@ -99,7 +99,7 @@ fn alloc_env_var_as_wide_str<'mir, 'tcx>(
9999
let mut name_osstring = name.to_os_string();
100100
name_osstring.push("=");
101101
name_osstring.push(value);
102-
Ok(ecx.alloc_os_str_as_wide_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into()))
102+
ecx.alloc_os_str_as_wide_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into())
103103
}
104104

105105
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
@@ -179,7 +179,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
179179
}
180180
// Allocate environment block & Store environment variables to environment block.
181181
// Final null terminator(block terminator) is added by `alloc_os_str_to_wide_str`.
182-
let envblock_ptr = this.alloc_os_str_as_wide_str(&env_vars, MiriMemoryKind::Env.into());
182+
let envblock_ptr = this.alloc_os_str_as_wide_str(&env_vars, MiriMemoryKind::Env.into())?;
183183
// If the function succeeds, the return value is a pointer to the environment block of the current process.
184184
Ok(envblock_ptr.into())
185185
}
@@ -442,7 +442,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
442442
// No `environ` allocated yet, let's do that.
443443
// This is memory backing an extern static, hence `ExternStatic`, not `Env`.
444444
let layout = this.machine.layouts.usize;
445-
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into());
445+
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
446446
this.machine.env_vars.environ = Some(place);
447447
}
448448

@@ -455,7 +455,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
455455
let tcx = this.tcx;
456456
let vars_layout =
457457
this.layout_of(tcx.mk_array(tcx.types.usize, u64::try_from(vars.len()).unwrap()))?;
458-
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Env.into());
458+
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Env.into())?;
459459
for (idx, var) in vars.into_iter().enumerate() {
460460
let place = this.mplace_field(&vars_place, idx)?;
461461
this.write_scalar(var, &place.into())?;

src/shims/foreign_items.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6767
Align::from_bytes(prev_power_of_two(size)).unwrap()
6868
}
6969

70-
fn malloc(&mut self, size: u64, zero_init: bool, kind: MiriMemoryKind) -> Scalar<Tag> {
70+
fn malloc(
71+
&mut self,
72+
size: u64,
73+
zero_init: bool,
74+
kind: MiriMemoryKind,
75+
) -> InterpResult<'tcx, Scalar<Tag>> {
7176
let this = self.eval_context_mut();
7277
if size == 0 {
73-
Scalar::null_ptr(this)
78+
Ok(Scalar::null_ptr(this))
7479
} else {
7580
let align = this.min_align(size, kind);
76-
let ptr = this.memory.allocate(Size::from_bytes(size), align, kind.into());
81+
let ptr = this.memory.allocate(Size::from_bytes(size), align, kind.into())?;
7782
if zero_init {
7883
// We just allocated this, the access is definitely in-bounds.
7984
this.memory.write_bytes(ptr.into(), iter::repeat(0u8).take(size as usize)).unwrap();
8085
}
81-
Scalar::Ptr(ptr)
86+
Ok(Scalar::Ptr(ptr))
8287
}
8388
}
8489

@@ -104,7 +109,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
104109
Ok(Scalar::null_ptr(this))
105110
} else {
106111
let new_ptr =
107-
this.memory.allocate(Size::from_bytes(new_size), new_align, kind.into());
112+
this.memory.allocate(Size::from_bytes(new_size), new_align, kind.into())?;
108113
Ok(Scalar::Ptr(new_ptr))
109114
}
110115
} else {
@@ -331,7 +336,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
331336
"malloc" => {
332337
let &[ref size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
333338
let size = this.read_scalar(size)?.to_machine_usize(this)?;
334-
let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C);
339+
let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C)?;
335340
this.write_scalar(res, dest)?;
336341
}
337342
"calloc" => {
@@ -340,7 +345,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
340345
let len = this.read_scalar(len)?.to_machine_usize(this)?;
341346
let size =
342347
items.checked_mul(len).ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?;
343-
let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C);
348+
let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C)?;
344349
this.write_scalar(res, dest)?;
345350
}
346351
"free" => {
@@ -368,7 +373,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
368373
Size::from_bytes(size),
369374
Align::from_bytes(align).unwrap(),
370375
MiriMemoryKind::Rust.into(),
371-
);
376+
)?;
372377
this.write_scalar(ptr, dest)?;
373378
}
374379
"__rust_alloc_zeroed" => {
@@ -380,7 +385,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
380385
Size::from_bytes(size),
381386
Align::from_bytes(align).unwrap(),
382387
MiriMemoryKind::Rust.into(),
383-
);
388+
)?;
384389
// We just allocated this, the access is definitely in-bounds.
385390
this.memory.write_bytes(ptr.into(), iter::repeat(0u8).take(usize::try_from(size).unwrap())).unwrap();
386391
this.write_scalar(ptr, dest)?;

src/shims/os_str.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -161,29 +161,29 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
161161
&mut self,
162162
os_str: &OsStr,
163163
memkind: MemoryKind<MiriMemoryKind>,
164-
) -> Pointer<Tag> {
164+
) -> InterpResult<'tcx, Pointer<Tag>> {
165165
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator.
166166
let this = self.eval_context_mut();
167167

168168
let arg_type = this.tcx.mk_array(this.tcx.types.u8, size);
169-
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind);
169+
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
170170
assert!(self.write_os_str_to_c_str(os_str, arg_place.ptr, size).unwrap().0);
171-
arg_place.ptr.assert_ptr()
171+
Ok(arg_place.ptr.assert_ptr())
172172
}
173173

174174
/// Allocate enough memory to store the given `OsStr` as a null-terminated sequence of `u16`.
175175
fn alloc_os_str_as_wide_str(
176176
&mut self,
177177
os_str: &OsStr,
178178
memkind: MemoryKind<MiriMemoryKind>,
179-
) -> Pointer<Tag> {
179+
) -> InterpResult<'tcx, Pointer<Tag>> {
180180
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0x0000` terminator.
181181
let this = self.eval_context_mut();
182182

183183
let arg_type = this.tcx.mk_array(this.tcx.types.u16, size);
184-
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind);
184+
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind)?;
185185
assert!(self.write_os_str_to_wide_str(os_str, arg_place.ptr, size).unwrap().0);
186-
arg_place.ptr.assert_ptr()
186+
Ok(arg_place.ptr.assert_ptr())
187187
}
188188

189189
/// Read a null-terminated sequence of bytes, and perform path separator conversion if needed.

src/shims/posix/foreign_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
159159
Size::from_bytes(size),
160160
Align::from_bytes(align).unwrap(),
161161
MiriMemoryKind::C.into(),
162-
);
162+
)?;
163163
this.write_scalar(ptr, &ret.into())?;
164164
}
165165
this.write_null(dest)?;

src/shims/posix/thread.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4747
// pthread_join below) because the Rust standard library does not use
4848
// it.
4949
let ret_place =
50-
this.allocate(this.layout_of(this.tcx.types.usize)?, MiriMemoryKind::Machine.into());
50+
this.allocate(this.layout_of(this.tcx.types.usize)?, MiriMemoryKind::Machine.into())?;
5151

5252
this.call_function(
5353
instance,

src/shims/windows/foreign_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
115115
let flags = this.read_scalar(flags)?.to_u32()?;
116116
let size = this.read_scalar(size)?.to_machine_usize(this)?;
117117
let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
118-
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap);
118+
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap)?;
119119
this.write_scalar(res, dest)?;
120120
}
121121
"HeapFree" => {

0 commit comments

Comments
 (0)