Repository: bytecodealliance/wasmtime (rust)

Issue:
Compile failed with aarch64-linux-android
when I compile wasmtime for android using: ```cargo build --target  aarch64-linux-android --release```

The output is: 
```
error[E0432]: unresolved import `crate::dir::SeekLoc`
 

--> crates/wasi-common/yanix/src/sys/mod.rs:1:5
  |
1 | use crate::dir::SeekLoc;
  |     ^^^^^^^^^^^^^^^^^^^ no `SeekLoc` in `dir`

error[E0432]: unresolved import `crate::dir::SeekLoc`
 --> crates/wasi-common/yanix/src/sys/linux/dir.rs:1:40
  |
1 | use crate::dir::{Dir, Entry, EntryExt, SeekLoc};
  |                                        ^^^^^^^ no `SeekLoc` in `dir`

error[E0425]: cannot find function `futimes` in crate `libc`
    --> crates/wasi-common/yanix/src/sys/linux/utimesat.rs:30:38
     |
30   |     from_success_code(unsafe { libc::futimes(f.as_raw_fd(), times.as_ptr()) })
     |                                      ^^^^^^^ help: a function with a similar name exists: `futimens`
     |
    ::: /Users/niexinxin/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.72/src/unix/linux_like/mod.rs:1319:5
     |
1319 |     pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int;
     |     ------------------------------------------------------------------ similarly named function `futimens` defined here

```

