VirtualBox

Changeset 4185 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Aug 16, 2007 10:44:44 PM (17 years ago)
Author:
vboxsync
Message:

Fixed x86/amd64 file header difference. Added SSMAFTER_DEBUG_IT for tstAnimate and (later) debugger usage.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/SSM.cpp

    r4071 r4185  
    9191    /** The VM handle. */
    9292    PVM             pVM;
     93    /** The size of the file header.
     94     * Because the file header was incorrectly aligned there we've ended up with
     95     * differences between the 64-bit and 32-bit file header. */
     96    size_t          cbFileHdr;
    9397    /** The current operation. */
    9498    SSMSTATE        enmOp;
     
    139143    /** File checksum. The actual calculation skips past the u32CRC field. */
    140144    uint32_t    u32CRC;
     145    /** Padding. */
     146    uint32_t    u32Reserved;
    141147    /** The machine UUID. (Ignored if NIL.) */
    142148    RTUUID      MachineUuid;
    143149} SSMFILEHDR, *PSSMFILEHDR;
     150AssertCompileSize(SSMFILEHDR, 64);
     151
     152
     153/**
     154 * The x86 edition of the 1.0 header.
     155 */
     156#pragma pack(1) /* darn, MachineUuid got missaligned! */
     157typedef struct SSMFILEHDRV10X86
     158{
     159    /** Magic string which identifies this file as a version of VBox saved state file format. */
     160    char        achMagic[32];
     161    /** The size of this file. Used to check
     162     * whether the save completed and that things are fine otherwise. */
     163    uint64_t    cbFile;
     164    /** File checksum. The actual calculation skips past the u32CRC field. */
     165    uint32_t    u32CRC;
     166    /** The machine UUID. (Ignored if NIL.) */
     167    RTUUID      MachineUuid;
     168} SSMFILEHDRV10X86, *PSSMFILEHDRV10X86;
     169#pragma pack()
     170
     171/**
     172 * The amd64 edition of the 1.0 header.
     173 */
     174typedef SSMFILEHDR SSMFILEHDRV10AMD64, *PSSMFILEHDRV10AMD64;
    144175
    145176/** Saved state file magic base string. */
    146177#define SSMFILEHDR_MAGIC_BASE   "\177VirtualBox SavedState "
    147178/** Saved state file v1.0 magic. */
    148 #define SSMFILEHDR_MAGIC_V1     "\177VirtualBox SavedState V1.0\n"
     179#define SSMFILEHDR_MAGIC_V1_0   "\177VirtualBox SavedState V1.0\n"
     180/** Saved state file v1.1 magic. */
     181#define SSMFILEHDR_MAGIC_V1_1   "\177VirtualBox SavedState V1.1\n"
    149182
    150183
     
    183216static int ssmr3CalcChecksum(RTFILE File, uint64_t cbFile, uint32_t *pu32CRC);
    184217static void ssmR3Progress(PSSMHANDLE pSSM, uint64_t cbAdvance);
    185 static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr);
     218static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr, size_t *pcbFileHdr);
    186219static PSSMUNIT ssmr3Find(PVM pVM, const char *pszName, uint32_t u32Instance);
    187220static int ssmr3WriteFinish(PSSMHANDLE pSSM);
     
    744777     * Validate input.
    745778     */
    746     if (enmAfter != SSMAFTER_DESTROY && enmAfter != SSMAFTER_CONTINUE)
     779    if (    enmAfter != SSMAFTER_DESTROY
     780        &&  enmAfter != SSMAFTER_CONTINUE)
    747781    {
    748782        AssertMsgFailed(("Invalid enmAfter=%d!\n", enmAfter));
     
    756790    Handle.enmAfter    = enmAfter;
    757791    Handle.pVM         = pVM;
     792    Handle.cbFileHdr   = sizeof(SSMFILEHDR);
    758793    Handle.pfnProgress = pfnProgress;
    759794    Handle.pvUser      = pvUser;
     
    778813     * Write header.
    779814     */
    780     SSMFILEHDR Hdr = { SSMFILEHDR_MAGIC_V1, 0, 0 };
     815    SSMFILEHDR Hdr = { SSMFILEHDR_MAGIC_V1_1, 0, 0, 0 };
    781816    rc = RTFileWrite(Handle.File, &Hdr, sizeof(Hdr), NULL);
    782817    if (VBOX_SUCCESS(rc))
     
    10711106 *
    10721107 * @returns VBox status.
    1073  * @param   File    File to validate.
    1074  *                  The file position is undefined on return.
    1075  * @param   pHdr    Where to store the file header.
    1076  */
    1077 static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr)
     1108 * @param   File        File to validate.
     1109 *                      The file position is undefined on return.
     1110 * @param   pHdr        Where to store the file header.
     1111 * @param   pcbFileHdr  Where to store the file header size.
     1112 */
     1113static int ssmr3Validate(RTFILE File, PSSMFILEHDR pHdr, size_t *pcbFileHdr)
    10781114{
    10791115    /*
     
    10881124
    10891125    /*
    1090      * Verify the magic.
     1126     * Verify the magic and make adjustments for versions differences.
    10911127     */
    10921128    if (memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_BASE, sizeof(SSMFILEHDR_MAGIC_BASE) - 1))
     
    10951131        return VERR_SSM_INTEGRITY_MAGIC;
    10961132    }
    1097     if (memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_V1, sizeof(SSMFILEHDR_MAGIC_V1)))
     1133
     1134    size_t offCrc32 = RT_OFFSETOF(SSMFILEHDR, u32CRC) + sizeof(pHdr->u32CRC);
     1135    *pcbFileHdr = sizeof(*pHdr);
     1136    if (!memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_V1_0, sizeof(SSMFILEHDR_MAGIC_V1_0)))
     1137    {
     1138        if (pHdr->MachineUuid.au32[3])
     1139        {
     1140            SSMFILEHDRV10X86 OldHdr;
     1141            memcpy(&OldHdr, pHdr, sizeof(OldHdr));
     1142            pHdr->cbFile = OldHdr.cbFile;
     1143            pHdr->u32CRC = OldHdr.u32CRC;
     1144            pHdr->u32Reserved = 0;
     1145            pHdr->MachineUuid = OldHdr.MachineUuid;
     1146
     1147            offCrc32 = RT_OFFSETOF(SSMFILEHDRV10X86, u32CRC) + sizeof(pHdr->u32CRC);
     1148            *pcbFileHdr = sizeof(OldHdr);
     1149        }
     1150        else
     1151        {
     1152            /* (It's identical, but this doesn't harm us and will continue working after future changes.) */
     1153            SSMFILEHDRV10AMD64 OldHdr;
     1154            memcpy(&OldHdr, pHdr, sizeof(OldHdr));
     1155            pHdr->cbFile = OldHdr.cbFile;
     1156            pHdr->u32CRC = OldHdr.u32CRC;
     1157            pHdr->u32Reserved = 0;
     1158            pHdr->MachineUuid = OldHdr.MachineUuid;
     1159
     1160            offCrc32 = RT_OFFSETOF(SSMFILEHDRV10AMD64, u32CRC) + sizeof(pHdr->u32CRC);
     1161            *pcbFileHdr = sizeof(OldHdr);
     1162        }
     1163    }
     1164    else if (memcmp(pHdr->achMagic, SSMFILEHDR_MAGIC_V1_1, sizeof(SSMFILEHDR_MAGIC_V1_1)))
    10981165    {
    10991166        Log(("SSM: Unknown file format version. magic=%.*s\n", sizeof(pHdr->achMagic) - 1, pHdr->achMagic));
     
    11201187     * Verify the checksum.
    11211188     */
    1122     rc = RTFileSeek(File, RT_OFFSETOF(SSMFILEHDR, u32CRC) + sizeof(pHdr->u32CRC), RTFILE_SEEK_BEGIN, NULL);
     1189    rc = RTFileSeek(File, offCrc32, RTFILE_SEEK_BEGIN, NULL);
    11231190    if (VBOX_FAILURE(rc))
    11241191    {
     
    11271194    }
    11281195    uint32_t u32CRC;
    1129     rc = ssmr3CalcChecksum(File, pHdr->cbFile - sizeof(*pHdr), &u32CRC);
     1196    rc = ssmr3CalcChecksum(File, pHdr->cbFile - *pcbFileHdr, &u32CRC);
    11301197    if (VBOX_FAILURE(rc))
    11311198        return rc;
     
    11391206     * Verify Virtual Machine UUID.
    11401207     */
    1141     RTUUID    Uuid;
     1208    RTUUID  Uuid;
    11421209    memset(&Uuid, 0, sizeof(Uuid));
    11431210/** @todo get machine uuids  CFGGetUuid(, &Uuid); */
     
    11821249 * @param   pVM             The VM handle.
    11831250 * @param   pszFilename     Name of the file to save the state in.
    1184  * @param   enmAfter        What is planned after a successful save operation.
     1251 * @param   enmAfter        What is planned after a successful load operation.
     1252 *                          Only acceptable values are SSMAFTER_RESUME and SSMAFTER_DEBUG_IT.
    11851253 * @param   pfnProgress     Progress callback. Optional.
    11861254 * @param   pvUser          User argument for the progress callback.
     
    11931261     * Validate input.
    11941262     */
    1195     if (enmAfter != SSMAFTER_RESUME)
     1263    if (    enmAfter != SSMAFTER_RESUME
     1264        &&  enmAfter != SSMAFTER_DEBUG_IT)
    11961265    {
    11971266        AssertMsgFailed(("Invalid enmAfter=%d!\n", enmAfter));
     
    12051274    Handle.enmAfter        = enmAfter;
    12061275    Handle.pVM             = pVM;
     1276    Handle.cbFileHdr       = sizeof(SSMFILEHDR);
    12071277    Handle.pfnProgress     = pfnProgress;
    12081278    Handle.pvUser          = pvUser;
     
    12201290     */
    12211291    SSMFILEHDR Hdr;
    1222     rc = ssmr3Validate(Handle.File, &Hdr);
     1292    rc = ssmr3Validate(Handle.File, &Hdr, &Handle.cbFileHdr);
    12231293    if (VBOX_SUCCESS(rc))
    12241294    {
     
    12851355         */
    12861356        if (VBOX_SUCCESS(rc))
    1287             rc = RTFileSeek(Handle.File, sizeof(Hdr), RTFILE_SEEK_BEGIN, NULL);
     1357            rc = RTFileSeek(Handle.File, Handle.cbFileHdr, RTFILE_SEEK_BEGIN, NULL);
    12881358        if (VBOX_SUCCESS(rc))
    12891359        {
     
    13961466                                        pUnit->fCalled = true;
    13971467                                        if (VBOX_SUCCESS(rc))
     1468                                            rc = Handle.rc;
     1469                                        if (VBOX_SUCCESS(rc))
    13981470                                        {
    13991471                                            /*
     
    14231495                                        else
    14241496                                        {
     1497                                            /*
     1498                                             * We failed, but if loading for the debugger ignore certain failures
     1499                                             * just to get it all loaded (big hack).
     1500                                             */
    14251501                                            LogRel(("SSM: LoadExec failed with rc=%Vrc for unit '%s'!\n", rc, pszName));
    1426                                             break;
     1502                                            if (    Handle.enmAfter != SSMAFTER_DEBUG_IT
     1503                                                ||  rc != VERR_SSM_LOADED_TOO_MUCH)
     1504                                                break;
     1505                                            Handle.rc = rc = VINF_SUCCESS;
     1506                                            ssmR3Progress(&Handle, Handle.offEstUnitEnd - Handle.offEst);
    14271507                                        }
    14281508                                    }
     
    14361516                                else
    14371517                                {
     1518                                    /*
     1519                                     * SSM unit wasn't found - ignore this when loading for the debugger.
     1520                                     */
    14381521                                    LogRel(("SSM: Found no handler for unit '%s'!\n", pszName));
    14391522                                    rc = VERR_SSM_INTEGRITY_UNIT_NOT_FOUND;
    1440                                     break;
     1523                                    if (Handle.enmAfter != SSMAFTER_DEBUG_IT)
     1524                                        break;
     1525                                    rc = RTFileSeek(Handle.File, offUnit + UnitHdr.cbUnit, RTFILE_SEEK_BEGIN, NULL);
    14411526                                }
    14421527                            }
     
    15601645    if (VBOX_SUCCESS(rc))
    15611646    {
     1647        size_t cbFileHdr;
    15621648        SSMFILEHDR Hdr;
    1563         rc = ssmr3Validate(File, &Hdr);
     1649        rc = ssmr3Validate(File, &Hdr, &cbFileHdr);
    15641650        RTFileClose(File);
    15651651    }
     
    16021688    {
    16031689        SSMFILEHDR Hdr;
    1604         rc = ssmr3Validate(pSSM->File, &Hdr);
     1690        size_t cbFileHdr;
     1691        rc = ssmr3Validate(pSSM->File, &Hdr, &cbFileHdr);
    16051692        if (VBOX_SUCCESS(rc))
    16061693        {
    16071694            //pSSM->pVM           = NULL;
     1695            pSSM->cbFileHdr       = cbFileHdr;
    16081696            pSSM->enmOp           = SSMSTATE_OPEN_READ;
    16091697            pSSM->enmAfter        = SSMAFTER_OPENED;
     
    17091797    size_t  cchName = 0;
    17101798    SSMFILEUNITHDR  UnitHdr;
    1711     for (RTFOFF off = sizeof(SSMFILEHDR); ; off += UnitHdr.cbUnit)
     1799    for (RTFOFF off = pSSM->cbFileHdr; ; off += UnitHdr.cbUnit)
    17121800    {
    17131801        /*
     
    23882476    }
    23892477
    2390     AssertMsgFailed(("SSM: attempted reading more than the unit!\n"));
     2478    /** @todo weed out lazy saving */
     2479    if (pSSM->enmAfter != SSMAFTER_DEBUG_IT)
     2480        AssertMsgFailed(("SSM: attempted reading more than the unit!\n"));
    23912481    return VERR_SSM_LOADED_TOO_MUCH;
    23922482}
     
    28642954 * @param   pSSM            SSM operation handle.
    28652955 */
    2866 SSMR3DECL(int) SSMR3HandleGetAfter(PSSMHANDLE pSSM)
     2956SSMR3DECL(SSMAFTER) SSMR3HandleGetAfter(PSSMHANDLE pSSM)
    28672957{
    28682958    return pSSM->enmAfter;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette