1
1
use crate :: * ;
2
+ use crate :: rustc_target:: abi:: LayoutOf ;
2
3
use rustc:: mir;
3
4
use rustc:: ty:: layout:: Size ;
4
5
use std:: iter;
6
+ use std:: convert:: TryFrom ;
5
7
6
8
impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
7
9
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
@@ -21,18 +23,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
21
23
// DWORD = ULONG = u32
22
24
// BOOL = i32
23
25
24
- "GetEnvironmentStringsW" => {
25
- // this.write_scalar(this.machine.env_vars.environ.unwrap().vtable(), dest)?;
26
- }
27
-
28
26
// Environment related shims
29
27
"GetEnvironmentVariableW" => {
30
28
let result = this. getenvironmentvariablew ( args[ 0 ] , args[ 1 ] , args[ 2 ] ) ?;
31
29
if result == 0 {
32
30
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)?;
36
31
}
37
32
this. write_scalar ( Scalar :: from_uint ( result, dest. layout . size ) , dest) ?;
38
33
}
@@ -42,6 +37,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
42
37
this. write_scalar ( Scalar :: from_int ( result, dest. layout . size ) , dest) ?;
43
38
}
44
39
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
+
45
69
// File related shims
46
70
"WriteFile" => {
47
71
let handle = this. read_scalar ( args[ 0 ] ) ?. to_machine_isize ( this) ?;
0 commit comments