@@ -252,6 +252,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
252252 this. write_scalar ( result, dest) ?;
253253 }
254254
255+ "reallocarray" => {
256+ // Currently this function does not exist on all Unixes, e.g. on macOS.
257+ if !matches ! ( & * this. tcx. sess. target. os, "linux" | "freebsd" ) {
258+ throw_unsup_format ! (
259+ "`reallocarray` is not supported on {}" ,
260+ this. tcx. sess. target. os
261+ ) ;
262+ }
263+ let [ ptr, nmemb, size] =
264+ this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
265+ let ptr = this. read_pointer ( ptr) ?;
266+ let nmemb = this. read_target_usize ( nmemb) ?;
267+ let size = this. read_target_usize ( size) ?;
268+ // reallocarray checks a possible overflow and returns ENOMEM
269+ // if that happens.
270+ //
271+ // Linux: https://www.unix.com/man-page/linux/3/reallocarray/
272+ // FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=reallocarray
273+ match nmemb. checked_mul ( size) {
274+ None => {
275+ let einval = this. eval_libc ( "ENOMEM" ) ;
276+ this. set_last_error ( einval) ?;
277+ this. write_null ( dest) ?;
278+ }
279+ Some ( len) => {
280+ let res = this. realloc ( ptr, len, MiriMemoryKind :: C ) ?;
281+ this. write_pointer ( res, dest) ?;
282+ }
283+ }
284+ }
285+
255286 // Dynamic symbol loading
256287 "dlsym" => {
257288 let [ handle, symbol] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
0 commit comments