Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 21926)
+++ /trunk/include/VBox/err.h	(revision 21927)
@@ -489,4 +489,5 @@
 /** The specified data unit wasn't owned by caller. */
 #define VERR_SSM_UNIT_NOT_OWNER                 (-1802)
+
 /** General saved state file integrity error. */
 #define VERR_SSM_INTEGRITY                      (-1810)
@@ -497,54 +498,73 @@
 /** The saved state file size didn't match the one in the header. */
 #define VERR_SSM_INTEGRITY_SIZE                 (-1813)
-/** The CRC of the saved state file did match. */
+/** The CRC of the saved state file did not match. */
 #define VERR_SSM_INTEGRITY_CRC                  (-1814)
-/** The current virtual machine id didn't match the virtual machine id. */
+/** The machine uuid field wasn't null. */
 #define VERR_SMM_INTEGRITY_MACHINE              (-1815)
+/** Saved state header integrity error. */
+#define VERR_SSM_INTEGRITY_HEADER               (-1816)
+/** Unit header integrity error. */
+#define VERR_SSM_INTEGRITY_UNIT                 (-1817)
 /** Invalid unit magic (internal data tag). */
-#define VERR_SSM_INTEGRITY_UNIT_MAGIC           (-1816)
+#define VERR_SSM_INTEGRITY_UNIT_MAGIC           (-1818)
 /** The file contained a data unit which no-one wants. */
-#define VERR_SSM_INTEGRITY_UNIT_NOT_FOUND       (-1817)
-/** Incorrect type sizes in the header. */
-#define VERR_SSM_INTEGRITY_SIZES                (-1818)
+#define VERR_SSM_INTEGRITY_UNIT_NOT_FOUND       (-1819)
 /** Incorrect version numbers in the header. */
-#define VERR_SSM_INTEGRITY_VBOX_VERSION         (-1819)
+#define VERR_SSM_INTEGRITY_VBOX_VERSION         (-1820)
+/** Footer integrity error. */
+#define VERR_SSM_INTEGRITY_FOOTER               (-1821)
+/** Record header integrity error. */
+#define VERR_SSM_INTEGRITY_REC_HDR              (-1822)
+/** Termination record integrity error. */
+#define VERR_SSM_INTEGRITY_REC_TERM             (-1823)
+/** Termination record CRC mismatch. */
+#define VERR_SSM_INTEGRITY_REC_TERM_CRC         (-1824)
+/** Decompression interity error.  */
+#define VERR_SSM_INTEGRITY_DECOMPRESSION        (-1825)
+/** Saved state directory iintegrity error.  */
+#define VERR_SSM_INTEGRITY_DIR                  (-1826)
+/** The saved state directory magic is wrong. */
+#define VERR_SSM_INTEGRITY_DIR_MAGIC            (-1827)
+
 /** A data unit in the saved state file was defined but didn't any
  * routine for processing it. */
-#define VERR_SSM_NO_LOAD_EXEC                   (-1820)
+#define VERR_SSM_NO_LOAD_EXEC                   (-1830)
 /** A restore routine attempted to load more data then the unit contained. */
-#define VERR_SSM_LOADED_TOO_MUCH                (-1821)
+#define VERR_SSM_LOADED_TOO_MUCH                (-1831)
 /** Not in the correct state for the attempted operation. */
-#define VERR_SSM_INVALID_STATE                  (-1822)
+#define VERR_SSM_INVALID_STATE                  (-1832)
+/** Not in the correct state for the attempted operation. */
+#define VERR_SSM_LOADED_TOO_LITTLE              (-1833)
 
 /** Unsupported data unit version.
  * A SSM user returns this if it doesn't know the u32Version. */
-#define VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION  (-1823)
+#define VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION  (-1840)
 /** The format of a data unit has changed.
  * A SSM user returns this if it's not able to read the format for
  * other reasons than u32Version. */
-#define VERR_SSM_DATA_UNIT_FORMAT_CHANGED       (-1824)
+#define VERR_SSM_DATA_UNIT_FORMAT_CHANGED       (-1841)
 /** The CPUID instruction returns different information when loading than when saved.
  * Normally caused by hardware changes on the host, but could also be caused by
  * changes in the BIOS setup. */
-#define VERR_SSM_LOAD_CPUID_MISMATCH            (-1825)
+#define VERR_SSM_LOAD_CPUID_MISMATCH            (-1842)
 /** The RAM size differes between the saved state and the VM config. */
