-
Notifications
You must be signed in to change notification settings - Fork 435
Convert Windows to use check_shim_sig instead of check_shim_sig_lenient #4779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Thank you for contributing to Miri! A reviewer will take a look at your PR, typically within a week or two. |
| "*const _" => $this.machine.layouts.const_raw_ptr.ty, | ||
| "*mut _" => $this.machine.layouts.mut_raw_ptr.ty, | ||
| ty if let Some(libc_ty) = ty.strip_prefix("libc::") => $this.libc_ty_layout(libc_ty).ty, | ||
| ty if let Some(win_ty) = ty.strip_prefix("winapi::") => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is shorthand for a longer path used by the windows_ty_layout function, I thought this made usage a lot nicer and more readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! Please document this in the doc comment for shim_sig!.
| getrandom_01::getrandom(&mut data).unwrap(); | ||
|
|
||
| // TODO: getrandom 0.2 uses the wrong return type for BCrypteGenRandom | ||
| #[cfg(not(target_os = "windows"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0.2 uses u32 for the return type, not i32. We now check this and report UB. Is this worth reporting upstream for a backport?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a getrandom 0.2 release this year... so yeah you might as well report it upstream, but no reason to block this PR on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened rust-random/getrandom#775
src/shims/windows/foreign_items.rs
Outdated
| } else { | ||
| CanonAbi::C | ||
| }; | ||
| // TODO: Use this in shim-sig instead of 'system'? Or is that good enough for ExternAbi? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drawing attention to this - no tests are failing, but I need to double check whether this works, or if I need to make the shim_sig macro support dynamic ABIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"system" was added exactly to support the Windows API, so extern "system" really ought to work. Please just remove this comment.
| let [token, buf, size] = | ||
| this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; | ||
| let [token, buf, size] = this.check_shim_sig( | ||
| shim_sig!(extern "system" fn(winapi::HANDLE, *mut _, *mut _) -> winapi::BOOL), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General note - I preferred using fundamental types in most places, but I left a couple fundamental windows API types as their winapi::* variants, for clarity or because they have somewhat odd Rust representations.
BOOL: Actually an i32, which is unexpected to most not familiar with it.HANDLE: This has switched betweenisizeand*mut _in the past, and many Windows shims actually treat it as its own special thing.HLOCALandHMODULE: Aliases forHANDLE, but with the implication they represent only certain types of handle.FARPROC: ActuallyOption<extern "C" fn()>. Much easier to load the resolved layout of that, instead of trying to addOptionandfnspecial-cased toshim_sig_arg.
I can swap some of these to their literal representations if preferred, it may be a bit more performant, but it also may be worth adding caching to the *_ty_layout functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add that a HLOCAL is a pointer to memory allocated by LocalAlloc and HMODULE is a pointer to a module's base address. Neither of these are handles in the same sense as HANDLE is despite being defined as a type alias (which is why they can't be passed to normal handle functions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! I will note though that this cuts both ways -- if someone reads just the Miri code, it's quite confusing to see winapi::BOOL and then later i32 for the same argument. Not sure if there's much we can do about that.
| let [_First, _Handler] = | ||
| this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; | ||
| let [first, handler] = this.check_shim_sig( | ||
| shim_sig!(extern "system" fn(u32, *mut _) -> *mut _), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I standardized all the names. I can undo this if desired, it just seemed like a good drive-by since most stuff uses Rust-style names, not the Windows API names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine for me; so far we just didn't have anyone care enough to try and standardize this code.
FWIW, we also have a mix of styles for the functions that implement these shims, if they are implemented in separate functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally have preferred the external function method,, and would be willing to make a PR to standardize on that as a follow-up at some point.
4824149 to
9cebf4e
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Nice to see the macro work at scale. :)
I will just trust that those signatures are correct based on the test passing; I have no intuition for Windows APIs so I'd have to check every one of them manually...
The only actually requested change here is a comment nit.
| "*const _" => $this.machine.layouts.const_raw_ptr.ty, | ||
| "*mut _" => $this.machine.layouts.mut_raw_ptr.ty, | ||
| ty if let Some(libc_ty) = ty.strip_prefix("libc::") => $this.libc_ty_layout(libc_ty).ty, | ||
| ty if let Some(win_ty) = ty.strip_prefix("winapi::") => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! Please document this in the doc comment for shim_sig!.
| getrandom_01::getrandom(&mut data).unwrap(); | ||
|
|
||
| // TODO: getrandom 0.2 uses the wrong return type for BCrypteGenRandom | ||
| #[cfg(not(target_os = "windows"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a getrandom 0.2 release this year... so yeah you might as well report it upstream, but no reason to block this PR on that.
tests/pass-dep/getrandom.rs
Outdated
| #[cfg(not(target_os = "solaris"))] | ||
| getrandom_01::getrandom(&mut data).unwrap(); | ||
|
|
||
| // TODO: getrandom 0.2 uses the wrong return type for BCrypteGenRandom |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // TODO: getrandom 0.2 uses the wrong return type for BCrypteGenRandom | |
| // On Windows, getrandom 0.2 uses the wrong return type for BCrypteGenRandom. |
src/shims/windows/foreign_items.rs
Outdated
| } else { | ||
| CanonAbi::C | ||
| }; | ||
| // TODO: Use this in shim-sig instead of 'system'? Or is that good enough for ExternAbi? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"system" was added exactly to support the Windows API, so extern "system" really ought to work. Please just remove this comment.
| let [token, buf, size] = | ||
| this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; | ||
| let [token, buf, size] = this.check_shim_sig( | ||
| shim_sig!(extern "system" fn(winapi::HANDLE, *mut _, *mut _) -> winapi::BOOL), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! I will note though that this cuts both ways -- if someone reads just the Miri code, it's quite confusing to see winapi::BOOL and then later i32 for the same argument. Not sure if there's much we can do about that.
src/shims/windows/foreign_items.rs
Outdated
| // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern. | ||
|
|
||
| // Windows API stubs. | ||
| // HANDLE = isize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // HANDLE = isize | |
| // HANDLE = *mut c_void (formerly: isize) |
| let [file, distance_to_move, new_file_pointer, move_method] = | ||
| this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; | ||
| let [file, distance_to_move, new_file_pointer, move_method] = this.check_shim_sig( | ||
| // i64 is actually a LARGE_INTEGER union of {u32, i32} and {i64} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And that becomes just i64 on the ABI level? Those types are not ABI-compatible under Rust rules... but I guess they are compatible on Windows targets so "it's fine".^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All Rust code just defines this as an i64, including the official windows-sys bindings. So I think Windows considers it 'the same' for the system ABI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would still be UB to do this if caller and callee are both defined in Rust, but for functions only invoked via FFI the rules are a bit less clear.
| let [_First, _Handler] = | ||
| this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?; | ||
| let [first, handler] = this.check_shim_sig( | ||
| shim_sig!(extern "system" fn(u32, *mut _) -> *mut _), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine for me; so far we just didn't have anyone care enough to try and standardize this code.
FWIW, we also have a mix of styles for the functions that implement these shims, if they are implemented in separate functions.
|
Reminder, once the PR becomes ready for a review, use |
|
@rustbot ready |
|
Coming here from rust-random/getrandom#775 it suprises me that using a Should this check be relaxed to not trigger when an ABI-identical type is used? |
|
I am not aware of any sense in which i32 and u32 are ABI-identical at the language level. On some targets under some configurations (in particular, without CFI) they may be passed identically on the assembly level, but to my knowledge neither LLVM nor C nor Rust allow the programmer to make use of that. |
src/shims/sig.rs
Outdated
| ty => panic!("unsupported signature type {ty:?}"), | ||
| ty if let Some(win_ty) = ty.strip_prefix("winapi::") => | ||
| $this.windows_ty_layout(win_ty).ty, | ||
| ty => helpers::path_ty_layout($this, &ty.split("::").collect::<Vec<_>>()).ty, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I only just realized you added a general fallback... not sure if we really want that. Is it needed for the PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, it's needed for _Unwind_Reason_Code... hm
681dad8 to
da2acc3
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
No description provided.