Enable capturing asserts inside simulator

When building in simulator mode, mock assert() to call an simulator
function which will enable other code to check if some path failed.

The assert checking interface, was added to boot_go which now
returns the low-level invocation results as well as the number of
asserts triggered.

Some new added tests check for assert() and expect it to happen. To not
abort tests, assert() was changed under sim env to not call c assert()
and instead just do some internal calculation which could be checked
by the simulator after a bootloader run and assert() catching behavior
was made optional (each test choses the behavior it needs).

Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index 0ec8605..7229a5d 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -34,6 +34,12 @@
 #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO
 #include "bootutil/bootutil_log.h"
 
+#ifdef __BOOTSIM__
+#undef assert
+void sim_assert(int, const char *test, const char *, unsigned int, const char *);
+#define assert(x) sim_assert((x), #x, __FILE__, __LINE__, __func__)
+#endif
+
 int boot_current_slot;
 
 const uint32_t boot_img_magic[] = {
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 99ffcd3..fb59401 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -41,6 +41,12 @@
 #include "mcuboot_config/mcuboot_config.h"
 #endif
 
+#ifdef __BOOTSIM__
+#undef assert
+void sim_assert(int, const char *test, const char *, unsigned int, const char *);
+#define assert(x) sim_assert((x), #x, __FILE__, __LINE__, __func__)
+#endif
+
 static struct boot_loader_state boot_data;
 
 struct boot_status_table {
diff --git a/sim/Cargo.lock b/sim/Cargo.lock
index 36f63c8..857adff 100644
--- a/sim/Cargo.lock
+++ b/sim/Cargo.lock
@@ -56,8 +56,8 @@
  "pem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "simflash 0.1.0",
  "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -102,8 +102,8 @@
 dependencies = [
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -165,6 +165,11 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "lazy_static"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "libc"
 version = "0.2.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -254,7 +259,7 @@
  "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -292,22 +297,22 @@
 
 [[package]]
 name = "serde"
-version = "1.0.23"
+version = "1.0.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.23"
+version = "1.0.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive_internals"
-version = "0.17.0"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -320,7 +325,7 @@
 dependencies = [
  "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -348,10 +353,10 @@
 
 [[package]]
 name = "thread_local"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -413,6 +418,7 @@
 "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
+"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
 "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
 "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
@@ -428,13 +434,13 @@
 "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
 "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
-"checksum serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c37d7f192f00041e8a613e936717923a71bc0c9051fc4425a49b104140f05"
-"checksum serde_derive 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "0672de7300b02bac3f3689f8faea813c4a1ea9fe0cb49e80f714231d267518a2"
-"checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab"
+"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1"
+"checksum serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "02c92ea07b6e49b959c1481804ebc9bfd92d3c459f1274c9a9546829e42a66ce"
+"checksum serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75c6aac7b99801a16db5b40b7bf0d7e4ba16e76fbf231e32a4677f271cac0603"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
-"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
+"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
diff --git a/sim/mcuboot-sys/csupport/run.c b/sim/mcuboot-sys/csupport/run.c
index d749e49..91d779a 100644
--- a/sim/mcuboot-sys/csupport/run.c
+++ b/sim/mcuboot-sys/csupport/run.c
@@ -1,5 +1,6 @@
 /* Run the boot image. */
 
+#include <assert.h>
 #include <setjmp.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -25,6 +26,8 @@
 int flash_counter;
 
 int jumped = 0;
+uint8_t c_asserts = 0;
+uint8_t c_catch_asserts = 0;
 
 int ecdsa256_sign_(const uint8_t *privkey, const uint8_t *hash,
                    unsigned hash_len, uint8_t *signature)
@@ -249,3 +252,19 @@
 
     return 0;
 }
+
+void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
+{
+    if (!(x)) {
+        if (c_catch_asserts) {
+            c_asserts++;
+        } else {
+            BOOT_LOG_ERR("%s:%d: %s: Assertion `%s' failed.", file, line, function, assertion);
+
+            /* NOTE: if the assert below is triggered, the place where it was originally
+             * asserted is printed by the message above...
+             */
+            assert(x);
+        }
+    }
+}
diff --git a/sim/mcuboot-sys/src/c.rs b/sim/mcuboot-sys/src/c.rs
index 9f364cb..3400bc0 100644
--- a/sim/mcuboot-sys/src/c.rs
+++ b/sim/mcuboot-sys/src/c.rs
@@ -13,11 +13,14 @@
 }
 
 /// Invoke the bootloader on this flash device.
-pub fn boot_go(flash: &mut Flash, areadesc: &AreaDesc, counter: Option<&mut i32>, align: u8) -> i32 {
+pub fn boot_go(flash: &mut Flash, areadesc: &AreaDesc, counter: Option<&mut i32>,
+               align: u8, catch_asserts: bool) -> (i32, u8) {
     let _lock = BOOT_LOCK.lock().unwrap();
 
     unsafe {
         api::set_flash(flash);
+        raw::c_catch_asserts = if catch_asserts { 1 } else { 0 };
+        raw::c_asserts = 0u8;
         raw::sim_flash_align = align;
         raw::flash_counter = match counter {
             None => 0,
@@ -25,11 +28,12 @@
         };
     }
     let result = unsafe { raw::invoke_boot_go(&areadesc.get_c() as *const _) as i32 };
+    let asserts = unsafe { raw::c_asserts };
     unsafe {
         counter.map(|c| *c = raw::flash_counter as i32);
         api::clear_flash();
     };
-    result
+    (result, asserts)
 }
 
 pub fn boot_trailer_sz(align: u8) -> u32 {
@@ -65,6 +69,8 @@
         // for information and tracking.
         pub fn invoke_boot_go(areadesc: *const CAreaDesc) -> libc::c_int;
         pub static mut flash_counter: libc::c_int;
+        pub static mut c_asserts: u8;
+        pub static mut c_catch_asserts: u8;
 
         pub static mut sim_flash_align: u8;
         pub fn boot_slots_trailer_sz(min_write_sz: u8) -> u32;
diff --git a/sim/src/lib.rs b/sim/src/lib.rs
index b83e31b..e22984e 100644
--- a/sim/src/lib.rs
+++ b/sim/src/lib.rs
@@ -518,7 +518,8 @@
         info!("Try norevert");
 
         // First do a normal upgrade...
-        if c::boot_go(&mut fl, &self.areadesc, None, self.align) != 0 {
+        let (result, _) = c::boot_go(&mut fl, &self.areadesc, None, self.align, false);
+        if result != 0 {
             warn!("Failed first boot");
             fails += 1;
         }
@@ -550,7 +551,8 @@
             fails += 1;
         }
 
-        if c::boot_go(&mut fl, &self.areadesc, None, self.align) != 0 {
+        let (result, _) = c::boot_go(&mut fl, &self.areadesc, None, self.align, false);
+        if result != 0 {
             warn!("Failed second boot");
             fails += 1;
         }
@@ -589,7 +591,8 @@
         }
 
         // Run the bootloader...
-        if c::boot_go(&mut fl, &self.areadesc, None, self.align) != 0 {
+        let (result, _) = c::boot_go(&mut fl, &self.areadesc, None, self.align, false);
+        if result != 0 {
             warn!("Failed first boot");
             fails += 1;
         }
@@ -636,7 +639,8 @@
         }
 
         // Run the bootloader...
-        if c::boot_go(&mut fl, &self.areadesc, None, self.align) != 0 {
+        let (result, _) = c::boot_go(&mut fl, &self.areadesc, None, self.align, false);
+        if result != 0 {
             warn!("Failed first boot");
             fails += 1;
         }
@@ -658,6 +662,155 @@
 
         fails > 0
     }
+
+    fn trailer_sz(&self) -> usize {
+        c::boot_trailer_sz(self.align) as usize
+    }
+
+    // FIXME: could get status sz from bootloader
+    fn status_sz(&self) -> usize {
+        self.trailer_sz() - (16 + 24)
+    }
+
+    /// This test runs a simple upgrade with no fails in the images, but
+    /// allowing for fails in the status area. This should run to the end
+    /// and warn that write fails were detected...
+    #[cfg(not(feature = "validate-slot0"))]
+    pub fn run_with_status_fails_complete(&self) -> bool { false }
+
+    #[cfg(feature = "validate-slot0")]
+    pub fn run_with_status_fails_complete(&self) -> bool {
+        let mut fl = self.flash.clone();
+        let mut fails = 0;
+
+        info!("Try swap with status fails");
+
+        mark_permanent_upgrade(&mut fl, &self.slot1, self.align);
+
+        let status_off = self.slot1.base_off - self.trailer_sz();
+
+        // Always fail writes to status area...
+        let _ = fl.add_bad_region(status_off, self.status_sz(), 1.0);
+
+        let (result, asserts) = c::boot_go(&mut fl, &self.areadesc, None, self.align, true);
+        if result != 0 {
+            warn!("Failed!");
+            fails += 1;
+        }
+
+        // Failed writes to the marked "bad" region don't assert anymore.
+        // Any detected assert() is happening in another part of the code.
+        if asserts != 0 {
+            warn!("At least one assert() was called");
+            fails += 1;
+        }
+
+        if !verify_trailer(&fl, self.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                           COPY_DONE) {
+            warn!("Mismatched trailer for Slot 0");
+            fails += 1;
+        }
+
+        if !verify_image(&fl, self.slot0.base_off, &self.upgrade) {
+            warn!("Failed image verification");
+            fails += 1;
+        }
+
+        info!("validate slot0 enabled; re-run of boot_go should just work");
+        let (result, _) = c::boot_go(&mut fl, &self.areadesc, None, self.align, false);
+        if result != 0 {
+            warn!("Failed!");
+            fails += 1;
+        }
+
+        if fails > 0 {
+            error!("Error running upgrade with status write fails");
+        }
+
+        fails > 0
+    }
+
+    /// This test runs a simple upgrade with no fails in the images, but
+    /// allowing for fails in the status area. This should run to the end
+    /// and warn that write fails were detected...
+    #[cfg(feature = "validate-slot0")]
+    pub fn run_with_status_fails_with_reset(&self) -> bool {
+        let mut fl = self.flash.clone();
+        let mut fails = 0;
+        let mut count = self.total_count.unwrap() / 2;
+
+        //info!("count={}\n", count);
+
+        info!("Try interrupted swap with status fails");
+
+        mark_permanent_upgrade(&mut fl, &self.slot1, self.align);
+
+        let status_off = self.slot1.base_off - self.trailer_sz();
+
+        // Mark the status area as a bad area
+        let _ = fl.add_bad_region(status_off, self.status_sz(), 0.5);
+
+        // Should not fail, writing to bad regions does not assert
+        let (_, asserts) = c::boot_go(&mut fl, &self.areadesc, Some(&mut count), self.align, true);
+        if asserts != 0 {
+            warn!("At least one assert() was called");
+            fails += 1;
+        }
+
+        fl.reset_bad_regions();
+
+        // Disabling write verification the only assert triggered by
+        // boot_go should be checking for integrity of status bytes.
+        fl.set_verify_writes(false);
+
+        info!("Resuming an interrupted swap operation");
+        let (_, asserts) = c::boot_go(&mut fl, &self.areadesc, None, self.align, true);
+
+        // This might throw no asserts, for large sector devices, where
+        // a single failure writing is indistinguishable from no failure,
+        // or throw a single assert for small sector devices that fail
+        // multiple times...
+        if asserts > 1 {
+            warn!("Expected single assert validating slot0, more detected {}", asserts);
+            fails += 1;
+        }
+
+        if fails > 0 {
+            error!("Error running upgrade with status write fails");
+        }
+
+        fails > 0
+    }
+
+    #[cfg(not(feature = "validate-slot0"))]
+    #[cfg(not(feature = "overwrite-only"))]
+    pub fn run_with_status_fails_with_reset(&self) -> bool {
+        let mut fl = self.flash.clone();
+        let mut fails = 0;
+
+        info!("Try interrupted swap with status fails");
+
+        mark_permanent_upgrade(&mut fl, &self.slot1, self.align);
+
+        let status_off = self.slot1.base_off - self.trailer_sz();
+
+        // Mark the status area as a bad area
+        let _ = fl.add_bad_region(status_off, self.status_sz(), 1.0);
+
+        // This is expected to fail while writing to bad regions...
+        let (_, asserts) = c::boot_go(&mut fl, &self.areadesc, None, self.align, true);
+        if asserts == 0 {
+            warn!("No assert() detected");
+            fails += 1;
+        }
+
+        fails > 0
+    }
+
+    #[cfg(feature = "overwrite-only")]
+    pub fn run_with_status_fails_with_reset(&self) -> bool {
+        false
+    }
 }
 
 /// Test a boot, optionally stopping after 'n' flash options.  Returns a count
@@ -671,19 +824,19 @@
 
     let mut counter = stop.unwrap_or(0);
 
-    let (first_interrupted, count) = match c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align) {
-        -0x13579 => (true, stop.unwrap()),
-        0 => (false, -counter),
-        x => panic!("Unknown return: {}", x),
+    let (first_interrupted, count) = match c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align, false) {
+        (-0x13579, _) => (true, stop.unwrap()),
+        (0, _) => (false, -counter),
+        (x, _) => panic!("Unknown return: {}", x),
     };
 
     counter = 0;
     if first_interrupted {
         // fl.dump();
-        match c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align) {
-            -0x13579 => panic!("Shouldn't stop again"),
-            0 => (),
-            x => panic!("Unknown return: {}", x),
+        match c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align, false) {
+            (-0x13579, _) => panic!("Shouldn't stop again"),
+            (0, _) => (),
+            (x, _) => panic!("Unknown return: {}", x),
         }
     }
 
@@ -697,7 +850,7 @@
     // fl.write_file("image0.bin").unwrap();
     for i in 0 .. count {
         info!("Running boot pass {}", i + 1);
-        assert_eq!(c::boot_go(&mut fl, &areadesc, None, align), 0);
+        assert_eq!(c::boot_go(&mut fl, &areadesc, None, align, false), (0, 0));
     }
     fl
 }