Pull request:
Adjust WASI implementation to build for Android
Fixes #2099.

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 64237674e..1de98625b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2365,9 +2365,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-smith"
-version = "0.2.0"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdd382e46cf44347f4d0c29122143cbab85cf248b9a8f680845c0239b6842a85"
+checksum = "509904d9c4c4659ac238a3f27c3656dd6d3931697eddd4b0f32e335769c298d0"
 dependencies = [
  "arbitrary",
  "leb128",
diff --git a/cranelift/codegen/meta/src/isa/x86/encodings.rs b/cranelift/codegen/meta/src/isa/x86/encodings.rs
index 9ee12656c..de48c57c5 100644
--- a/cranelift/codegen/meta/src/isa/x86/encodings.rs
+++ b/cranelift/codegen/meta/src/isa/x86/encodings.rs
@@ -549,10 +549,13 @@ fn define_moves(e: &mut PerCpuModeEncodings, shared_defs: &SharedDefinitions, r:
     }
     e.enc64(bconst.bind(B64), rec_pu_id_bool.opcodes(&MOV_IMM).rex());
 
+    // You may expect that i8 encodings would use 0x30 (XORB) to indicate that encodings should be
+    // on 8-bit operands (f.ex "xor %al, %al"). Cranelift currently does not know when it can
+    // safely drop the 0x66 prefix, so we explicitly select a wider but permissible opcode.
     let is_zero_int = InstructionPredicate::new_is_zero_int(&formats.unary_imm, "imm");
     e.enc_both_instp(
         iconst.bind(I8),
-        rec_u_id_z.opcodes(&XORB),
+        rec_u_id_z.opcodes(&XOR),
         is_zero_int.clone(),
     );
 
diff --git a/cranelift/codegen/meta/src/isa/x86/opcodes.rs b/cranelift/codegen/meta/src/isa/x86/opcodes.rs
index 09c07c458..595d13ba2 100644
--- a/cranelift/codegen/meta/src/isa/x86/opcodes.rs
+++ b/cranelift/codegen/meta/src/isa/x86/opcodes.rs
@@ -711,9 +711,6 @@ pub static XOR_IMM8_SIGN_EXTEND: [u8; 1] = [0x83];
 /// r/m{16,32,64} XOR register of the same size.
 pub static XOR: [u8; 1] = [0x31];
 
-/// r/m8 XOR r8.
-pub static XORB: [u8; 1] = [0x30];
-
 /// Bitwise logical XOR of packed double-precision floating-point values.
 pub static XORPD: [u8; 3] = [0x66, 0x0f, 0x57];
 
diff --git a/cranelift/codegen/src/ir/memflags.rs b/cranelift/codegen/src/ir/memflags.rs
index 87fd6bf3a..3c9c8c98b 100644
--- a/cranelift/codegen/src/ir/memflags.rs
+++ b/cranelift/codegen/src/ir/memflags.rs
@@ -6,15 +6,31 @@ enum FlagBit {
     Notrap,
     Aligned,
     Readonly,
+    LittleEndian,
+    BigEndian,
 }
 
-const NAMES: [&str; 3] = ["notrap", "aligned", "readonly"];
+const NAMES: [&str; 5] = ["notrap", "aligned", "readonly", "little", "big"];
+
+/// Endianness of a memory access.
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+pub enum Endianness {
+    /// Little-endian
+    Little,
+    /// Big-endian
+    Big,
+}
 
 /// Flags for memory operations like load/store.
 ///
 /// Each of these flags introduce a limited form of undefined behavior. The flags each enable
 /// certain optimizations that need to make additional assumptions. Generally, the semantics of a
 /// program does not change when a flag is removed, but adding a flag will.
+///
+/// In addition, the flags determine the endianness of the memory access.  By default,
+/// any memory access uses the native endianness determined by the target ISA.  This can
+/// be overridden for individual accesses by explicitly specifying little- or big-endian
+/// semantics via the flags.
 #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
 pub struct MemFlags {
     bits: u8,
@@ -48,16 +64,48 @@ impl MemFlags {
     /// Set a flag bit by name.
     ///
     /// Returns true if the flag was found and set, false for an unknown flag name.
+    /// Will also return false when trying to set inconsistent endianness flags.
     pub fn set_by_name(&mut self, name: &str) -> bool {
         match NAMES.iter().position(|&s| s == name) {
             Some(bit) => {
-                self.bits |= 1 << bit;
-                true
+                let bits = self.bits | 1 << bit;
+                if (bits & (1 << FlagBit::LittleEndian as usize)) != 0
+                    && (bits & (1 << FlagBit::BigEndian as usize)) != 0
+                {
+                    false
+                } else {
+                    self.bits = bits;
+                    true
+                }
             }
             None => false,
         }
     }
 
+    /// Return endianness of the memory access.  This will return the endianness
+    /// explicitly specified by the flags if any, and will default to the native
+    /// endianness otherwise.  The native endianness has to be provided by the
+    /// caller since it is not explicitly encoded in CLIF IR -- this allows a
+    /// front end to create IR without having to know the target endianness.
+    pub fn endianness(self, native_endianness: Endianness) -> Endianness {
+        if self.read(FlagBit::LittleEndian) {
+            Endianness::Little
+        } else if self.read(FlagBit::BigEndian) {
+            Endianness::Big
+        } else {
+            native_endianness
+        }
+    }
+
+    /// Set endianness of the memory access.
+    pub fn set_endianness(&mut self, endianness: Endianness) {
+        match endianness {
+            Endianness::Little => self.set(FlagBit::LittleEndian),
+            Endianness::Big => self.set(FlagBit::BigEndian),
+        };
+        assert!(!(self.read(FlagBit::LittleEndian) && self.read(FlagBit::BigEndian)));
+    }
+
     /// Test if the `notrap` flag is set.
     ///
     /// Normally, trapping is part of the semantics of a load/store operation. If the platform
diff --git a/cranelift/codegen/src/ir/mod.rs b/cranelift/codegen/src/ir/mod.rs
index 4dbe90df3..c5e827db3 100644
--- a/cranelift/codegen/src/ir/mod.rs
+++ b/cranelift/codegen/src/ir/mod.rs
@@ -50,7 +50,7 @@ pub use crate::ir::instructions::{
 pub use crate::ir::jumptable::JumpTableData;
 pub use crate::ir::layout::Layout;
 pub use crate::ir::libcall::{get_probestack_funcref, LibCall};
-pub use crate::ir::memflags::MemFlags;
+pub use crate::ir::memflags::{Endianness, MemFlags};
 pub use crate::ir::progpoint::{ExpandedProgramPoint, ProgramOrder, ProgramPoint};
 pub use crate::ir::sourceloc::SourceLoc;
 pub use crate::ir::stackslot::{StackLayoutInfo, StackSlotData, StackSlotKind, StackSlots};
diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs
index a1a4c3c39..1ce10a155 100644
--- a/cranelift/codegen/src/isa/mod.rs
+++ b/cranelift/codegen/src/isa/mod.rs
@@ -235,6 +235,14 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
         CallConv::triple_default(self.triple())
     }
 
+    /// Get the endianness of this ISA.
+    fn endianness(&self) -> ir::Endianness {
+        match self.triple().endianness().unwrap() {
+            target_lexicon::Endianness::Little => ir::Endianness::Little,
+            target_lexicon::Endianness::Big => ir::Endianness::Big,
+        }
+    }
+
     /// Get the pointer type of this ISA.
     fn pointer_type(&self) -> ir::Type {
         ir::Type::int(u16::from(self.pointer_bits())).unwrap()
diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs
index 1900b144c..149a65b63 100644
--- a/cranelift/codegen/src/legalizer/mod.rs
+++ b/cranelift/codegen/src/legalizer/mod.rs
@@ -659,7 +659,7 @@ fn narrow_load(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    _isa: &dyn TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
@@ -684,6 +684,10 @@ fn narrow_load(
         ptr,
         offset.try_add_i64(8).expect("load offset overflow"),
     );
+    let (al, ah) = match flags.endianness(isa.endianness()) {
+        ir::Endianness::Little => (al, ah),
+        ir::Endianness::Big => (ah, al),
+    };
     pos.func.dfg.replace(inst).iconcat(al, ah);
 }
 
@@ -692,7 +696,7 @@ fn narrow_store(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
-    _isa: &dyn TargetIsa,
+    isa: &dyn TargetIsa,
 ) {
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
@@ -708,6 +712,10 @@ fn narrow_store(
     };
 
     let (al, ah) = pos.ins().isplit(val);
+    let (al, ah) = match flags.endianness(isa.endianness()) {
+        ir::Endianness::Little => (al, ah),
+        ir::Endianness::Big => (ah, al),
+    };
     pos.ins().store(flags, al, ptr, offset);
     pos.ins().store(
         flags,
diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs
index cf15787c1..2fe171842 100644
--- a/cranelift/wasm/src/code_translator.rs
+++ b/cranelift/wasm/src/code_translator.rs
@@ -2056,7 +2056,9 @@ fn prepare_load<FE: FuncEnvironment + ?Sized>(
     // Note that we don't set `is_aligned` here, even if the load instruction's
     // alignment immediate says it's aligned, because WebAssembly's immediate
     // field is just a hint, while Cranelift's aligned flag needs a guarantee.
-    let flags = MemFlags::new();
+    // WebAssembly memory accesses are always little-endian.
+    let mut flags = MemFlags::new();
+    flags.set_endianness(ir::Endianness::Little);
 
     Ok((flags, base, offset.into()))
 }
@@ -2103,7 +2105,8 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
         builder,
     );
     // See the comments in `prepare_load` about the flags.
-    let flags = MemFlags::new();
+    let mut flags = MemFlags::new();
+    flags.set_endianness(ir::Endianness::Little);
     builder
         .ins()
         .Store(opcode, val_ty, flags, offset.into(), val, base);
@@ -2207,7 +2210,8 @@ fn translate_atomic_rmw<FE: FuncEnvironment + ?Sized>(
         finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
 
     // See the comments in `prepare_load` about the flags.
-    let flags = MemFlags::new();
+    let mut flags = MemFlags::new();
+    flags.set_endianness(ir::Endianness::Little);
     let mut res = builder
         .ins()
         .atomic_rmw(access_ty, flags, op, final_effective_address, arg2);
@@ -2260,7 +2264,8 @@ fn translate_atomic_cas<FE: FuncEnvironment + ?Sized>(
         finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
 
     // See the comments in `prepare_load` about the flags.
-    let flags = MemFlags::new();
+    let mut flags = MemFlags::new();
+    flags.set_endianness(ir::Endianness::Little);
     let mut res = builder
         .ins()
         .atomic_cas(flags, final_effective_address, expected, replacement);
@@ -2302,7 +2307,8 @@ fn translate_atomic_load<FE: FuncEnvironment + ?Sized>(
         finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
 
     // See the comments in `prepare_load` about the flags.
-    let flags = MemFlags::new();
+    let mut flags = MemFlags::new();
+    flags.set_endianness(ir::Endianness::Little);
     let mut res = builder
         .ins()
         .atomic_load(access_ty, flags, final_effective_address);
@@ -2348,7 +2354,8 @@ fn translate_atomic_store<FE: FuncEnvironment + ?Sized>(
         finalise_atomic_mem_addr(linear_mem_addr, memarg, access_ty, builder, state, environ)?;
 
     // See the comments in `prepare_load` about the flags.
-    let flags = MemFlags::new();
+    let mut flags = MemFlags::new();
+    flags.set_endianness(ir::Endianness::Little);
     builder
         .ins()
         .atomic_store(flags, data, final_effective_address);
diff --git a/crates/environ/src/module_environ.rs b/crates/environ/src/module_environ.rs
index 6d36b4e7a..7b2cca611 100644
--- a/crates/environ/src/module_environ.rs
+++ b/crates/environ/src/module_environ.rs
@@ -31,6 +31,10 @@ pub struct ModuleEnvironment<'data> {
     /// the module linking proposal.
     results: Vec<ModuleTranslation<'data>>,
 
+    /// How many modules that have not yet made their way into `results` which
+    /// are coming at some point.
+    modules_to_be: usize,
+
     /// Intern'd types for this entire translation, shared by all modules.
     types: TypeTables,
 
@@ -138,6 +142,7 @@ impl<'data> ModuleEnvironment<'data> {
         Self {
             result: ModuleTranslation::default(),
             results: Vec::with_capacity(1),
+            modules_to_be: 1,
             cur: 0,
             types: Default::default(),
             target_config,
@@ -741,8 +746,8 @@ and for re-adding support for interface types you can see this issue:
     fn reserve_modules(&mut self, amount: u32) {
         // Go ahead and reserve space in the final `results` array for `amount`
         // more modules.
-        let extra = self.results.capacity() + (amount as usize) - self.results.len();
-        self.results.reserve(extra);
+        self.modules_to_be += amount as usize;
+        self.results.reserve(self.modules_to_be);
 
         // Then also reserve space in our own local module's metadata fields
         // we'll be adding to.
@@ -796,6 +801,7 @@ and for re-adding support for interface types you can see this issue:
         self.cur = index;
         assert_eq!(index, self.results.len());
         self.results.push(prev);
+        self.modules_to_be -= 1;
     }
 
     fn module_end(&mut self, index: usize) {
diff --git a/crates/fuzzing/Cargo.toml b/crates/fuzzing/Cargo.toml
index b0dd625c0..7120601b2 100644
--- a/crates/fuzzing/Cargo.toml
+++ b/crates/fuzzing/Cargo.toml
@@ -16,7 +16,7 @@ wasmparser = "0.70"
 wasmprinter = "0.2.17"
 wasmtime = { path = "../wasmtime" }
 wasmtime-wast = { path = "../wast" }
-wasm-smith = "0.2.0"
+wasm-smith = "0.3.0"
 wasmi = "0.7.0"
 
 [dev-dependencies]
diff --git a/crates/fuzzing/src/oracles.rs b/crates/fuzzing/src/oracles.rs
index 91e676c58..9f04dc44d 100644
--- a/crates/fuzzing/src/oracles.rs
+++ b/crates/fuzzing/src/oracles.rs
@@ -57,8 +57,13 @@ fn log_wat(wat: &str) {
 /// Performs initial validation, and returns early if the Wasm is invalid.
 ///
 /// You can control which compiler is used via passing a `Strategy`.
-pub fn instantiate(wasm: &[u8], strategy: Strategy) {
-    instantiate_with_config(wasm, crate::fuzz_default_config(strategy).unwrap(), None);
+pub fn instantiate(wasm: &[u8], known_valid: bool, strategy: Strategy) {
+    instantiate_with_config(
+        wasm,
+        known_valid,
+        crate::fuzz_default_config(strategy).unwrap(),
+        None,
+    );
 }
 
 /// Instantiate the Wasm buffer, and implicitly fail if we have an unexpected
@@ -67,7 +72,12 @@ pub fn instantiate(wasm: &[u8], strategy: Strategy) {
 /// The engine will be configured using provided config.
 ///
 /// See also `instantiate` functions.
-pub fn instantiate_with_config(wasm: &[u8], mut config: Config, timeout: Option<Duration>) {
+pub fn instantiate_with_config(
+    wasm: &[u8],
+    known_valid: bool,
+    mut config: Config,
+    timeout: Option<Duration>,
+) {
     crate::init_fuzzing();
 
     config.interruptable(timeout.is_some());
@@ -91,7 +101,11 @@ pub fn instantiate_with_config(wasm: &[u8], mut config: Config, timeout: Option<
     }
 
     log_wasm(wasm);
-    let module = Module::new(&engine, wasm).unwrap();
+    let module = match Module::new(&engine, wasm) {
+        Ok(module) => module,
+        Err(_) if !known_valid => return,
+        Err(e) => panic!("failed to compile module: {:?}", e),
+    };
     let imports = dummy_imports(&store, module.imports());
 
     match Instance::new(&store, &module, &imports) {
@@ -446,7 +460,7 @@ pub fn table_ops(config: crate::generators::Config, ops: crate::generators::tabl
 
 /// Configuration options for wasm-smith such that generated modules always
 /// conform to certain specifications.
-#[derive(Default, Debug, Arbitrary)]
+#[derive(Default, Debug, Arbitrary, Clone)]
 pub struct DifferentialWasmiModuleConfig;
 
 impl wasm_smith::Config for DifferentialWasmiModuleConfig {
diff --git a/crates/wasi-common/src/sys/unix/mod.rs b/crates/wasi-common/src/sys/unix/mod.rs
index 7135486ec..84d8ec581 100644
--- a/crates/wasi-common/src/sys/unix/mod.rs
+++ b/crates/wasi-common/src/sys/unix/mod.rs
@@ -9,7 +9,8 @@ pub(crate) mod poll;
 pub(crate) mod stdio;
 
 cfg_if::cfg_if! {
-    if #[cfg(target_os = "linux")] {
+    if #[cfg(any(target_os = "linux",
+                 target_os = "android"))] {
         mod linux;
         use linux as sys_impl;
     } else if #[cfg(target_os = "emscripten")] {
diff --git a/crates/wasi-common/yanix/src/dir.rs b/crates/wasi-common/yanix/src/dir.rs
index 50166a35b..8e6c70a40 100644
--- a/crates/wasi-common/yanix/src/dir.rs
+++ b/crates/wasi-common/yanix/src/dir.rs
@@ -36,9 +36,15 @@ impl Dir {
     }
 
     /// Set the position of the directory stream, see `seekdir(3)`.
-    #[cfg(not(target_os = "android"))]
     pub fn seek(&mut self, loc: SeekLoc) {
-        unsafe { libc::seekdir(self.0.as_ptr(), loc.0) }
+        // https://github.com/rust-lang/libc/pull/1996
+        #[cfg(not(target_os = "android"))]
+        use libc::seekdir;
+        #[cfg(target_os = "android")]
+        extern "C" {
+            fn seekdir(dirp: *mut libc::DIR, loc: libc::c_long);
+        }
+        unsafe { seekdir(self.0.as_ptr(), loc.0) }
     }
 
     /// Reset directory stream, see `rewinddir(3)`.
@@ -50,10 +56,16 @@ impl Dir {
     ///
     /// If this location is given to `Dir::seek`, the entries up to the previously returned
     /// will be omitted and the iteration will start from the currently pending directory entry.
-    #[cfg(not(target_os = "android"))]
     #[allow(dead_code)]
     pub fn tell(&self) -> SeekLoc {
-        let loc = unsafe { libc::telldir(self.0.as_ptr()) };
+        #[cfg(not(target_os = "android"))]
+        use libc::telldir;
+        #[cfg(target_os = "android")]
+        extern "C" {
+            fn telldir(dirp: *mut libc::DIR) -> libc::c_long;
+        }
+        // https://github.com/rust-lang/libc/pull/1996
+        let loc = unsafe { telldir(self.0.as_ptr()) };
         SeekLoc(loc)
     }
 
@@ -93,11 +105,9 @@ impl Entry {
     }
 }
 
-#[cfg(not(target_os = "android"))]
 #[derive(Clone, Copy, Debug)]
 pub struct SeekLoc(pub(crate) libc::c_long);
 
-#[cfg(not(target_os = "android"))]
 impl SeekLoc {
     pub fn to_raw(&self) -> i64 {
         self.0.into()
diff --git a/crates/wasi-common/yanix/src/file.rs b/crates/wasi-common/yanix/src/file.rs
index 1764d2912..62af1c9d7 100644
--- a/crates/wasi-common/yanix/src/file.rs
+++ b/crates/wasi-common/yanix/src/file.rs
@@ -90,11 +90,26 @@ bitflags! {
         const WRONLY = libc::O_WRONLY;
         const RDWR = libc::O_RDWR;
         #[cfg(any(target_os = "linux",
+                  target_os = "android",
                   target_os = "netbsd",
                   target_os = "openbsd",
                   target_os = "wasi",
                   target_os = "emscripten"))]
-        const RSYNC = libc::O_RSYNC;
+        const RSYNC = {
+            // Have to use cfg_if: https://github.com/bitflags/bitflags/issues/137
+            cfg_if! {
+                if #[cfg(any(target_os = "linux",
+                             target_os = "netbsd",
+                             target_os = "openbsd",
+                             target_os = "wasi",
+                             target_os = "emscripten"))] {
+                    libc::O_RSYNC
+                } else if #[cfg(target_os = "android")] {
+                    // Android defines O_RSYNC as O_SYNC
+                    libc::O_SYNC
+                }
+            }
+        };
         const SYNC = libc::O_SYNC;
         const TRUNC = libc::O_TRUNC;
         #[cfg(any(target_os = "linux",
diff --git a/crates/wasi-common/yanix/src/sys/linux/filetime.rs b/crates/wasi-common/yanix/src/sys/linux/filetime.rs
index 3c4cdfa9f..34faefc6d 100644
--- a/crates/wasi-common/yanix/src/sys/linux/filetime.rs
+++ b/crates/wasi-common/yanix/src/sys/linux/filetime.rs
@@ -53,5 +53,8 @@ pub fn utimensat(
         return Err(err);
     }
 
-    super::utimesat::utimesat(dirfd, path, atime, mtime, symlink_nofollow)
+    #[cfg(not(target_os = "android"))]
+    return super::utimesat::utimesat(dirfd, path, atime, mtime, symlink_nofollow);
+    #[cfg(target_os = "android")]
+    unreachable!();
 }
diff --git a/crates/wasi-common/yanix/src/sys/linux/mod.rs b/crates/wasi-common/yanix/src/sys/linux/mod.rs
index 26432d36d..37d8a0a8a 100644
--- a/crates/wasi-common/yanix/src/sys/linux/mod.rs
+++ b/crates/wasi-common/yanix/src/sys/linux/mod.rs
@@ -2,4 +2,5 @@ pub(crate) mod dir;
 pub(crate) mod fadvise;
 pub(crate) mod file;
 pub(crate) mod filetime;
+#[cfg(not(target_os = "android"))]
 pub(crate) mod utimesat;
diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
index 6220bdcb9..73bd003e1 100644
--- a/fuzz/Cargo.toml
+++ b/fuzz/Cargo.toml
@@ -17,7 +17,7 @@ target-lexicon = "0.11"
 peepmatic-fuzzing = { path = "../cranelift/peepmatic/crates/fuzzing", optional = true }
 wasmtime = { path = "../crates/wasmtime" }
 wasmtime-fuzzing = { path = "../crates/fuzzing" }
-wasm-smith = "0.2.0"
+wasm-smith = "0.3.0"
 
 [features]
 experimental_x64 = ["wasmtime-fuzzing/experimental_x64"]
diff --git a/fuzz/fuzz_targets/instantiate-maybe-invalid.rs b/fuzz/fuzz_targets/instantiate-maybe-invalid.rs
index 5b9657b92..219986a25 100644
--- a/fuzz/fuzz_targets/instantiate-maybe-invalid.rs
+++ b/fuzz/fuzz_targets/instantiate-maybe-invalid.rs
@@ -9,6 +9,7 @@ use wasmtime_fuzzing::oracles;
 fuzz_target!(|module: MaybeInvalidModule| {
     oracles::instantiate_with_config(
         &module.to_bytes(),
+        false,
         wasmtime_fuzzing::fuzz_default_config(Strategy::Auto).unwrap(),
         Some(Duration::from_secs(20)),
     );
diff --git a/fuzz/fuzz_targets/instantiate-swarm.rs b/fuzz/fuzz_targets/instantiate-swarm.rs
index a3049ad99..092a32e92 100644
--- a/fuzz/fuzz_targets/instantiate-swarm.rs
+++ b/fuzz/fuzz_targets/instantiate-swarm.rs
@@ -9,5 +9,5 @@ use wasmtime_fuzzing::oracles;
 fuzz_target!(|module: ConfiguredModule<SwarmConfig>| {
     let mut cfg = wasmtime_fuzzing::fuzz_default_config(Strategy::Auto).unwrap();
     cfg.wasm_multi_memory(true);
-    oracles::instantiate_with_config(&module.to_bytes(), cfg, Some(Duration::from_secs(20)));
+    oracles::instantiate_with_config(&module.to_bytes(), true, cfg, Some(Duration::from_secs(20)));
 });
diff --git a/fuzz/fuzz_targets/instantiate-wasm-smith.rs b/fuzz/fuzz_targets/instantiate-wasm-smith.rs
index 9c081eff8..546a198ff 100644
--- a/fuzz/fuzz_targets/instantiate-wasm-smith.rs
+++ b/fuzz/fuzz_targets/instantiate-wasm-smith.rs
@@ -9,5 +9,5 @@ fuzz_target!(|module: Module| {
     let mut module = module;
     module.ensure_termination(1000);
     let wasm_bytes = module.to_bytes();
-    oracles::instantiate(&wasm_bytes, Strategy::Auto);
+    oracles::instantiate(&wasm_bytes, true, Strategy::Auto);
 });
diff --git a/fuzz/fuzz_targets/instantiate.rs b/fuzz/fuzz_targets/instantiate.rs
index 61b22c187..ec41c5910 100644
--- a/fuzz/fuzz_targets/instantiate.rs
+++ b/fuzz/fuzz_targets/instantiate.rs
@@ -5,5 +5,5 @@ use wasmtime::Strategy;
 use wasmtime_fuzzing::oracles;
 
 fuzz_target!(|data: &[u8]| {
-    oracles::instantiate(data, Strategy::Auto);
+    oracles::instantiate(data, false, Strategy::Auto);
 });


Test patch:
diff --git a/cranelift/filetests/filetests/isa/x86/optimized-zero-constants-32bit.clif b/cranelift/filetests/filetests/isa/x86/optimized-zero-constants-32bit.clif
index 0f0f06e6f..6ce39a5c3 100644
--- a/cranelift/filetests/filetests/isa/x86/optimized-zero-constants-32bit.clif
+++ b/cranelift/filetests/filetests/isa/x86/optimized-zero-constants-32bit.clif
@@ -44,9 +44,9 @@ block0:
 
 function %zero_byte() -> i8 fast {
 block0:
-  ; asm: xor %al, %al
-  [-,%rax]     v0 = iconst.i8 0     ; bin: 30 c0
-  ; asm: xor %dh, %dh
-  [-,%rdi]     v1 = iconst.i8 0     ; bin: 30 ff
+  ; asm: xor %eax, %eax
+  [-,%rax]     v0 = iconst.i8 0     ; bin: 31 c0
+  ; asm: xor %edi, %edi
+  [-,%rdi]     v1 = iconst.i8 0     ; bin: 31 ff
   return v0
 }
diff --git a/cranelift/filetests/filetests/isa/x86/optimized-zero-constants.clif b/cranelift/filetests/filetests/isa/x86/optimized-zero-constants.clif
index 7f5890a1a..4ff2865a2 100644
--- a/cranelift/filetests/filetests/isa/x86/optimized-zero-constants.clif
+++ b/cranelift/filetests/filetests/isa/x86/optimized-zero-constants.clif
@@ -62,11 +62,11 @@ block0:
 
 function %zero_byte() -> i8 fast {
 block0:
-  ; asm: xor %r8b, %r8b
-  [-,%r15]     v0 = iconst.i8 0     ; bin: 45 30 ff
-  ; asm: xor %al, %al
-  [-,%rax]     v1 = iconst.i8 0     ; bin: 30 c0
-  ; asm: xor %dh, %dh
-  [-,%rdi]     v2 = iconst.i8 0     ; bin: 30 ff
+  ; asm: xor %r8d, %r8d
+  [-,%r15]     v0 = iconst.i8 0     ; bin: 45 31 ff
+  ; asm: xor %eax, eax
+  [-,%rax]     v1 = iconst.i8 0     ; bin: 31 c0
+  ; asm: xor %edi, %edi
+  [-,%rdi]     v2 = iconst.i8 0     ; bin: 31 ff
   return v0
 }
diff --git a/tests/all/fuzzing.rs b/tests/all/fuzzing.rs
index 9e71add57..3e46af2d7 100644
--- a/tests/all/fuzzing.rs
+++ b/tests/all/fuzzing.rs
@@ -11,13 +11,13 @@ use wasmtime_fuzzing::oracles;
 #[test]
 fn instantiate_empty_module() {
     let data = wat::parse_str(include_str!("./fuzzing/empty.wat")).unwrap();
-    oracles::instantiate(&data, Strategy::Auto);
+    oracles::instantiate(&data, true, Strategy::Auto);
 }
 
 #[test]
 fn instantiate_empty_module_with_memory() {
     let data = wat::parse_str(include_str!("./fuzzing/empty_with_memory.wat")).unwrap();
-    oracles::instantiate(&data, Strategy::Auto);
+    oracles::instantiate(&data, true, Strategy::Auto);
 }
 
 #[test]
@@ -26,5 +26,5 @@ fn instantiate_module_that_compiled_to_x64_has_register_32() {
     let mut config = Config::new();
     config.debug_info(true);
     let data = wat::parse_str(include_str!("./fuzzing/issue694.wat")).unwrap();
-    oracles::instantiate_with_config(&data, config, None);
+    oracles::instantiate_with_config(&data, true, config, None);
 }