@@ -196,7 +196,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
196
196
if size == 0 {
197
197
throw_ub_format ! ( "creating allocation with size 0" ) ;
198
198
}
199
- if i128 :: from ( size) > this. tcx . data_layout . pointer_size . signed_int_max ( ) {
199
+ if size > this. max_size_of_val ( ) . bytes ( ) {
200
200
throw_ub_format ! ( "creating an allocation larger than half the address space" ) ;
201
201
}
202
202
if let Err ( e) = Align :: from_bytes ( align) {
@@ -441,19 +441,34 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
441
441
"malloc" => {
442
442
let [ size] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
443
443
let size = this. read_target_usize ( size) ?;
444
- let res = this. malloc ( size, /*zero_init:*/ false ) ?;
445
- this. write_pointer ( res, dest) ?;
444
+ if size <= this. max_size_of_val ( ) . bytes ( ) {
445
+ let res = this. malloc ( size, /*zero_init:*/ false ) ?;
446
+ this. write_pointer ( res, dest) ?;
447
+ } else {
448
+ // If this does not fit in an isize, return null and, on Unix, set errno.
449
+ if this. target_os_is_unix ( ) {
450
+ let einval = this. eval_libc ( "ENOMEM" ) ;
451
+ this. set_last_error ( einval) ?;
452
+ }
453
+ this. write_null ( dest) ?;
454
+ }
446
455
}
447
456
"calloc" => {
448
- let [ items, len ] =
457
+ let [ items, elem_size ] =
449
458
this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
450
459
let items = this. read_target_usize ( items) ?;
451
- let len = this. read_target_usize ( len) ?;
452
- let size = items
453
- . checked_mul ( len)
454
- . ok_or_else ( || err_ub_format ! ( "overflow during calloc size computation" ) ) ?;
455
- let res = this. malloc ( size, /*zero_init:*/ true ) ?;
456
- this. write_pointer ( res, dest) ?;
460
+ let elem_size = this. read_target_usize ( elem_size) ?;
461
+ if let Some ( size) = this. compute_size_in_bytes ( Size :: from_bytes ( elem_size) , items) {
462
+ let res = this. malloc ( size. bytes ( ) , /*zero_init:*/ true ) ?;
463
+ this. write_pointer ( res, dest) ?;
464
+ } else {
465
+ // On size overflow, return null and, on Unix, set errno.
466
+ if this. target_os_is_unix ( ) {
467
+ let einval = this. eval_libc ( "ENOMEM" ) ;
468
+ this. set_last_error ( einval) ?;
469
+ }
470
+ this. write_null ( dest) ?;
471
+ }
457
472
}
458
473
"free" => {
459
474
let [ ptr] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
@@ -465,8 +480,17 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
465
480
this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
466
481
let old_ptr = this. read_pointer ( old_ptr) ?;
467
482
let new_size = this. read_target_usize ( new_size) ?;
468
- let res = this. realloc ( old_ptr, new_size) ?;
469
- this. write_pointer ( res, dest) ?;
483
+ if new_size <= this. max_size_of_val ( ) . bytes ( ) {
484
+ let res = this. realloc ( old_ptr, new_size) ?;
485
+ this. write_pointer ( res, dest) ?;
486
+ } else {
487
+ // If this does not fit in an isize, return null and, on Unix, set errno.
488
+ if this. target_os_is_unix ( ) {
489
+ let einval = this. eval_libc ( "ENOMEM" ) ;
490
+ this. set_last_error ( einval) ?;
491
+ }
492
+ this. write_null ( dest) ?;
493
+ }
470
494
}
471
495
472
496
// Rust allocation
0 commit comments