Skip to content
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

Added get_arg to check and transmute opty #4185

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

geetanshjuneja
Copy link
Contributor

Links to #3842

@geetanshjuneja
Copy link
Contributor Author

I have made changes only in a single place to make sure that this what we want.

Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

Judging from the CI failures, this does not seem to be quite right. And (as noted inline) I think this will never be able to do the "proper" check. So I don't think this is the right approach.

The right approach has to be somewhat similar to what happens for regular function calls in Miri. Basically, we need a helper function that takes a list of types (the expected argument types) and a return type, and then somehow checks that against the FnAbi that is passed around in the Miri shim handling. This likely involved constructing our own FnAbi to compare, and I have no idea how to do that...

Also, I would suggest to not touch intrinsics for now. They are somewhat special ABI-wise. Let's start with normal shims, i.e. all the things on foreign_items.

@@ -1312,3 +1312,15 @@ pub(crate) fn windows_check_buffer_size((success, len): (bool, u64)) -> u32 {
u32::try_from(len).unwrap()
}
}

pub(crate) fn get_arg<'tcx>(
ecx: &mut MiriInterpCx<'tcx>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make this a method on the extension trait instead.

Copy link
Contributor Author

@geetanshjuneja geetanshjuneja Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the MiriInterpCxExt trait?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the big block that beings with pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {.

Comment on lines +1322 to +1324
if !op.layout.backend_repr.eq_up_to_validity(&ty_layout.backend_repr) {
throw_ub_format!("Invalid argument type: ABI mismatch");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, this is not quite the same logic as what we use to test ABI compatibility. That check cannot really be done on a per-argument / per-type basis; it works on ArgAbi which is part of FnAbi.

So, while this gives some extra coverage, it doesn't really go far enough, and we'd have to change everything completely again if we wanted to do the "proper" thing. I am not convinced it is worth investing a lot of effort into a half-way solution.

@geetanshjuneja
Copy link
Contributor Author

The right approach has to be somewhat similar to what happens for regular function calls in Miri. Basically, we need a helper function that takes a list of types (the expected argument types) and a return type, and then somehow checks that against the FnAbi that is passed around in the Miri shim handling. This likely involved constructing our own FnAbi to compare, and I have no idea how to do that...

For non variadic fn's can't we just simply create FnAbi struct using the types available in docs. The issue only comes for variadic fn's as we dont know the types of the extra args.

@RalfJung
Copy link
Member

Yes we "just" have to do that but it is not necessarily so easy. :)
But we can probably construct a fn ptr type corresponding to the desired signature, and then use fn_abi_of_fn_ptr.

@geetanshjuneja
Copy link
Contributor Author

geetanshjuneja commented Feb 13, 2025

Yes we "just" have to do that but it is not necessarily so easy. :)

Why can't we directly instantiate an object of FnAbi struct?
Also are you talking about this fn_abi_of_fn_ptr ?

@RalfJung
Copy link
Member

Why can't we instantiate an object of FnAbi struct?

That involves computing a PassMode, and we most definitely do not want to compute those ourselves. We want to use the logic in the Rust compiler for computing those.

Also are you talking about this fn_abi_of_fn_ptr ?

Yes. It can be invoked in Miri via this.fn_abi_of_fn_ptr (where this is an InterpCx).

@geetanshjuneja
Copy link
Contributor Author

geetanshjuneja commented Feb 13, 2025

To resolve I was thinking of implementing the following things:

Create a fn check_fn_abi which would take a list of input types , an output type and Fnabi that is passed in the miri shim handling. This fn would create a FnSig using the args. Now we will create expected FnAbi using this fn sig and compare it with the input Fnsig. If it doesn't matches throw ub.
Now Transmute can be called safely inside shim.

@RalfJung
Copy link
Member

That sounds like a good plan. There are methods defined in https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/call.rs that are probably useful but have to be made pub before they can be called from Miri.

@geetanshjuneja
Copy link
Contributor Author

geetanshjuneja commented Feb 14, 2025

There are methods defined in https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/call.rs that are probably useful but have to be made pub before they can be called from Miri.

Are you talking about check_argument_compatmethod here? If yes now then I think we can compare the two FnAbi by iterating over the args of the two abis by calling check_argument_compat method.

Also inputs_and_output field of FnSig requires list as RawList<(), T> so I need to convert given input and output arg slice into RawList<(), T> using from_arena method?

@RalfJung
Copy link
Member

RalfJung commented Feb 14, 2025

Are you talking about check_argument_compatmethod here?

Yes.

Also inputs_and_output field of FnSig requires list as RawList<(), T> so I need to convert given input and output arg slice into RawList<(), T> using from_arena method?

You can use these methods: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/?search=mk_type_list.

@geetanshjuneja
Copy link
Contributor Author

I am mostly done with the code now I just need check_argument_compat to be public.

@RalfJung
Copy link
Member

Okay, please make a PR against the rustc repo to make that function public then. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants