11use crate :: * ;
2+ use crate :: rustc_target:: abi:: LayoutOf ;
23use rustc:: mir;
34use rustc:: ty:: layout:: Size ;
45use std:: iter;
6+ use std:: convert:: TryFrom ;
57
68impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
79pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
@@ -21,18 +23,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2123 // DWORD = ULONG = u32
2224 // BOOL = i32
2325
24- "GetEnvironmentStringsW" => {
25- // this.write_scalar(this.machine.env_vars.environ.unwrap().vtable(), dest)?;
26- }
27-
2826 // Environment related shims
2927 "GetEnvironmentVariableW" => {
3028 let result = this. getenvironmentvariablew ( args[ 0 ] , args[ 1 ] , args[ 2 ] ) ?;
3129 if result == 0 {
3230 this. set_last_error ( Scalar :: from_u32 ( 203 ) ) ?; // ERROR_ENVVAR_NOT_FOUND
33- // this.write_null(dest)?;
34- } else {
35- // this.write_scalar(Scalar::from_uint(result, dest.layout.size), dest)?;
3631 }
3732 this. write_scalar ( Scalar :: from_uint ( result, dest. layout . size ) , dest) ?;
3833 }
@@ -42,6 +37,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4237 this. write_scalar ( Scalar :: from_int ( result, dest. layout . size ) , dest) ?;
4338 }
4439
40+ "GetEnvironmentStringsW" => {
41+ // Info on layout of environment blocks in Windows:
42+ // https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables
43+ let mut env_vars = std:: ffi:: OsString :: new ( ) ;
44+ for & item in this. machine . env_vars . values ( ) ? {
45+ let env_var = this. read_os_str_from_target_str ( Scalar :: from ( item) ) ?;
46+ env_vars. push ( env_var) ;
47+ env_vars. push ( " " ) ;
48+ }
49+
50+ // Allocate environment block
51+ let tcx = this. tcx ;
52+ let env_block_size = env_vars. len ( ) + 1 ;
53+ let env_block_type = tcx. mk_array ( tcx. types . u16 , u64:: try_from ( env_block_size) . unwrap ( ) ) ;
54+ let env_block_place = this. allocate ( this. layout_of ( env_block_type) ?, MiriMemoryKind :: Machine . into ( ) ) ;
55+
56+ // Store environment variables to environment block
57+ // Final null terminator(block terminator) is pushed by `write_os_str_to_wide_str`
58+ this. write_os_str_to_wide_str ( & env_vars, env_block_place, u64:: try_from ( env_block_size) . unwrap ( ) ) ?;
59+
60+ // If the function succeeds, the return value is a pointer to the environment block of the current process.
61+ this. write_scalar ( env_block_place. ptr , dest) ?;
62+ }
63+
64+ "FreeEnvironmentStringsW" => {
65+ // let old_vars_ptr = this.read_scalar(args[0])?.not_undef()?;
66+ // this.memory.deallocate(this.force_ptr(old_vars_ptr)?, None, MiriMemoryKind::Machine.into())?;
67+ }
68+
4569 // File related shims
4670 "WriteFile" => {
4771 let handle = this. read_scalar ( args[ 0 ] ) ?. to_machine_isize ( this) ?;
0 commit comments