@@ -706,11 +859,10 @@
 fn try_revert_with_fail_at(flash: &SimFlash, images: &Images,
                            stop: i32) -> bool {
     let mut fl = flash.clone();
-    let mut x: i32;
     let mut fails = 0;
 
     let mut counter = stop;
-    x = c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align);
+    let (x, _) = c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align, false);
     if x != -0x13579 {
         warn!("Should have stopped at interruption point");
         fails += 1;
@@ -721,7 +873,7 @@
         fails += 1;
     }
 
-    x = c::boot_go(&mut fl, &images.areadesc, None, images.align);
+    let (x, _) = c::boot_go(&mut fl, &images.areadesc, None, images.align, false);
     if x != 0 {
         warn!("Should have finished upgrade");
         fails += 1;
@@ -747,7 +899,7 @@
     }
 
     // Do Revert
-    x = c::boot_go(&mut fl, &images.areadesc, None, images.align);
+    let (x, _) = c::boot_go(&mut fl, &images.areadesc, None, images.align, false);
     if x != 0 {
         warn!("Should have finished a revert");
         fails += 1;
@@ -788,18 +940,18 @@
         let ops = Range::new(1, remaining_ops / 2);
         let reset_counter = ops.ind_sample(&mut rng);
         let mut counter = reset_counter;
-        match c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align) {
-            0 | -0x13579 => (),
-            x => panic!("Unknown return: {}", x),
+        match c::boot_go(&mut fl, &images.areadesc, Some(&mut counter), images.align, false) {
+            (0, _) | (-0x13579, _) => (),
+            (x, _) => panic!("Unknown return: {}", x),
         }
         remaining_ops -= reset_counter;
         resets[i] = reset_counter;
     }
 
-    match c::boot_go(&mut fl, &images.areadesc, None, images.align) {
-        -0x13579 => panic!("Should not be have been interrupted!"),
-        0 => (),
-        x => panic!("Unknown return: {}", x),
+    match c::boot_go(&mut fl, &images.areadesc, None, images.align, false) {
+        (-0x13579, _) => panic!("Should not be have been interrupted!"),
+        (0, _) => (),
+        (x, _) => panic!("Unknown return: {}", x),
     }
 
     (fl, resets)