Skip to content

Commit f2f8fb2

Browse files
committed
migrate more functions
1 parent e7d6e71 commit f2f8fb2

File tree

4 files changed

+160
-157
lines changed

4 files changed

+160
-157
lines changed

src/shims/foreign_items.rs

Lines changed: 0 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -702,163 +702,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
702702
this.write_null(dest)?;
703703
}
704704

705-
// macOS API stubs.
706-
| "pthread_attr_get_np"
707-
| "pthread_getattr_np"
708-
=> {
709-
this.write_null(dest)?;
710-
}
711-
"pthread_get_stackaddr_np" => {
712-
let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
713-
this.write_scalar(stack_addr, dest)?;
714-
}
715-
"pthread_get_stacksize_np" => {
716-
let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);
717-
this.write_scalar(stack_size, dest)?;
718-
}
719-
"_tlv_atexit" => {
720-
// FIXME: register the destructor.
721-
}
722-
"_NSGetArgc" => {
723-
this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;
724-
}
725-
"_NSGetArgv" => {
726-
this.write_scalar(this.machine.argv.expect("machine must be initialized"), dest)?;
727-
}
728-
"SecRandomCopyBytes" => {
729-
let len = this.read_scalar(args[1])?.to_machine_usize(this)?;
730-
let ptr = this.read_scalar(args[2])?.not_undef()?;
731-
this.gen_random(ptr, len as usize)?;
732-
this.write_null(dest)?;
733-
}
734-
735-
// Windows API stubs.
736-
// HANDLE = isize
737-
// DWORD = ULONG = u32
738-
// BOOL = i32
739-
"GetProcessHeap" => {
740-
// Just fake a HANDLE
741-
this.write_scalar(Scalar::from_int(1, this.pointer_size()), dest)?;
742-
}
743-
"HeapAlloc" => {
744-
let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
745-
let flags = this.read_scalar(args[1])?.to_u32()?;
746-
let size = this.read_scalar(args[2])?.to_machine_usize(this)?;
747-
let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
748-
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap);
749-
this.write_scalar(res, dest)?;
750-
}
751-
"HeapFree" => {
752-
let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
753-
let _flags = this.read_scalar(args[1])?.to_u32()?;
754-
let ptr = this.read_scalar(args[2])?.not_undef()?;
755-
this.free(ptr, MiriMemoryKind::WinHeap)?;
756-
this.write_scalar(Scalar::from_int(1, Size::from_bytes(4)), dest)?;
757-
}
758-
"HeapReAlloc" => {
759-
let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
760-
let _flags = this.read_scalar(args[1])?.to_u32()?;
761-
let ptr = this.read_scalar(args[2])?.not_undef()?;
762-
let size = this.read_scalar(args[3])?.to_machine_usize(this)?;
763-
let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
764-
this.write_scalar(res, dest)?;
765-
}
766-
767-
"SetLastError" => {
768-
this.set_last_error(this.read_scalar(args[0])?.not_undef()?)?;
769-
}
770-
"GetLastError" => {
771-
let last_error = this.get_last_error()?;
772-
this.write_scalar(last_error, dest)?;
773-
}
774-
775-
"AddVectoredExceptionHandler" => {
776-
// Any non zero value works for the stdlib. This is just used for stack overflows anyway.
777-
this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
778-
}
779-
780-
| "InitializeCriticalSection"
781-
| "EnterCriticalSection"
782-
| "LeaveCriticalSection"
783-
| "DeleteCriticalSection"
784-
=> {
785-
// Nothing to do, not even a return value.
786-
}
787-
788-
| "GetModuleHandleW"
789-
| "GetProcAddress"
790-
| "TryEnterCriticalSection"
791-
| "GetConsoleScreenBufferInfo"
792-
| "SetConsoleTextAttribute"
793-
=> {
794-
// Pretend these do not exist / nothing happened, by returning zero.
795-
this.write_null(dest)?;
796-
}
797-
798-
"GetSystemInfo" => {
799-
let system_info = this.deref_operand(args[0])?;
800-
// Initialize with `0`.
801-
this.memory.write_bytes(
802-
system_info.ptr,
803-
iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
804-
)?;
805-
// Set number of processors.
806-
let dword_size = Size::from_bytes(4);
807-
let num_cpus = this.mplace_field(system_info, 6)?;
808-
this.write_scalar(Scalar::from_int(NUM_CPUS, dword_size), num_cpus.into())?;
809-
}
810-
811-
"TlsAlloc" => {
812-
// This just creates a key; Windows does not natively support TLS destructors.
813-
814-
// Create key and return it.
815-
let key = this.machine.tls.create_tls_key(None) as u128;
816-
817-
// Figure out how large a TLS key actually is. This is `c::DWORD`.
818-
if dest.layout.size.bits() < 128
819-
&& key >= (1u128 << dest.layout.size.bits() as u128)
820-
{
821-
throw_unsup!(OutOfTls);
822-
}
823-
this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
824-
}
825-
"TlsGetValue" => {
826-
let key = this.read_scalar(args[0])?.to_u32()? as u128;
827-
let ptr = this.machine.tls.load_tls(key, tcx)?;
828-
this.write_scalar(ptr, dest)?;
829-
}
830-
"TlsSetValue" => {
831-
let key = this.read_scalar(args[0])?.to_u32()? as u128;
832-
let new_ptr = this.read_scalar(args[1])?.not_undef()?;
833-
this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;
834-
835-
// Return success (`1`).
836-
this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
837-
}
838-
"GetStdHandle" => {
839-
let which = this.read_scalar(args[0])?.to_i32()?;
840-
// We just make this the identity function, so we know later in `WriteFile`
841-
// which one it is.
842-
this.write_scalar(Scalar::from_int(which, this.pointer_size()), dest)?;
843-
}
844-
"GetConsoleMode" => {
845-
// Everything is a pipe.
846-
this.write_null(dest)?;
847-
}
848-
"GetCommandLineW" => {
849-
this.write_scalar(
850-
this.machine.cmd_line.expect("machine must be initialized"),
851-
dest,
852-
)?;
853-
}
854-
// The actual name of 'RtlGenRandom'
855-
"SystemFunction036" => {
856-
let ptr = this.read_scalar(args[0])?.not_undef()?;
857-
let len = this.read_scalar(args[1])?.to_u32()?;
858-
this.gen_random(ptr, len as usize)?;
859-
this.write_scalar(Scalar::from_bool(true), dest)?;
860-
}
861-
862705
_ => match this.tcx.sess.target.target.target_os.to_lowercase().as_str() {
863706
"linux" | "macos" => posix::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest)?,
864707
"windows" => windows::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest)?,

