@@ -23,6 +23,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2323
2424 // Windows API stubs.
2525 // HANDLE = isize
26+ // NTSTATUS = LONH = i32
2627 // DWORD = ULONG = u32
2728 // BOOL = i32
2829 // BOOLEAN = u8
@@ -64,49 +65,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6465 this. write_scalar ( Scalar :: from_i32 ( result) , dest) ?;
6566 }
6667
67- // File related shims
68- "GetStdHandle" => {
69- let & [ ref which] =
70- this. check_shim ( abi, Abi :: System { unwind : false } , link_name, args) ?;
71- let which = this. read_scalar ( which) ?. to_i32 ( ) ?;
72- // We just make this the identity function, so we know later in `WriteFile`
73- // which one it is.
74- this. write_scalar ( Scalar :: from_machine_isize ( which. into ( ) , this) , dest) ?;
75- }
76- "WriteFile" => {
77- let & [ ref handle, ref buf, ref n, ref written_ptr, ref overlapped] =
78- this. check_shim ( abi, Abi :: System { unwind : false } , link_name, args) ?;
79- this. read_scalar ( overlapped) ?. to_machine_usize ( this) ?; // this is a poiner, that we ignore
80- let handle = this. read_scalar ( handle) ?. to_machine_isize ( this) ?;
81- let buf = this. read_pointer ( buf) ?;
82- let n = this. read_scalar ( n) ?. to_u32 ( ) ?;
83- let written_place = this. deref_operand ( written_ptr) ?;
84- // Spec says to always write `0` first.
85- this. write_null ( & written_place. into ( ) ) ?;
86- let written = if handle == -11 || handle == -12 {
87- // stdout/stderr
88- use std:: io:: { self , Write } ;
89-
90- let buf_cont = this. read_bytes_ptr ( buf, Size :: from_bytes ( u64:: from ( n) ) ) ?;
91- let res = if handle == -11 {
92- io:: stdout ( ) . write ( buf_cont)
93- } else {
94- io:: stderr ( ) . write ( buf_cont)
95- } ;
96- res. ok ( ) . map ( |n| n as u32 )
97- } else {
98- throw_unsup_format ! (
99- "on Windows, writing to anything except stdout/stderr is not supported"
100- )
101- } ;
102- // If there was no error, write back how much was written.
103- if let Some ( n) = written {
104- this. write_scalar ( Scalar :: from_u32 ( n) , & written_place. into ( ) ) ?;
105- }
106- // Return whether this was a success.
107- this. write_scalar ( Scalar :: from_i32 ( if written. is_some ( ) { 1 } else { 0 } ) , dest) ?;
108- }
109-
11068 // Allocation
11169 "HeapAlloc" => {
11270 let & [ ref handle, ref flags, ref size] =
@@ -333,6 +291,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
333291 // value if this call does result in switching to another thread.
334292 this. write_null ( dest) ?;
335293 }
294+ "GetStdHandle" => {
295+ let & [ ref which] =
296+ this. check_shim ( abi, Abi :: System { unwind : false } , link_name, args) ?;
297+ let which = this. read_scalar ( which) ?. to_i32 ( ) ?;
298+ // We just make this the identity function, so we know later in `NtWriteFile` which
299+ // one it is. This is very fake, but libtest needs it so we cannot make it a
300+ // std-only shim.
301+ this. write_scalar ( Scalar :: from_machine_isize ( which. into ( ) , this) , dest) ?;
302+ }
336303
337304 // Better error for attempts to create a thread
338305 "CreateThread" => {
@@ -345,11 +312,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
345312
346313 // Incomplete shims that we "stub out" just to get pre-main initialization code to work.
347314 // These shims are enabled only when the caller is in the standard library.
315+ "GetStdHandle" if this. frame_in_std ( ) => {
316+ let & [ ref which] =
317+ this. check_shim ( abi, Abi :: System { unwind : false } , link_name, args) ?;
318+ let which = this. read_scalar ( which) ?. to_i32 ( ) ?;
319+ // We just make this the identity function, so we know later in `NtWriteFile`
320+ // which one it is.
321+ this. write_scalar ( Scalar :: from_machine_isize ( which. into ( ) , this) , dest) ?;
322+ }
348323 "GetProcessHeap" if this. frame_in_std ( ) => {
349324 let & [ ] = this. check_shim ( abi, Abi :: System { unwind : false } , link_name, args) ?;
350325 // Just fake a HANDLE
351326 this. write_scalar ( Scalar :: from_machine_isize ( 1 , this) , dest) ?;
352327 }
328+ "GetModuleHandleA" if this. frame_in_std ( ) => {
329+ #[ allow( non_snake_case) ]
330+ let & [ _lpModuleName] =
331+ this. check_shim ( abi, Abi :: System { unwind : false } , link_name, args) ?;
332+ // We need to return something non-null here to make `compat_fn!` work.
333+ this. write_scalar ( Scalar :: from_machine_isize ( 1 , this) , dest) ?;
334+ }
353335 "SetConsoleTextAttribute" if this. frame_in_std ( ) => {
354336 #[ allow( non_snake_case) ]
355337 let & [ ref _hConsoleOutput, ref _wAttribute] =
0 commit comments