-#define VERR_SSM_LOAD_MEMORY_SIZE_MISMATCH      (-1826)
+#define VERR_SSM_LOAD_MEMORY_SIZE_MISMATCH      (-1843)
 /** The state doesn't match the VM configuration in one or another way.
  * (There are certain PCI reconfiguration which the OS could potentially
  * do which can cause this problem. Check this out when it happens.) */
-#define VERR_SSM_LOAD_CONFIG_MISMATCH           (-1827)
+#define VERR_SSM_LOAD_CONFIG_MISMATCH           (-1844)
 /** The virtual clock freqency differs too much.
  * The clock source for the virtual time isn't reliable or the code have changed. */
-#define VERR_SSM_VIRTUAL_CLOCK_HZ               (-1828)
+#define VERR_SSM_VIRTUAL_CLOCK_HZ               (-1845)
 /** A timeout occured while waiting for async IDE operations to finish. */
-#define VERR_SSM_IDE_ASYNC_TIMEOUT              (-1829)
+#define VERR_SSM_IDE_ASYNC_TIMEOUT              (-1846)
 /** One of the structure magics was wrong. */
-#define VERR_SSM_STRUCTURE_MAGIC                (-1830)
+#define VERR_SSM_STRUCTURE_MAGIC                (-1847)
 /** The data in the saved state doesn't confirm to expectations. */
-#define VERR_SSM_UNEXPECTED_DATA                (-1831)
+#define VERR_SSM_UNEXPECTED_DATA                (-1848)
 /** Trying to read a 64-bit guest physical address into a 32-bit variable. */
-#define VERR_SSM_GCPHYS_OVERFLOW                (-1832)
+#define VERR_SSM_GCPHYS_OVERFLOW                (-1849)
 /** Trying to read a 64-bit guest virtual address into a 32-bit variable. */
-#define VERR_SSM_GCPTR_OVERFLOW                 (-1833)
+#define VERR_SSM_GCPTR_OVERFLOW                 (-1850)
 /** @} */
 
Index: /trunk/include/VBox/ssm.h
===================================================================
--- /trunk/include/VBox/ssm.h	(revision 21926)
+++ /trunk/include/VBox/ssm.h	(revision 21927)
@@ -513,4 +513,5 @@
 VMMR3DECL(int) SSMR3GetTimer(PSSMHANDLE pSSM, PTMTIMER pTimer);
 VMMR3DECL(int) SSMR3Skip(PSSMHANDLE pSSM, size_t cb);
+VMMR3DECL(int) SSMR3SkipToEndOfUnit(PSSMHANDLE pSSM);
 
 /** @} */
Index: /trunk/src/VBox/VMM/SSM-new.cpp
===================================================================
--- /trunk/src/VBox/VMM/SSM-new.cpp	(revision 21926)
+++ /trunk/src/VBox/VMM/SSM-new.cpp	(revision 21927)
@@ -2832,5 +2832,6 @@
                 }
             }
-            LogRel(("SSM: Failed to finalize state file! rc=%Rrc\n", rc));
+            if (RT_FAILURE(rc))
+                LogRel(("SSM: Failed to finalize state file! rc=%Rrc\n", rc));
         }
 
@@ -2994,9 +2995,9 @@
         {
             LogRel(("SSM: Incorrect cHostBits value: %u\n", pSSM->u.Read.cHostBits));
-            return VERR_SSM_INTEGRITY_SIZES;
+            return VERR_SSM_INTEGRITY_HEADER;
         }
     }
     else
