treat prctl like a variadic function
This commit is contained in:
parent
59ee672fef
commit
cac48dd734
@ -921,7 +921,7 @@ fn linux_statx(
|
|||||||
dirfd_op: &OpTy<'tcx, Tag>, // Should be an `int`
|
dirfd_op: &OpTy<'tcx, Tag>, // Should be an `int`
|
||||||
pathname_op: &OpTy<'tcx, Tag>, // Should be a `const char *`
|
pathname_op: &OpTy<'tcx, Tag>, // Should be a `const char *`
|
||||||
flags_op: &OpTy<'tcx, Tag>, // Should be an `int`
|
flags_op: &OpTy<'tcx, Tag>, // Should be an `int`
|
||||||
mask_op: &OpTy<'tcx, Tag>, // Should be an `unsigned int`
|
mask_op: &OpTy<'tcx, Tag>, // Should be an `unsigned int`
|
||||||
statxbuf_op: &OpTy<'tcx, Tag>, // Should be a `struct statx *`
|
statxbuf_op: &OpTy<'tcx, Tag>, // Should be a `struct statx *`
|
||||||
) -> InterpResult<'tcx, i32> {
|
) -> InterpResult<'tcx, i32> {
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
|
@ -106,9 +106,9 @@ fn emulate_foreign_item_by_name(
|
|||||||
|
|
||||||
// Threading
|
// Threading
|
||||||
"prctl" => {
|
"prctl" => {
|
||||||
let &[ref option, ref arg2, ref arg3, ref arg4, ref arg5] =
|
// prctl is variadic. (It is not documented like that in the manpage, but defined like that in the libc crate.)
|
||||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
|
||||||
let result = this.prctl(option, arg2, arg3, arg4, arg5)?;
|
let result = this.prctl(args)?;
|
||||||
this.write_scalar(Scalar::from_i32(result), dest)?;
|
this.write_scalar(Scalar::from_i32(result), dest)?;
|
||||||
}
|
}
|
||||||
"pthread_condattr_setclock" => {
|
"pthread_condattr_setclock" => {
|
||||||
|
@ -97,20 +97,27 @@ fn pthread_self(&mut self, dest: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
|
|||||||
this.write_scalar(Scalar::from_uint(thread_id.to_u32(), dest.layout.size), dest)
|
this.write_scalar(Scalar::from_uint(thread_id.to_u32(), dest.layout.size), dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prctl(
|
fn prctl(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> {
|
||||||
&mut self,
|
|
||||||
option: &OpTy<'tcx, Tag>,
|
|
||||||
arg2: &OpTy<'tcx, Tag>,
|
|
||||||
_arg3: &OpTy<'tcx, Tag>,
|
|
||||||
_arg4: &OpTy<'tcx, Tag>,
|
|
||||||
_arg5: &OpTy<'tcx, Tag>,
|
|
||||||
) -> InterpResult<'tcx, i32> {
|
|
||||||
let this = self.eval_context_mut();
|
let this = self.eval_context_mut();
|
||||||
this.assert_target_os("linux", "prctl");
|
this.assert_target_os("linux", "prctl");
|
||||||
|
|
||||||
let option = this.read_scalar(option)?.to_i32()?;
|
if args.len() < 1 {
|
||||||
|
throw_ub_format!(
|
||||||
|
"incorrect number of arguments for `prctl`: got {}, expected at least 1",
|
||||||
|
args.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let option = this.read_scalar(&args[0])?.to_i32()?;
|
||||||
if option == this.eval_libc_i32("PR_SET_NAME")? {
|
if option == this.eval_libc_i32("PR_SET_NAME")? {
|
||||||
let address = this.read_pointer(arg2)?;
|
if args.len() < 2 {
|
||||||
|
throw_ub_format!(
|
||||||
|
"incorrect number of arguments for `prctl` with `PR_SET_NAME`: got {}, expected at least 2",
|
||||||
|
args.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let address = this.read_pointer(&args[1])?;
|
||||||
let mut name = this.read_c_str(address)?.to_owned();
|
let mut name = this.read_c_str(address)?.to_owned();
|
||||||
// The name should be no more than 16 bytes, including the null
|
// The name should be no more than 16 bytes, including the null
|
||||||
// byte. Since `read_c_str` returns the string without the null
|
// byte. Since `read_c_str` returns the string without the null
|
||||||
@ -118,7 +125,14 @@ fn prctl(
|
|||||||
name.truncate(15);
|
name.truncate(15);
|
||||||
this.set_active_thread_name(name);
|
this.set_active_thread_name(name);
|
||||||
} else if option == this.eval_libc_i32("PR_GET_NAME")? {
|
} else if option == this.eval_libc_i32("PR_GET_NAME")? {
|
||||||
let address = this.read_pointer(arg2)?;
|
if args.len() < 2 {
|
||||||
|
throw_ub_format!(
|
||||||
|
"incorrect number of arguments for `prctl` with `PR_SET_NAME`: got {}, expected at least 2",
|
||||||
|
args.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let address = this.read_pointer(&args[1])?;
|
||||||
let mut name = this.get_active_thread_name().to_vec();
|
let mut name = this.get_active_thread_name().to_vec();
|
||||||
name.push(0u8);
|
name.push(0u8);
|
||||||
assert!(name.len() <= 16);
|
assert!(name.len() <= 16);
|
||||||
|
@ -12,5 +12,5 @@ fn main() {
|
|||||||
fn test_file_open_missing_needed_mode() {
|
fn test_file_open_missing_needed_mode() {
|
||||||
let name = b"missing_arg.txt\0";
|
let name = b"missing_arg.txt\0";
|
||||||
let name_ptr = name.as_ptr().cast::<libc::c_char>();
|
let name_ptr = name.as_ptr().cast::<libc::c_char>();
|
||||||
let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected 3
|
let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
// ignore-windows: No libc on Windows
|
|
||||||
// compile-flags: -Zmiri-disable-isolation
|
|
||||||
|
|
||||||
#![feature(rustc_private)]
|
|
||||||
|
|
||||||
extern crate libc;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
test_open_too_many_args();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_open_too_many_args() {
|
|
||||||
let name = b"too_many_args.txt\0";
|
|
||||||
let name_ptr = name.as_ptr().cast::<libc::c_char>();
|
|
||||||
let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY, 0, 0) }; //~ ERROR Undefined Behavior: incorrect number of arguments for `open`: got 4, expected 2 or 3
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user