profile
viewpoint

japaric/xargo 691

The sysroot manager that lets you build and customize `std`

Gilnaa/memoffset 54

offsetof for Rust

opatut/dudel 28

This used to be a webapp for scheduling meetings easily. Now it's no longer maintained. Have a look at Bitpoll instead:

Diggsey/rust-field-offset 18

Safe pointer-to-member functionality for rust

RalfJung/ansible 1

ansible playbooks for my servers

freifunk-saar/tunneldigger 0

Client and broker for our custom L2TPv3 NAT-traversing tunnel setup protocol based on L2TPv3 support in the Linux kernel.

hacksaar/Firmware 0

ESP32 firmware for the SHA2017 badge

hacksaar/micropython-esp32 0

MicroPython ported to the SHA2017 badge

issue openedrust-lang/cargo

Confusing output when checking crate with build script (?)

<!-- Thanks for filing a 🐛 bug report 😄! -->

Problem <!-- A clear and concise description of what the bug is. --> <!-- including what currently happens and what you expected to happen. --> Running ./x.py check src/librustc_mir in the rustc repo produces output like this:

Checking std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
   Compiling cc v1.0.50
    Checking core v0.0.0 (/home/r/src/rust/rustc/src/libcore)
   Compiling libc v0.2.66
   Compiling autocfg v0.1.7
   Compiling std v0.0.0 (/home/r/src/rust/rustc/src/libstd)
   Compiling hashbrown v0.6.2
   Compiling compiler_builtins v0.1.25
   Compiling backtrace-sys v0.1.32
   Compiling unwind v0.0.0 (/home/r/src/rust/rustc/src/libunwind)
    Checking rustc-std-workspace-core v1.99.0 (/home/r/src/rust/rustc/src/tools/rustc-std-workspace-core)
    Checking cfg-if v0.1.10
    Checking alloc v0.0.0 (/home/r/src/rust/rustc/src/liballoc)
    Checking rustc-demangle v0.1.16
    Checking panic_abort v0.0.0 (/home/r/src/rust/rustc/src/libpanic_abort)
    Checking backtrace v0.3.44
    Checking rustc-std-workspace-alloc v1.99.0 (/home/r/src/rust/rustc/src/tools/rustc-std-workspace-alloc)
    Checking panic_unwind v0.0.0 (/home/r/src/rust/rustc/src/libpanic_unwind)
    Checking rustc-std-workspace-std v1.99.0 (/home/r/src/rust/rustc/src/tools/rustc-std-workspace-std)
    Checking term v0.0.0 (/home/r/src/rust/rustc/src/libterm)
    Checking proc_macro v0.0.0 (/home/r/src/rust/rustc/src/libproc_macro)
    Checking unicode-width v0.1.6
    Checking getopts v0.2.21
    Checking test v0.0.0 (/home/r/src/rust/rustc/src/libtest)
    Finished release [optimized + debuginfo] target(s) in 28.53s

Notice that it says "Compiling std", but "Checking core". That seems very odd. With some extra levels of verbosity, I see the expected --emit=dep-info,metadata, so it looks like it is actually just checking std and not building it.

Possible Solution(s) <!-- Not obligatory, but suggest a fix/reason for the bug, --> <!-- or ideas how to implement the addition or change --> My guess is that the key difference between "core" and "std" here is that "std" has a build script. Of course it needs to actually compile the build script, not just check it. But describing that as "Compiling std" is pretty confusing, given that the actual library is not being built, just checked.