-        AssertLogRelReturn(pSSM->u.Read.cHostBits == 0, VERR_SSM_INTEGRITY_SIZES);
+        AssertLogRelReturn(pSSM->u.Read.cHostBits == 0, VERR_SSM_INTEGRITY_HEADER);
 
     if (    pSSM->u.Read.cbGCPhys != sizeof(uint32_t)
@@ -3004,5 +3005,5 @@
     {
         LogRel(("SSM: Incorrect cbGCPhys value: %d\n", pSSM->u.Read.cbGCPhys));
-        return VERR_SSM_INTEGRITY_SIZES;
+        return VERR_SSM_INTEGRITY_HEADER;
     }
     if (    pSSM->u.Read.cbGCPtr != sizeof(uint32_t)
@@ -3010,5 +3011,5 @@
     {
         LogRel(("SSM: Incorrect cbGCPtr value: %d\n", pSSM->u.Read.cbGCPtr));
-        return VERR_SSM_INTEGRITY_SIZES;
+        return VERR_SSM_INTEGRITY_HEADER;
     }
 
@@ -3148,5 +3149,5 @@
             {
                 LogRel(("SSM: Bad footer magic: %.*Rhxs\n", sizeof(Footer.szMagic), &Footer.szMagic[0]));
-                return VERR_SSM_INTEGRITY;
+                return VERR_SSM_INTEGRITY_FOOTER;
             }
             SSM_CHECK_CRC32_RET(&Footer, sizeof(Footer), ("Footer CRC mismatch: %08x, correct is %08x\n", u32CRC, u32ActualCRC));
@@ -3154,10 +3155,10 @@
             {
                 LogRel(("SSM: SSMFILEFTR::offStream is wrong: %llx, expected %llx\n", Footer.offStream, offFooter));
-                return VERR_SSM_INTEGRITY;
+                return VERR_SSM_INTEGRITY_FOOTER;
             }
             if (Footer.u32Reserved)
             {
                 LogRel(("SSM: Reserved footer field isn't zero: %08x\n", Footer.u32Reserved));
-                return VERR_SSM_INTEGRITY;
+                return VERR_SSM_INTEGRITY_FOOTER;
             }
             if (    !fChecksummed
@@ -3165,5 +3166,5 @@
             {
                 LogRel(("SSM: u32StreamCRC field isn't zero, but header says stream checksumming is disabled.\n"));
-                return VERR_SSM_INTEGRITY;
+                return VERR_SSM_INTEGRITY_FOOTER;
             }
 
@@ -3464,5 +3465,5 @@
                     {
                         LogRel(("SSM: Unit name '%.*s' was not properly terminated.\n", UnitHdr.cchName, pszName));
-                        rc = VERR_SSM_INTEGRITY;
+                        rc = VERR_SSM_INTEGRITY_UNIT;
                         break;
                     }
@@ -3530,6 +3531,6 @@
                             {
                                 LogRel(("SSM: Unit '%s' read %lld bytes too much!\n", pszName, i64Diff));
-                                VMSetError(pVM, rc, RT_SRC_POS, N_("Unit '%s' read %lld bytes too much"), pszName, i64Diff);
-                                rc = VERR_SSM_INTEGRITY;
+                                rc = VMSetError(pVM, VERR_SSM_LOADED_TOO_MUCH, RT_SRC_POS,
+                                                N_("Unit '%s' read %lld bytes too much"), pszName, i64Diff);
                                 break;
                             }
@@ -3543,5 +3544,4 @@
                             VMSetError(pVM, rc, RT_SRC_POS, N_("Load exec failed for '%s' instance #%u (version %u)"),
                                        pszName, UnitHdr.u32Instance, UnitHdr.u32Version);
-                            rc = VERR_SSM_INTEGRITY;
                             break;
                         }
@@ -3610,30 +3610,26 @@
         if (UnitHdr.cbName)
         {
-            if (RT_UNLIKELY(UnitHdr.cbName > sizeof(UnitHdr.szName)))
-            {
-                LogRel(("SSM: Unit at %#llx (%lld): UnitHdr.cbName=%u > %u\n",
-                        offUnit, offUnit, UnitHdr.cbName, sizeof(UnitHdr.szName)));
-                return VERR_SSM_INTEGRITY;
-            }
+            AssertLogRelMsgReturn(UnitHdr.cbName <= sizeof(UnitHdr.szName),
+                                  ("Unit at %#llx (%lld): UnitHdr.cbName=%u > %u\n",
+                                   offUnit, offUnit, UnitHdr.cbName, sizeof(UnitHdr.szName)),
+                                  VERR_SSM_INTEGRITY_UNIT);
             rc = ssmR3StrmRead(&pSSM->Strm, &UnitHdr.szName[0], UnitHdr.cbName);
             if (RT_FAILURE(rc))
                 return rc;
-            if (RT_UNLIKELY(UnitHdr.szName[UnitHdr.cbName - 1]))
-            {
-                LogRel(("SSM: Unit at %#llx (%lld): Name %.*Rhxs was not properly terminated.\n",
-                        offUnit, offUnit, UnitHdr.cbName, UnitHdr.szName));
-                return VERR_SSM_INTEGRITY;
-            }
+            AssertLogRelMsgReturn(!UnitHdr.szName[UnitHdr.cbName - 1],
+                                  ("Unit at %#llx (%lld): Name %.*Rhxs was not properly terminated.\n",
+                                   offUnit, offUnit, UnitHdr.cbName, UnitHdr.szName),
+                                  VERR_SSM_INTEGRITY_UNIT);
         }
         SSM_CHECK_CRC32_RET(&UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName[UnitHdr.cbName]),
                             ("Unit at %#llx (%lld): CRC mismatch: %08x, correct is %08x\n", offUnit, offUnit, u32CRC, u32ActualCRC));
-        if (RT_UNLIKELY(UnitHdr.offStream != offUnit))
-        {
-            LogRel(("SSM: Unit at %#llx (%lld): offStream=%#llx, expected %#llx\n", offUnit, offUnit, UnitHdr.offStream, offUnit));
-            return VERR_SSM_INTEGRITY;
-        }
+        AssertLogRelMsgReturn(UnitHdr.offStream == offUnit,
+                              ("Unit at %#llx (%lld): offStream=%#llx, expected %#llx\n", offUnit, offUnit, UnitHdr.offStream, offUnit),
+                              VERR_SSM_INTEGRITY_UNIT);
         AssertLogRelMsgReturn(UnitHdr.u32CurStreamCRC == u32CurStreamCRC || !pSSM->Strm.fChecksummed,
-                              ("Unit at %#llx (%lld): Stream CRC mismatch: %08x, correct is %08x\n", offUnit, offUnit, UnitHdr.u32CurStreamCRC, u32CurStreamCRC), VERR_SSM_INTEGRITY);
-        AssertLogRelMsgReturn(!UnitHdr.fFlags, ("Unit at %#llx (%lld): fFlags=%08x\n", offUnit, offUnit, UnitHdr.fFlags), VERR_SSM_INTEGRITY);
+                              ("Unit at %#llx (%lld): Stream CRC mismatch: %08x, correct is %08x\n", offUnit, offUnit, UnitHdr.u32CurStreamCRC, u32CurStreamCRC),
+                              VERR_SSM_INTEGRITY_UNIT);
+        AssertLogRelMsgReturn(!UnitHdr.fFlags, ("Unit at %#llx (%lld): fFlags=%08x\n", offUnit, offUnit, UnitHdr.fFlags),
+                              VERR_SSM_INTEGRITY_UNIT);
         if (!memcmp(&UnitHdr.szMagic[0], SSMFILEUNITHDR_END,   sizeof(UnitHdr.szMagic)))
         {
@@ -3643,5 +3639,5 @@
                                   && UnitHdr.u32Phase     == SSM_PHASE_FINAL,
                                   ("Unit at %#llx (%lld): Malformed END unit\n", offUnit, offUnit),
-                                  VERR_SSM_INTEGRITY);
+                                  VERR_SSM_INTEGRITY_UNIT);
 
             /*
@@ -3704,8 +3700,9 @@
              */
             LogRel(("SSM: Found no handler for unit '%s' instance #%u!\n", UnitHdr.szName, UnitHdr.u32Instance));
