@@ -4,14 +4,14 @@ use log::trace;
44
55use rustc_hir:: def_id:: DefId ;
66use rustc_middle:: mir;
7- use rustc_target:: { abi:: { Align , Size } , spec:: PanicStrategy } ;
7+ use rustc_target:: { abi:: { Align , Size } , spec:: { PanicStrategy , abi :: Abi } } ;
88use rustc_middle:: ty;
99use rustc_apfloat:: Float ;
1010use rustc_span:: symbol:: sym;
1111
1212use crate :: * ;
1313use super :: backtrace:: EvalContextExt as _;
14- use helpers:: check_arg_count;
14+ use helpers:: { check_abi , check_arg_count} ;
1515
1616impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
1717pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
@@ -112,6 +112,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
112112 fn emulate_foreign_item (
113113 & mut self ,
114114 def_id : DefId ,
115+ abi : Abi ,
115116 args : & [ OpTy < ' tcx , Tag > ] ,
116117 ret : Option < ( PlaceTy < ' tcx , Tag > , mir:: BasicBlock ) > ,
117118 unwind : Option < mir:: BasicBlock > ,
@@ -130,25 +131,29 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
130131 let ( dest, ret) = match ret {
131132 None => match link_name {
132133 "miri_start_panic" => {
134+ check_abi ( abi, Abi :: Rust ) ?;
133135 this. handle_miri_start_panic ( args, unwind) ?;
134136 return Ok ( None ) ;
135137 }
136138 // This matches calls to the foreign item `panic_impl`.
137139 // The implementation is provided by the function with the `#[panic_handler]` attribute.
138140 "panic_impl" => {
141+ check_abi ( abi, Abi :: Rust ) ?;
139142 let panic_impl_id = tcx. lang_items ( ) . panic_impl ( ) . unwrap ( ) ;
140143 let panic_impl_instance = ty:: Instance :: mono ( tcx, panic_impl_id) ;
141144 return Ok ( Some ( & * this. load_mir ( panic_impl_instance. def , None ) ?) ) ;
142145 }
143146 | "exit"
144147 | "ExitProcess"
145148 => {
149+ check_abi ( abi, if link_name == "exit" { Abi :: C } else { Abi :: System } ) ?;
146150 let & [ code] = check_arg_count ( args) ?;
147151 // it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway
148152 let code = this. read_scalar ( code) ?. to_i32 ( ) ?;
149153 throw_machine_stop ! ( TerminationInfo :: Exit ( code. into( ) ) ) ;
150154 }
151155 "abort" => {
156+ check_abi ( abi, Abi :: C ) ?;
152157 throw_machine_stop ! ( TerminationInfo :: Abort ( "the program aborted execution" . to_owned( ) ) )
153158 }
154159 _ => throw_unsup_format ! ( "can't call (diverging) foreign function: {}" , link_name) ,
@@ -165,6 +170,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
165170 // Normally, this will be either `libpanic_unwind` or `libpanic_abort`, but it could
166171 // also be a custom user-provided implementation via `#![feature(panic_runtime)]`
167172 "__rust_start_panic" | "__rust_panic_cleanup" => {
173+ check_abi ( abi, Abi :: C ) ?;
168174 // This replicates some of the logic in `inject_panic_runtime`.
169175 // FIXME: is there a way to reuse that logic?
170176 let panic_runtime = match this. tcx . sess . panic_strategy ( ) {
@@ -179,7 +185,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
179185 }
180186
181187 // Third: functions that return.
182- if this. emulate_foreign_item_by_name ( link_name, args, dest, ret) ? {
188+ if this. emulate_foreign_item_by_name ( link_name, abi , args, dest, ret) ? {
183189 trace ! ( "{:?}" , this. dump_place( * dest) ) ;
184190 this. go_to_block ( ret) ;
185191 }
@@ -193,6 +199,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
193199 fn emulate_foreign_item_by_name (
194200 & mut self ,
195201 link_name : & str ,
202+ abi : Abi ,
196203 args : & [ OpTy < ' tcx , Tag > ] ,
197204 dest : PlaceTy < ' tcx , Tag > ,
198205 ret : mir:: BasicBlock ,
@@ -204,6 +211,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
204211 match link_name {
205212 // Miri-specific extern functions
206213 "miri_static_root" => {
214+ check_abi ( abi, Abi :: Rust ) ?;
207215 let & [ ptr] = check_arg_count ( args) ?;
208216 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
209217 let ptr = this. force_ptr ( ptr) ?;
@@ -215,23 +223,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
215223
216224 // Obtains a Miri backtrace. See the README for details.
217225 "miri_get_backtrace" => {
226+ check_abi ( abi, Abi :: Rust ) ?;
218227 this. handle_miri_get_backtrace ( args, dest) ?;
219228 }
220229
221230 // Resolves a Miri backtrace frame. See the README for details.
222231 "miri_resolve_frame" => {
232+ check_abi ( abi, Abi :: Rust ) ?;
223233 this. handle_miri_resolve_frame ( args, dest) ?;
224234 }
225235
226236
227237 // Standard C allocation
228238 "malloc" => {
239+ check_abi ( abi, Abi :: C ) ?;
229240 let & [ size] = check_arg_count ( args) ?;
230241 let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
231242 let res = this. malloc ( size, /*zero_init:*/ false , MiriMemoryKind :: C ) ;
232243 this. write_scalar ( res, dest) ?;
233244 }
234245 "calloc" => {
246+ check_abi ( abi, Abi :: C ) ?;
235247 let & [ items, len] = check_arg_count ( args) ?;
236248 let items = this. read_scalar ( items) ?. to_machine_usize ( this) ?;
237249 let len = this. read_scalar ( len) ?. to_machine_usize ( this) ?;
@@ -241,11 +253,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
241253 this. write_scalar ( res, dest) ?;
242254 }
243255 "free" => {
256+ check_abi ( abi, Abi :: C ) ?;
244257 let & [ ptr] = check_arg_count ( args) ?;
245258 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
246259 this. free ( ptr, MiriMemoryKind :: C ) ?;
247260 }
248261 "realloc" => {
262+ check_abi ( abi, Abi :: C ) ?;
249263 let & [ old_ptr, new_size] = check_arg_count ( args) ?;
250264 let old_ptr = this. read_scalar ( old_ptr) ?. check_init ( ) ?;
251265 let new_size = this. read_scalar ( new_size) ?. to_machine_usize ( this) ?;
@@ -257,6 +271,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
257271 // (Usually these would be forwarded to to `#[global_allocator]`; we instead implement a generic
258272 // allocation that also checks that all conditions are met, such as not permitting zero-sized allocations.)
259273 "__rust_alloc" => {
274+ check_abi ( abi, Abi :: Rust ) ?;
260275 let & [ size, align] = check_arg_count ( args) ?;
261276 let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
262277 let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
@@ -269,6 +284,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
269284 this. write_scalar ( ptr, dest) ?;
270285 }
271286 "__rust_alloc_zeroed" => {
287+ check_abi ( abi, Abi :: Rust ) ?;
272288 let & [ size, align] = check_arg_count ( args) ?;
273289 let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
274290 let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
@@ -283,6 +299,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
283299 this. write_scalar ( ptr, dest) ?;
284300 }
285301 "__rust_dealloc" => {
302+ check_abi ( abi, Abi :: Rust ) ?;
286303 let & [ ptr, old_size, align] = check_arg_count ( args) ?;
287304 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
288305 let old_size = this. read_scalar ( old_size) ?. to_machine_usize ( this) ?;
@@ -296,6 +313,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
296313 ) ?;
297314 }
298315 "__rust_realloc" => {
316+ check_abi ( abi, Abi :: Rust ) ?;
299317 let & [ ptr, old_size, align, new_size] = check_arg_count ( args) ?;
300318 let ptr = this. force_ptr ( this. read_scalar ( ptr) ?. check_init ( ) ?) ?;
301319 let old_size = this. read_scalar ( old_size) ?. to_machine_usize ( this) ?;
@@ -316,6 +334,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
316334
317335 // C memory handling functions
318336 "memcmp" => {
337+ check_abi ( abi, Abi :: C ) ?;
319338 let & [ left, right, n] = check_arg_count ( args) ?;
320339 let left = this. read_scalar ( left) ?. check_init ( ) ?;
321340 let right = this. read_scalar ( right) ?. check_init ( ) ?;
@@ -336,6 +355,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
336355 this. write_scalar ( Scalar :: from_i32 ( result) , dest) ?;
337356 }
338357 "memrchr" => {
358+ check_abi ( abi, Abi :: C ) ?;
339359 let & [ ptr, val, num] = check_arg_count ( args) ?;
340360 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
341361 let val = this. read_scalar ( val) ?. to_i32 ( ) ? as u8 ;
@@ -354,6 +374,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
354374 }
355375 }
356376 "memchr" => {
377+ check_abi ( abi, Abi :: C ) ?;
357378 let & [ ptr, val, num] = check_arg_count ( args) ?;
358379 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
359380 let val = this. read_scalar ( val) ?. to_i32 ( ) ? as u8 ;
@@ -371,6 +392,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
371392 }
372393 }
373394 "strlen" => {
395+ check_abi ( abi, Abi :: C ) ?;
374396 let & [ ptr] = check_arg_count ( args) ?;
375397 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
376398 let n = this. memory . read_c_str ( ptr) ?. len ( ) ;
@@ -386,6 +408,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
386408 | "asinf"
387409 | "atanf"
388410 => {
411+ check_abi ( abi, Abi :: C ) ?;
389412 let & [ f] = check_arg_count ( args) ?;
390413 // FIXME: Using host floats.
391414 let f = f32:: from_bits ( this. read_scalar ( f) ?. to_u32 ( ) ?) ;
@@ -405,6 +428,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
405428 | "hypotf"
406429 | "atan2f"
407430 => {
431+ check_abi ( abi, Abi :: C ) ?;
408432 let & [ f1, f2] = check_arg_count ( args) ?;
409433 // underscore case for windows, here and below
410434 // (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/floating-point-primitives?view=vs-2019)
@@ -426,6 +450,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
426450 | "asin"
427451 | "atan"
428452 => {
453+ check_abi ( abi, Abi :: C ) ?;
429454 let & [ f] = check_arg_count ( args) ?;
430455 // FIXME: Using host floats.
431456 let f = f64:: from_bits ( this. read_scalar ( f) ?. to_u64 ( ) ?) ;
@@ -445,6 +470,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
445470 | "hypot"
446471 | "atan2"
447472 => {
473+ check_abi ( abi, Abi :: C ) ?;
448474 let & [ f1, f2] = check_arg_count ( args) ?;
449475 // FIXME: Using host floats.
450476 let f1 = f64:: from_bits ( this. read_scalar ( f1) ?. to_u64 ( ) ?) ;
@@ -460,6 +486,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
460486 | "ldexp"
461487 | "scalbn"
462488 => {
489+ check_abi ( abi, Abi :: C ) ?;
463490 let & [ x, exp] = check_arg_count ( args) ?;
464491 // For radix-2 (binary) systems, `ldexp` and `scalbn` are the same.
465492 let x = this. read_scalar ( x) ?. to_f64 ( ) ?;
@@ -481,10 +508,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
481508
482509 // Architecture-specific shims
483510 "llvm.x86.sse2.pause" if this. tcx . sess . target . arch == "x86" || this. tcx . sess . target . arch == "x86_64" => {
511+ check_abi ( abi, Abi :: C ) ?;
484512 let & [ ] = check_arg_count ( args) ?;
485513 this. yield_active_thread ( ) ;
486514 }
487515 "llvm.aarch64.hint" if this. tcx . sess . target . arch == "aarch64" => {
516+ check_abi ( abi, Abi :: C ) ?;
488517 let & [ hint] = check_arg_count ( args) ?;
489518 let hint = this. read_scalar ( hint) ?. to_i32 ( ) ?;
490519 match hint {
@@ -499,8 +528,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
499528
500529 // Platform-specific shims
501530 _ => match this. tcx . sess . target . os . as_str ( ) {
502- "linux" | "macos" => return shims:: posix:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, args, dest, ret) ,
503- "windows" => return shims:: windows:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, args, dest, ret) ,
531+ "linux" | "macos" => return shims:: posix:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, abi , args, dest, ret) ,
532+ "windows" => return shims:: windows:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, abi , args, dest, ret) ,
504533 target => throw_unsup_format ! ( "the target `{}` is not supported" , target) ,
505534 }
506535 } ;
0 commit comments