@@ -25,6 +25,7 @@ use rustc_target::{
2525
2626use super :: backtrace:: EvalContextExt as _;
2727use crate :: * ;
28+ use helpers:: strip_linker_suffix;
2829
2930/// Returned by `emulate_foreign_item_by_name`.
3031pub enum EmulateByNameResult {
@@ -215,8 +216,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
215216 . first_attr_value_str_by_name ( & attrs, sym:: link_name)
216217 . unwrap_or_else ( || this. tcx . item_name ( def_id) ) ;
217218 let link_name = link_name_sym. as_str ( ) ;
218- // Strip linker suffixes (seen on 32-bit macOS).
219- let link_name = link_name. trim_end_matches ( "$UNIX2003" ) ;
219+ let link_name = strip_linker_suffix ( & link_name) ;
220220 let tcx = this. tcx . tcx ;
221221
222222 // First: functions that diverge.
@@ -274,7 +274,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
274274 } ;
275275
276276 // Second: functions that return.
277- match this. emulate_foreign_item_by_name ( link_name , link_name_sym, abi, args, dest, ret) ? {
277+ match this. emulate_foreign_item_by_name ( link_name_sym, abi, args, dest, ret) ? {
278278 EmulateByNameResult :: NeedsJumping => {
279279 trace ! ( "{:?}" , this. dump_place( * * dest) ) ;
280280 this. go_to_block ( ret) ;
@@ -296,8 +296,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
296296 /// Emulates calling a foreign item using its name.
297297 fn emulate_foreign_item_by_name (
298298 & mut self ,
299- link_name : & str ,
300- link_name_sym : Symbol ,
299+ link_name : Symbol ,
301300 abi : Abi ,
302301 args : & [ OpTy < ' tcx , Tag > ] ,
303302 dest : & PlaceTy < ' tcx , Tag > ,
@@ -307,10 +306,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
307306
308307 // Here we dispatch all the shims for foreign functions. If you have a platform specific
309308 // shim, add it to the corresponding submodule.
310- match link_name {
309+ let shim_name = link_name. as_str ( ) ;
310+ let shim_name = strip_linker_suffix ( & shim_name) ;
311+ match shim_name {
311312 // Miri-specific extern functions
312313 "miri_static_root" => {
313- let & [ ref ptr] = this. check_shim ( abi, Abi :: Rust , link_name_sym , args) ?;
314+ let & [ ref ptr] = this. check_shim ( abi, Abi :: Rust , link_name , args) ?;
314315 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
315316 let ptr = this. force_ptr ( ptr) ?;
316317 if ptr. offset != Size :: ZERO {
@@ -322,25 +323,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
322323 // Obtains a Miri backtrace. See the README for details.
323324 "miri_get_backtrace" => {
324325 // `check_shim` happens inside `handle_miri_get_backtrace`.
325- this. handle_miri_get_backtrace ( abi, link_name_sym , args, dest) ?;
326+ this. handle_miri_get_backtrace ( abi, link_name , args, dest) ?;
326327 }
327328
328329 // Resolves a Miri backtrace frame. See the README for details.
329330 "miri_resolve_frame" => {
330331 // `check_shim` happens inside `handle_miri_resolve_frame`.
331- this. handle_miri_resolve_frame ( abi, link_name_sym , args, dest) ?;
332+ this. handle_miri_resolve_frame ( abi, link_name , args, dest) ?;
332333 }
333334
334335
335336 // Standard C allocation
336337 "malloc" => {
337- let & [ ref size] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
338+ let & [ ref size] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
338339 let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
339340 let res = this. malloc ( size, /*zero_init:*/ false , MiriMemoryKind :: C ) ;
340341 this. write_scalar ( res, dest) ?;
341342 }
342343 "calloc" => {
343- let & [ ref items, ref len] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
344+ let & [ ref items, ref len] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
344345 let items = this. read_scalar ( items) ?. to_machine_usize ( this) ?;
345346 let len = this. read_scalar ( len) ?. to_machine_usize ( this) ?;
346347 let size =
@@ -349,12 +350,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
349350 this. write_scalar ( res, dest) ?;
350351 }
351352 "free" => {
352- let & [ ref ptr] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
353+ let & [ ref ptr] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
353354 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
354355 this. free ( ptr, MiriMemoryKind :: C ) ?;
355356 }
356357 "realloc" => {
357- let & [ ref old_ptr, ref new_size] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
358+ let & [ ref old_ptr, ref new_size] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
358359 let old_ptr = this. read_scalar ( old_ptr) ?. check_init ( ) ?;
359360 let new_size = this. read_scalar ( new_size) ?. to_machine_usize ( this) ?;
360361 let res = this. realloc ( old_ptr, new_size, MiriMemoryKind :: C ) ?;
@@ -365,7 +366,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
365366 // (Usually these would be forwarded to to `#[global_allocator]`; we instead implement a generic
366367 // allocation that also checks that all conditions are met, such as not permitting zero-sized allocations.)
367368 "__rust_alloc" => {
368- let & [ ref size, ref align] = this. check_shim ( abi, Abi :: Rust , link_name_sym , args) ?;
369+ let & [ ref size, ref align] = this. check_shim ( abi, Abi :: Rust , link_name , args) ?;
369370 let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
370371 let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
371372 Self :: check_alloc_request ( size, align) ?;
@@ -377,7 +378,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
377378 this. write_scalar ( ptr, dest) ?;
378379 }
379380 "__rust_alloc_zeroed" => {
380- let & [ ref size, ref align] = this. check_shim ( abi, Abi :: Rust , link_name_sym , args) ?;
381+ let & [ ref size, ref align] = this. check_shim ( abi, Abi :: Rust , link_name , args) ?;
381382 let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
382383 let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
383384 Self :: check_alloc_request ( size, align) ?;
@@ -391,7 +392,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
391392 this. write_scalar ( ptr, dest) ?;
392393 }
393394 "__rust_dealloc" => {
394- let & [ ref ptr, ref old_size, ref align] = this. check_shim ( abi, Abi :: Rust , link_name_sym , args) ?;
395+ let & [ ref ptr, ref old_size, ref align] = this. check_shim ( abi, Abi :: Rust , link_name , args) ?;
395396 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
396397 let old_size = this. read_scalar ( old_size) ?. to_machine_usize ( this) ?;
397398 let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
@@ -404,7 +405,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
404405 ) ?;
405406 }
406407 "__rust_realloc" => {
407- let & [ ref ptr, ref old_size, ref align, ref new_size] = this. check_shim ( abi, Abi :: Rust , link_name_sym , args) ?;
408+ let & [ ref ptr, ref old_size, ref align, ref new_size] = this. check_shim ( abi, Abi :: Rust , link_name , args) ?;
408409 let ptr = this. force_ptr ( this. read_scalar ( ptr) ?. check_init ( ) ?) ?;
409410 let old_size = this. read_scalar ( old_size) ?. to_machine_usize ( this) ?;
410411 let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
@@ -424,7 +425,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
424425
425426 // C memory handling functions
426427 "memcmp" => {
427- let & [ ref left, ref right, ref n] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
428+ let & [ ref left, ref right, ref n] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
428429 let left = this. read_scalar ( left) ?. check_init ( ) ?;
429430 let right = this. read_scalar ( right) ?. check_init ( ) ?;
430431 let n = Size :: from_bytes ( this. read_scalar ( n) ?. to_machine_usize ( this) ?) ;
@@ -444,7 +445,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
444445 this. write_scalar ( Scalar :: from_i32 ( result) , dest) ?;
445446 }
446447 "memrchr" => {
447- let & [ ref ptr, ref val, ref num] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
448+ let & [ ref ptr, ref val, ref num] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
448449 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
449450 let val = this. read_scalar ( val) ?. to_i32 ( ) ? as u8 ;
450451 let num = this. read_scalar ( num) ?. to_machine_usize ( this) ?;
@@ -462,7 +463,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
462463 }
463464 }
464465 "memchr" => {
465- let & [ ref ptr, ref val, ref num] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
466+ let & [ ref ptr, ref val, ref num] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
466467 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
467468 let val = this. read_scalar ( val) ?. to_i32 ( ) ? as u8 ;
468469 let num = this. read_scalar ( num) ?. to_machine_usize ( this) ?;
@@ -479,7 +480,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
479480 }
480481 }
481482 "strlen" => {
482- let & [ ref ptr] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
483+ let & [ ref ptr] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
483484 let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
484485 let n = this. read_c_str ( ptr) ?. len ( ) ;
485486 this. write_scalar ( Scalar :: from_machine_usize ( u64:: try_from ( n) . unwrap ( ) , this) , dest) ?;
@@ -495,10 +496,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
495496 | "asinf"
496497 | "atanf"
497498 => {
498- let & [ ref f] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
499+ let & [ ref f] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
499500 // FIXME: Using host floats.
500501 let f = f32:: from_bits ( this. read_scalar ( f) ?. to_u32 ( ) ?) ;
501- let f = match link_name {
502+ let f = match shim_name {
502503 "cbrtf" => f. cbrt ( ) ,
503504 "coshf" => f. cosh ( ) ,
504505 "sinhf" => f. sinh ( ) ,
@@ -515,13 +516,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
515516 | "hypotf"
516517 | "atan2f"
517518 => {
518- let & [ ref f1, ref f2] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
519+ let & [ ref f1, ref f2] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
519520 // underscore case for windows, here and below
520521 // (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/floating-point-primitives?view=vs-2019)
521522 // FIXME: Using host floats.
522523 let f1 = f32:: from_bits ( this. read_scalar ( f1) ?. to_u32 ( ) ?) ;
523524 let f2 = f32:: from_bits ( this. read_scalar ( f2) ?. to_u32 ( ) ?) ;
524- let n = match link_name {
525+ let n = match shim_name {
525526 "_hypotf" | "hypotf" => f1. hypot ( f2) ,
526527 "atan2f" => f1. atan2 ( f2) ,
527528 _ => bug ! ( ) ,
@@ -537,10 +538,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
537538 | "asin"
538539 | "atan"
539540 => {
540- let & [ ref f] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
541+ let & [ ref f] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
541542 // FIXME: Using host floats.
542543 let f = f64:: from_bits ( this. read_scalar ( f) ?. to_u64 ( ) ?) ;
543- let f = match link_name {
544+ let f = match shim_name {
544545 "cbrt" => f. cbrt ( ) ,
545546 "cosh" => f. cosh ( ) ,
546547 "sinh" => f. sinh ( ) ,
@@ -557,11 +558,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
557558 | "hypot"
558559 | "atan2"
559560 => {
560- let & [ ref f1, ref f2] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
561+ let & [ ref f1, ref f2] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
561562 // FIXME: Using host floats.
562563 let f1 = f64:: from_bits ( this. read_scalar ( f1) ?. to_u64 ( ) ?) ;
563564 let f2 = f64:: from_bits ( this. read_scalar ( f2) ?. to_u64 ( ) ?) ;
564- let n = match link_name {
565+ let n = match shim_name {
565566 "_hypot" | "hypot" => f1. hypot ( f2) ,
566567 "atan2" => f1. atan2 ( f2) ,
567568 _ => bug ! ( ) ,
@@ -573,7 +574,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
573574 | "ldexp"
574575 | "scalbn"
575576 => {
576- let & [ ref x, ref exp] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
577+ let & [ ref x, ref exp] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
577578 // For radix-2 (binary) systems, `ldexp` and `scalbn` are the same.
578579 let x = this. read_scalar ( x) ?. to_f64 ( ) ?;
579580 let exp = this. read_scalar ( exp) ?. to_i32 ( ) ?;
@@ -594,11 +595,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
594595
595596 // Architecture-specific shims
596597 "llvm.x86.sse2.pause" if this. tcx . sess . target . arch == "x86" || this. tcx . sess . target . arch == "x86_64" => {
597- let & [ ] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
598+ let & [ ] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
598599 this. yield_active_thread ( ) ;
599600 }
600601 "llvm.aarch64.isb" if this. tcx . sess . target . arch == "aarch64" => {
601- let & [ ref arg] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name_sym , args) ?;
602+ let & [ ref arg] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name , args) ?;
602603 let arg = this. read_scalar ( arg) ?. to_i32 ( ) ?;
603604 match arg {
604605 15 => { // SY ("full system scope")
@@ -612,8 +613,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
612613
613614 // Platform-specific shims
614615 _ => match this. tcx . sess . target . os . as_str ( ) {
615- "linux" | "macos" => return shims:: posix:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, link_name_sym , abi, args, dest, ret) ,
616- "windows" => return shims:: windows:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, link_name_sym , abi, args, dest, ret) ,
616+ "linux" | "macos" => return shims:: posix:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, abi, args, dest, ret) ,
617+ "windows" => return shims:: windows:: foreign_items:: EvalContextExt :: emulate_foreign_item_by_name ( this, link_name, abi, args, dest, ret) ,
617618 target => throw_unsup_format ! ( "the target `{}` is not supported" , target) ,
618619 }
619620 } ;
0 commit comments