-            //if (pSSM->enmAfter != SSMAFTER_DEBUG_IT)
+            if (pSSM->enmAfter != SSMAFTER_DEBUG_IT)
                 return VMSetError(pVM, VERR_SSM_INTEGRITY_UNIT_NOT_FOUND, RT_SRC_POS,
                                   N_("Found no handler for unit '%s' instance #%u"), UnitHdr.szName, UnitHdr.u32Instance);
-            /** @todo Read data unit to /dev/null. */
+            SSMR3SkipToEndOfUnit(pSSM);
+            ssmR3DataReadFinishV2(pSSM);
         }
     }
@@ -4040,5 +4037,5 @@
                 AssertLogRelMsgReturn(!szName[UnitHdr.cchName - 1],
                                       (" Unit name '%.*s' was not properly terminated.\n", cbUnitNm, szName),
-                                      VERR_SSM_INTEGRITY);
+                                      VERR_SSM_INTEGRITY_UNIT);
 
                 /*
@@ -4088,13 +4085,13 @@
     int rc = ssmR3StrmPeekAt(&pSSM->Strm, offDir, pDir, cbDir, NULL);
     AssertLogRelRCReturn(rc, rc);
-    AssertLogRelReturn(!memcmp(pDir->szMagic, SSMFILEDIR_MAGIC, sizeof(pDir->szMagic)), VERR_SSM_INTEGRITY);
+    AssertLogRelReturn(!memcmp(pDir->szMagic, SSMFILEDIR_MAGIC, sizeof(pDir->szMagic)), VERR_SSM_INTEGRITY_DIR_MAGIC);
     SSM_CHECK_CRC32_RET(pDir, cbDir, ("Bad directory CRC: %08x, actual %08x\n", u32CRC, u32ActualCRC));
     AssertLogRelMsgReturn(pDir->cEntries == cDirEntries,
                           ("Bad directory entry count: %#x, expected %#x (from the footer)\n", pDir->cEntries, cDirEntries),
-                          VERR_SSM_INTEGRITY);
+                           VERR_SSM_INTEGRITY_DIR);
     for (uint32_t i = 0; i < cDirEntries; i++)
         AssertLogRelMsgReturn(pDir->aEntries[i].off < offDir,
                               ("i=%u off=%lld offDir=%lld\n", i, pDir->aEntries[i].off, offDir),
-                              VERR_SSM_INTEGRITY);
+                              VERR_SSM_INTEGRITY_DIR);
 
     /*
@@ -4123,12 +4120,12 @@
             AssertLogRelMsgReturn(!memcmp(UnitHdr.szMagic, SSMFILEUNITHDR_MAGIC, sizeof(UnitHdr.szMagic)),
                                   ("Bad unit header or dictionary offset: i=%u off=%lld\n", i, pDir->aEntries[i].off),
-                                  VERR_SSM_INTEGRITY);
+                                  VERR_SSM_INTEGRITY_UNIT);
             AssertLogRelMsgReturn(UnitHdr.offStream == pDir->aEntries[i].off,
                                   ("Bad unit header: i=%d off=%lld offStream=%lld\n", i, pDir->aEntries[i].off, UnitHdr.offStream),
-                                  VERR_SSM_INTEGRITY);
+                                  VERR_SSM_INTEGRITY_UNIT);
             AssertLogRelMsgReturn(UnitHdr.u32Instance == pDir->aEntries[i].u32Instance,
                                   ("Bad unit header: i=%d off=%lld u32Instance=%u Dir.u32Instance=%u\n",
                                    i, pDir->aEntries[i].off, UnitHdr.u32Instance, pDir->aEntries[i].u32Instance),
-                                  VERR_SSM_INTEGRITY);
+                                  VERR_SSM_INTEGRITY_UNIT);
             uint32_t cbUnitHdr = RT_UOFFSETOF(SSMFILEUNITHDR, szName[UnitHdr.cbName]);
             AssertLogRelMsgReturn(   UnitHdr.cbName > 0
@@ -4136,5 +4133,5 @@
                                   && cbUnitHdr <= cbToRead,
                                   ("Bad unit header: i=%u off=%lld cbName=%#x cbToRead=%#x\n", i, pDir->aEntries[i].off, UnitHdr.cbName, cbToRead),
-                                  VERR_SSM_INTEGRITY);
+                                  VERR_SSM_INTEGRITY_UNIT);
             SSM_CHECK_CRC32_RET(&UnitHdr, RT_OFFSETOF(SSMFILEUNITHDR, szName[UnitHdr.cbName]),
                                 ("Bad unit header CRC: i=%u off=%lld u32CRC=%#x u32ActualCRC=%#x\n",
@@ -5041,5 +5038,4 @@
     }
 
-    /** @todo weed out lazy saving */
     if (pSSM->enmAfter != SSMAFTER_DEBUG_IT)
         AssertMsgFailed(("SSM: attempted reading more than the unit!\n"));
