@@ -25,6 +25,7 @@ use rustc_target::{
25
25
26
26
use super :: backtrace:: EvalContextExt as _;
27
27
use crate :: * ;
28
+ use helpers:: strip_linker_suffix;
28
29
29
30
/// Returned by `emulate_foreign_item_by_name`.
30
31
pub enum EmulateByNameResult {
@@ -215,8 +216,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
215
216
. first_attr_value_str_by_name ( & attrs, sym:: link_name)
216
217
. unwrap_or_else ( || this. tcx . item_name ( def_id) ) ;
217
218
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) ;
220
220
let tcx = this. tcx . tcx ;
221
221
222
222
// First: functions that diverge.
@@ -274,7 +274,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
274
274
} ;
275
275
276
276
// 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) ? {
278
278
EmulateByNameResult :: NeedsJumping => {
279
279
trace ! ( "{:?}" , this. dump_place( * * dest) ) ;
280
280
this. go_to_block ( ret) ;
@@ -296,8 +296,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
296
296
/// Emulates calling a foreign item using its name.
297
297
fn emulate_foreign_item_by_name (
298
298
& mut self ,
299
- link_name : & str ,
300
- link_name_sym : Symbol ,
299
+ link_name : Symbol ,
301
300
abi : Abi ,
302
301
args : & [ OpTy < ' tcx , Tag > ] ,
303
302
dest : & PlaceTy < ' tcx , Tag > ,
@@ -307,10 +306,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
307
306
308
307
// Here we dispatch all the shims for foreign functions. If you have a platform specific
309
308
// 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 {
311
312
// Miri-specific extern functions
312
313
"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) ?;
314
315
let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
315
316
let ptr = this. force_ptr ( ptr) ?;
316
317
if ptr. offset != Size :: ZERO {
@@ -322,25 +323,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
322
323
// Obtains a Miri backtrace. See the README for details.
323
324
"miri_get_backtrace" => {
324
325
// `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) ?;
326
327
}
327
328
328
329
// Resolves a Miri backtrace frame. See the README for details.
329
330
"miri_resolve_frame" => {
330
331
// `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) ?;
332
333
}
333
334
334
335
335
336
// Standard C allocation
336
337
"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) ?;
338
339
let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
339
340
let res = this. malloc ( size, /*zero_init:*/ false , MiriMemoryKind :: C ) ;
340
341
this. write_scalar ( res, dest) ?;
341
342
}
342
343
"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) ?;
344
345
let items = this. read_scalar ( items) ?. to_machine_usize ( this) ?;
345
346
let len = this. read_scalar ( len) ?. to_machine_usize ( this) ?;
346
347
let size =
@@ -349,12 +350,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
349
350
this. write_scalar ( res, dest) ?;
350
351
}
351
352
"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) ?;
353
354
let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
354
355
this. free ( ptr, MiriMemoryKind :: C ) ?;
355
356
}
356
357
"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) ?;
358
359
let old_ptr = this. read_scalar ( old_ptr) ?. check_init ( ) ?;
359
360
let new_size = this. read_scalar ( new_size) ?. to_machine_usize ( this) ?;
360
361
let res = this. realloc ( old_ptr, new_size, MiriMemoryKind :: C ) ?;
@@ -365,7 +366,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
365
366
// (Usually these would be forwarded to to `#[global_allocator]`; we instead implement a generic
366
367
// allocation that also checks that all conditions are met, such as not permitting zero-sized allocations.)
367
368
"__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) ?;
369
370
let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
370
371
let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
371
372
Self :: check_alloc_request ( size, align) ?;
@@ -377,7 +378,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
377
378
this. write_scalar ( ptr, dest) ?;
378
379
}
379
380
"__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) ?;
381
382
let size = this. read_scalar ( size) ?. to_machine_usize ( this) ?;
382
383
let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
383
384
Self :: check_alloc_request ( size, align) ?;
@@ -391,7 +392,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
391
392
this. write_scalar ( ptr, dest) ?;
392
393
}
393
394
"__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) ?;
395
396
let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
396
397
let old_size = this. read_scalar ( old_size) ?. to_machine_usize ( this) ?;
397
398
let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
@@ -404,7 +405,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
404
405
) ?;
405
406
}
406
407
"__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) ?;
408
409
let ptr = this. force_ptr ( this. read_scalar ( ptr) ?. check_init ( ) ?) ?;
409
410
let old_size = this. read_scalar ( old_size) ?. to_machine_usize ( this) ?;
410
411
let align = this. read_scalar ( align) ?. to_machine_usize ( this) ?;
@@ -424,7 +425,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
424
425
425
426
// C memory handling functions
426
427
"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) ?;
428
429
let left = this. read_scalar ( left) ?. check_init ( ) ?;
429
430
let right = this. read_scalar ( right) ?. check_init ( ) ?;
430
431
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
444
445
this. write_scalar ( Scalar :: from_i32 ( result) , dest) ?;
445
446
}
446
447
"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) ?;
448
449
let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
449
450
let val = this. read_scalar ( val) ?. to_i32 ( ) ? as u8 ;
450
451
let num = this. read_scalar ( num) ?. to_machine_usize ( this) ?;
@@ -462,7 +463,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
462
463
}
463
464
}
464
465
"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) ?;
466
467
let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
467
468
let val = this. read_scalar ( val) ?. to_i32 ( ) ? as u8 ;
468
469
let num = this. read_scalar ( num) ?. to_machine_usize ( this) ?;
@@ -479,7 +480,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
479
480
}
480
481
}
481
482
"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) ?;
483
484
let ptr = this. read_scalar ( ptr) ?. check_init ( ) ?;
484
485
let n = this. read_c_str ( ptr) ?. len ( ) ;
485
486
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
495
496
| "asinf"
496
497
| "atanf"
497
498
=> {
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) ?;
499
500
// FIXME: Using host floats.
500
501
let f = f32:: from_bits ( this. read_scalar ( f) ?. to_u32 ( ) ?) ;
501
- let f = match link_name {
502
+ let f = match shim_name {
502
503
"cbrtf" => f. cbrt ( ) ,
503
504
"coshf" => f. cosh ( ) ,
504
505
"sinhf" => f. sinh ( ) ,
@@ -515,13 +516,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
515
516
| "hypotf"
516
517
| "atan2f"
517
518
=> {
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) ?;
519
520
// underscore case for windows, here and below
520
521
// (see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/floating-point-primitives?view=vs-2019)
521
522
// FIXME: Using host floats.
522
523
let f1 = f32:: from_bits ( this. read_scalar ( f1) ?. to_u32 ( ) ?) ;
523
524
let f2 = f32:: from_bits ( this. read_scalar ( f2) ?. to_u32 ( ) ?) ;
524
- let n = match link_name {
525
+ let n = match shim_name {
525
526
"_hypotf" | "hypotf" => f1. hypot ( f2) ,
526
527
"atan2f" => f1. atan2 ( f2) ,
527
528
_ => bug ! ( ) ,
@@ -537,10 +538,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
537
538
| "asin"
538
539
| "atan"
539
540
=> {
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) ?;
541
542
// FIXME: Using host floats.
542
543
let f = f64:: from_bits ( this. read_scalar ( f) ?. to_u64 ( ) ?) ;
543
- let f = match link_name {
544
+ let f = match shim_name {
544
545
"cbrt" => f. cbrt ( ) ,
545
546
"cosh" => f. cosh ( ) ,
546
547
"sinh" => f. sinh ( ) ,
@@ -557,11 +558,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
557
558
| "hypot"
558
559
| "atan2"
559
560
=> {
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) ?;
561
562
// FIXME: Using host floats.
562
563
let f1 = f64:: from_bits ( this. read_scalar ( f1) ?. to_u64 ( ) ?) ;
563
564
let f2 = f64:: from_bits ( this. read_scalar ( f2) ?. to_u64 ( ) ?) ;
564
- let n = match link_name {
565
+ let n = match shim_name {
565
566
"_hypot" | "hypot" => f1. hypot ( f2) ,
566
567
"atan2" => f1. atan2 ( f2) ,
567
568
_ => bug ! ( ) ,
@@ -573,7 +574,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
573
574
| "ldexp"
574
575
| "scalbn"
575
576
=> {
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) ?;
577
578
// For radix-2 (binary) systems, `ldexp` and `scalbn` are the same.
578
579
let x = this. read_scalar ( x) ?. to_f64 ( ) ?;
579
580
let exp = this. read_scalar ( exp) ?. to_i32 ( ) ?;
@@ -594,11 +595,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
594
595
595
596
// Architecture-specific shims
596
597
"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) ?;
598
599
this. yield_active_thread ( ) ;
599
600
}
600
601
"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) ?;
602
603
let arg = this. read_scalar ( arg) ?. to_i32 ( ) ?;
603
604
match arg {
604
605
15 => { // SY ("full system scope")
@@ -612,8 +613,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
612
613
613
614
// Platform-specific shims
614
615
_ => 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) ,
617
618
target => throw_unsup_format ! ( "the target `{}` is not supported" , target) ,
618
619
}
619
620
} ;
0 commit comments