<!-- Also, any additional context or information you feel may be relevant to the issue. --> <!-- (e.g rust version, OS platform/distribution/version, target toolchain(s), release channel.. -->

created time in a day

PR opened rust-lang/rust

move const_eval.rs into the module folder

This groups the file together with the other const_eval files in editors, diff views, etc.

r? @oli-obk

+0 -0

0 comment

1 changed file

pr created time in a day

create barnchRalfJung/rust

branch : const-eval-mod

created branch time in a day

delete branch RalfJung/miri

delete branch : rustup

delete time in a day

delete branch RalfJung/miri

delete branch : readme

delete time in a day

delete branch RalfJung/miri

delete branch : bootstrap

delete time in a day

Pull request review commentrust-lang/rust

mir-interpret: add methods to read/write wide strings

 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {         Ok(str)     } +    // Turn the wide MPlace into a OsString (must already be dereferenced!)+    pub fn read_os_str_from_wide_str(+        &self,+        mplace: MPlaceTy<'tcx, M::PointerTag>,+    ) -> InterpResult<'tcx, std::ffi::OsString> {+        let len = mplace.len(self)? as u64;+        let mut u16_vec: Vec<u16> = Vec::with_capacity(len as usize);+        for idx in 0..len {+            let place = self.mplace_field(mplace, idx)?;+            match self.read_scalar(OpTy::from(place))? {+                ScalarMaybeUndef::Scalar(scalar) => {+                    let item = Scalar::to_u16(scalar)?;+                    u16_vec.push(item);+                }+                ScalarMaybeUndef::Undef => panic!("ScalarMaybeUndef: Undef error"),+            }+        }+        let fetched_string = std::char::decode_utf16(u16_vec.into_iter())

So probably this is a reasonable fallback on non-Windows hosts? It will error if there is a surrogate, but work correctly otherwise?

JOE1994

comment created time in a day

pull request commentrust-lang/rust

mir-interpret: add methods to read/write wide strings

read_os_str_from_wide_str doesn't use a NULL terminator to check the length(or termination) of a string

That is pretty odd, and why should that work? The users of these APIs have no idea how long the string is going to be.

You used mplace.len(), that makes little sense as it assumes that this is a slice or array. But the case where you need this method is when you got a raw ptr to some memory, and you have no idea how long the string is. That is all you got in the Windows APIs you want to implement: you have a place containing the pointer, which you read to get the pointer, and then you have to work with that. You don't get a place containing the string.

Current return type of read_os_str_from_wide_str is InterpResult<'tcx, std::ffi::OsString>. Is that okay as it is? Or should it instead be InterpResult<'tcx, &std::ffi::OsStr>

There should be nothing about OsStr or OsString on the rustc side, only Miri needs this.

You only need to add on the rustc side whatever primitives are needed to implement this in Miri. And I think the only primitive you need is Memory::read_wide_c_str, which should be like Memory:read_c_str except that it returns a Vec<u16>. That should use read_scalar to repeatedly read u16 until it finds a NULL, and push everything into a Vec, and return that.

All that business about actually interpreting this sequence of u16 should be left to Miri.

JOE1994

comment created time in a day

pull request commentrust-lang/miri

fix README

@bors r+

RalfJung

comment created time in a day

push eventRalfJung/miri

Ralf Jung

commit sha 86a4354746c81d06fc09c5c0633449a26bee442a

fix README

view details

push time in a day

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx         this.try_unwrap_io_result(create_link(target, linkpath).map(|_| 0))     } -    fn stat(+    fn macos_stat(         &mut self,         path_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();         this.check_no_isolation("stat")?;+        this.check_platform("macos", "stat")?;         // `stat` always follows symlinks.-        this.stat_or_lstat(true, path_op, buf_op)+        this.macos_stat_or_lstat(true, path_op, buf_op)     }      // `lstat` is used to get symlink metadata.-    fn lstat(+    fn macos_lstat(         &mut self,         path_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();         this.check_no_isolation("lstat")?;-        this.stat_or_lstat(false, path_op, buf_op)+        this.check_platform("macos", "lstat")?;+        this.macos_stat_or_lstat(false, path_op, buf_op)     } -    fn fstat(+    fn macos_fstat(         &mut self,         fd_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();          this.check_no_isolation("fstat")?;--        if this.tcx.sess.target.target.target_os.to_lowercase() != "macos" {-            throw_unsup_format!("The `fstat` shim is only available for `macos` targets.")-        }+        this.check_platform("macos", "fstat")?;

Actually, thinking about this again... if the user cannot trigger these errors any more, I think they should be assertions; no need to give a nice error.

Sorry for the back-and-forth.

christianpoveda

comment created time in a day

pull request commentrust-lang/miri

Environ shim

@christianpoveda I am going to implement what I proposed above; I got some time this week-end.

christianpoveda

comment created time in a day

pull request commentrust-lang/reference

Fix an error in repr(C) struct offset pseudocode

Lol, I had no idea. Also, I didn't say I wanted approval powers here. ;)

Anyway, in terms of the code here, I think at the very least "pad-to-align" should be a helper method. It's sufficiently subtle to implement, entirely non-obvious to read but has a very intuitive meaning.

Also Cc @gnzlbg and @hanna-kruppe who are much more familiar with data layout matters than I am.

rkanati

comment created time in a day

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__errno_location" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+            "close" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Time related shims++            // This is a POSIX function but it has only been tested on linux.+            "clock_gettime" => {+                let result = this.clock_gettime(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Other shims+            "pthread_getattr_np" => {+                this.write_null(dest)?;+            }++            "syscall" => {+                let sys_getrandom = this+                    .eval_path_scalar(&["libc", "SYS_getrandom"])?+                    .expect("Failed to get libc::SYS_getrandom")+                    .to_machine_usize(this)?;++                let sys_statx = this+                    .eval_path_scalar(&["libc", "SYS_statx"])?+                    .expect("Failed to get libc::SYS_statx")+                    .to_machine_usize(this)?;++                match this.read_scalar(args[0])?.to_machine_usize(this)? {+                    // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`+                    // is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).+                    id if id == sys_getrandom => {+                        // The first argument is the syscall id,+                        // so skip over it.+                        getrandom(this, &args[1..], dest)?;+                    }+                    id if id == sys_statx => {

Please add a comment saying that this corresponds to macOS stat, lstat, fstat.

christianpoveda

comment created time in a day

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__errno_location" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+            "close" => {

Well but the same is true for stat, lstat, fstat, right?

Ah but for those we have statx as a syscall below, I see. Please add a comment along the lines of what you wrote here.

christianpoveda

comment created time in a day

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx         this.try_unwrap_io_result(create_link(target, linkpath).map(|_| 0))     } -    fn stat(+    fn macos_stat(         &mut self,         path_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();         this.check_no_isolation("stat")?;+        this.check_platform("macos", "stat")?;         // `stat` always follows symlinks.-        this.stat_or_lstat(true, path_op, buf_op)+        this.macos_stat_or_lstat(true, path_op, buf_op)     }      // `lstat` is used to get symlink metadata.-    fn lstat(+    fn macos_lstat(         &mut self,         path_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();         this.check_no_isolation("lstat")?;-        this.stat_or_lstat(false, path_op, buf_op)+        this.check_platform("macos", "lstat")?;+        this.macos_stat_or_lstat(false, path_op, buf_op)     } -    fn fstat(+    fn macos_fstat(         &mut self,         fd_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();          this.check_no_isolation("fstat")?;--        if this.tcx.sess.target.target.target_os.to_lowercase() != "macos" {-            throw_unsup_format!("The `fstat` shim is only available for `macos` targets.")-        }+        this.check_platform("macos", "fstat")?;          let fd = this.read_scalar(fd_op)?.to_i32()?;          let metadata = match FileMetadata::from_fd(this, fd)? {             Some(metadata) => metadata,             None => return Ok(-1),         };-        stat_macos_write_buf(this, metadata, buf_op)+        macos_stat_write_buf(this, metadata, buf_op)     } -    fn stat_or_lstat(+    fn macos_stat_or_lstat(

Then please add a doc comment saying what checks it expects the caller to have made.

christianpoveda

comment created time in a day

pull request commentrust-lang/reference

Fix an error in repr(C) struct offset pseudocode

I indicated above how I think this should be written.

Also I have no approval powers here. Cc @Centril

rkanati

comment created time in a day

Pull request review commentrust-lang/reference

Fix an error in repr(C) struct offset pseudocode

 for field in struct.fields_in_declaration_order() {     // Increase the current offset so that it's a multiple of the alignment     // of this field. For the first field, this will always be zero.     // The skipped bytes are called padding bytes.-    current_offset += field.alignment % current_offset;

There's another "current_offset + current_offset % struct.alignment" further down, why doesn't that need fixing, too?

rkanati

comment created time in a day

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx         this.try_unwrap_io_result(create_link(target, linkpath).map(|_| 0))     } -    fn stat(+    fn macos_stat(         &mut self,         path_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();         this.check_no_isolation("stat")?;+        this.check_platform("macos", "stat")?;         // `stat` always follows symlinks.-        this.stat_or_lstat(true, path_op, buf_op)+        this.macos_stat_or_lstat(true, path_op, buf_op)     }      // `lstat` is used to get symlink metadata.-    fn lstat(+    fn macos_lstat(         &mut self,         path_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();         this.check_no_isolation("lstat")?;-        this.stat_or_lstat(false, path_op, buf_op)+        this.check_platform("macos", "lstat")?;+        this.macos_stat_or_lstat(false, path_op, buf_op)     } -    fn fstat(+    fn macos_fstat(         &mut self,         fd_op: OpTy<'tcx, Tag>,         buf_op: OpTy<'tcx, Tag>,     ) -> InterpResult<'tcx, i32> {         let this = self.eval_context_mut();          this.check_no_isolation("fstat")?;--        if this.tcx.sess.target.target.target_os.to_lowercase() != "macos" {-            throw_unsup_format!("The `fstat` shim is only available for `macos` targets.")-        }+        this.check_platform("macos", "fstat")?;          let fd = this.read_scalar(fd_op)?.to_i32()?;          let metadata = match FileMetadata::from_fd(this, fd)? {             Some(metadata) => metadata,             None => return Ok(-1),         };-        stat_macos_write_buf(this, metadata, buf_op)+        macos_stat_write_buf(this, metadata, buf_op)     } -    fn stat_or_lstat(+    fn macos_stat_or_lstat(

This one has no platform check though?

christianpoveda

comment created time in 2 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__errno_location" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+            "close" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Time related shims+            "clock_gettime" => {+                let result = this.clock_gettime(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Other shims+            "pthread_getattr_np" => {+                this.write_null(dest)?;+            }++            "syscall" => {+                let sys_getrandom = this+                    .eval_path_scalar(&["libc", "SYS_getrandom"])?+                    .expect("Failed to get libc::SYS_getrandom")+                    .to_machine_usize(this)?;++                let sys_statx = this+                    .eval_path_scalar(&["libc", "SYS_statx"])?+                    .expect("Failed to get libc::SYS_statx")+                    .to_machine_usize(this)?;++                match this.read_scalar(args[0])?.to_machine_usize(this)? {+                    // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`+                    // is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).+                    id if id == sys_getrandom => {+                        // The first argument is the syscall id,+                        // so skip over it.+                        getrandom(this, &args[1..], dest)?;+                    }+                    id if id == sys_statx => {+                        // The first argument is the syscall id,+                        // so skip over it.+                        let result = this.linux_statx(args[1], args[2], args[3], args[4], args[5])?;+                        this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+                    }+                    id => throw_unsup_format!("miri does not support syscall ID {}", id),+                }+            }++            "getrandom" => {+                getrandom(this, args, dest)?;+            }++            "sched_getaffinity" => {+                // Return an error; `num_cpus` then falls back to `sysconf`.+                this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?;+            }++            _ => throw_unsup_format!("can't call foreign function: {}", link_name),+        };++        Ok(true)+    }+}++// Shims the posix 'getrandom()' syscall.
// Shims the Linux `getrandom()` syscall.
christianpoveda

comment created time in 2 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__errno_location" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+            "close" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Time related shims+            "clock_gettime" => {

Technically clock_gettime is a POSIX function... maybe add a comment that this is only tested to work on Linux.

christianpoveda

comment created time in 2 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__errno_location" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+            "close" => {

Why is close the only linux-specific one? That seems odd.^^

christianpoveda

comment created time in 2 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx                 this.write_scalar(Scalar::from_int(result, Size::from_bits(32)), dest)?;             } -            "memrchr" => {+            "memchr" => {

In the interest of keeping the diff smaller, please keep the original order: memrchr first, then memchr.

christianpoveda

comment created time in 2 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx         };          // Next: functions that return.+        if this.emulate_foreign_item_by_name(link_name, args, dest, ret)? {+            this.dump_place(*dest);+            this.go_to_block(ret);+        }++        Ok(None)+    }++    /// Emulates calling a foreign item using its name, failing if the item is not supported.+    /// Returns Ok(false) if after calling this function, the call should return earlier instead of+    /// going to the next block.

What does this mean, "the call should return earlier"?

What about: "Returns true if the caller is expected to jump to the return block, and false if jumping has already been taken care of"

christianpoveda

comment created time in 2 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx         }         Ok(())     }+    /// Helper function used inside the shims of foreign functions to check that the target+    /// platform is `platform`. It returns an error using the `name` of the foreign function if+    /// this is not the case.+    fn check_platform(&mut self, platform: &str, name: &str) -> InterpResult<'tcx> {+        if self.eval_context_mut().tcx.sess.target.target.target_os.to_lowercase() != platform {+            throw_unsup_format!(+                "`{}` is only available in the `{}` platform",
                "`{}` is only available on the `{}` platform",

I'm not a native speaker, but I think I usually see people saying something is available "on" a platform.

christianpoveda

comment created time in 2 days

pull request commentrust-lang/rust

bump Miri

All right I think I fixed this, it also needed a change on the Miri side.

r? @oli-obk because bootstrap changes

RalfJung

comment created time in 2 days

push eventRalfJung/rust

Ralf Jung

commit sha 1a0e2001bca6cbb3fc8496b83d5f847e11f459e6

fix miri and bootstrap interaction

view details

push time in 2 days

pull request commentrust-lang/miri

dont overwrite bootstrap flags

@bors r+

RalfJung

comment created time in 2 days

PR opened rust-lang/miri

dont overwrite bootstrap flags
+0 -2

0 comment

1 changed file

pr created time in 2 days

create barnchRalfJung/miri

branch : bootstrap

created branch time in 2 days

Pull request review commentrust-lang/miri

Add shims for RwLock::try_read/RwLock::try_write

-// Just instantiate some data structures to make sure we got all their foreign items covered. // Requires full MIR on Windows.

No I mean the "Requires full MIR on Windows", which so far you did not remove as far as I can see.

divergentdave

comment created time in 2 days

Pull request review commentrust-lang/rust

Make Layout::new const

 impl Layout {      /// Constructs a `Layout` suitable for holding a value of type `T`.     #[stable(feature = "alloc_layout", since = "1.28.0")]+    #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]     #[inline]-    pub fn new<T>() -> Self {+    pub const fn new<T>() -> Self {         let (size, align) = size_align::<T>();         // Note that the align is guaranteed by rustc to be a power of two and         // the size+align combo is guaranteed to fit in our address space. As a         // result use the unchecked constructor here to avoid inserting code         // that panics if it isn't optimized well enough.-        debug_assert!(Layout::from_size_align(size, align).is_ok());

This would just use it for a debug assertion though, which we can remove again any time if we have to.

CAD97

comment created time in 2 days

pull request commentrust-lang/rust

bump Miri

@bors r- looks like libstd doesn't come with the debug assertions we expect it to have... odd.

RalfJung

comment created time in 2 days

issue openedcoq/coq

significant slowdown with ocaml 4.08.1

<!-- Thank you for reporting a bug to Coq! -->

Description of the problem

<!-- If you can, it's helpful to provide self-contained example of some code that reproduces the bug. If not, a link to a larger example is also helpful. --> I just noticed a significant build time regression in Iris even though these commits did not actually change the Coq code at all. But what did change around that time is the OCaml version that we are using on CI: we used to use 4.07.1, but I recently bumped that to 4.08.1 (to match Debian testing).

That resulted in an almost 14% slowdown for Iris.

Cc @robbertkrebbers

Coq Version

<!-- You can get this information by running coqtop -v. If relevant, please also include your operating system. --> 8.11.0

created time in 2 days

pull request commentrust-lang/rust

bump Miri

Submodule-only toolstate-fix @bors r+ p=1

RalfJung

comment created time in 2 days

pull request commentrust-lang/rust

bump Miri

@divergentdave with this, some of your PRs are finally being shipped. :)

RalfJung

comment created time in 2 days

PR opened rust-lang/rust

bump Miri

Fixes https://github.com/rust-lang/rust/issues/69331

r? @ghost Cc @oli-obk

+1 -1

0 comment

1 changed file

pr created time in 2 days

create barnchRalfJung/rust

branch : miri

created branch time in 2 days

Pull request review commentrust-lang/rust

Make Layout::new const

 impl Layout {      /// Constructs a `Layout` suitable for holding a value of type `T`.     #[stable(feature = "alloc_layout", since = "1.28.0")]+    #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]     #[inline]-    pub fn new<T>() -> Self {+    pub const fn new<T>() -> Self {         let (size, align) = size_align::<T>();         // Note that the align is guaranteed by rustc to be a power of two and         // the size+align combo is guaranteed to fit in our address space. As a         // result use the unchecked constructor here to avoid inserting code         // that panics if it isn't optimized well enough.-        debug_assert!(Layout::from_size_align(size, align).is_ok());

Actually looks like we already have stable const fn that opt into using conditionals, so just adding #[allow_internal_unstable(const_if_match)] should be fine.

CAD97

comment created time in 2 days

Pull request review commentrust-lang/rust

Make Layout::new const

 impl Layout {      /// Constructs a `Layout` suitable for holding a value of type `T`.     #[stable(feature = "alloc_layout", since = "1.28.0")]+    #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]     #[inline]-    pub fn new<T>() -> Self {+    pub const fn new<T>() -> Self {         let (size, align) = size_align::<T>();         // Note that the align is guaranteed by rustc to be a power of two and         // the size+align combo is guaranteed to fit in our address space. As a         // result use the unchecked constructor here to avoid inserting code         // that panics if it isn't optimized well enough.-        debug_assert!(Layout::from_size_align(size, align).is_ok());

@CAD97 Stable const fn cannot use unstable features. There's allow_internal_unstable to work around this, but at this point we might not yet want to stabilize methods that use these features internally.

Also @oli-obk is the better person for such questions. :) Or just ping the entire team: @rust-lang/wg-const-eval

CAD97

comment created time in 2 days

pull request commentrust-lang/miri

fix for const-prop lint changes

@bors r+

RalfJung

comment created time in 2 days

push eventRalfJung/miri

Ralf Jung

commit sha 0e7e5b9655cd1baab18e7ef28693cb22a94b3d0d

fix test-cargo-miri

view details

Ralf Jung

commit sha 3e2f29a0796af501485e13cfa06302aa6e479d6a

remove some no-longer-needed allow(const_err)

view details

push time in 2 days

delete branch RalfJung/rust

delete branch : const-prop-lints

delete time in 2 days

pull request commentrust-lang/rust

Unify and improve const-prop lints

I marked this for relnotes, given the user-visible changes here. I hope that is appropriate.

RalfJung

comment created time in 2 days

Pull request review commentrust-lang/miri

Add shims for RwLock::try_read/RwLock::try_write

-// Just instantiate some data structures to make sure we got all their foreign items covered. // Requires full MIR on Windows.

This comment is awfully outdated, these days we use full MIR everywhere anyway. Could you remove it?

divergentdave

comment created time in 2 days

pull request commentrust-lang/miri

Add shims for RwLock::try_read/RwLock::try_write

I just added a separate test that exercises PTHREAD_MUTEX_RECURSIVE, by calling println!() from within a println!(). If I copy-paste the PTHREAD_MUTEX_NORMAL behavior where RECURSIVE is in the shims, this test case fails with the deadlock error message.

Nice catch! I didn't even know that relied in reentrant mutexes.

It would also be good to have a test that exercises the locking API more directly, as we have little control over how e.g. println! locking will change in the future. You already do some of that in sync.rs; also doing it for PTHREAD_MUTEX_RECURSIVE would be great.

divergentdave

comment created time in 2 days

pull request commentrust-lang/miri

fix for const-prop lint changes

@bors r+

RalfJung

comment created time in 2 days

push eventRalfJung/miri

Ralf Jung

commit sha 627d7cba644575467eb276a853acc07f7fcf2b33

fix for const-prop lint changes

view details

push time in 2 days

PR opened rust-lang/miri

fix for const-prop lint changes

Cc https://github.com/rust-lang/rust/issues/69331

+7 -8

0 comment

7 changed files

pr created time in 2 days

delete branch rust-lang/miri

delete branch : rustup

delete time in 2 days

PR closed rust-lang/miri

Rustup

Cc https://github.com/rust-lang/rust/issues/69331

+15 -8

0 comment

8 changed files

RalfJung

pr closed time in 2 days

push eventRalfJung/miri

David Cook

commit sha 32a354efa3c089b1f47c8c72c24a6100422be5b8

Test error case of std::fs::rename

view details

bors

commit sha fe8068d1456a695f03d17ebe3ff0c517b8271d7d

Auto merge of #1184 - divergentdave:rename-error-test, r=RalfJung Test error case of std::fs::rename As suggested [here](https://github.com/rust-lang/miri/pull/1158#issuecomment-586459463) this PR adds an additional test case for calling rename on a file path that doesn't exist.

view details

Ralf Jung

commit sha c71eca8f039d0d5e3c3c4fea128a951e79999572

fix for const-prop lint changes

view details

push time in 2 days

PR opened rust-lang/miri

Rustup

Cc https://github.com/rust-lang/rust/issues/69331

+7 -8

0 comment

7 changed files

pr created time in 2 days

create barnchRalfJung/miri

branch : rustup

created branch time in 2 days

pull request commentrust-lang/miri

Test error case of std::fs::rename

Thanks! @bors r+

divergentdave

comment created time in 2 days

PR opened rust-lang/miri

fix README

With https://github.com/rust-lang/miri/pull/1127, we do not abort execution any more when the tracked tag gets popped, we just show a backtrace.

+4 -5

0 comment

1 changed file

pr created time in 2 days

create barnchRalfJung/miri

branch : readme

created branch time in 2 days

issue openedrust-lang/miri

Add option to disable Stacked Borrows but keep validation

For cases where Stacked Borrows is impossible to satisfy (e.g. because &raw is not stable yet), that would be useful.

created time in 3 days

Pull request review commentrust-lang/rust

mir-interpret: add methods to read/write wide strings

 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {         Ok(str)     } +    // Turn the wide MPlace into a OsString (must already be dereferenced!)+    #[cfg(target_os = "windows")]

Also, a Linux host might totally run a Windows target. So this should definitely be built for all platforms.

JOE1994

comment created time in 3 days

issue commentrust-lang/rust

ICE in constprop to out of bounds access in a zero sized array

The ICE seems to be gone on nightly, though. So likely just needs a test?

gwafotapa

comment created time in 3 days

issue commentrust-lang/rust

ICE in constprop to out of bounds access in a zero sized array

@oli-obk https://github.com/rust-lang/rust/pull/69257 is still waiting for review if that's the one you mean.

gwafotapa

comment created time in 3 days

issue commentfreifunk-saar/ff-node-monitor

missing ssl certificate

That is the interesting bit:

smtp_host = "10.77.77.101"

I have never tried using TLS with an IP address, but I don't think it works very well. Currently, the only smtp_host for ff-node-monitor that I know will work are "localhost" and hostnames with a valid cert for that hostname. Maybe there is a way to get TLS working with bare IP addresses, but I have never tried anything along those lines.

You can do openssl s_client -connect 10.77.77.101:25 -starttls smtp to show more information about that certificate.

rubo77

comment created time in 3 days

pull request commentrust-lang/miri

rustup

@bors r+

RalfJung

comment created time in 3 days

PR opened rust-lang/miri

rustup

We got a CI failure from our cronjob. It looks spurious, but better safe than sorry.

+1 -1

0 comment

1 changed file

pr created time in 3 days

create barnchrust-lang/miri

branch : rustup

created branch time in 3 days

delete branch RalfJung/miri

delete branch : rustup

delete time in 3 days

delete branch RalfJung/miri

delete branch : fs-refact

delete time in 3 days

issue closedocaml/opam

"opam upgrade" wants to switch my switch from system to custom ocaml

My default switch is a system switch:

$ opam list | grep ocaml
[WARNING] File /usr/bin/ocamlc, which package ocaml-system.4.08.1 depends upon, was changed on your system. ocaml-system has been marked as removed, and will be reinstalled if necessary.
ocaml            4.08.1      The OCaml compiler (virtual package)
ocaml-config     1           OCaml Switch Configuration
ocamlbuild       0.14.0      OCamlbuild is a build system with builtin rules to easily build most OCaml projects.
ocamlfind        1.8.1       A library manager for OCaml
ocamlgraph       1.8.8       A generic graph library for OCaml

As usual when this warning appears, I'd like to run opam upgrade to make the necessary adjustments. However, what happens then is:

$ opam upgrade
[WARNING] File /usr/bin/ocamlc, which package ocaml-system.4.08.1 depends upon, was changed on your system. ocaml-system has been marked as removed, and will be reinstalled if necessary.
The following actions will be performed:
  ∗ install   ocaml-base-compiler 4.09.0           [required by ocaml]
  ↻ recompile ocaml-config        1                [uses ocaml-base-compiler]
  ↗ upgrade   ocaml               4.08.1 to 4.09.0

It decides my switch should no longer be a system switch, and installs ocaml-base-compiler! That's not okay, it shouldn't do that.

How can I stop it from doing so? Is this switch even salvageable, or has using the same switch for years just broken it beyond repair?

# opam config report
# opam-version      2.0.6 
# self-upgrade      no
# system            arch=x86_64 os=linux os-distribution=debian os-version=testing
[WARNING] File /usr/bin/ocamlc, which package ocaml-system.4.08.1 depends upon, was changed on your system. ocaml-system has been marked as removed, and will be reinstalled if necessary.
# solver            builtin-mccs+glpk
# install-criteria  -removed,-count[version-lag,request],-count[version-lag,changed],-changed
# upgrade-criteria  -removed,-count[version-lag,solution],-new
# jobs              8
# repositories      4 (http), 3 (local), 2 (version-controlled) (default repo at d74ac435)
# pinned            0
# current-switch    system

closed time in 3 days

RalfJung

issue commentocaml/opam

"opam upgrade" wants to switch my switch from system to custom ocaml

Your system compiler changed, and opam detects it

Yeah, I know, but usually (and in all other switches), it then just recompiles everything with the new system compiler.

But here, it installs a different compiler instead. Not sure what's going on, but given that this switch already acted weird recently (and you helped me with that), I think I am going to just declare it a lost cause.^^

RalfJung

comment created time in 3 days

issue commentfreifunk-saar/ff-node-monitor

missing ssl certificate

So this is probably related to sending the email? It sounds like the address given in the cert is not the same as the one that the server actually has. What is your configuration (secrets removed, of course)?

That issue you mention looks different, it doesn't say "IP address mismatch".

rubo77

comment created time in 3 days

pull request commentrust-lang/rfcs

Inline assembly

Is there a practical difference between "the ASM may have written to this memory" and "the ASM did write to this memory"?

@comex gave an example where this can make a difference: if the ASM did write, then memory is frozen. At least, that is one possible approach.

But, anyway, given this is intended to support run-time patching, I think there is no way the compiler can make statements like "the ASM did write".

Amanieu

comment created time in 3 days

pull request commentrust-lang/miri

Reorganize shims by platform

@bors try

christianpoveda

comment created time in 3 days

issue commentrust-lang/miri

Confusing false positives and negatives calling `mmap`

Yeah, what we do with mmap is quite gross. Really it should just return as "not supported" immediately, but we need to somehow make this call work out. I suppose we could check that the pointer is NULL? Or we would go even further and make sure the caller is in libstd, to make sure user code doesn't run into this.

HeroicKatora

comment created time in 3 days

push eventRalfJung/opam-ci

Ralf Jung

commit sha 8bf367a24659a1173219dcd5b61ba48272943b18

update opam

view details

push time in 3 days

push eventRalfJung/opam-ci

Ralf Jung

commit sha 8bf367a24659a1173219dcd5b61ba48272943b18

update opam

view details

push time in 3 days

issue openedocaml/opam

"opam upgrade" wants to switch my switch from system to custom ocaml

My default switch is a system switch:

$ opam list | grep ocaml
[WARNING] File /usr/bin/ocamlc, which package ocaml-system.4.08.1 depends upon, was changed on your system. ocaml-system has been marked as removed, and will be reinstalled if necessary.
ocaml            4.08.1      The OCaml compiler (virtual package)
ocaml-config     1           OCaml Switch Configuration
ocamlbuild       0.14.0      OCamlbuild is a build system with builtin rules to easily build most OCaml projects.
ocamlfind        1.8.1       A library manager for OCaml
ocamlgraph       1.8.8       A generic graph library for OCaml

As usual when this warning appears, I'd like to run opam upgrade to make the necessary adjustments. However, what happens then is:

$ opam upgrade
[WARNING] File /usr/bin/ocamlc, which package ocaml-system.4.08.1 depends upon, was changed on your system. ocaml-system has been marked as removed, and will be reinstalled if necessary.
The following actions will be performed:
  ∗ install   ocaml-base-compiler 4.09.0           [required by ocaml]
  ↻ recompile ocaml-config        1                [uses ocaml-base-compiler]
  ↗ upgrade   ocaml               4.08.1 to 4.09.0

It decides my switch should no longer be a system switch, and installs ocaml-base-compiler! That's not okay, it shouldn't do that.

How can I stop it from doing so? Is this switch even salvageable, or has using the same switch for years just broken it beyond repair?

# opam config report
# opam-version      2.0.6 
# self-upgrade      no
# system            arch=x86_64 os=linux os-distribution=debian os-version=testing
[WARNING] File /usr/bin/ocamlc, which package ocaml-system.4.08.1 depends upon, was changed on your system. ocaml-system has been marked as removed, and will be reinstalled if necessary.
# solver            builtin-mccs+glpk
# install-criteria  -removed,-count[version-lag,request],-count[version-lag,changed],-changed
# upgrade-criteria  -removed,-count[version-lag,solution],-new
# jobs              8
# repositories      4 (http), 3 (local), 2 (version-controlled) (default repo at d74ac435)
# pinned            0
# current-switch    system

created time in 3 days

pull request commentrust-lang/rfcs

Inline assembly

Indeed, and I said nothing to the contrary.

Amanieu

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx                 this.write_scalar(Scalar::from_int(result, Size::from_bits(32)), dest)?;             } -            "memrchr" => {

I'd stay still keep it with memchr -- it just belongs together thematically, and also the implementation should work just fine on Windows.

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+mod linux;+mod macos;++use crate::*;+use rustc::mir;+use rustc::ty::layout::{Align, LayoutOf, Size};++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();+        let tcx = &{ this.tcx.tcx };++        match link_name {+            // Environment related shims+            "getenv" => {+                let result = this.getenv(args[0])?;+                this.write_scalar(result, dest)?;+            }++            "unsetenv" => {+                let result = this.unsetenv(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "setenv" => {+                let result = this.setenv(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "getcwd" => {+                let result = this.getcwd(args[0], args[1])?;+                this.write_scalar(result, dest)?;+            }++            "chdir" => {+                let result = this.chdir(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // File related shims+            "fcntl" => {+                let result = this.fcntl(args[0], args[1], args.get(2).cloned())?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "read" => {+                let result = this.read(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "write" => {+                let fd = this.read_scalar(args[0])?.to_i32()?;+                let buf = this.read_scalar(args[1])?.not_undef()?;+                let n = this.read_scalar(args[2])?.to_machine_usize(tcx)?;+                trace!("Called write({:?}, {:?}, {:?})", fd, buf, n);+                let result = if fd == 1 || fd == 2 {+                    // stdout/stderr+                    use std::io::{self, Write};++                    let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(n))?;+                    // We need to flush to make sure this actually appears on the screen+                    let res = if fd == 1 {+                        // Stdout is buffered, flush to make sure it appears on the screen.+                        // This is the write() syscall of the interpreted program, we want it+                        // to correspond to a write() syscall on the host -- there is no good+                        // in adding extra buffering here.+                        let res = io::stdout().write(buf_cont);+                        io::stdout().flush().unwrap();+                        res+                    } else {+                        // No need to flush, stderr is not buffered.+                        io::stderr().write(buf_cont)+                    };+                    match res {+                        Ok(n) => n as i64,+                        Err(_) => -1,+                    }+                } else {+                    this.write(args[0], args[1], args[2])?+                };+                // Now, `result` is the value we return back to the program.+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "unlink" => {+                let result = this.unlink(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "symlink" => {+                let result = this.symlink(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "rename" => {+                let result = this.rename(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "posix_memalign" => {+                let ret = this.deref_operand(args[0])?;+                let align = this.read_scalar(args[1])?.to_machine_usize(this)?;+                let size = this.read_scalar(args[2])?.to_machine_usize(this)?;+                // Align must be power of 2, and also at least ptr-sized (POSIX rules).+                if !align.is_power_of_two() {+                    throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));+                }+                if align < this.pointer_size().bytes() {+                    throw_ub_format!(+                        "posix_memalign: alignment must be at least the size of a pointer, but is {}",+                        align,+                    );+                }++                if size == 0 {+                    this.write_null(ret.into())?;+                } else {+                    let ptr = this.memory.allocate(+                        Size::from_bytes(size),+                        Align::from_bytes(align).unwrap(),+                        MiriMemoryKind::C.into(),+                    );+                    this.write_scalar(ptr, ret.into())?;+                }+                this.write_null(dest)?;+            }++            "dlsym" => {+                let _handle = this.read_scalar(args[0])?;+                let symbol = this.read_scalar(args[1])?.not_undef()?;+                let symbol_name = this.memory.read_c_str(symbol)?;+                let err = format!("bad c unicode symbol: {:?}", symbol_name);+                let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err);+                if let Some(dlsym) = Dlsym::from_str(symbol_name)? {+                    let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym));+                    this.write_scalar(Scalar::from(ptr), dest)?;+                } else {+                    this.write_null(dest)?;+                }+            }++            "memrchr" => {+                let ptr = this.read_scalar(args[0])?.not_undef()?;+                let val = this.read_scalar(args[1])?.to_i32()? as u8;+                let num = this.read_scalar(args[2])?.to_machine_usize(this)?;+                if let Some(idx) = this+                    .memory+                    .read_bytes(ptr, Size::from_bytes(num))?+                    .iter()+                    .rev()+                    .position(|&c| c == val)+                {+                    let new_ptr = ptr.ptr_offset(Size::from_bytes(num - idx as u64 - 1), this)?;+                    this.write_scalar(new_ptr, dest)?;+                } else {+                    this.write_null(dest)?;+                }+            }++            // Hook pthread calls that go to the thread-local storage memory subsystem.+            "pthread_key_create" => {+                let key_place = this.deref_operand(args[0])?;++                // Extract the function type out of the signature (that seems easier than constructing it ourselves).+                let dtor = match this.test_null(this.read_scalar(args[1])?.not_undef()?)? {+                    Some(dtor_ptr) => Some(this.memory.get_fn(dtor_ptr)?.as_instance()?),+                    None => None,+                };++                // Figure out how large a pthread TLS key actually is.+                // This is `libc::pthread_key_t`.+                let key_type = args[0].layout.ty+                    .builtin_deref(true)+                    .ok_or_else(|| err_ub_format!(+                        "wrong signature used for `pthread_key_create`: first argument must be a raw pointer."+                    ))?+                    .ty;+                let key_layout = this.layout_of(key_type)?;++                // Create key and write it into the memory where `key_ptr` wants it.+                let key = this.machine.tls.create_tls_key(dtor) as u128;+                if key_layout.size.bits() < 128 && key >= (1u128 << key_layout.size.bits() as u128)+                {+                    throw_unsup!(OutOfTls);+                }++                this.write_scalar(Scalar::from_uint(key, key_layout.size), key_place.into())?;++                // Return success (`0`).+                this.write_null(dest)?;+            }+            "pthread_key_delete" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                this.machine.tls.delete_tls_key(key)?;+                // Return success (0)+                this.write_null(dest)?;+            }+            "pthread_getspecific" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                let ptr = this.machine.tls.load_tls(key, tcx)?;+                this.write_scalar(ptr, dest)?;+            }+            "pthread_setspecific" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                let new_ptr = this.read_scalar(args[1])?.not_undef()?;+                this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;++                // Return success (`0`).+                this.write_null(dest)?;+            }++            // Stack size/address stuff.+            | "pthread_attr_init"+            | "pthread_attr_destroy"+            | "pthread_self"+            | "pthread_attr_setstacksize" => {+                this.write_null(dest)?;+            }+            "pthread_attr_getstack" => {+                let addr_place = this.deref_operand(args[1])?;+                let size_place = this.deref_operand(args[2])?;++                this.write_scalar(+                    Scalar::from_uint(STACK_ADDR, addr_place.layout.size),+                    addr_place.into(),+                )?;+                this.write_scalar(+                    Scalar::from_uint(STACK_SIZE, size_place.layout.size),+                    size_place.into(),+                )?;++                // Return success (`0`).+                this.write_null(dest)?;+            }++            // We don't support threading. (Also for Windows.)+            | "pthread_create"+            | "CreateThread"+            => {+                throw_unsup_format!("Miri does not support threading");+            }++            // Stub out calls for condvar, mutex and rwlock, to just return `0`.+            | "pthread_mutexattr_init"+            | "pthread_mutexattr_settype"+            | "pthread_mutex_init"+            | "pthread_mutexattr_destroy"+            | "pthread_mutex_lock"+            | "pthread_mutex_unlock"+            | "pthread_mutex_destroy"+            | "pthread_rwlock_rdlock"+            | "pthread_rwlock_unlock"+            | "pthread_rwlock_wrlock"+            | "pthread_rwlock_destroy"+            | "pthread_condattr_init"+            | "pthread_condattr_setclock"+            | "pthread_cond_init"+            | "pthread_condattr_destroy"+            | "pthread_cond_destroy"+            => {+                this.write_null(dest)?;+            }++            // We don't support fork so we don't have to do anything for atfork.+            "pthread_atfork" => {+                this.write_null(dest)?;+            }++            // Some things needed for `sys::thread` initialization to go through.+            | "signal"+            | "sigaction"+            | "sigaltstack"+            => {+                this.write_scalar(Scalar::from_int(0, dest.layout.size), dest)?;+            }++            "sysconf" => {+                let name = this.read_scalar(args[0])?.to_i32()?;++                trace!("sysconf() called with name {}", name);+                // TODO: Cache the sysconf integers via Miri's global cache.+                let paths = &[+                    (&["libc", "_SC_PAGESIZE"], Scalar::from_int(PAGE_SIZE, dest.layout.size)),+                    (&["libc", "_SC_GETPW_R_SIZE_MAX"], Scalar::from_int(-1, dest.layout.size)),+                    (+                        &["libc", "_SC_NPROCESSORS_ONLN"],+                        Scalar::from_int(NUM_CPUS, dest.layout.size),+                    ),+                ];+                let mut result = None;+                for &(path, path_value) in paths {+                    if let Some(val) = this.eval_path_scalar(path)? {+                        let val = val.to_i32()?;+                        if val == name {+                            result = Some(path_value);+                            break;+                        }+                    }+                }+                if let Some(result) = result {+                    this.write_scalar(result, dest)?;+                } else {+                    throw_unsup_format!("Unimplemented sysconf name: {}", name)+                }+            }++            "isatty" => {+                this.write_null(dest)?;+            }++            "posix_fadvise" => {+                // fadvise is only informational, we can ignore it.+                this.write_null(dest)?;+            }++            "mmap" => {+                // This is a horrible hack, but since the guard page mechanism calls mmap and expects a particular return value, we just give it that value.+                let addr = this.read_scalar(args[0])?.not_undef()?;+                this.write_scalar(addr, dest)?;+            }++            "mprotect" => {+                this.write_null(dest)?;+            }++            _ => {+                match this.tcx.sess.target.target.target_os.to_lowercase().as_str() {+                    "linux" => return linux::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),+                    "macos" => return macos::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),+                    _ => unreachable!(),+                }+            }+        };++        Ok(true)+    }+}++// Shims the posix 'getrandom()' syscall.+fn getrandom<'tcx>(

But macOS has SecRandomCopyBytes, it shouldn't use the syscall

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__error" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+             "open" => {+                let result = this.open(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "close$NOCANCEL" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "stat$INODE64" => {+                let result = this.stat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lstat$INODE64" => {+                let result = this.lstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "fstat$INODE64" => {+                let result = this.fstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lseek" => {

Alternatively, add a comment here saying that we only implement the macOS variant of this general posix function.

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__error" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+             "open" => {+                let result = this.open(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "close$NOCANCEL" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "stat$INODE64" => {+                let result = this.stat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lstat$INODE64" => {+                let result = this.lstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "fstat$INODE64" => {+                let result = this.fstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lseek" => {+                let result = this.lseek64(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Time related shims+            "gettimeofday" => {+                let result = this.gettimeofday(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // macOS API stubs.+            "pthread_attr_get_np" => {+                this.write_null(dest)?;+            }++            "pthread_get_stackaddr_np" => {+                let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);+                this.write_scalar(stack_addr, dest)?;+            }++            "pthread_get_stacksize_np" => {+                let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);+                this.write_scalar(stack_size, dest)?;+            }++            "_tlv_atexit" => {+                // FIXME: register the destructor.+            }++            "_NSGetArgc" => {+                this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;+            }++            "_NSGetArgv" => {+                this.write_scalar(this.machine.argv.expect("machine must be initialized"), dest)?;+            }++            "SecRandomCopyBytes" => {+                let len = this.read_scalar(args[1])?.to_machine_usize(this)?;+                let ptr = this.read_scalar(args[2])?.not_undef()?;+                this.gen_random(ptr, len as usize)?;+                this.write_null(dest)?;+            }++            "syscall" => {

But also, are you sure this macos code here is reachable? This interface strikes me as very linux-specific.

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__error" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+             "open" => {+                let result = this.open(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "close$NOCANCEL" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "stat$INODE64" => {+                let result = this.stat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lstat$INODE64" => {+                let result = this.lstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "fstat$INODE64" => {+                let result = this.fstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lseek" => {+                let result = this.lseek64(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Time related shims+            "gettimeofday" => {+                let result = this.gettimeofday(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // macOS API stubs.+            "pthread_attr_get_np" => {+                this.write_null(dest)?;+            }++            "pthread_get_stackaddr_np" => {+                let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);+                this.write_scalar(stack_addr, dest)?;+            }++            "pthread_get_stacksize_np" => {+                let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);+                this.write_scalar(stack_size, dest)?;+            }++            "_tlv_atexit" => {+                // FIXME: register the destructor.+            }++            "_NSGetArgc" => {+                this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;+            }++            "_NSGetArgv" => {+                this.write_scalar(this.machine.argv.expect("machine must be initialized"), dest)?;+            }++            "SecRandomCopyBytes" => {+                let len = this.read_scalar(args[1])?.to_machine_usize(this)?;+                let ptr = this.read_scalar(args[2])?.not_undef()?;+                this.gen_random(ptr, len as usize)?;+                this.write_null(dest)?;+            }++            "syscall" => {

Hm. The code duplication is not great though.

Can you make this its own dispatch function? With a common base case in posix.rs, then dispatching to linux and macos for more target-specific syscalls?

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx          this.check_no_isolation("fstat")?; -        if this.tcx.sess.target.target.target_os.to_lowercase() != "macos" {

Yeah that's too fragile, please keep the checks here.

Also it might be a good convention to make sure all such platform-specific methods have the platform in their name, like macos_fstat or so.

christianpoveda

comment created time in 4 days

pull request commentrust-lang/rust

Check `RUSTC_CTFE_BACKTRACE` much less by generating fewer errors

@bors r- for commit msg ediitng

wesleywiser

comment created time in 4 days

pull request commentrust-lang/rfcs

Inline assembly

@comex it looks like you switched questions? As far as I was concerned, before we were talking about the question "is the compiler forced to accept that the asm block semantics might be that of freezing". You explicitly want that to be the case it seems, and I think I can at least rationalize that choice and leave it up to the lang team to decide if they are okay with it. ;)

But now you seem to ask "is the compiler permitted to assume that the asm block definitely froze all inputs/outputs". That is a different question, but also an interesting one.

My proposed model answers this question with "no", as the asm block is perfectly allowed to leave all state unchanged. I think it would be odd to require the asm block action to do anything. In the extreme case, for an asm block that's empty, behaving as a NOP should be a possible behavior of that block (even if the compiler may not assume that it is the only possible behavior). Everything else seems pretty odd to me.

Amanieu

comment created time in 4 days

issue closedcoq/coq

coqchk regression: "Fatal Error: User error: Inconsistent assumptions over module Coq.Init.Byte ."

<!-- Thank you for reporting a bug to Coq! -->

Description of the problem

<!-- If you can, it's helpful to provide self-contained example of some code that reproduces the bug. If not, a link to a larger example is also helpful. --> Yesterday, coqchk started failing on our CI. The commit where it started touches only docs, so this is most likely caused by a coqchk regression. You can see a failing log here.

Coq Version

Last version that worked:

name        coq
version     dev
source-hash fdcfe8b7
The Coq Proof Assistant, version 8.12+alpha (February 2020)
compiled on Feb 18 2020 8:27:53 with OCaml 4.07.1

First version that broke:

name        coq
version     dev
source-hash 43c3c7d6
The Coq Proof Assistant, version 8.12+alpha (February 2020)
compiled on Feb 18 2020 21:14:55 with OCaml 4.07.1

That corresponds to this commit range.

closed time in 4 days

RalfJung

issue commentcoq/coq

coqchk regression: "Fatal Error: User error: Inconsistent assumptions over module Coq.Init.Byte ."

Yeah looks like clearing the opam state made this issue go away. Sorry for the noise!

RalfJung

comment created time in 4 days

issue commentSergioBenitez/Rocket

Clean shutdown?

pthread_cancel is unsound in general, yes. It's pretty easy to construct a situation where another thread still has a reference into this thread's stack (e.g. via rayon::join). Also it is unsound to deallocate memory without calling destructors (various things rely on this, e.g. scoped threads and pinning). Also see https://github.com/rust-lang/unsafe-code-guidelines/issues/211.

lilyball

comment created time in 4 days

pull request commentrust-lang/miri

Reorganize shims by platform

Let's see if this works on Windows.

@bors try

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx          this.check_no_isolation("fstat")?; -        if this.tcx.sess.target.target.target_os.to_lowercase() != "macos" {

Uh... what makes you so confident as to remove these checks? We should have a helper method for them though I think.

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;+use rustc::ty::layout::Size;+use std::iter;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();+        let tcx = &{ this.tcx.tcx };++        match link_name {+            // Environment related shims+            "GetEnvironmentVariableW" => {+                // args[0] : LPCWSTR lpName (32-bit ptr to a const string of 16-bit Unicode chars)+                // args[1] : LPWSTR lpBuffer (32-bit pointer to a string of 16-bit Unicode chars)+                // lpBuffer : ptr to buffer that receives contents of the env_var as a null-terminated string.+                // Return `# of chars` stored in the buffer pointed to by lpBuffer, excluding null-terminator.+                // Return 0 upon failure.++                // This is not the env var you are looking for.+                this.set_last_error(Scalar::from_u32(203))?; // ERROR_ENVVAR_NOT_FOUND+                this.write_null(dest)?;+            }++            "SetEnvironmentVariableW" => {+                // args[0] : LPCWSTR lpName (32-bit ptr to a const string of 16-bit Unicode chars)+                // args[1] : LPCWSTR lpValue (32-bit ptr to a const string of 16-bit Unicode chars)+                // Return nonzero if success, else return 0.+                throw_unsup_format!("can't set environment variable on Windows");+            }++            // File related shims+            "WriteFile" => {+                let handle = this.read_scalar(args[0])?.to_machine_isize(this)?;+                let buf = this.read_scalar(args[1])?.not_undef()?;+                let n = this.read_scalar(args[2])?.to_u32()?;+                let written_place = this.deref_operand(args[3])?;+                // Spec says to always write `0` first.+                this.write_null(written_place.into())?;+                let written = if handle == -11 || handle == -12 {+                    // stdout/stderr+                    use std::io::{self, Write};++                    let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(u64::from(n)))?;+                    let res = if handle == -11 {+                        io::stdout().write(buf_cont)+                    } else {+                        io::stderr().write(buf_cont)+                    };+                    res.ok().map(|n| n as u32)+                } else {+                    eprintln!("Miri: Ignored output to handle {}", handle);+                    // Pretend it all went well.+                    Some(n)+                };+                // If there was no error, write back how much was written.+                if let Some(n) = written {+                    this.write_scalar(Scalar::from_u32(n), written_place.into())?;+                }+                // Return whether this was a success.+                this.write_scalar(+                    Scalar::from_int(if written.is_some() { 1 } else { 0 }, dest.layout.size),+                    dest,+                )?;+            }+            // Windows API stubs.+            // HANDLE = isize+            // DWORD = ULONG = u32+            // BOOL = i32

This comment should be moved all the way up now

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__error" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+             "open" => {+                let result = this.open(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "close$NOCANCEL" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "stat$INODE64" => {+                let result = this.stat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lstat$INODE64" => {+                let result = this.lstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "fstat$INODE64" => {+                let result = this.fstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lseek" => {+                let result = this.lseek64(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Time related shims+            "gettimeofday" => {+                let result = this.gettimeofday(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // macOS API stubs.+            "pthread_attr_get_np" => {+                this.write_null(dest)?;+            }++            "pthread_get_stackaddr_np" => {+                let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);+                this.write_scalar(stack_addr, dest)?;+            }++            "pthread_get_stacksize_np" => {+                let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);+                this.write_scalar(stack_size, dest)?;+            }++            "_tlv_atexit" => {+                // FIXME: register the destructor.+            }++            "_NSGetArgc" => {+                this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;+            }++            "_NSGetArgv" => {+                this.write_scalar(this.machine.argv.expect("machine must be initialized"), dest)?;+            }++            "SecRandomCopyBytes" => {+                let len = this.read_scalar(args[1])?.to_machine_usize(this)?;+                let ptr = this.read_scalar(args[2])?.not_undef()?;+                this.gen_random(ptr, len as usize)?;+                this.write_null(dest)?;+            }++            "syscall" => {

Oh you duplicated this between Linux and macOS? Hm... that's a bit odd I feel.

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__error" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+             "open" => {+                let result = this.open(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "close$NOCANCEL" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "stat$INODE64" => {+                let result = this.stat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lstat$INODE64" => {+                let result = this.lstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "fstat$INODE64" => {+                let result = this.fstat(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lseek" => {

Another general POSIX function... does our implementation work in general or just for macOS?

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__error" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+             "open" => {

This is a general POSIX function (Rust just doesn't use it on Linux).

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+use crate::*;+use rustc::mir;++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        _ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();++        match link_name {+            "__errno_location" => {+                let errno_place = this.machine.last_error.unwrap();+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;+            }++            // File related shims+            "open64" => {+                let result = this.open(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "close" => {+                let result = this.close(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "lseek64" => {+                let result = this.lseek64(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // Time related shims+            "clock_gettime" => {+                let result = this.clock_gettime(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "pthread_getattr_np" => {

"Time related shims" doesn't really fit here...

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+mod linux;+mod macos;++use crate::*;+use rustc::mir;+use rustc::ty::layout::{Align, LayoutOf, Size};++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();+        let tcx = &{ this.tcx.tcx };++        match link_name {+            // Environment related shims+            "getenv" => {+                let result = this.getenv(args[0])?;+                this.write_scalar(result, dest)?;+            }++            "unsetenv" => {+                let result = this.unsetenv(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "setenv" => {+                let result = this.setenv(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "getcwd" => {+                let result = this.getcwd(args[0], args[1])?;+                this.write_scalar(result, dest)?;+            }++            "chdir" => {+                let result = this.chdir(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // File related shims+            "fcntl" => {+                let result = this.fcntl(args[0], args[1], args.get(2).cloned())?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "read" => {+                let result = this.read(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "write" => {+                let fd = this.read_scalar(args[0])?.to_i32()?;+                let buf = this.read_scalar(args[1])?.not_undef()?;+                let n = this.read_scalar(args[2])?.to_machine_usize(tcx)?;+                trace!("Called write({:?}, {:?}, {:?})", fd, buf, n);+                let result = if fd == 1 || fd == 2 {+                    // stdout/stderr+                    use std::io::{self, Write};++                    let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(n))?;+                    // We need to flush to make sure this actually appears on the screen+                    let res = if fd == 1 {+                        // Stdout is buffered, flush to make sure it appears on the screen.+                        // This is the write() syscall of the interpreted program, we want it+                        // to correspond to a write() syscall on the host -- there is no good+                        // in adding extra buffering here.+                        let res = io::stdout().write(buf_cont);+                        io::stdout().flush().unwrap();+                        res+                    } else {+                        // No need to flush, stderr is not buffered.+                        io::stderr().write(buf_cont)+                    };+                    match res {+                        Ok(n) => n as i64,+                        Err(_) => -1,+                    }+                } else {+                    this.write(args[0], args[1], args[2])?+                };+                // Now, `result` is the value we return back to the program.+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "unlink" => {+                let result = this.unlink(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "symlink" => {+                let result = this.symlink(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "rename" => {+                let result = this.rename(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "posix_memalign" => {+                let ret = this.deref_operand(args[0])?;+                let align = this.read_scalar(args[1])?.to_machine_usize(this)?;+                let size = this.read_scalar(args[2])?.to_machine_usize(this)?;+                // Align must be power of 2, and also at least ptr-sized (POSIX rules).+                if !align.is_power_of_two() {+                    throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));+                }+                if align < this.pointer_size().bytes() {+                    throw_ub_format!(+                        "posix_memalign: alignment must be at least the size of a pointer, but is {}",+                        align,+                    );+                }++                if size == 0 {+                    this.write_null(ret.into())?;+                } else {+                    let ptr = this.memory.allocate(+                        Size::from_bytes(size),+                        Align::from_bytes(align).unwrap(),+                        MiriMemoryKind::C.into(),+                    );+                    this.write_scalar(ptr, ret.into())?;+                }+                this.write_null(dest)?;+            }++            "dlsym" => {+                let _handle = this.read_scalar(args[0])?;+                let symbol = this.read_scalar(args[1])?.not_undef()?;+                let symbol_name = this.memory.read_c_str(symbol)?;+                let err = format!("bad c unicode symbol: {:?}", symbol_name);+                let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err);+                if let Some(dlsym) = Dlsym::from_str(symbol_name)? {+                    let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym));+                    this.write_scalar(Scalar::from(ptr), dest)?;+                } else {+                    this.write_null(dest)?;+                }+            }++            "memrchr" => {+                let ptr = this.read_scalar(args[0])?.not_undef()?;+                let val = this.read_scalar(args[1])?.to_i32()? as u8;+                let num = this.read_scalar(args[2])?.to_machine_usize(this)?;+                if let Some(idx) = this+                    .memory+                    .read_bytes(ptr, Size::from_bytes(num))?+                    .iter()+                    .rev()+                    .position(|&c| c == val)+                {+                    let new_ptr = ptr.ptr_offset(Size::from_bytes(num - idx as u64 - 1), this)?;+                    this.write_scalar(new_ptr, dest)?;+                } else {+                    this.write_null(dest)?;+                }+            }++            // Hook pthread calls that go to the thread-local storage memory subsystem.+            "pthread_key_create" => {+                let key_place = this.deref_operand(args[0])?;++                // Extract the function type out of the signature (that seems easier than constructing it ourselves).+                let dtor = match this.test_null(this.read_scalar(args[1])?.not_undef()?)? {+                    Some(dtor_ptr) => Some(this.memory.get_fn(dtor_ptr)?.as_instance()?),+                    None => None,+                };++                // Figure out how large a pthread TLS key actually is.+                // This is `libc::pthread_key_t`.+                let key_type = args[0].layout.ty+                    .builtin_deref(true)+                    .ok_or_else(|| err_ub_format!(+                        "wrong signature used for `pthread_key_create`: first argument must be a raw pointer."+                    ))?+                    .ty;+                let key_layout = this.layout_of(key_type)?;++                // Create key and write it into the memory where `key_ptr` wants it.+                let key = this.machine.tls.create_tls_key(dtor) as u128;+                if key_layout.size.bits() < 128 && key >= (1u128 << key_layout.size.bits() as u128)+                {+                    throw_unsup!(OutOfTls);+                }++                this.write_scalar(Scalar::from_uint(key, key_layout.size), key_place.into())?;++                // Return success (`0`).+                this.write_null(dest)?;+            }+            "pthread_key_delete" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                this.machine.tls.delete_tls_key(key)?;+                // Return success (0)+                this.write_null(dest)?;+            }+            "pthread_getspecific" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                let ptr = this.machine.tls.load_tls(key, tcx)?;+                this.write_scalar(ptr, dest)?;+            }+            "pthread_setspecific" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                let new_ptr = this.read_scalar(args[1])?.not_undef()?;+                this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;++                // Return success (`0`).+                this.write_null(dest)?;+            }++            // Stack size/address stuff.+            | "pthread_attr_init"+            | "pthread_attr_destroy"+            | "pthread_self"+            | "pthread_attr_setstacksize" => {+                this.write_null(dest)?;+            }+            "pthread_attr_getstack" => {+                let addr_place = this.deref_operand(args[1])?;+                let size_place = this.deref_operand(args[2])?;++                this.write_scalar(+                    Scalar::from_uint(STACK_ADDR, addr_place.layout.size),+                    addr_place.into(),+                )?;+                this.write_scalar(+                    Scalar::from_uint(STACK_SIZE, size_place.layout.size),+                    size_place.into(),+                )?;++                // Return success (`0`).+                this.write_null(dest)?;+            }++            // We don't support threading. (Also for Windows.)+            | "pthread_create"+            | "CreateThread"+            => {+                throw_unsup_format!("Miri does not support threading");+            }++            // Stub out calls for condvar, mutex and rwlock, to just return `0`.+            | "pthread_mutexattr_init"+            | "pthread_mutexattr_settype"+            | "pthread_mutex_init"+            | "pthread_mutexattr_destroy"+            | "pthread_mutex_lock"+            | "pthread_mutex_unlock"+            | "pthread_mutex_destroy"+            | "pthread_rwlock_rdlock"+            | "pthread_rwlock_unlock"+            | "pthread_rwlock_wrlock"+            | "pthread_rwlock_destroy"+            | "pthread_condattr_init"+            | "pthread_condattr_setclock"+            | "pthread_cond_init"+            | "pthread_condattr_destroy"+            | "pthread_cond_destroy"+            => {+                this.write_null(dest)?;+            }++            // We don't support fork so we don't have to do anything for atfork.+            "pthread_atfork" => {+                this.write_null(dest)?;+            }++            // Some things needed for `sys::thread` initialization to go through.+            | "signal"+            | "sigaction"+            | "sigaltstack"+            => {+                this.write_scalar(Scalar::from_int(0, dest.layout.size), dest)?;+            }++            "sysconf" => {+                let name = this.read_scalar(args[0])?.to_i32()?;++                trace!("sysconf() called with name {}", name);+                // TODO: Cache the sysconf integers via Miri's global cache.+                let paths = &[+                    (&["libc", "_SC_PAGESIZE"], Scalar::from_int(PAGE_SIZE, dest.layout.size)),+                    (&["libc", "_SC_GETPW_R_SIZE_MAX"], Scalar::from_int(-1, dest.layout.size)),+                    (+                        &["libc", "_SC_NPROCESSORS_ONLN"],+                        Scalar::from_int(NUM_CPUS, dest.layout.size),+                    ),+                ];+                let mut result = None;+                for &(path, path_value) in paths {+                    if let Some(val) = this.eval_path_scalar(path)? {+                        let val = val.to_i32()?;+                        if val == name {+                            result = Some(path_value);+                            break;+                        }+                    }+                }+                if let Some(result) = result {+                    this.write_scalar(result, dest)?;+                } else {+                    throw_unsup_format!("Unimplemented sysconf name: {}", name)+                }+            }++            "isatty" => {+                this.write_null(dest)?;+            }++            "posix_fadvise" => {+                // fadvise is only informational, we can ignore it.+                this.write_null(dest)?;+            }++            "mmap" => {+                // This is a horrible hack, but since the guard page mechanism calls mmap and expects a particular return value, we just give it that value.+                let addr = this.read_scalar(args[0])?.not_undef()?;+                this.write_scalar(addr, dest)?;+            }++            "mprotect" => {+                this.write_null(dest)?;+            }++            _ => {+                match this.tcx.sess.target.target.target_os.to_lowercase().as_str() {+                    "linux" => return linux::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),+                    "macos" => return macos::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),+                    _ => unreachable!(),+                }+            }+        };++        Ok(true)+    }+}++// Shims the posix 'getrandom()' syscall.+fn getrandom<'tcx>(

This is only used on Linux, why is it in the POSIX file?

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+mod linux;+mod macos;++use crate::*;+use rustc::mir;+use rustc::ty::layout::{Align, LayoutOf, Size};++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();+        let tcx = &{ this.tcx.tcx };++        match link_name {+            // Environment related shims+            "getenv" => {+                let result = this.getenv(args[0])?;+                this.write_scalar(result, dest)?;+            }++            "unsetenv" => {+                let result = this.unsetenv(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "setenv" => {+                let result = this.setenv(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "getcwd" => {+                let result = this.getcwd(args[0], args[1])?;+                this.write_scalar(result, dest)?;+            }++            "chdir" => {+                let result = this.chdir(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // File related shims+            "fcntl" => {+                let result = this.fcntl(args[0], args[1], args.get(2).cloned())?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "read" => {+                let result = this.read(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "write" => {+                let fd = this.read_scalar(args[0])?.to_i32()?;+                let buf = this.read_scalar(args[1])?.not_undef()?;+                let n = this.read_scalar(args[2])?.to_machine_usize(tcx)?;+                trace!("Called write({:?}, {:?}, {:?})", fd, buf, n);+                let result = if fd == 1 || fd == 2 {+                    // stdout/stderr+                    use std::io::{self, Write};++                    let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(n))?;+                    // We need to flush to make sure this actually appears on the screen+                    let res = if fd == 1 {+                        // Stdout is buffered, flush to make sure it appears on the screen.+                        // This is the write() syscall of the interpreted program, we want it+                        // to correspond to a write() syscall on the host -- there is no good+                        // in adding extra buffering here.+                        let res = io::stdout().write(buf_cont);+                        io::stdout().flush().unwrap();+                        res+                    } else {+                        // No need to flush, stderr is not buffered.+                        io::stderr().write(buf_cont)+                    };+                    match res {+                        Ok(n) => n as i64,+                        Err(_) => -1,+                    }+                } else {+                    this.write(args[0], args[1], args[2])?+                };+                // Now, `result` is the value we return back to the program.+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "unlink" => {+                let result = this.unlink(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "symlink" => {+                let result = this.symlink(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "rename" => {+                let result = this.rename(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "posix_memalign" => {+                let ret = this.deref_operand(args[0])?;+                let align = this.read_scalar(args[1])?.to_machine_usize(this)?;+                let size = this.read_scalar(args[2])?.to_machine_usize(this)?;+                // Align must be power of 2, and also at least ptr-sized (POSIX rules).+                if !align.is_power_of_two() {+                    throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));+                }+                if align < this.pointer_size().bytes() {+                    throw_ub_format!(+                        "posix_memalign: alignment must be at least the size of a pointer, but is {}",+                        align,+                    );+                }++                if size == 0 {+                    this.write_null(ret.into())?;+                } else {+                    let ptr = this.memory.allocate(+                        Size::from_bytes(size),+                        Align::from_bytes(align).unwrap(),+                        MiriMemoryKind::C.into(),+                    );+                    this.write_scalar(ptr, ret.into())?;+                }+                this.write_null(dest)?;+            }++            "dlsym" => {+                let _handle = this.read_scalar(args[0])?;+                let symbol = this.read_scalar(args[1])?.not_undef()?;+                let symbol_name = this.memory.read_c_str(symbol)?;+                let err = format!("bad c unicode symbol: {:?}", symbol_name);+                let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err);+                if let Some(dlsym) = Dlsym::from_str(symbol_name)? {+                    let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym));+                    this.write_scalar(Scalar::from(ptr), dest)?;+                } else {+                    this.write_null(dest)?;+                }+            }++            "memrchr" => {+                let ptr = this.read_scalar(args[0])?.not_undef()?;+                let val = this.read_scalar(args[1])?.to_i32()? as u8;+                let num = this.read_scalar(args[2])?.to_machine_usize(this)?;+                if let Some(idx) = this+                    .memory+                    .read_bytes(ptr, Size::from_bytes(num))?+                    .iter()+                    .rev()+                    .position(|&c| c == val)+                {+                    let new_ptr = ptr.ptr_offset(Size::from_bytes(num - idx as u64 - 1), this)?;+                    this.write_scalar(new_ptr, dest)?;+                } else {+                    this.write_null(dest)?;+                }+            }++            // Hook pthread calls that go to the thread-local storage memory subsystem.+            "pthread_key_create" => {+                let key_place = this.deref_operand(args[0])?;++                // Extract the function type out of the signature (that seems easier than constructing it ourselves).+                let dtor = match this.test_null(this.read_scalar(args[1])?.not_undef()?)? {+                    Some(dtor_ptr) => Some(this.memory.get_fn(dtor_ptr)?.as_instance()?),+                    None => None,+                };++                // Figure out how large a pthread TLS key actually is.+                // This is `libc::pthread_key_t`.+                let key_type = args[0].layout.ty+                    .builtin_deref(true)+                    .ok_or_else(|| err_ub_format!(+                        "wrong signature used for `pthread_key_create`: first argument must be a raw pointer."+                    ))?+                    .ty;+                let key_layout = this.layout_of(key_type)?;++                // Create key and write it into the memory where `key_ptr` wants it.+                let key = this.machine.tls.create_tls_key(dtor) as u128;+                if key_layout.size.bits() < 128 && key >= (1u128 << key_layout.size.bits() as u128)+                {+                    throw_unsup!(OutOfTls);+                }++                this.write_scalar(Scalar::from_uint(key, key_layout.size), key_place.into())?;++                // Return success (`0`).+                this.write_null(dest)?;+            }+            "pthread_key_delete" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                this.machine.tls.delete_tls_key(key)?;+                // Return success (0)+                this.write_null(dest)?;+            }+            "pthread_getspecific" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                let ptr = this.machine.tls.load_tls(key, tcx)?;+                this.write_scalar(ptr, dest)?;+            }+            "pthread_setspecific" => {+                let key = this.read_scalar(args[0])?.to_bits(args[0].layout.size)?;+                let new_ptr = this.read_scalar(args[1])?.not_undef()?;+                this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;++                // Return success (`0`).+                this.write_null(dest)?;+            }++            // Stack size/address stuff.+            | "pthread_attr_init"+            | "pthread_attr_destroy"+            | "pthread_self"+            | "pthread_attr_setstacksize" => {+                this.write_null(dest)?;+            }+            "pthread_attr_getstack" => {+                let addr_place = this.deref_operand(args[1])?;+                let size_place = this.deref_operand(args[2])?;++                this.write_scalar(+                    Scalar::from_uint(STACK_ADDR, addr_place.layout.size),+                    addr_place.into(),+                )?;+                this.write_scalar(+                    Scalar::from_uint(STACK_SIZE, size_place.layout.size),+                    size_place.into(),+                )?;++                // Return success (`0`).+                this.write_null(dest)?;+            }++            // We don't support threading. (Also for Windows.)+            | "pthread_create"+            | "CreateThread"

CreateThread is Windows-only.

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

+mod linux;+mod macos;++use crate::*;+use rustc::mir;+use rustc::ty::layout::{Align, LayoutOf, Size};++impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {+    fn emulate_foreign_item_by_name(+        &mut self,+        link_name: &str,+        args: &[OpTy<'tcx, Tag>],+        dest: PlaceTy<'tcx, Tag>,+        ret: mir::BasicBlock,+    ) -> InterpResult<'tcx, bool> {+        let this = self.eval_context_mut();+        let tcx = &{ this.tcx.tcx };++        match link_name {+            // Environment related shims+            "getenv" => {+                let result = this.getenv(args[0])?;+                this.write_scalar(result, dest)?;+            }++            "unsetenv" => {+                let result = this.unsetenv(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "setenv" => {+                let result = this.setenv(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "getcwd" => {+                let result = this.getcwd(args[0], args[1])?;+                this.write_scalar(result, dest)?;+            }++            "chdir" => {+                let result = this.chdir(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            // File related shims+            "fcntl" => {+                let result = this.fcntl(args[0], args[1], args.get(2).cloned())?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "read" => {+                let result = this.read(args[0], args[1], args[2])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "write" => {+                let fd = this.read_scalar(args[0])?.to_i32()?;+                let buf = this.read_scalar(args[1])?.not_undef()?;+                let n = this.read_scalar(args[2])?.to_machine_usize(tcx)?;+                trace!("Called write({:?}, {:?}, {:?})", fd, buf, n);+                let result = if fd == 1 || fd == 2 {+                    // stdout/stderr+                    use std::io::{self, Write};++                    let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(n))?;+                    // We need to flush to make sure this actually appears on the screen+                    let res = if fd == 1 {+                        // Stdout is buffered, flush to make sure it appears on the screen.+                        // This is the write() syscall of the interpreted program, we want it+                        // to correspond to a write() syscall on the host -- there is no good+                        // in adding extra buffering here.+                        let res = io::stdout().write(buf_cont);+                        io::stdout().flush().unwrap();+                        res+                    } else {+                        // No need to flush, stderr is not buffered.+                        io::stderr().write(buf_cont)+                    };+                    match res {+                        Ok(n) => n as i64,+                        Err(_) => -1,+                    }+                } else {+                    this.write(args[0], args[1], args[2])?+                };+                // Now, `result` is the value we return back to the program.+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "unlink" => {+                let result = this.unlink(args[0])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "symlink" => {+                let result = this.symlink(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "rename" => {+                let result = this.rename(args[0], args[1])?;+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;+            }++            "posix_memalign" => {

This is still under "file related shims"... ;)

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx                 this.write_scalar(Scalar::from_int(result, Size::from_bits(32)), dest)?;             } -            "memrchr" => {

I think this one should stay here.

christianpoveda

comment created time in 4 days

Pull request review commentrust-lang/miri

Reorganize shims by platform

 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx                 this.write_scalar(Scalar::from_int(result, Size::from_bits(32)), dest)?;             } -            "memrchr" => {

Why move memrchr but not memchr? That's odd.

christianpoveda

comment created time in 4 days

more