@@ -5121,5 +5117,8 @@
         if (    RT_SUCCESS(rc)
             &&  !pSSM->u.Read.fEndOfData)
-            rc = VERR_SSM_LOADED_TOO_MUCH; /** @todo More error codes! */
+        {
+            rc = VERR_SSM_LOADED_TOO_LITTLE;
+            AssertFailed();
+        }
         pSSM->rc = rc;
     }
@@ -5167,8 +5166,6 @@
                           && pSSM->u.Read.cbRecLeft <= RT_SIZEOFMEMB(SSMHANDLE, u.Read.abComprBuffer) + 2,
                           ("%#x\n", pSSM->u.Read.cbRecLeft),
-                          VERR_SSM_INTEGRITY);
-
-/** @todo this isn't very efficient, we know we have to read it all, so both
- *        reading the first byte separately.  */
+                          VERR_SSM_INTEGRITY_DECOMPRESSION);
+
     uint8_t cKB;
     int rc = ssmR3DataReadV2Raw(pSSM, &cKB, 1);
@@ -5181,5 +5178,5 @@
                           && cbDecompr <= RT_SIZEOFMEMB(SSMHANDLE, u.Read.abDataBuffer),
                           ("%#x\n", cbDecompr),
-                          VERR_SSM_INTEGRITY);
+                          VERR_SSM_INTEGRITY_DECOMPRESSION);
 
     *pcbDecompr = cbDecompr;