src/shims/foreign_items/posix/linux.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
3838
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
3939
}
4040

41+
"pthread_getattr_np" => {
42+
this.write_null(dest)?;
43+
}
4144
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
4245
};
4346

src/shims/foreign_items/posix/macos.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5353
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
5454
}
5555

56+
// macOS API stubs.
57+
"pthread_attr_get_np" => {
58+
this.write_null(dest)?;
59+
}
60+
"pthread_get_stackaddr_np" => {
61+
let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
62+
this.write_scalar(stack_addr, dest)?;
63+
}
64+
"pthread_get_stacksize_np" => {
65+
let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);
66+
this.write_scalar(stack_size, dest)?;
67+
}
68+
"_tlv_atexit" => {
69+
// FIXME: register the destructor.
70+
}
71+
"_NSGetArgc" => {
72+
this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;
73+
}
74+
"_NSGetArgv" => {
75+
this.write_scalar(this.machine.argv.expect("machine must be initialized"), dest)?;
76+
}
77+
"SecRandomCopyBytes" => {
78+
let len = this.read_scalar(args[1])?.to_machine_usize(this)?;
79+
let ptr = this.read_scalar(args[2])?.not_undef()?;
80+
this.gen_random(ptr, len as usize)?;
81+
this.write_null(dest)?;
82+
}
83+
84+
5685
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
5786
};
5887

src/shims/foreign_items/windows.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::*;
22
use rustc::ty::layout::Size;
3+
use std::iter;
34

45
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
56
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
@@ -10,6 +11,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1011
dest: PlaceTy<'tcx, Tag>,
1112
) -> InterpResult<'tcx> {
1213
let this = self.eval_context_mut();
14+
let tcx = &{ this.tcx.tcx };
1315

