-
Notifications
You must be signed in to change notification settings - Fork 388
implement shim_sig macro #4342
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
base: master
Are you sure you want to change the base?
implement shim_sig macro #4342
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1435,3 +1435,36 @@ impl ToU64 for usize { | |
self.try_into().unwrap() | ||
} | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! shim_sig { | ||
($this:ident, extern $abi:literal fn($($arg:tt),*) -> $ret:tt) => { | ||
( | ||
std::str::FromStr::from_str($abi).expect("incorrect abi specified"), | ||
[$(layout!($this, $arg)),*], | ||
layout!($this, $ret) | ||
) | ||
}; | ||
|
||
// default Rust abi | ||
($this:ident, extern $abi:literal fn($($arg:tt),*) -> $ret:tt) => { | ||
shim_sig!($this, extern "Rust" fn($($arg),*) -> $ret) | ||
}; | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! layout { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please give this macro a more clear name, such as |
||
($this:ident, ) => {}; | ||
($this:ident, (*const _)) => { | ||
$this.machine.layouts.const_raw_ptr.ty | ||
}; | ||
($this:ident, (*mut _)) => { | ||
$this.machine.layouts.mut_raw_ptr.ty | ||
}; | ||
($this:ident, $arg:ident) => { | ||
$this.tcx.types.$arg | ||
}; | ||
($this:ident, $arg:literal) => { | ||
$this.libc_ty_layout($arg).ty | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ use self::shims::unix::solarish::foreign_items as solarish; | |
use crate::concurrency::cpu_affinity::CpuAffinityMask; | ||
use crate::shims::alloc::EvalContextExt as _; | ||
use crate::shims::unix::*; | ||
use crate::*; | ||
use crate::{shim_sig, *}; | ||
|
||
pub fn is_dyn_sym(name: &str, target_os: &str) -> bool { | ||
match name { | ||
|
@@ -112,26 +112,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | |
match link_name.as_str() { | ||
// Environment related shims | ||
"getenv" => { | ||
let [name] = this.check_shim_abi( | ||
link_name, | ||
abi, | ||
ExternAbi::C { unwind: false }, | ||
[this.machine.layouts.const_raw_ptr.ty], | ||
this.machine.layouts.mut_raw_ptr.ty, | ||
args, | ||
)?; | ||
let (callee_abi, arg_types, ret_type) = | ||
shim_sig!(this, extern "C" fn((*const _)) -> (*const _)); | ||
let [name] = | ||
this.check_shim_abi(link_name, abi, callee_abi, arg_types, ret_type, args)?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Outsider question: How many places is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It is used in
Yes, I'll package them into one argument . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that is what I suggested in the first place: let [name, value, overwrite] = this.check_shim_abi(
shim_sig!(extern "C" fn(*const _, *const _, i32) -> i32),
link_name,
abi,
args,
)?; |
||
let result = this.getenv(name)?; | ||
this.write_pointer(result, dest)?; | ||
} | ||
"unsetenv" => { | ||
let [name] = this.check_shim_abi( | ||
link_name, | ||
abi, | ||
ExternAbi::C { unwind: false }, | ||
[this.machine.layouts.const_raw_ptr.ty], | ||
this.tcx.types.i32, | ||
args, | ||
)?; | ||
let (callee_abi, arg_types, ret_type) = | ||
shim_sig!(this, extern "C" fn((*const _)) -> i32); | ||
let [name] = | ||
this.check_shim_abi(link_name, abi, callee_abi, arg_types, ret_type, args)?; | ||
let result = this.unsetenv(name)?; | ||
this.write_scalar(result, dest)?; | ||
} | ||
|
@@ -177,14 +169,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | |
this.write_scalar(result, dest)?; | ||
} | ||
"getpid" => { | ||
let [] = this.check_shim_abi( | ||
link_name, | ||
abi, | ||
ExternAbi::C { unwind: false }, | ||
[], | ||
this.libc_ty_layout("pid_t").ty, | ||
args, | ||
)?; | ||
let (callee_abi, arg_types, ret_type) = shim_sig!(this, extern "C" fn() -> "pid_t"); | ||
let [] = | ||
this.check_shim_abi(link_name, abi, callee_abi, arg_types, ret_type, args)?; | ||
let result = this.getpid()?; | ||
this.write_scalar(result, dest)?; | ||
} | ||
|
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.
Having to use
:tt
instead of:ty
here is unfortunate. I guess that's because*const _
is not a valid type? Maybe we can use*const T
instead?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.
Then I won't be able to match libc types.
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.
Why not? Please explain the problem.
Uh oh!
There was an error while loading. Please reload this page.
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.
"pid_t" won't be able to match
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.
Why not? That's a valid type, syntactically.
Uh oh!
There was an error while loading. Please reload this page.
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.
When I call this macro
layout_and_ty($this, i32)
, it matches with($this:ident, $x:ty)
not($this:ident, i32)
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.
In the macro arm of
layout_and_ty
, is it takingi32
as a keyword not a rust type?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.
i32
is not a keyword though...But I would anyway say the fallback arm should be
Does that help?
Also your macro should probably return the entire layout, not just the type.
Uh oh!
There was an error while loading. Please reload this page.
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 think the issue is that when I pass already matched
ty
token inshim_sig
tolayout_and_ty
, then I can only match$x:ty
arm. But if I would have directly calledlayout_and_ty
macro then I would have been able to matchi32
arm. See this.Am I correct here?
So I think I have do
if-else
insidex:ty
arm and return the correct layout.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.
Hm, I don't know if there is a trick to "degenerate" a
ty
token back to a series oftt
. Maybe ask on Zulip? I'm not a macro expert unfortunately.