@@ -5229,8 +5226,10 @@
     if (RT_SUCCESS(rc))
     {
-        AssertLogRelMsgReturn(cbDstActual == cbDecompr, ("%#x %#x\n", cbDstActual, cbDecompr), VERR_SSM_INTEGRITY);
+        AssertLogRelMsgReturn(cbDstActual == cbDecompr, ("%#x %#x\n", cbDstActual, cbDecompr), VERR_SSM_INTEGRITY_DECOMPRESSION);
         return VINF_SUCCESS;
     }
-    return rc;
+
+    AssertLogRelMsgFailed(("cbCompr=%#x cbDecompr=%#x rc=%Rrc\n", cbCompr, cbDecompr, rc));
+    return VERR_SSM_INTEGRITY_DECOMPRESSION;
 }
 
@@ -5263,11 +5262,11 @@
      */
     pSSM->u.Read.u8TypeAndFlags = abHdr[0];
-    AssertLogRelMsgReturn(SSM_REC_ARE_TYPE_AND_FLAGS_VALID(abHdr[0]), ("%#x %#x\n", abHdr[0], abHdr[1]), VERR_SSM_INTEGRITY);
+    AssertLogRelMsgReturn(SSM_REC_ARE_TYPE_AND_FLAGS_VALID(abHdr[0]), ("%#x %#x\n", abHdr[0], abHdr[1]), VERR_SSM_INTEGRITY_REC_HDR);
     if ((abHdr[0] & SSM_REC_TYPE_MASK) == SSM_REC_TYPE_TERM)
     {
         pSSM->u.Read.cbRecLeft = 0;
         pSSM->u.Read.fEndOfData = true;
-        AssertLogRelMsgReturn(abHdr[1] == sizeof(SSMRECTERM) - 2, ("%#x\n", abHdr[1]), VERR_SSM_INTEGRITY);
-        AssertLogRelMsgReturn(abHdr[0] & SSM_REC_FLAGS_IMPORTANT, ("%#x\n", abHdr[0]), VERR_SSM_INTEGRITY);
+        AssertLogRelMsgReturn(abHdr[1] == sizeof(SSMRECTERM) - 2, ("%#x\n", abHdr[1]), VERR_SSM_INTEGRITY_REC_TERM);
+        AssertLogRelMsgReturn(abHdr[0] & SSM_REC_FLAGS_IMPORTANT, ("%#x\n", abHdr[0]), VERR_SSM_INTEGRITY_REC_TERM);
 
         /* get the rest */
@@ -5281,10 +5280,11 @@
         AssertLogRelMsgReturn(TermRec.cbUnit == pSSM->offUnit,
                               ("cbUnit=%#llx offUnit=%#llx\n", TermRec.cbUnit, pSSM->offUnit),
-                              VERR_SSM_INTEGRITY);
-        AssertLogRelMsgReturn(!(TermRec.fFlags & ~SSMRECTERM_FLAGS_CRC32), ("%#x\n", TermRec.fFlags), VERR_SSM_INTEGRITY);
+                              VERR_SSM_INTEGRITY_REC_TERM);
+        AssertLogRelMsgReturn(!(TermRec.fFlags & ~SSMRECTERM_FLAGS_CRC32), ("%#x\n", TermRec.fFlags), VERR_SSM_INTEGRITY_REC_TERM);
         if (!(TermRec.fFlags & SSMRECTERM_FLAGS_CRC32))
-            AssertLogRelMsgReturn(TermRec.u32StreamCRC == 0, ("%#x\n", TermRec.u32StreamCRC), VERR_SSM_INTEGRITY);
+            AssertLogRelMsgReturn(TermRec.u32StreamCRC == 0, ("%#x\n", TermRec.u32StreamCRC), VERR_SSM_INTEGRITY_REC_TERM);
         else if (pSSM->Strm.fChecksummed)