1416
match link_name {
1517
// Environment related shims
@@ -66,6 +68,132 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6668
dest,
6769
)?;
6870
}
71+
// Windows API stubs.
72+
// HANDLE = isize
73+
// DWORD = ULONG = u32
74+
// BOOL = i32
75+
"GetProcessHeap" => {
76+
// Just fake a HANDLE
77+
this.write_scalar(Scalar::from_int(1, this.pointer_size()), dest)?;
78+
}
79+
"HeapAlloc" => {
80+
let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
81+
let flags = this.read_scalar(args[1])?.to_u32()?;
82+
let size = this.read_scalar(args[2])?.to_machine_usize(this)?;
83+
let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
84+
let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap);
85+
this.write_scalar(res, dest)?;
86+
}
87+
"HeapFree" => {
88+
let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
89+
let _flags = this.read_scalar(args[1])?.to_u32()?;
90+
let ptr = this.read_scalar(args[2])?.not_undef()?;
91+
this.free(ptr, MiriMemoryKind::WinHeap)?;
92+
this.write_scalar(Scalar::from_int(1, Size::from_bytes(4)), dest)?;
93+
}
94+
"HeapReAlloc" => {
95+
let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
96+
let _flags = this.read_scalar(args[1])?.to_u32()?;
97+
let ptr = this.read_scalar(args[2])?.not_undef()?;
98+
let size = this.read_scalar(args[3])?.to_machine_usize(this)?;
99+
let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
100+
this.write_scalar(res, dest)?;
101+
}
102+
103+
"SetLastError" => {
104+
this.set_last_error(this.read_scalar(args[0])?.not_undef()?)?;
105+
}
106+
"GetLastError" => {
107+
let last_error = this.get_last_error()?;
108+
this.write_scalar(last_error, dest)?;
109+
}
110+
111+
"AddVectoredExceptionHandler" => {
112+
// Any non zero value works for the stdlib. This is just used for stack overflows anyway.
113+
this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
114+
}
115+
116+
| "InitializeCriticalSection"
117+
| "EnterCriticalSection"
118+
| "LeaveCriticalSection"
119+
| "DeleteCriticalSection"
120+
=> {
121+
// Nothing to do, not even a return value.
122+
}
123+
124+
| "GetModuleHandleW"
125+
| "GetProcAddress"
126+
| "TryEnterCriticalSection"
127+
| "GetConsoleScreenBufferInfo"
128+
| "SetConsoleTextAttribute"
129+
=> {
130+
// Pretend these do not exist / nothing happened, by returning zero.
131+
this.write_null(dest)?;
132+
}
133+
134+
"GetSystemInfo" => {
135+
let system_info = this.deref_operand(args[0])?;
136+
// Initialize with `0`.
137+
this.memory.write_bytes(
138+
system_info.ptr,
139+
iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
140+
)?;
141+
// Set number of processors.
142+
let dword_size = Size::from_bytes(4);
143+
let num_cpus = this.mplace_field(system_info, 6)?;
144+
this.write_scalar(Scalar::from_int(NUM_CPUS, dword_size), num_cpus.into())?;
145+
}
146+
147+
"TlsAlloc" => {
148+
// This just creates a key; Windows does not natively support TLS destructors.
149+
150+
// Create key and return it.
151+
let key = this.machine.tls.create_tls_key(None) as u128;
152+
153+
// Figure out how large a TLS key actually is. This is `c::DWORD`.
154+
if dest.layout.size.bits() < 128
155+
&& key >= (1u128 << dest.layout.size.bits() as u128)
156+
{
157+
throw_unsup!(OutOfTls);
158+
}
159+
this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
160+
}
161+
"TlsGetValue" => {
162+
let key = this.read_scalar(args[0])?.to_u32()? as u128;
163+
let ptr = this.machine.tls.load_tls(key, tcx)?;
164+
this.write_scalar(ptr, dest)?;
165+
}
166+
"TlsSetValue" => {
167+
let key = this.read_scalar(args[0])?.to_u32()? as u128;
168+
let new_ptr = this.read_scalar(args[1])?.not_undef()?;
169+
this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;
170+
171+
// Return success (`1`).
172+
this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
173+
}
174+
"GetStdHandle" => {
175+
let which = this.read_scalar(args[0])?.to_i32()?;
176+
// We just make this the identity function, so we know later in `WriteFile`
177+
// which one it is.
178+
this.write_scalar(Scalar::from_int(which, this.pointer_size()), dest)?;
179+
}
180+
"GetConsoleMode" => {
181+
// Everything is a pipe.
182+
this.write_null(dest)?;
183+
}
184+
"GetCommandLineW" => {
185+
this.write_scalar(
186+
this.machine.cmd_line.expect("machine must be initialized"),
187+
dest,
188+
)?;
189+
}
190+
// The actual name of 'RtlGenRandom'
191+
"SystemFunction036" => {
192+
let ptr = this.read_scalar(args[0])?.not_undef()?;
193+
let len = this.read_scalar(args[1])?.to_u32()?;
194+
this.gen_random(ptr, len as usize)?;
195+
this.write_scalar(Scalar::from_bool(true), dest)?;
196+
}
69197
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
70198
}
71199

0 commit comments

Comments
 (0)