-            AssertLogRelMsgReturn(TermRec.u32StreamCRC == u32StreamCRC, ("%#x, %#x\n", TermRec.u32StreamCRC, u32StreamCRC), VERR_SSM_INTEGRITY_CRC);
+            AssertLogRelMsgReturn(TermRec.u32StreamCRC == u32StreamCRC, ("%#x, %#x\n", TermRec.u32StreamCRC, u32StreamCRC),
+                                  VERR_SSM_INTEGRITY_REC_TERM_CRC);
 
         Log3(("ssmR3DataReadRecHdrV2: %08llx|%08llx: TERM\n", ssmR3StrmTell(&pSSM->Strm) - sizeof(SSMRECTERM), pSSM->offUnit));
@@ -5316,5 +5316,5 @@
             cb = 6;
         else
-            AssertLogRelMsgFailedReturn(("Invalid record size byte: %#x\n", cb), VERR_SSM_INTEGRITY);
+            AssertLogRelMsgFailedReturn(("Invalid record size byte: %#x\n", cb), VERR_SSM_INTEGRITY_REC_HDR);
         cbHdr = cb + 1;
 
@@ -5329,13 +5329,13 @@
         {
             case 6:
-                AssertLogRelMsgReturn((abHdr[6] & 0xc0) == 0x80, ("6/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn((abHdr[6] & 0xc0) == 0x80, ("6/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY_REC_HDR);
             case 5:
-                AssertLogRelMsgReturn((abHdr[5] & 0xc0) == 0x80, ("5/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn((abHdr[5] & 0xc0) == 0x80, ("5/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY_REC_HDR);
             case 4:
-                AssertLogRelMsgReturn((abHdr[4] & 0xc0) == 0x80, ("4/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn((abHdr[4] & 0xc0) == 0x80, ("4/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY_REC_HDR);
             case 3:
-                AssertLogRelMsgReturn((abHdr[3] & 0xc0) == 0x80, ("3/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn((abHdr[3] & 0xc0) == 0x80, ("3/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY_REC_HDR);
             case 2:
-                AssertLogRelMsgReturn((abHdr[2] & 0xc0) == 0x80, ("2/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn((abHdr[2] & 0xc0) == 0x80, ("2/%u: %.*Rhxs\n", cb, cb + 1, &abHdr[0]), VERR_SSM_INTEGRITY_REC_HDR);
                 break;
             default:
@@ -5355,5 +5355,5 @@
                     | ((uint32_t)(abHdr[2] & 0x3f) << 24)
                     | ((uint32_t)(abHdr[1] & 0x01) << 30);
-                AssertLogRelMsgReturn(cb >= 0x04000000 && cb <= 0x7fffffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn(cb >= 0x04000000 && cb <= 0x7fffffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY_REC_HDR);
                 break;
             case 5:
@@ -5363,5 +5363,5 @@
                     | ((uint32_t)(abHdr[2] & 0x3f) << 18)
                     | ((uint32_t)(abHdr[1] & 0x03) << 24);
-                AssertLogRelMsgReturn(cb >= 0x00200000 && cb <= 0x03ffffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn(cb >= 0x00200000 && cb <= 0x03ffffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY_REC_HDR);
                 break;
             case 4:
@@ -5370,5 +5370,5 @@
                     | ((uint32_t)(abHdr[2] & 0x3f) << 12)
                     | ((uint32_t)(abHdr[1] & 0x07) << 18);
-                AssertLogRelMsgReturn(cb >= 0x00010000 && cb <= 0x001fffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn(cb >= 0x00010000 && cb <= 0x001fffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY_REC_HDR);
                 break;
             case 3:
@@ -5377,5 +5377,5 @@
                     | ((uint32_t)(abHdr[1] & 0x0f) << 12);
 #if 0  /* disabled to optimize buffering */
-                AssertLogRelMsgReturn(cb >= 0x00000800 && cb <= 0x0000ffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn(cb >= 0x00000800 && cb <= 0x0000ffff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY_REC_HDR);
 #endif
                 break;
@@ -5384,5 +5384,5 @@
                     | ((uint32_t)(abHdr[1] & 0x1f) << 6);
 #if 0  /* disabled to optimize buffering */
-                AssertLogRelMsgReturn(cb >= 0x00000080 && cb <= 0x000007ff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY);
+                AssertLogRelMsgReturn(cb >= 0x00000080 && cb <= 0x000007ff, ("cb=%#x\n", cb), VERR_SSM_INTEGRITY_REC_HDR);
 #endif
                 break;
@@ -6238,4 +6238,55 @@
 
 /**
+ * Skips to the end of the current data unit.
+ *
+ * Since version 2 of the format, the load exec callback have to explicitly call
+ * this API if it wish to be lazy for some reason.  This is because there seldom
+ * is a good reason to not read your entire data unit and it was hiding bugs.
+ *
+ * @returns VBox status code.
+ * @param   pSSM                The saved state handle.
+ */
+VMMR3DECL(int) SSMR3SkipToEndOfUnit(PSSMHANDLE pSSM)
+{
+    AssertMsgReturn(   pSSM->enmOp == SSMSTATE_LOAD_EXEC
+                    || pSSM->enmOp == SSMSTATE_OPEN_READ,
+                    ("Invalid state %d\n", pSSM->enmOp),
+                     VERR_SSM_INVALID_STATE);
+    if (pSSM->u.Read.uFmtVerMajor >= 2)
+    {
+        /*
+         * Read until we the end of data condition is raised.
+         */
+        pSSM->u.Read.cbDataBuffer  = 0;
+        pSSM->u.Read.offDataBuffer = 0;
+        if (!pSSM->u.Read.fEndOfData)
+        {
+            do
+            {
+                /* read the rest of the current record */
+                while (pSSM->u.Read.cbRecLeft)
+                {
+                    uint8_t abBuf[8192];
+                    size_t  cbToRead = RT_MIN(sizeof(pSSM->u.Read.cbRecLeft), sizeof(abBuf));
+                    int rc = ssmR3DataReadV2Raw(pSSM, abBuf, cbToRead);
+                    if (RT_FAILURE(rc))
+                        return pSSM->rc = rc;
+                    pSSM->u.Read.cbRecLeft -= cbToRead;
+                }
+
+                /* read the next header. */
+                int rc = ssmR3DataReadRecHdrV2(pSSM);
+                if (RT_FAILURE(rc))
+                    return pSSM->rc = rc;
+            } while (!pSSM->u.Read.fEndOfData);
+        }
+    }
+    /* else: Doesn't matter for the version 1 loading. */
+
+    return VINF_SUCCESS;
+}
+
+
+/**
  * Query what the VBox status code of the operation is.
  *
Index: /trunk/src/VBox/VMM/SSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/SSM.cpp	(revision 21926)
+++ /trunk/src/VBox/VMM/SSM.cpp	(revision 21927)
@@ -1507,5 +1507,5 @@
         {
             LogRel(("SSM: Incorrect cHostBits value: %d\n", pHdr->cHostBits));
-            return VERR_SSM_INTEGRITY_SIZES;
+            return VERR_SSM_INTEGRITY_HEADER;
         }
         if (    pHdr->cbGCPhys != sizeof(uint32_t)
@@ -1513,5 +1513,5 @@
         {
             LogRel(("SSM: Incorrect cbGCPhys value: %d\n", pHdr->cbGCPhys));
-            return VERR_SSM_INTEGRITY_SIZES;
+            return VERR_SSM_INTEGRITY_HEADER;
         }
         if (    pHdr->cbGCPtr != sizeof(uint32_t)
@@ -1519,5 +1519,5 @@
         {
             LogRel(("SSM: Incorrect cbGCPtr value: %d\n", pHdr->cbGCPtr));
-            return VERR_SSM_INTEGRITY_SIZES;
+            return VERR_SSM_INTEGRITY_HEADER;
         }
     }
@@ -3502,4 +3502,21 @@
 
 /**
+ * Skips to the end of the current data unit.
+ *
+ * Since version 2 of the format, the load exec callback have to explicitly call
+ * this API if it wish to be lazy for some reason.  This is because there seldom
+ * is a good reason to not read your entire data unit and it was hiding bugs.
+ *
+ * @returns VBox status code.
+ * @param   pSSM                The saved state handle.
+ */
+VMMR3DECL(int) SSMR3SkipToEndOfUnit(PSSMHANDLE pSSM)
+{
+    /* nothing to do here.  */
+    return VINF_SUCCESS;
+}
+
+
+/**
  * Query what the VBox status code of the operation is.
  *
