Exemple #1
0
int main(void)
{
  uint32_t j;

  /* Test the 32-bit add-with-carry kiss generator. */
  kiss32a_state_t * kiss32a_state;
  kiss32a_state = (kiss32a_state_t*) malloc(sizeof(kiss32a_state_t));

  kiss32a_state->mx = UINT32_C(123456789);
  kiss32a_state->my = UINT32_C(362436069);
  kiss32a_state->mz = UINT32_C(21288629);
  kiss32a_state->mw = UINT32_C(14921776);
  kiss32a_state->mc = UINT32_C(0);
  /* TODO kiss32a_state_t * seed_kiss32a(kiss32a_t *state, uint32_t mx,
       uint32_t my, uint32_t mz, uint32_t mw, uint32_t mc);
     Populate state (malloc if required). If NULL pointer returned, not
     successful.
  */

  /* Note, the following test corrects the original Usenet posting (Fortran and
     C: United with a kiss) of Marsaglia: we use 100000, not 10000 iterations.
   */
  for (int i = 0; i < 99996; i++)
  {
    _unused(j = kiss32a(kiss32a_state));
  }

  /* Test next four values for correctness */
  assert(kiss32a(kiss32a_state) == UINT32_C( 199275006));
  assert(kiss32a(kiss32a_state) == UINT32_C(  86473693));
  assert(kiss32a(kiss32a_state) == UINT32_C(2209597521));
  assert(kiss32a(kiss32a_state) == UINT32_C(1298124039));

#ifdef UINT64_C
  uint64_t k;

  /* Test the 32-bit multiply-with-carry kiss generator. */
  kiss32_state_t * kiss32_state;
  kiss32_state = (kiss32_state_t*) malloc(sizeof(kiss32_state_t));

  kiss32_state->mx = UINT32_C(123456789);
  kiss32_state->my = UINT32_C(362436000);
  kiss32_state->mz = UINT32_C(521288629);
  kiss32_state->mc = UINT32_C(7654321);
  /* TODO kiss32_state_t * seed_kiss32(kiss32_t *state, uint32_t mx,
       uint32_t my, uint32_t mz, uint32_t mc);
     Populate state (malloc if required). If NULL pointer returned, not
     successful.
  */

  for (int i = 0; i < 1000000; i++)
  {
    _unused(j = kiss32(kiss32_state));
  }

  /* The following test is from simplerandom, see
   * https://bitbucket.org/cmcqueen1975/simplerandom/wiki/Home */
  assert(j == UINT32_C(1010846401));

  /* Test the 64-bit multiply-with-carry kiss generator. */
  kiss64_state_t * kiss64_state;
  kiss64_state = (kiss64_state_t*) malloc(sizeof(kiss64_state_t));

  kiss64_state->mx = UINT64_C(1066149217761810);
  kiss64_state->my = UINT64_C(362436362436362436);
  kiss64_state->mz = UINT64_C(1234567890987654321);
  kiss64_state->mc = UINT64_C(123456123456123456);
  /* TODO kiss64_state_t * seed_kiss64(kiss64_t *state, uint64_t mx,
       uint64_t my, uint64_t mz, uint64_t mc);
     Populate state (malloc if required). If NULL pointer returned, not
     successful.
  */

  for (int i = 0; i < 100000000; i++)
  {
    _unused(k = kiss64(kiss64_state));
  }

  assert(k == UINT64_C(1666297717051644203));

#endif /* ifdef UINT64_C */

  return EXIT_SUCCESS;
}
/**
 * Wipes free space on one or more volumes by creating large files.
 */
static RTEXITCODE handlerWipeFreeSpace(int argc, char **argv)
{
    /*
     * Parse arguments.
     */
    const char *apszDefFiles[2] = { "./wipefree.spc", NULL };
    bool        fAll            = false;
    uint32_t    u32Filler       = UINT32_C(0xf6f6f6f6);
    uint64_t    cbMinLeftOpt    = _32M;

    static RTGETOPTDEF const s_aOptions[] =
    {
        { "--all",      'a', RTGETOPT_REQ_NOTHING },
        { "--filler",   'f', RTGETOPT_REQ_UINT32 },
        { "--min-free", 'm', RTGETOPT_REQ_UINT64 },
    };
    RTGETOPTSTATE State;
    RTGetOptInit(&State, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    RTGETOPTUNION ValueUnion;
    int chOpt;
    while (  (chOpt = RTGetOpt(&State, &ValueUnion)) != 0
           && chOpt != VINF_GETOPT_NOT_OPTION)
    {
        switch (chOpt)
        {
            case 'a':
                fAll = true;
                break;
            case 'f':
                u32Filler = ValueUnion.u32;
                break;
            case 'm':
                cbMinLeftOpt = ValueUnion.u64;
                break;
            case 'h':
                RTPrintf("usage: wipefrespace [options] [filename1 [..]]\n"
                         "\n"
                         "Options:\n"
                         "  -a, --all\n"
                         "    Try do the free space wiping on all seemingly relevant file systems.\n"
                         "    Changes the meaning of the filenames  "
                         "    This is not yet implemented\n"
                         "  -p, --filler <32-bit value>\n"
                         "    What to fill the blocks we write with.\n"
                         "    Default: 0xf6f6f6f6\n"
                         "  -m, --min-free <64-bit byte count>\n"
                         "    Specifies when to stop in terms of free disk space (in bytes).\n"
                         "    Default: 32MB\n"
                         "\n"
                         "Zero or more names of files to do the free space wiping thru can be given.\n"
                         "When --all is NOT used, each of the files are used to do free space wiping on\n"
                         "the volume they will live on.  However, when --all is in effect the files are\n"
                         "appended to the volume mountpoints and only the first that can be created will\n"
                         "be used.  Files (used ones) will be removed when done.\n"
                         "\n"
                         "If no filename is given, the default is: %s\n"
                         , apszDefFiles[0]);
                return RTEXITCODE_SUCCESS;

            default:
                return RTGetOptPrintError(chOpt, &ValueUnion);
        }
    }

    char **papszFiles;
    if (chOpt == 0)
        papszFiles = (char **)apszDefFiles;
    else
        papszFiles = RTGetOptNonOptionArrayPtr(&State);

    /*
     * Allocate and prep a memory which we'll write over and over again.
     */
    uint32_t  cbFiller   = _2M;
    uint32_t *pu32Filler = (uint32_t *)RTMemPageAlloc(cbFiller);
    while (!pu32Filler)
    {
        cbFiller <<= 1;
        if (cbFiller >= _4K)
            pu32Filler = (uint32_t *)RTMemPageAlloc(cbFiller);
        else
            return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTMemPageAlloc failed for sizes between 4KB and 2MB!\n");
    }
    for (uint32_t i = 0; i < cbFiller / sizeof(pu32Filler[0]); i++)
        pu32Filler[i] = u32Filler;

    /*
     * Do the requested work.
     */
    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
    if (!fAll)
    {
        for (uint32_t iFile = 0; papszFiles[iFile] != NULL; iFile++)
        {
            RTEXITCODE rcExit2 = doOneFreeSpaceWipe(papszFiles[iFile], pu32Filler, cbFiller, cbMinLeftOpt);
            if (rcExit2 != RTEXITCODE_SUCCESS && rcExit == RTEXITCODE_SUCCESS)
                rcExit = rcExit2;
        }
    }
    else
    {
        /*
         * Reject --all for now.
         */
        rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE,  "The --all option is not yet implemented!\n");
    }

    RTMemPageFree(pu32Filler, cbFiller);
    return rcExit;
}
Exemple #3
0
#define RT_SHA256_PRIVATE_ALT_CONTEXT
#include <iprt/sha.h>


AssertCompile(RT_SIZEOFMEMB(RTSHA256CONTEXT, abPadding) >= RT_SIZEOFMEMB(RTSHA256CONTEXT, AltPrivate));
AssertCompileMemberSize(RTSHA256ALTPRIVATECTX, auH, RTSHA256_HASH_SIZE);


/*******************************************************************************
*   Global Variables                                                           *
*******************************************************************************/
#ifndef RTSHA256_UNROLLED
/** The K constants */
static uint32_t const g_auKs[] =
{
    UINT32_C(0x428a2f98), UINT32_C(0x71374491), UINT32_C(0xb5c0fbcf), UINT32_C(0xe9b5dba5),
    UINT32_C(0x3956c25b), UINT32_C(0x59f111f1), UINT32_C(0x923f82a4), UINT32_C(0xab1c5ed5),
    UINT32_C(0xd807aa98), UINT32_C(0x12835b01), UINT32_C(0x243185be), UINT32_C(0x550c7dc3),
    UINT32_C(0x72be5d74), UINT32_C(0x80deb1fe), UINT32_C(0x9bdc06a7), UINT32_C(0xc19bf174),
    UINT32_C(0xe49b69c1), UINT32_C(0xefbe4786), UINT32_C(0x0fc19dc6), UINT32_C(0x240ca1cc),
    UINT32_C(0x2de92c6f), UINT32_C(0x4a7484aa), UINT32_C(0x5cb0a9dc), UINT32_C(0x76f988da),
    UINT32_C(0x983e5152), UINT32_C(0xa831c66d), UINT32_C(0xb00327c8), UINT32_C(0xbf597fc7),
    UINT32_C(0xc6e00bf3), UINT32_C(0xd5a79147), UINT32_C(0x06ca6351), UINT32_C(0x14292967),
    UINT32_C(0x27b70a85), UINT32_C(0x2e1b2138), UINT32_C(0x4d2c6dfc), UINT32_C(0x53380d13),
    UINT32_C(0x650a7354), UINT32_C(0x766a0abb), UINT32_C(0x81c2c92e), UINT32_C(0x92722c85),
    UINT32_C(0xa2bfe8a1), UINT32_C(0xa81a664b), UINT32_C(0xc24b8b70), UINT32_C(0xc76c51a3),
    UINT32_C(0xd192e819), UINT32_C(0xd6990624), UINT32_C(0xf40e3585), UINT32_C(0x106aa070),
    UINT32_C(0x19a4c116), UINT32_C(0x1e376c08), UINT32_C(0x2748774c), UINT32_C(0x34b0bcb5),
    UINT32_C(0x391c0cb3), UINT32_C(0x4ed8aa4a), UINT32_C(0x5b9cca4f), UINT32_C(0x682e6ff3),
    UINT32_C(0x748f82ee), UINT32_C(0x78a5636f), UINT32_C(0x84c87814), UINT32_C(0x8cc70208),
    UINT32_C(0x90befffa), UINT32_C(0xa4506ceb), UINT32_C(0xbef9a3f7), UINT32_C(0xc67178f2),
Exemple #4
0
/**
 * Deals with complicated MMIO reads.
 *
 * Complicated means unaligned or non-dword/qword sized accesses depending on
 * the MMIO region's access mode flags.
 *
 * @returns Strict VBox status code. Any EM scheduling status code,
 *          VINF_IOM_R3_MMIO_READ, VINF_IOM_R3_MMIO_READ_WRITE or
 *          VINF_IOM_R3_MMIO_WRITE may be returned.
 *
 * @param   pVM                 The cross context VM structure.
 * @param   pRange              The range to read from.
 * @param   GCPhys              The physical address to start reading.
 * @param   pvValue             Where to store the value.
 * @param   cbValue             The size of the value to read.
 */
static VBOXSTRICTRC iomMMIODoComplicatedRead(PVM pVM, PIOMMMIORANGE pRange, RTGCPHYS GCPhys, void *pvValue, unsigned cbValue)
{
    AssertReturn(   (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_DWORD
                 || (pRange->fFlags & IOMMMIO_FLAGS_READ_MODE) == IOMMMIO_FLAGS_READ_DWORD_QWORD,
                 VERR_IOM_MMIO_IPE_1);
    AssertReturn(cbValue != 0 && cbValue <= 16, VERR_IOM_MMIO_IPE_2);
    RTGCPHYS const GCPhysStart = GCPhys; NOREF(GCPhysStart);

    /*
     * Do debug stop if requested.
     */
    int rc = VINF_SUCCESS; NOREF(pVM);
#ifdef VBOX_STRICT
    if (pRange->fFlags & IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_READ)
    {
# ifdef IN_RING3
        rc = DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, RT_SRC_POS,
                            "Complicated read %#x byte at %RGp to %s\n", cbValue, GCPhys, R3STRING(pRange->pszDesc));
        if (rc == VERR_DBGF_NOT_ATTACHED)
            rc = VINF_SUCCESS;
# else
        return VINF_IOM_R3_MMIO_READ;
# endif
    }
#endif

    /*
     * Split and conquer.
     */
    for (;;)
    {
        /*
         * Do DWORD read from the device.
         */
        uint32_t u32Value;
        int rc2 = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
                                                    GCPhys & ~(RTGCPHYS)3, &u32Value, sizeof(u32Value));
        switch (rc2)
        {
            case VINF_SUCCESS:
                break;
            case VINF_IOM_MMIO_UNUSED_FF:
                u32Value = UINT32_C(0xffffffff);
                break;
            case VINF_IOM_MMIO_UNUSED_00:
                u32Value = 0;
                break;
            case VINF_IOM_R3_MMIO_READ:
            case VINF_IOM_R3_MMIO_READ_WRITE:
            case VINF_IOM_R3_MMIO_WRITE:
                /** @todo What if we've split a transfer and already read
                 * something?  Since reads can have sideeffects we could be
                 * kind of screwed here... */
                LogFlow(("iomMMIODoComplicatedRead: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc\n", GCPhys, GCPhysStart, cbValue, rc2));
                return rc2;
            default:
                if (RT_FAILURE(rc2))
                {
                    Log(("iomMMIODoComplicatedRead: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc\n", GCPhys, GCPhysStart, cbValue, rc2));
                    return rc2;
                }
                AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS);
                if (rc == VINF_SUCCESS || rc2 < rc)
                    rc = rc2;
                break;
        }
        u32Value >>= (GCPhys & 3) * 8;

        /*
         * Write what we've read.
         */
        unsigned cbThisPart = 4 - (GCPhys & 3);
        if (cbThisPart > cbValue)
            cbThisPart = cbValue;

        switch (cbThisPart)
        {
            case 1:
                *(uint8_t *)pvValue = (uint8_t)u32Value;
                break;
            case 2:
                *(uint16_t *)pvValue = (uint16_t)u32Value;
                break;
            case 3:
                ((uint8_t *)pvValue)[0] = RT_BYTE1(u32Value);
                ((uint8_t *)pvValue)[1] = RT_BYTE2(u32Value);
                ((uint8_t *)pvValue)[2] = RT_BYTE3(u32Value);
                break;
            case 4:
                *(uint32_t *)pvValue = u32Value;
                break;
        }

        /*
         * Advance.
         */
        cbValue -= cbThisPart;
        if (!cbValue)
            break;
        GCPhys += cbThisPart;
        pvValue = (uint8_t *)pvValue + cbThisPart;
    }

    return rc;
}
Exemple #5
0
static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
{
#ifndef UNIT_TEST
    LogRel2 (("svcLoadState: u32ClientID = %d\n", u32ClientID));

    VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient;

    /* Existing client can not be in async state yet. */
    Assert (!pClient->fAsync);

    /* Save the client ID for data validation. */
    /** @todo isn't this the same as u32ClientID? Playing safe for now... */
    uint32_t const u32ClientIDOld = pClient->u32ClientID;

    /* Restore the client data. */
    uint32_t lenOrVer;
    int rc = SSMR3GetU32 (pSSM, &lenOrVer);
    AssertRCReturn (rc, rc);
    if (lenOrVer == UINT32_C (0x80000002))
    {
        rc = SSMR3GetStructEx (pSSM, pClient, sizeof(*pClient), 0 /*fFlags*/, &g_aClipboardClientDataFields[0], NULL);
        AssertRCReturn (rc, rc);
    }
    else if (lenOrVer == (SSMR3HandleHostBits (pSSM) == 64 ? 72 : 48))
    {
        /**
         * SSM descriptor table for the CLIPSAVEDSTATEDATA structure.
         */
        static SSMFIELD const s_aClipSavedStateDataFields30[] =
        {
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, pNext),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, pPrev),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, pCtx),
            SSMFIELD_ENTRY(                 CLIPSAVEDSTATEDATA, u32ClientID),
            SSMFIELD_ENTRY_CUSTOM(fMsgQuit+fMsgReadData+fMsgFormats, RT_OFFSETOF(CLIPSAVEDSTATEDATA, u32ClientID) + 4, 4),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, async.callHandle),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, async.paParms),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, data.pv),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, data.cb),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, data.u32Format),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, u32AvailableFormats),
            SSMFIELD_ENTRY(                 CLIPSAVEDSTATEDATA, u32RequestedFormat),
            SSMFIELD_ENTRY_TERM()
        };

        CLIPSAVEDSTATEDATA savedState;
        RT_ZERO (savedState);
        rc = SSMR3GetStructEx (pSSM, &savedState, sizeof(savedState), SSMSTRUCT_FLAGS_MEM_BAND_AID,
                               &s_aClipSavedStateDataFields30[0], NULL);
        AssertRCReturn (rc, rc);

        pClient->fMsgQuit           = savedState.fMsgQuit;
        pClient->fMsgReadData       = savedState.fMsgReadData;
        pClient->fMsgFormats        = savedState.fMsgFormats;
        pClient->u32RequestedFormat = savedState.u32RequestedFormat;
    }
    else
    {
        LogRel (("Client data size mismatch: got %#x\n", lenOrVer));
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Verify the client ID. */
    if (pClient->u32ClientID != u32ClientIDOld)
    {
        LogRel (("Client ID mismatch: expected %d, got %d\n", u32ClientIDOld, pClient->u32ClientID));
        pClient->u32ClientID = u32ClientIDOld;
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Actual host data are to be reported to guest (SYNC). */
    vboxClipboardSync (pClient);

#endif /* !UNIT_TEST */
    return VINF_SUCCESS;
}
Exemple #6
0
/**
 * Initializes the KVM GIM provider.
 *
 * @returns VBox status code.
 * @param   pVM         Pointer to the VM.
 * @param   uVersion    The interface version this VM should use.
 */
VMMR3_INT_DECL(int) gimR3KvmInit(PVM pVM)
{
    AssertReturn(pVM, VERR_INVALID_PARAMETER);
    AssertReturn(pVM->gim.s.enmProviderId == GIMPROVIDERID_KVM, VERR_INTERNAL_ERROR_5);

    int rc;
    PGIMKVM pKvm = &pVM->gim.s.u.Kvm;

    /*
     * Determine interface capabilities based on the version.
     */
    if (!pVM->gim.s.u32Version)
    {
        /* Basic features. */
        pKvm->uBaseFeat = 0
                        | GIM_KVM_BASE_FEAT_CLOCK_OLD
                        //| GIM_KVM_BASE_FEAT_NOP_IO_DELAY
                        //|  GIM_KVM_BASE_FEAT_MMU_OP
                        | GIM_KVM_BASE_FEAT_CLOCK
                        //| GIM_KVM_BASE_FEAT_ASYNC_PF
                        //| GIM_KVM_BASE_FEAT_STEAL_TIME
                        //| GIM_KVM_BASE_FEAT_PV_EOI
                        | GIM_KVM_BASE_FEAT_PV_UNHALT
                        ;
        /* Rest of the features are determined in gimR3KvmInitCompleted(). */
    }

    /*
     * Expose HVP (Hypervisor Present) bit to the guest.
     */
    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_HVP);

    /*
     * Modify the standard hypervisor leaves for KVM.
     */
    CPUMCPUIDLEAF HyperLeaf;
    RT_ZERO(HyperLeaf);
    HyperLeaf.uLeaf        = UINT32_C(0x40000000);
    HyperLeaf.uEax         = UINT32_C(0x40000001); /* Minimum value for KVM is 0x40000001. */
    HyperLeaf.uEbx         = 0x4B4D564B;           /* 'KVMK' */
    HyperLeaf.uEcx         = 0x564B4D56;           /* 'VMKV' */
    HyperLeaf.uEdx         = 0x0000004D;           /* 'M000' */
    rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
    AssertLogRelRCReturn(rc, rc);

    /*
     * Add KVM specific leaves.
     */
    HyperLeaf.uLeaf        = UINT32_C(0x40000001);
    HyperLeaf.uEax         = pKvm->uBaseFeat;
    HyperLeaf.uEbx         = 0;                    /* Reserved */
    HyperLeaf.uEcx         = 0;                    /* Reserved */
    HyperLeaf.uEdx         = 0;                    /* Reserved */
    rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
    AssertLogRelRCReturn(rc, rc);

    /*
     * Insert all MSR ranges of KVM.
     */
    for (unsigned i = 0; i < RT_ELEMENTS(g_aMsrRanges_Kvm); i++)
    {
        rc = CPUMR3MsrRangesInsert(pVM, &g_aMsrRanges_Kvm[i]);
        AssertLogRelRCReturn(rc, rc);
    }

    /*
     * Setup hypercall and #UD handling.
     */
    for (VMCPUID i = 0; i < pVM->cCpus; i++)
        VMMHypercallsEnable(&pVM->aCpus[i]);

    if (ASMIsAmdCpu())
    {
        pKvm->fTrapXcptUD   = true;
        pKvm->uOpCodeNative = OP_VMMCALL;
    }
    else
    {
        Assert(ASMIsIntelCpu() || ASMIsViaCentaurCpu());
        pKvm->fTrapXcptUD   = false;
        pKvm->uOpCodeNative = OP_VMCALL;
    }

    /* We always need to trap VMCALL/VMMCALL hypercall using #UDs for raw-mode VMs. */
    if (!HMIsEnabled(pVM))
        pKvm->fTrapXcptUD = true;

    return VINF_SUCCESS;
}
static void Test4(unsigned cThreads, unsigned cSeconds, unsigned uWritePercent, bool fYield, bool fQuiet)
{
    unsigned i;
    uint64_t acIterations[32];
    RTTHREAD aThreads[RT_ELEMENTS(acIterations)];
    AssertRelease(cThreads <= RT_ELEMENTS(acIterations));

    RTTestSubF(g_hTest, "Test4 - %u threads, %u sec, %u%% writes, %syielding",
               cThreads, cSeconds, uWritePercent, fYield ? "" : "non-");

    /*
     * Init globals.
     */
    g_fYield = fYield;
    g_fQuiet = fQuiet;
    g_fTerminate = false;
    g_uWritePercent = uWritePercent;
    g_cConcurrentWriters = 0;
    g_cConcurrentReaders = 0;

    RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectRwInit(&g_CritSectRw), VINF_SUCCESS);

    /*
     * Create the threads and let them block on the semrw.
     */
    RTTEST_CHECK_RC_RETV(g_hTest, RTCritSectRwEnterExcl(&g_CritSectRw), VINF_SUCCESS);

    for (i = 0; i < cThreads; i++)
    {
        acIterations[i] = 0;
        RTTEST_CHECK_RC_RETV(g_hTest, RTThreadCreateF(&aThreads[i], Test4Thread, &acIterations[i], 0,
                                                      RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
                                                      "test-%u", i), VINF_SUCCESS);
    }

    /*
     * Do the test run.
     */
    uint32_t cErrorsBefore = RTTestErrorCount(g_hTest);
    uint64_t u64StartTS = RTTimeNanoTS();
    RTTEST_CHECK_RC(g_hTest, RTCritSectRwLeaveExcl(&g_CritSectRw), VINF_SUCCESS);
    RTThreadSleep(cSeconds * 1000);
    ASMAtomicWriteBool(&g_fTerminate, true);
    uint64_t ElapsedNS = RTTimeNanoTS() - u64StartTS;

    /*
     * Clean up the threads and semaphore.
     */
    for (i = 0; i < cThreads; i++)
        RTTEST_CHECK_RC(g_hTest, RTThreadWait(aThreads[i], 5000, NULL), VINF_SUCCESS);

    RTTEST_CHECK_MSG(g_hTest, g_cConcurrentWriters == 0, (g_hTest, "g_cConcurrentWriters=%u at end of test\n", g_cConcurrentWriters));
    RTTEST_CHECK_MSG(g_hTest, g_cConcurrentReaders == 0, (g_hTest, "g_cConcurrentReaders=%u at end of test\n", g_cConcurrentReaders));

    RTTEST_CHECK_RC(g_hTest, RTCritSectRwDelete(&g_CritSectRw), VINF_SUCCESS);

    if (RTTestErrorCount(g_hTest) != cErrorsBefore)
        RTThreadSleep(100);

    /*
     * Collect and display the results.
     */
    uint64_t cItrTotal = acIterations[0];
    for (i = 1; i < cThreads; i++)
        cItrTotal += acIterations[i];

    uint64_t cItrNormal = cItrTotal / cThreads;
    uint64_t cItrMinOK = cItrNormal / 20; /* 5% */
    uint64_t cItrMaxDeviation = 0;
    for (i = 0; i < cThreads; i++)
    {
        uint64_t cItrDelta = RT_ABS((int64_t)(acIterations[i] - cItrNormal));
        if (acIterations[i] < cItrMinOK)
            RTTestFailed(g_hTest, "Thread %u did less than 5%% of the iterations - %llu (it) vs. %llu (5%%) - %llu%%\n",
                         i, acIterations[i], cItrMinOK, cItrDelta * 100 / cItrNormal);
        else if (cItrDelta > cItrNormal / 2)
            RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
                         "Warning! Thread %u deviates by more than 50%% - %llu (it) vs. %llu (avg) - %llu%%\n",
                         i, acIterations[i], cItrNormal, cItrDelta * 100 / cItrNormal);
        if (cItrDelta > cItrMaxDeviation)
            cItrMaxDeviation = cItrDelta;

    }

    //RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS,
    //             "Threads: %u  Total: %llu  Per Sec: %llu  Avg: %llu ns  Max dev: %llu%%\n",
    //             cThreads,
    //             cItrTotal,
    //             cItrTotal / cSeconds,
    //             ElapsedNS / cItrTotal,
    //             cItrMaxDeviation * 100 / cItrNormal
    //             );
    //
    RTTestValue(g_hTest, "Thruput", cItrTotal * UINT32_C(1000000000) / ElapsedNS, RTTESTUNIT_CALLS_PER_SEC);
    RTTestValue(g_hTest, "Max diviation", cItrMaxDeviation * 100 / cItrNormal, RTTESTUNIT_PCT);
}
Exemple #8
0
RTDECL(int) RTSemRWCreateEx(PRTSEMRW phRWSem, uint32_t fFlags,
                            RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...)
{
    AssertReturn(!(fFlags & ~RTSEMRW_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);

    /*
     * Allocate memory.
     */
    int rc;
    struct RTSEMRWINTERNAL *pThis = (struct RTSEMRWINTERNAL *)RTMemAlloc(sizeof(struct RTSEMRWINTERNAL));
    if (pThis)
    {
        /*
         * Create the semaphores.
         */
        rc = RTSemEventCreateEx(&pThis->WriteEvent, RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL);
        if (RT_SUCCESS(rc))
        {
            rc = RTSemEventMultiCreateEx(&pThis->ReadEvent, RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL);
            if (RT_SUCCESS(rc))
            {
                rc = RTCritSectInitEx(&pThis->CritSect, RTCRITSECT_FLAGS_NO_LOCK_VAL,
                                      NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
                if (RT_SUCCESS(rc))
                {
                    /*
                     * Signal the read semaphore and initialize other variables.
                     */
                    rc = RTSemEventMultiSignal(pThis->ReadEvent);
                    if (RT_SUCCESS(rc))
                    {
                        pThis->u32Padding           = UINT32_C(0xa5a55a5a);
                        pThis->cReads               = 0;
                        pThis->cWrites              = 0;
                        pThis->cWriterReads         = 0;
                        pThis->cWritesWaiting       = 0;
                        pThis->hWriter              = NIL_RTNATIVETHREAD;
                        pThis->fNeedResetReadEvent  = true;
                        pThis->u32Magic             = RTSEMRW_MAGIC;
#ifdef RTSEMRW_STRICT
                        bool const fLVEnabled = !(fFlags & RTSEMRW_FLAGS_NO_LOCK_VAL);
                        if (!pszNameFmt)
                        {
                            static uint32_t volatile s_iSemRWAnon = 0;
                            uint32_t i = ASMAtomicIncU32(&s_iSemRWAnon) - 1;
                            RTLockValidatorRecExclInit(&pThis->ValidatorWrite, hClass, uSubClass, pThis,
                                                       fLVEnabled, "RTSemRW-%u", i);
                            RTLockValidatorRecSharedInit(&pThis->ValidatorRead, hClass, uSubClass, pThis,
                                                         false /*fSignaller*/, fLVEnabled, "RTSemRW-%u", i);
                        }
                        else
                        {
                            va_list va;
                            va_start(va, pszNameFmt);
                            RTLockValidatorRecExclInitV(&pThis->ValidatorWrite, hClass, uSubClass, pThis,
                                                        fLVEnabled, pszNameFmt, va);
                            va_end(va);
                            va_start(va, pszNameFmt);
                            RTLockValidatorRecSharedInitV(&pThis->ValidatorRead, hClass, uSubClass, pThis,
                                                          false /*fSignaller*/, fLVEnabled, pszNameFmt, va);
                            va_end(va);
                        }
                        RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
#endif
                        *phRWSem = pThis;
                        return VINF_SUCCESS;
                    }
                    RTCritSectDelete(&pThis->CritSect);
                }
                RTSemEventMultiDestroy(pThis->ReadEvent);
            }
            RTSemEventDestroy(pThis->WriteEvent);
        }
        RTMemFree(pThis);
    }
    else
        rc = VERR_NO_MEMORY;

    return rc;
}
static void checkStruct(struct capn *ctx) {
  capn_ptr ptr = capn_getp(capn_root(ctx), 0, 1);
  EXPECT_EQ(CAPN_STRUCT, ptr.type);
  EXPECT_EQ(16, ptr.datasz);
  EXPECT_EQ(6, ptr.ptrs);
  EXPECT_EQ(UINT64_C(0x1011121314151617), capn_read64(ptr, 0));
  EXPECT_EQ(UINT32_C(0x20212223), capn_read32(ptr, 8));
  EXPECT_EQ(0x3031, capn_read16(ptr, 12));
  EXPECT_EQ(0x40, capn_read8(ptr, 14));
  EXPECT_EQ((1 << 6) | (1 << 5) | (1 << 4) | (1 << 2), capn_read8(ptr, 15));

  capn_ptr subStruct = capn_getp(ptr, 0, 1);
  EXPECT_EQ(CAPN_STRUCT, subStruct.type);
  EXPECT_EQ(8, subStruct.datasz);
  EXPECT_EQ(0, subStruct.ptrs);
  EXPECT_EQ(123, capn_read32(subStruct, 0));

  capn_list32 list32 = {capn_getp(ptr, 1, 1)};
  capn_list8 list8 = {list32.p};
  capn_list16 list16 = {list32.p};
  capn_list64 list64 = {list32.p};
  EXPECT_EQ(CAPN_LIST, list32.p.type);
  EXPECT_EQ(3, list32.p.len);
  EXPECT_EQ(4, list32.p.datasz);
  EXPECT_EQ(0, list32.p.ptrs);
  EXPECT_EQ(200, capn_get32(list32, 0));
  EXPECT_EQ(201, capn_get32(list32, 1));
  EXPECT_EQ(202, capn_get32(list32, 2));
  EXPECT_EQ(0, capn_get32(list32, 3));
  EXPECT_EQ(0, capn_get64(list64, 0));
  EXPECT_EQ(201, capn_get8(list8, 1));
  EXPECT_EQ(202, capn_get16(list16, 2));

  capn_ptr list = capn_getp(ptr, 2, 1);
  EXPECT_EQ(CAPN_LIST, list.type);
  EXPECT_EQ(1, list.is_composite_list);
  EXPECT_EQ(4, list.len);
  EXPECT_EQ(8, list.datasz);
  EXPECT_EQ(1, list.ptrs);

  for (int i = 0; i < 4; i++) {
    capn_ptr element = capn_getp(list, i, 1);
    EXPECT_EQ(CAPN_STRUCT, element.type);
    EXPECT_EQ(1, element.is_list_member);
    EXPECT_EQ(8, element.datasz);
    EXPECT_EQ(1, element.ptrs);
    EXPECT_EQ(300+i, capn_read32(element,0));

    capn_ptr subelement = capn_getp(element, 0, 1);
    EXPECT_EQ(CAPN_STRUCT, subelement.type);
    EXPECT_EQ(8, subelement.datasz);
    EXPECT_EQ(0, subelement.ptrs);
    EXPECT_EQ(400+i, capn_read32(subelement, 0));
  }

  list = capn_getp(ptr, 3, 1);
  EXPECT_EQ(CAPN_PTR_LIST, list.type);
  EXPECT_EQ(5, list.len);
  for (int i = 0; i < 5; i++) {
    capn_list16 element = {capn_getp(list, i, 1)};
    EXPECT_EQ(CAPN_LIST, element.p.type);
    EXPECT_EQ(i+1, element.p.len);
    EXPECT_EQ(2, element.p.datasz);
    EXPECT_EQ(0, element.p.ptrs);
    for (int j = 0; j <= i; j++) {
      EXPECT_EQ(500+j, capn_get16(element, j));
    }
  }

  capn_ptr recurse = capn_getp(ptr, 4, 1);
  EXPECT_EQ(CAPN_STRUCT, recurse.type);
  EXPECT_EQ(0, recurse.datasz);
  EXPECT_EQ(2, recurse.ptrs);
  capn_ptr recurse_mbr = capn_getp(recurse, 0, 1);
  EXPECT_EQ(CAPN_STRUCT, recurse_mbr.type);
  EXPECT_EQ(0, recurse_mbr.datasz);
  EXPECT_EQ(2, recurse_mbr.ptrs);
  EXPECT_EQ(recurse.seg, recurse_mbr.seg);
  EXPECT_EQ(recurse.data, recurse_mbr.data);
  EXPECT_EQ(CAPN_NULL, capn_getp(recurse, 1, 1).type);
}
Exemple #10
0
uint32_t FNV32_step8(uint32_t current, uint8_t byte) {
  return (current ^ byte) * UINT32_C(16777619);
}
Exemple #11
0
int
main()	{
	int	status = 0;		/* exit status to be returned */

    OPENTEST();
	
	/* <stdint.h> features: */

	fprintf(outfile,"CHAR_BIT=%u\n", (unsigned)CHAR_BIT );
	fprintf(outfile,"sizeof(char)=%u\n", (unsigned)sizeof(char));	/* s.b. 1 */
	fprintf(outfile,"sizeof(short)=%u\n", (unsigned)sizeof(short));
	fprintf(outfile,"sizeof(int)=%u\n", (unsigned)sizeof(int));
	fprintf(outfile,"sizeof(long)=%u\n", (unsigned)sizeof(long));
#ifdef	__Q8_QT
	fprintf(outfile,"sizeof(long long)=%u\n", (unsigned)sizeof(__Q8_QT));
#else
	fprintf(outfile,"*** long long isn't defined ***\n");
#endif
	fprintf(outfile,"sizeof(intmax_t)=%u\n", (unsigned)sizeof(intmax_t));
	fprintf(outfile,"sizeof(ptrdiff_t)=%u\n", (unsigned)sizeof(ptrdiff_t));
	fprintf(outfile,"sizeof(size_t)=%u\n", (unsigned)sizeof(size_t));
	fprintf(outfile,"sizeof(sig_atomic_t)=%u\n", (unsigned)sizeof(sig_atomic_t));
	fprintf(outfile,"sizeof(wchar_t)=%u\n", (unsigned)sizeof(wchar_t));
#if	defined(WINT_MAX) || __STDC_VERSION__ >= 199901
	fprintf(outfile,"sizeof(wint_t)=%u\n", (unsigned)sizeof(wint_t));
#else
	fprintf(outfile,"*** wint_t isn't defined ***\n");
	status = EXIT_FAILURE;
#endif
#ifdef	INT8_MAX
	fprintf(outfile,"sizeof(int8_t)=%u\n", (unsigned)sizeof(int8_t));
	fprintf(outfile,"sizeof(uint8_t)=%u\n", (unsigned)sizeof(uint8_t));
#endif
#ifdef	INT9_MAX
	fprintf(outfile,"sizeof(int9_t)=%u\n", (unsigned)sizeof(int9_t));
	fprintf(outfile,"sizeof(uint9_t)=%u\n", (unsigned)sizeof(uint9_t));
#endif
#ifdef	INT12_MAX
	fprintf(outfile,"sizeof(int12_t)=%u\n", (unsigned)sizeof(int12_t));
	fprintf(outfile,"sizeof(uint12_t)=%u\n", (unsigned)sizeof(uint12_t));
#endif
#ifdef	INT16_MAX
	fprintf(outfile,"sizeof(int16_t)=%u\n", (unsigned)sizeof(int16_t));
	fprintf(outfile,"sizeof(uint16_t)=%u\n", (unsigned)sizeof(uint16_t));
#endif
#ifdef	INT18_MAX
	fprintf(outfile,"sizeof(int18_t)=%u\n", (unsigned)sizeof(int18_t));
	fprintf(outfile,"sizeof(uint18_t)=%u\n", (unsigned)sizeof(uint18_t));
#endif
#ifdef	INT24_MAX
	fprintf(outfile,"sizeof(int24_t)=%u\n", (unsigned)sizeof(int24_t));
	fprintf(outfile,"sizeof(uint24_t)=%u\n", (unsigned)sizeof(uint24_t));
#endif
#ifdef	INT32_MAX
	fprintf(outfile,"sizeof(int32_t)=%u\n", (unsigned)sizeof(int32_t));
	fprintf(outfile,"sizeof(uint32_t)=%u\n", (unsigned)sizeof(uint32_t));
#endif
#ifdef	INT36_MAX
	fprintf(outfile,"sizeof(int36_t)=%u\n", (unsigned)sizeof(int36_t));
	fprintf(outfile,"sizeof(uint36_t)=%u\n", (unsigned)sizeof(uint36_t));
#endif
#ifdef	INT40_MAX
	fprintf(outfile,"sizeof(int40_t)=%u\n", (unsigned)sizeof(int40_t));
	fprintf(outfile,"sizeof(uint40_t)=%u\n", (unsigned)sizeof(uint40_t));
#endif
#ifdef	INT48_MAX
	fprintf(outfile,"sizeof(int48_t)=%u\n", (unsigned)sizeof(int48_t));
	fprintf(outfile,"sizeof(uint48_t)=%u\n", (unsigned)sizeof(uint48_t));
#endif
#ifdef	INT60_MAX
	fprintf(outfile,"sizeof(int60_t)=%u\n", (unsigned)sizeof(int60_t));
	fprintf(outfile,"sizeof(uint60_t)=%u\n", (unsigned)sizeof(uint60_t));
#endif
#ifdef	INT64_MAX
	fprintf(outfile,"sizeof(int64_t)=%u\n", (unsigned)sizeof(int64_t));
	fprintf(outfile,"sizeof(uint64_t)=%u\n", (unsigned)sizeof(uint64_t));
#endif
#ifdef	INT72_MAX
	fprintf(outfile,"sizeof(int72_t)=%u\n", (unsigned)sizeof(int72_t));
	fprintf(outfile,"sizeof(uint72_t)=%u\n", (unsigned)sizeof(uint72_t));
#endif
#ifdef	INT128_MAX
	fprintf(outfile,"sizeof(int128_t)=%u\n", (unsigned)sizeof(int128_t));
	fprintf(outfile,"sizeof(uint128_t)=%u\n", (unsigned)sizeof(uint128_t));
#endif
	fprintf(outfile,"sizeof(int_least8_t)=%u\n", (unsigned)sizeof(int_least8_t));
	fprintf(outfile,"sizeof(uint_least8_t)=%u\n", (unsigned)sizeof(uint_least8_t));
	fprintf(outfile,"sizeof(int_least16_t)=%u\n", (unsigned)sizeof(int_least16_t));
	fprintf(outfile,"sizeof(uint_least16_t)=%u\n", (unsigned)sizeof(uint_least16_t));
	fprintf(outfile,"sizeof(int_least32_t)=%u\n", (unsigned)sizeof(int_least32_t));
	fprintf(outfile,"sizeof(uint_least32_t)=%u\n", (unsigned)sizeof(uint_least32_t));
#ifdef	INT_LEAST64_MAX
	fprintf(outfile,"sizeof(int_least64_t)=%u\n", (unsigned)sizeof(int_least64_t));
	fprintf(outfile,"sizeof(uint_least64_t)=%u\n", (unsigned)sizeof(uint_least64_t));
#else
	fprintf(outfile,"*** uint_least64_t isn't defined ***\n");
	status = EXIT_FAILURE;
#endif
#ifdef	INT_LEAST128_MAX
	fprintf(outfile,"sizeof(int_least128_t)=%u\n", (unsigned)sizeof(int_least128_t));
	fprintf(outfile,"sizeof(uint_least128_t)=%u\n",
		(unsigned)sizeof(uint_least128_t));
#endif
	fprintf(outfile,"sizeof(int_fast8_t)=%u\n", (unsigned)sizeof(int_fast8_t));
	fprintf(outfile,"sizeof(uint_fast8_t)=%u\n", (unsigned)sizeof(uint_fast8_t));
	fprintf(outfile,"sizeof(int_fast16_t)=%u\n", (unsigned)sizeof(int_fast16_t));
	fprintf(outfile,"sizeof(uint_fast16_t)=%u\n", (unsigned)sizeof(uint_fast16_t));
	fprintf(outfile,"sizeof(int_fast32_t)=%u\n", (unsigned)sizeof(int_fast32_t));
	fprintf(outfile,"sizeof(uint_fast32_t)=%u\n", (unsigned)sizeof(uint_fast32_t));
#ifdef	INT_FAST64_MAX
	fprintf(outfile,"sizeof(int_fast64_t)=%u\n", (unsigned)sizeof(int_fast64_t));
	fprintf(outfile,"sizeof(uint_fast64_t)=%u\n", (unsigned)sizeof(uint_fast64_t));
#else
	fprintf(outfile,"*** int_fast64_t isn't defined ***\n");
	status = EXIT_FAILURE;
#endif
#ifdef	INT_FAST128_MAX
	fprintf(outfile,"sizeof(int_fast128_t)=%u\n", (unsigned)sizeof(int_fast128_t));
	fprintf(outfile,"sizeof(uint_fast128_t)=%u\n", (unsigned)sizeof(uint_fast128_t));
#endif
#if	defined(INTPTR_MAX)
	fprintf(outfile,"sizeof(intptr_t)=%u\n", (unsigned)sizeof(intptr_t));
#if	defined(UINTPTR_MAX)
	fprintf(outfile,"sizeof(uintptr_t)=%u\n", (unsigned)sizeof(uintptr_t));
#else
	fprintf(outfile,"*** intptr_t is defined but uintptr_t isn't ***\n");
	status = EXIT_FAILURE;
#endif
#elif	defined(UINTPTR_MAX)
	fprintf(outfile,"sizeof(uintptr_t)=%u\n", (unsigned)sizeof(uintptr_t));
	fprintf(outfile,"*** uintptr_t is defined but intptr_t isn't ***\n");
	status = EXIT_FAILURE;
#else
	fprintf(outfile,"*** neither intptr_t nor uintptr_t is defined ***\n");
	status = EXIT_FAILURE;
#endif
#ifdef	INTMAX_MAX
	fprintf(outfile,"sizeof(intmax_t)=%u\n", (unsigned)sizeof(intmax_t));
	fprintf(outfile,"sizeof(uintmax_t)=%u\n", (unsigned)sizeof(uintmax_t));
#else
	fprintf(outfile,"*** intmax_t isn't defined ***\n");
	status = EXIT_FAILURE;
#endif

#ifdef	INT8_MAX
	fprintf(outfile,"INT8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT8_MIN);
	fprintf(outfile,"INT8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT8_MAX);
	fprintf(outfile,"UINT8_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT8_MAX);
#endif
#ifdef	INT9_MAX
	fprintf(outfile,"INT9_MIN=%"PRIdMAX"\n", (__Q8_MT)INT9_MIN);
	fprintf(outfile,"INT9_MAX=%"PRIdMAX"\n", (__Q8_MT)INT9_MAX);
	fprintf(outfile,"UINT9_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT9_MAX);
#endif
#ifdef	INT12_MAX
	fprintf(outfile,"INT12_MIN=%"PRIdMAX"\n", (__Q8_MT)INT12_MIN);
	fprintf(outfile,"INT12_MAX=%"PRIdMAX"\n", (__Q8_MT)INT12_MAX);
	fprintf(outfile,"UINT12_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT12_MAX);
#endif
#ifdef	INT16_MAX
	fprintf(outfile,"INT16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT16_MIN);
	fprintf(outfile,"INT16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT16_MAX);
	fprintf(outfile,"UINT16_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT16_MAX);
#endif
#ifdef	INT18_MAX
	fprintf(outfile,"INT18_MIN=%"PRIdMAX"\n", (__Q8_MT)INT18_MIN);
	fprintf(outfile,"INT18_MAX=%"PRIdMAX"\n", (__Q8_MT)INT18_MAX);
	fprintf(outfile,"UINT18_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT18_MAX);
#endif
#ifdef	INT24_MAX
	fprintf(outfile,"INT24_MIN=%"PRIdMAX"\n", (__Q8_MT)INT24_MIN);
	fprintf(outfile,"INT24_MAX=%"PRIdMAX"\n", (__Q8_MT)INT24_MAX);
	fprintf(outfile,"UINT24_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT24_MAX);
#endif
#ifdef	INT32_MAX
	fprintf(outfile,"INT32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT32_MIN);
	fprintf(outfile,"INT32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT32_MAX);
	fprintf(outfile,"UINT32_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT32_MAX);
#endif
#ifdef	INT36_MAX
	fprintf(outfile,"INT36_MIN=%"PRIdMAX"\n", (__Q8_MT)INT36_MIN);
	fprintf(outfile,"INT36_MAX=%"PRIdMAX"\n", (__Q8_MT)INT36_MAX);
	fprintf(outfile,"UINT36_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT36_MAX);
#endif
#ifdef	INT40_MAX
	fprintf(outfile,"INT40_MIN=%"PRIdMAX"\n", (__Q8_MT)INT40_MIN);
	fprintf(outfile,"INT40_MAX=%"PRIdMAX"\n", (__Q8_MT)INT40_MAX);
	fprintf(outfile,"UINT40_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT40_MAX);
#endif
#ifdef	INT48_MAX
	fprintf(outfile,"INT48_MIN=%"PRIdMAX"\n", (__Q8_MT)INT48_MIN);
	fprintf(outfile,"INT48_MAX=%"PRIdMAX"\n", (__Q8_MT)INT48_MAX);
	fprintf(outfile,"UINT48_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT48_MAX);
#endif
#ifdef	INT60_MAX
	fprintf(outfile,"INT60_MIN=%"PRIdMAX"\n", (__Q8_MT)INT60_MIN);
	fprintf(outfile,"INT60_MAX=%"PRIdMAX"\n", (__Q8_MT)INT60_MAX);
	fprintf(outfile,"UINT60_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT60_MAX);
#endif
#ifdef	INT64_MAX
	fprintf(outfile,"INT64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT64_MIN);
	fprintf(outfile,"INT64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT64_MAX);
	fprintf(outfile,"UINT64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT64_MAX);
#endif
#ifdef	INT72_MAX
	fprintf(outfile,"INT72_MIN=%"PRIdMAX"\n", (__Q8_MT)INT72_MIN);
	fprintf(outfile,"INT72_MAX=%"PRIdMAX"\n", (__Q8_MT)INT72_MAX);
	fprintf(outfile,"UINT72_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT72_MAX);
#endif
#ifdef	INT128_MAX
	fprintf(outfile,"INT128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT128_MIN);
	fprintf(outfile,"INT128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT128_MAX);
	fprintf(outfile,"UINT128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT128_MAX);
#endif
	fprintf(outfile,"INT_LEAST8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST8_MIN);
	fprintf(outfile,"INT_LEAST8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST8_MAX);
	fprintf(outfile,"UINT_LEAST8_MAX=%"PRIuMAX"\n",
		(U__Q8_MT)UINT_LEAST8_MAX);
	fprintf(outfile,"INT_LEAST16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST16_MIN);
	fprintf(outfile,"INT_LEAST16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST16_MAX);
	fprintf(outfile,"UINT_LEAST16_MAX=%"PRIuMAX"\n",
		(U__Q8_MT)UINT_LEAST16_MAX);
	fprintf(outfile,"INT_LEAST32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST32_MIN);
	fprintf(outfile,"INT_LEAST32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST32_MAX);
	fprintf(outfile,"UINT_LEAST32_MAX=%"PRIuMAX"\n",
		(U__Q8_MT)UINT_LEAST32_MAX);
#ifdef	INT_LEAST64_MAX
	fprintf(outfile,"INT_LEAST64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST64_MIN);
	fprintf(outfile,"INT_LEAST64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST64_MAX);
	fprintf(outfile,"UINT_LEAST64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_LEAST64_MAX);
#endif
#ifdef	INT_LEAST128_MAX
	fprintf(outfile,"INT_LEAST128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST128_MIN);
	fprintf(outfile,"INT_LEAST128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_LEAST128_MAX);
	fprintf(outfile,"UINT_LEAST128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_LEAST128_MAX);
#endif
	fprintf(outfile,"INT_FAST8_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST8_MIN);
	fprintf(outfile,"INT_FAST8_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST8_MAX);
	fprintf(outfile,"UINT_FAST8_MAX=%"PRIuMAX"\n",
		(U__Q8_MT)UINT_FAST8_MAX);
	fprintf(outfile,"INT_FAST16_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST16_MIN);
	fprintf(outfile,"INT_FAST16_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST16_MAX);
	fprintf(outfile,"UINT_FAST16_MAX=%"PRIuMAX"\n",
		(U__Q8_MT)UINT_FAST16_MAX);
	fprintf(outfile,"INT_FAST32_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST32_MIN);
	fprintf(outfile,"INT_FAST32_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST32_MAX);
	fprintf(outfile,"UINT_FAST32_MAX=%"PRIuMAX"\n",
		(U__Q8_MT)UINT_FAST32_MAX);
#ifdef	INT_FAST64_MAX
	fprintf(outfile,"INT_FAST64_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST64_MIN);
	fprintf(outfile,"INT_FAST64_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST64_MAX);
	fprintf(outfile,"UINT_FAST64_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_FAST64_MAX);
#endif
#ifdef	INT_FAST128_MAX
	fprintf(outfile,"INT_FAST128_MIN=%"PRIdMAX"\n", (__Q8_MT)INT_FAST128_MIN);
	fprintf(outfile,"INT_FAST128_MAX=%"PRIdMAX"\n", (__Q8_MT)INT_FAST128_MAX);
	fprintf(outfile,"UINT_FAST128_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINT_FAST128_MAX);
#endif
#ifdef	INTPTR_MAX
	fprintf(outfile,"INTPTR_MIN=%"PRIdMAX"\n", (__Q8_MT)INTPTR_MIN);
	fprintf(outfile,"INTPTR_MAX=%"PRIdMAX"\n", (__Q8_MT)INTPTR_MAX);
#endif
#ifdef	UINTPTR_MAX
	fprintf(outfile,"UINTPTR_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINTPTR_MAX);
#endif
#ifdef	INTMAX_MAX
	fprintf(outfile,"INTMAX_MIN=%"PRIdMAX"\n", (__Q8_MT)INTMAX_MIN);
	fprintf(outfile,"INTMAX_MAX=%"PRIdMAX"\n", (__Q8_MT)INTMAX_MAX);
	fprintf(outfile,"UINTMAX_MAX=%"PRIuMAX"\n", (U__Q8_MT)UINTMAX_MAX);
#endif
#ifdef	PTRDIFF_MAX
	fprintf(outfile,"PTRDIFF_MIN=%"PRIdMAX"\n", (__Q8_MT)PTRDIFF_MIN);
	fprintf(outfile,"PTRDIFF_MAX=%"PRIdMAX"\n", (__Q8_MT)PTRDIFF_MAX);
#endif
#ifdef	SIG_ATOMIC_MAX
#if	SIG_ATOMIC_MIN < 0
	fprintf(outfile,"SIG_ATOMIC_MIN=%"PRIdMAX"\n", (__Q8_MT)SIG_ATOMIC_MIN);
	fprintf(outfile,"SIG_ATOMIC_MAX=%"PRIdMAX"\n", (__Q8_MT)SIG_ATOMIC_MAX);
#else
	fprintf(outfile,"SIG_ATOMIC_MIN=%"PRIuMAX"\n", (U__Q8_MT)SIG_ATOMIC_MIN);
	fprintf(outfile,"SIG_ATOMIC_MAX=%"PRIuMAX"\n", (U__Q8_MT)SIG_ATOMIC_MAX);
#endif
#endif
#ifdef	SIZE_MAX
	fprintf(outfile,"SIZE_MAX=%"PRIuMAX"\n", (U__Q8_MT)SIZE_MAX);
#endif

#ifdef	WCHAR_MAX
#if	WCHAR_MIN < 0
	fprintf(outfile,"WCHAR_MIN=%"PRIdMAX"\n", (__Q8_MT)WCHAR_MIN);
	fprintf(outfile,"WCHAR_MAX=%"PRIdMAX"\n", (__Q8_MT)WCHAR_MAX);
#else
	fprintf(outfile,"WCHAR_MIN=%"PRIuMAX"\n", (U__Q8_MT)WCHAR_MIN);
	fprintf(outfile,"WCHAR_MAX=%"PRIuMAX"\n", (U__Q8_MT)WCHAR_MAX);
#endif
#endif
#ifdef	WINT_MAX
#if	WINT_MIN < 0
	fprintf(outfile,"WINT_MIN=%"PRIdMAX"\n", (__Q8_MT)WINT_MIN);
	fprintf(outfile,"WINT_MAX=%"PRIdMAX"\n", (__Q8_MT)WINT_MAX);
#else
	fprintf(outfile,"WINT_MIN=%"PRIuMAX"\n", (U__Q8_MT)WINT_MIN);
	fprintf(outfile,"WINT_MAX=%"PRIuMAX"\n", (U__Q8_MT)WINT_MAX);
#endif
#endif

	/*
		7.18.4	Macros for integer constants
	*/

	/* INTn_C for n=8 and 16 were at one point unimplementable
	   on most platforms, so they're treated as "optional": */
#ifdef	INT8_C
	if ( INT8_C(-123) != -123 )
		fprintf(outfile,"*** INT8_C(-123) produced %"PRIdMAX" ***\n",
		       (__Q8_MT)INT8_C(-123)
		      );
	if ( UINT8_C(123) != 123 )
		fprintf(outfile,"*** UINT8_C(123) produced %"PRIuMAX" ***\n",
		       (U__Q8_MT)UINT8_C(123)
		      );
#endif
#ifdef	INT16_C
	if ( INT16_C(-12345) != -12345 )
		fprintf(outfile,"*** INT16_C(-12345) produced %"PRIdMAX" ***\n",
		       (__Q8_MT)INT16_C(-12345)
		      );
	if ( UINT16_C(12345) != 12345 )
		fprintf(outfile,"*** UINT16_C(12345) produced %"PRIuMAX" ***\n",
		       (U__Q8_MT)UINT16_C(12345)
		      );
#endif
	if ( INT32_C(-123456789) != -123456789 )
		fprintf(outfile,"*** INT32_C(-123456789) produced %"PRIdMAX" ***\n",
		       (__Q8_MT)INT32_C(-123456789)
		      );
	if ( UINT32_C(123456789) != 123456789 )
		fprintf(outfile,"*** UINT32_C(123456789) produced %"PRIuMAX" ***\n",
		       (U__Q8_MT)UINT32_C(123456789)
		      );
#ifdef	INT_LEAST64_MAX
	if ( INT64_C(-1234567890123456789) != -1234567890123456789 )
		fprintf(outfile,"*** INT64_C(-1234567890123456789) produced %"PRIdMAX
		       " ***\n",
		       (__Q8_MT)INT64_C(-1234567890123456789)
		      );
	if ( UINT64_C(1234567890123456789) != 1234567890123456789 )
		fprintf(outfile,"*** UINT64_C(1234567890123456789) produced %"PRIuMAX
		       " ***\n",
		       (U__Q8_MT)UINT64_C(1234567890123456789)
		      );
#endif
#ifdef	INTMAX_MAX
	if ( INTMAX_C(-1234567890123456789) != -1234567890123456789 )
		fprintf(outfile,"*** INTMAX_C(-1234567890123456789) produced %"PRIdMAX
		       " ***\n",
		       (__Q8_MT)INTMAX_C(-1234567890123456789)
		      );
	if ( UINTMAX_C(1234567890123456789) != 1234567890123456789 )
		fprintf(outfile,"*** UINTMAX_C(1234567890123456789) produced %"PRIuMAX
		       " ***\n",
		       (U__Q8_MT)UINTMAX_C(1234567890123456789)
		      );
#endif

	/* <inttypes.h> features: */

#if	__STDC_VERSION__ >= 199901
	fprintf(outfile,"sizeof(imaxdiv_t)=%u\n", (unsigned)sizeof(imaxdiv_t));
#endif

	/*
		7.8.1	Macros for format specifiers
	*/

	{
	/* scanf these strings */
	static const char	in_dn[] = "Z119bZ";
	static const char	in_dmo[] = "Z-0119bZ";
	static const char	in_dspx[] = "Z \t\n +0X119bZ";
	static const char	in_dsmx[] = "Z \t\n -0x119bZ";
	static const char	in_dsn[] = "Z \t\n 119bZ";
	static const char	in_dp[] = "Z+119bZ";
	static const char	in_dpx[] = "Z+0X119bz";

	/* sprintf into this */
	static char		buffer[1024];

#if 1

#define	SCAN(buf,fs,var,exp)	if ( sscanf(buf, "Z%" fs, &var) != 1 ) \
					{ \
					fprintf(outfile,"***%s=",fs, STR_SUB(fs) \
					       " failed ***\n" \
					      ); \
					status = EXIT_FAILURE; \
					} \
				else if ( var != (exp) ) \
					{ \
					fprintf(outfile,"***%s=",fs,  STR_SUB(fs) \
					       " should be: " STR_SUB(exp) \
					       ", was: %" fs " ***\n", var \
					      ); \
					status = EXIT_FAILURE; \
					} \
				else	/* for trailing semicolon */

#define	PRINT(fs,var,exp)	if ( sprintf(buffer, "%" fs, var ) <= 0 ) \
					{ \
					fprintf(outfile,"***%s=",fs, STR_SUB(fs) \
					       " failed ***\n" \
					      ); \
					status = EXIT_FAILURE; \
					} \
				else if ( strcmp(buffer, STR_SUB(exp)) != 0 ) \
					{ \
					fprintf(outfile,"***%s=",fs,  STR_SUB(fs) \
					       " should be: " STR_SUB(exp) \
					       ", was: %s ***\n", buffer \
					      ); \
					status = EXIT_FAILURE; \
					} \
				else	/* for trailing semicolon */

#else
								 
#define	SCAN(buf,fs,var,exp)
#define	PRINT(fs,var,exp)

#endif
								 
#ifdef	SCNo32

	SCAN(in_dn, SCNo32, int32, 9);

#endif
#ifdef	PRIo32
	PRINT(PRIo32, int32, 11);
#endif
	SCAN(in_dmo, SCNiLEAST16, intl16, -9);
	SCAN(in_dspx, SCNdLEAST16, intl16, 0);
	SCAN(in_dsmx, SCNiLEAST16, intl16, -4507);
	PRINT(PRIdLEAST16, intl16, -4507);
	PRINT(PRIiLEAST16, intl16, -4507);
	SCAN(in_dsn, SCNxLEAST16, uintl16, 4507);
	PRINT(PRIoLEAST16, uintl16, 10633);
	PRINT(PRIuLEAST16, uintl16, 4507);
	PRINT(PRIxLEAST16, uintl16, 119b);
	PRINT(PRIXLEAST16, uintl16, 119B);
	SCAN(in_dp, SCNxFAST16, uintf16, 4507);
	PRINT(PRIxFAST16, uintf16, 119b);
#ifdef	SCNdMAX
	SCAN(in_dp, SCNdMAX, intmax, 119);
#endif
#ifdef	PRIiMAX
	PRINT(PRIiMAX, intmax, 119);
#endif
#ifdef	SCNoMAX
	SCAN(in_dpx, SCNoMAX, uintmax, 0);
#endif
#ifdef	PRIxMAX
	PRINT(PRIxMAX, uintmax, 0);
#endif
	/* Obviously there should be a much larger battery of such tests. */
	}

#if	defined(INTMAX_MAX)		/* <inttypes.h> has C99 features */
	/*
		7.8.2	Functions for greatest-width integer types
	*/

	{
	static struct
		{
		intmax_t	input;
		intmax_t	expect;
		}	abs_data[] =
		{
#ifdef	INT8_MAX
	  { INT8_MAX,		INT8_MAX,   },
	  { -INT8_MAX,		INT8_MAX,   },
	 { 	UINT8_MAX,		UINT8_MAX,  },
#endif

#if 0
  
#ifdef	INT16_MAX
	 { 	INT16_MAX,		INT16_MAX,  },
	 { 	-INT16_MAX,		INT16_MAX,  },
	 { 	UINT16_MAX,		UINT16_MAX, },
#endif
#ifdef	INT32_MAX
	 { 	INT32_MAX,		INT32_MAX,  },
	 { 	-INT32_MAX,		INT32_MAX,  },
#ifdef	INT_LEAST64_MAX			/* else might support only 32 bits */
	 { 	UINT32_MAX,		UINT32_MAX, },
#endif
#endif
#ifdef	INT64_MAX
	 { 	INT64_MAX,		INT64_MAX,  },
	 { 	-INT64_MAX,		INT64_MAX,  },
#endif
	 { 	INT_LEAST8_MAX,		INT_LEAST8_MAX,      },
	 { 	-INT_LEAST8_MAX,	INT_LEAST8_MAX,      },
	 { 	UINT_LEAST8_MAX,	UINT_LEAST8_MAX,     },
	 { 	INT_LEAST16_MAX,	INT_LEAST16_MAX,     },
	 { 	-INT_LEAST16_MAX,	INT_LEAST16_MAX,     },
	 { 	UINT_LEAST16_MAX,	UINT_LEAST16_MAX,    },
	 { 	INT_LEAST32_MAX,	INT_LEAST32_MAX,     },
	 { 	-INT_LEAST32_MAX,	INT_LEAST32_MAX,     },
#ifdef	INT_LEAST64_MAX
	 { 	UINT_LEAST32_MAX,	UINT_LEAST32_MAX,    },
	 { 	INT_LEAST64_MAX,	INT_LEAST64_MAX,     },
	 { 	-INT_LEAST64_MAX,	INT_LEAST64_MAX,     },
#endif
	 { 	INT_FAST8_MAX,		INT_FAST8_MAX,       },
	 { 	-INT_FAST8_MAX,	INT_FAST8_MAX,           },
	 { 	UINT_FAST8_MAX,	UINT_FAST8_MAX,          },
	 { 	INT_FAST16_MAX,	INT_FAST16_MAX,          },
	 { 	-INT_FAST16_MAX,	INT_FAST16_MAX,      },
	 { 	UINT_FAST16_MAX,	UINT_FAST16_MAX,     },
	 { 	INT_FAST32_MAX,	INT_FAST32_MAX,          },
	 { 	-INT_FAST32_MAX,	INT_FAST32_MAX,      },
#ifdef	INT_FAST64_MAX
	 { 	UINT_FAST32_MAX,	UINT_FAST32_MAX,     },
	 { 	INT_FAST64_MAX,	INT_FAST64_MAX,          },
	 { 	-INT_FAST64_MAX,	INT_FAST64_MAX,      },
#endif
#ifdef	INTPTR_MAX
	 { 	INTPTR_MAX,		INTPTR_MAX,              },
	 { 	-INTPTR_MAX,		INTPTR_MAX,          },
#endif
#ifdef	UINTPTR_MAX
	 { 	UINTPTR_MAX,		UINTPTR_MAX,         },
#endif
	 { 	INTMAX_MAX,		INTMAX_MAX,              },
#ifdef	PTRDIFF_MAX
	 { 	PTRDIFF_MAX,		PTRDIFF_MAX,         },
#endif
#ifdef	SIG_ATOMIC_MAX
	 { 	SIG_ATOMIC_MAX,		SIG_ATOMIC_MAX,      },
#if	SIG_ATOMIC_MIN < 0
	 { 	-SIG_ATOMIC_MAX,	SIG_ATOMIC_MAX,      },
#endif
#endif
#ifdef	SIZE_MAX
	 { 	SIZE_MAX,		SIZE_MAX,                },
#endif
#ifdef	WCHAR_MAX
	 { 	WCHAR_MAX,		WCHAR_MAX,               },
#if	WCHAR_MIN < 0
	 { 	-WCHAR_MAX,		WCHAR_MAX,               },
#endif
#endif
#ifdef	WINT_MAX
	 { 	WINT_MAX,		WINT_MAX,                },
#if	WINT_MIN < 0
	 {  -WINT_MAX,		WINT_MAX,                },
#endif
#endif
	 { 	127,				127,                 },
	 { 	-127,				127,                 },
	 { 	128,				128,                 },
	 { 	-127-1,				128,                 },
	 { 	255,				255,                 },
	 { 	-256+1,				255,                 },
	 { 	256,				256,                 },
	 { 	-256,				256,                 },
	 { 	32767,				32767,               },
	 { 	-32767,				32767,               },
	 { 	32768,				32768,               },
	 { 	-32767-1,			32768,               },
	 { 	65535,				65535,               },
	 { 	-65536+1,			65535,               },
	 { 	65536,				65536,               },
	 { 	-65536,				65536,               },
	 { 	2147483647,			2147483647,          },
	 { 	-2147483647,			2147483647,      },
	 { 	2147483648,			2147483648,          },
	 { 	-2147483647-1,			2147483648,      },
#ifdef	INT_LEAST64_MAX			/* else might support only 32 bits */
	 { 	4294967295,			4294967295,          },
	 { 	-4294967296+1,			4294967295,      },
	 { 	4294967296,			4294967296,          },
	 { 	-4294967296,			4294967296,      },
	 { 	9223372036854775807,		9223372036854775807,    },
	 { 	-9223372036854775807,		9223372036854775807,    },
	 { 	1234567890123456789,		1234567890123456789,    },
	 { 	-1234567890123456789,		1234567890123456789,    },
#endif
	 { 	1,				1,                                  },
	 { 	-1,				1,                                  },
	 { 	2,				2,                                  },
	 { 	-2,				2,                                  },
	 { 	10,				10,                                 },
	 { 	-10,				10,                             },
	 { 	16,				16,                                 },
	 { 	-16,				16,                             },
#endif
		/* Other test cases can be added here. */
	 { 	0,		0	/* terminates the list */              },
		},	*adp = abs_data;

	do	{
		if ( (intmax = imaxabs(adp->input)) != adp->expect )
			{
			fprintf(outfile,"*** imaxabs(%"PRIdMAX") failed; should be: %"
			       PRIdMAX", was: %"PRIdMAX" ***\n",
			       adp->input, adp->expect, intmax
			      );
			status = EXIT_FAILURE;
			}
//		} while ( adp++->input != 0 );
		} while ( (adp++)->input != 0 );
	}

	{
	imaxdiv_t	result;
	static struct
		{
		intmax_t	numer;
		intmax_t	denom;
		intmax_t	exp_quot;
		intmax_t	exp_rem;
		}	div_data[] =
		{
	{	0, 1,				0, 0,   },
#if 0
	{	0, -1,				0, 0,   },
	{	0, 2,				0, 0,   },
	{	0, -2,				0, 0,   },
	{	0, 5,				0, 0,   },
	{	0, -5,				0, 0,   },
	{	1, 1,				1, 0,   },
	{	1, -1,				-1, 0,  },
	{	1, 2,				0, 1,   },
	{	1, -2,				0, 1,   },
	{	1, 5,				0, 1,   },
	{	1, -5,				0, 1,   },
	{	-1, 1,				-1, 0,  },
	{	-1, -1,				1, 0,   },
	{	-1, 2,				0, -1,  },
	{	-1, -2,				0, -1,  },
	{	-1, 5,				0, -1,  },
	{	-1, -5,				0, -1,  },
	{	2, 1,				2, 0,   },
	{	2, -1,				-2, 0,  },
	{	2, 2,				1, 0,   },
	{	2, -2,				-1, 0,  },
	{	2, 5,				0, 2,   },
	{	2, -5,				0, 2,   },
	{	-2, 1,				-2, 0,  },
	{	-2, -1,				2, 0,   },
	{	-2, 2,				-1, 0,  },
	{	-2, -2,				1, 0,   },
	{	-2, 5,				0, -2,  },
	{	-2, -5,				0, -2,  },
	{	17, 5,				3, 2,   },
	{	-17, -5,			3, -2,  },
	{	17, -5,				-3, 2,  },
	{	-17, 5,				-3, -2, },
	{	2147483647, 1,			2147483647, 0,         },
	{	-2147483647, 1,			-2147483647, 0,        },
	{	2147483648, 1,			2147483648, 0,         },
	{	-2147483647-1, 1,		-2147483647-1, 0,      },
	{	2147483647, 2,			1073741823, 1,         },
	{	-2147483647, 2,			-1073741823, -1,       },
	{	2147483648, 2,			1073741824, 0,         },
	{	-2147483647-1, 2,		-1073741824, 0,        },
#ifdef	INT_LEAST64_MAX			/* else might support only 32 bits */
	{	4294967295, 1,			4294967295, 0,         },
	{	-4294967296+1, 1,		-4294967296+1, 0,      },
	{	4294967296, 1,			4294967296, 0,         },
	{	-4294967296, 1,			-4294967296, 0,        },
	{	4294967295, -1,			-4294967296+1, 0,      },
	{	-4294967296+1, -1,		4294967295, 0,         },
	{	4294967296, -1,			-4294967296, 0,        },
	{	-4294967296, -1,		4294967296, 0,         },
	{	4294967295, 2,			2147483647, 1,         },
	{	-4294967296+1, 2,		-2147483647, -1,       },
	{	4294967296, 2,			2147483648, 0,         },
	{	-4294967296, 2,			-2147483647-1, 0,      },
	{	4294967295, 2147483647,		2, 1,              },
	{	-4294967296+1, 2147483647,	-2, -1,            },
	{	4294967296, 2147483647,		2, 2,              },
	{	-4294967296, 2147483647,	-2, -2,            },
	{	4294967295, -2147483647,	-2, 1,             },
	{	-4294967296+1, -2147483647,	2, -1,             },
	{	4294967296, -2147483647,	-2, 2,             },
	{	-4294967296, -2147483647,	2, -2,             },
	{	4294967295, 2147483648,		1, 2147483647,     },
	{	-4294967296+1, 2147483648,	-1, -2147483647,   },
	{	4294967296, 2147483648,		2, 0,              },
	{	-4294967296, 2147483648,	-2, 0,             },
	{	4294967295, -2147483647-1,	-1, 2147483647,    },
	{	-4294967296+1, -2147483647-1,	1, -2147483647,},
	{	4294967296, -2147483647-1,	-2, 0,             },
	{	-4294967296, -2147483647-1,	2, 0,              },
	{	9223372036854775807, 1,		9223372036854775807, 0,         },
	{	-9223372036854775807, 1,	-9223372036854775807, 0,        },
	{	9223372036854775807, 2,		4611686018427387903, 1,         },
	{	-9223372036854775807, 2,	-4611686018427387903, -1,       },
#endif
#endif
		/* There should be a much larger battery of such tests. */
	{	0, 0,		0, 0 },	/* 0 denom terminates the list */
		},	*ddp;

#if 0
	for ( ddp = div_data; ddp->denom != 0; ++ddp )
		if ( (result = imaxdiv(ddp->numer, ddp->denom)).quot
		     != ddp->exp_quot || result.rem != ddp->exp_rem
		   )	{
//			fprintf(outfile,"*** imaxdiv(%"PRIdMAX",%"PRIdMAX
//			       ") failed; should be: (%"PRIdMAX",%"PRIdMAX
//			       "), was: (%"PRIdMAX",%"PRIdMAX") ***\n",
//			       ddp->numer, ddp->denom, ddp->exp_quot,
//			       ddp->exp_rem, result.quot, result.rem
//			      );
			fprintf(outfile,"err:imaxdiv(%"PRIdMAX",%"PRIdMAX
			       ") = (%"PRIdMAX",%"PRIdMAX
			       "), is: (%"PRIdMAX",%"PRIdMAX")\n",
			       ddp->numer, ddp->denom, ddp->exp_quot,
			       ddp->exp_rem, result.quot, result.rem
			      );
			status = EXIT_FAILURE;
			}
#endif
	}
	
	{
	char		*endptr;
	wchar_t		*wendptr;
	static char	saved[64];	/* holds copy of input string */
	static wchar_t	wnptr[64];	/* holds wide copy of test string */
	static int	warned;		/* "warned for null endptr" flag */
	register int	i;
	static struct
		{
		char *		nptr;
		int		base;
		intmax_t	exp_val;
		int		exp_len;
		}	str_data[] =
		{
	{	"", 0,				0, 0,      },
	{	"", 2,				0, 0,      },
	{	"", 8,				0, 0,      },
	{	"", 9,				0, 0,      },
	{	"", 10,				0, 0,      },
	{	"", 16,				0, 0,      },
	{	"", 36,				0, 0,      },
	{	"0", 0,				0, 1,      },
	{	"0", 2,				0, 1,      },
	{	"0", 8,				0, 1,      },
	{	"0", 9,				0, 1,      },
	{	"0", 10,			0, 1,      },
	{	"0", 16,			0, 1,      },
	{	"0", 36,			0, 1,      },
	{	"+0", 0,			0, 2,      },
	{	"+0", 2,			0, 2,      },
	{	"+0", 8,			0, 2,      },
	{	"+0", 9,			0, 2,      },
	{	"+0", 10,			0, 2,      },
	{	"+0", 16,			0, 2,      },
	{	"+0", 36,			0, 2,      },
	{	"-0", 0,			0, 2,      },
	{	"-0", 2,			0, 2,      },
	{	"-0", 8,			0, 2,      },
	{	"-0", 9,			0, 2,      },
	{	"-0", 10,			0, 2,      },
	{	"-0", 16,			0, 2,      },
	{	"-0", 36,			0, 2,      },
	{	"Inf", 0,			0, 0,      },
	{	"Inf", 2,			0, 0,      },
	{	"Inf", 8,			0, 0,      },
	{	"Inf", 9,			0, 0,      },
	{	"Inf", 10,			0, 0,      },
	{	"Inf", 16,			0, 0,      },
	{	"Inf", 36,			24171, 3,  },
	{	"+Inf", 0,			0, 0,      },
	{	"+Inf", 2,			0, 0,      },
	{	"+Inf", 8,			0, 0,      },
	{	"+Inf", 9,			0, 0,      },
	{	"+Inf", 10,			0, 0,      },
	{	"+Inf", 16,			0, 0,      },
	{	"+Inf", 36,			24171, 4,  },
	{	"-Inf", 0,			0, 0,      },
	{	"-Inf", 2,			0, 0,      },
	{	"-Inf", 8,			0, 0,      },
	{	"-Inf", 9,			0, 0,      },
	{	"-Inf", 10,			0, 0,      },
	{	"-Inf", 16,			0, 0,      },
	{	"-Inf", 36,			-24171, 4, },
	{	"inf", 0,			0, 0,      },
	{	"inf", 2,			0, 0,      },
	{	"inf", 8,			0, 0,      },
	{	"inf", 9,			0, 0,      },
	{	"inf", 10,			0, 0,      },
	{	"inf", 16,			0, 0,      },
	{	"inf", 36,			24171, 3,  },
	{	"+inf", 0,			0, 0,      },
	{	"+inf", 2,			0, 0,      },
	{	"+inf", 8,			0, 0,      },
	{	"+inf", 9,			0, 0,      },
	{	"+inf", 10,			0, 0,      },
	{	"+inf", 16,			0, 0,      },
	{	"+inf", 36,			24171, 4,  },
	{	"-inf", 0,			0, 0,      },
	{	"-inf", 2,			0, 0,      },
	{	"-inf", 8,			0, 0,      },
	{	"-inf", 9,			0, 0,      },
	{	"-inf", 10,			0, 0,      },
	{	"-inf", 16,			0, 0,      },
	{	"-inf", 36,			-24171, 4, },
	{	"119b8Z", 0,			119, 3,         },
	{	"119bZ", 0,			119, 3,             },
	{	"-0119bZ", 0,			-9, 4,          },
	{	" \t\n 0X119bZ", 0,		4507, 10,       },
	{	" \t\n +0X119bZ", 0,		4507, 11,   },
	{	" \t\n -0x119bZ", 0,		-4507, 11,  },
	{	" \t\n 119bZ", 0,		119, 7,         },
	{	"+119bZ", 0,			119, 4,         },
	{	"+0X119bz", 0,			4507, 7,        },
	{	"119b8Z", 2,			3, 2,           },
	{	"119bZ", 2,			3, 2,               },
	{	"-0119bZ", 2,			-3, 4,          },
	{	" \t\n 0X119bZ", 2,		0, 5,           },
	{	" \t\n +0X119bZ", 2,		0, 6,       },
	{	" \t\n -0x119bZ", 2,		0, 6,       },
	{	" \t\n 119bZ", 2,		3, 6,           },
	{	"+119bZ", 2,			3, 3,           },
	{	"+0X119bz", 2,			0, 2,           },
	{	"119b8Z", 8,			9, 2,           },
	{	"119bZ", 8,			9, 2,               },
	{	"-0119bZ", 8,			-9, 4,          },
	{	" \t\n 0X119bZ", 8,		0, 5,           },
	{	" \t\n +0X119bZ", 8,		0, 6,       },
	{	" \t\n -0x119bZ", 8,		0, 6,       },
	{	" \t\n 119bZ", 8,		9, 6,           },
	{	"+119bZ", 8,			9, 3,           },
	{	"+0X119bz", 8,			0, 2,           },
	{	"119b8Z", 9,			10, 2,          },
	{	"119bZ", 9,			10, 2,              },
	{	"-0119bZ", 9,			-10, 4,         },
	{	" \t\n 0X119bZ", 9,		0, 5,           },
	{	" \t\n +0X119bZ", 9,		0, 6,       },
	{	" \t\n -0x119bZ", 9,		0, 6,       },
	{	" \t\n 119bZ", 9,		10, 6,          },
	{	"+119bZ", 9,			10, 3,          },
	{	"+0X119bz", 9,			0, 2,           },
	{	"119b8Z", 10,			119, 3,         },
	{	"119bZ", 10,			119, 3,         },
	{	"-0119bZ", 10,			-119, 5,        },
	{	" \t\n 0X119bZ", 10,		0, 5,       },
	{	" \t\n +0X119bZ", 10,		0, 6,       },
	{	" \t\n -0x119bZ", 10,		0, 6,       },
	{	" \t\n 119bZ", 10,		119, 7,         },
	{	"+119bZ", 10,			119, 4,         },
	{	"+0X119bz", 10,			0, 2,           },
	{	"119b8Z", 16,			72120, 5,       },
	{	"119bZ", 16,			4507, 4,        },
	{	"-0119bZ", 16,			-4507, 6,       },
	{	" \t\n 0X119bZ", 16,		4507, 10,   },
	{	" \t\n +0X119bZ", 16,		4507, 11,   },
	{	" \t\n -0x119bZ", 16,		-4507, 11,  },
	{	" \t\n 119bZ", 16,		4507,8,         },
	{	"+119bZ", 16,			4507, 5,        },
	{	"+0X119bz", 16,			4507, 7,        },
	{	"119b8Z", 36,			62580275, 6,    },
	{	"119bZ", 36,			1738367, 5,     },
	{	"-0119bZ", 36,			-1738367, 7,                 },
	{	" \t\n 0X119bZ", 36,		1997122175, 11,          },
	{	" \t\n +0X119bZ", 36,		1997122175, 12,          },
	{	" \t\n -0x119bZ", 36,		-1997122175, 12,         },
	{	" \t\n 119bZ", 36,		1738367, 9,                  },
	{	"+119bZ", 36,			1738367, 6,                  },
	{	"+0X119bz", 36,			1997122175, 8,               },
	 	/* There should be a much larger battery of such tests. */
	{	"127", 0,			127, 3,                          },
	{	"-127", 0,			-127, 4,                         },
	{	"128", 0,			128, 3,                          },
	{	"-128", 0,			-127-1, 4,                       },
	{	"255", 0,			255, 3,                          },
	{	"-255", 0,			-255, 4,                         },
	{	"256", 0,			256, 3,                          },
	{	"-256", 0,			-255-1, 4,                       },
	{	"32767", 0,			32767, 5,                        },
	{	"-32767", 0,			-32767, 6,                   },
	{	"32768", 0,			32768, 5,                        },
	{	"-32768", 0,			-32767-1, 6,                 },
	{	"65535", 0,			65535, 5,                        },
	{	"-65535", 0,			-65536+1, 6,                 },
	{	"65536", 0,			65536, 5,                        },
	{	"-65536", 0,			-65536, 6,                   },
	{	"2147483647", 0,		2147483647, 10,              },
	{	"-2147483647", 0,		-2147483647, 11,             },
	{	"2147483648", 0,		2147483648, 10,              },
	{	"-2147483648", 0,		-2147483647-1, 11,           },
	{	"4294967295", 0,		4294967295, 10,              },
	{	"-4294967295", 0,		-4294967296+1, 11,           },
	{	"4294967296", 0,		4294967296, 10,              },
	{	"-4294967296", 0,		-4294967296, 11,                        },
	{	"9223372036854775807", 0,	9223372036854775807, 19,            },
	{	"-9223372036854775807", 0,	-9223372036854775807, 20,           },
	{	"1234567890123456789", 0,	1234567890123456789, 19,            },
	{	"-1234567890123456789", 0,	-1234567890123456789, 20,           },
	{	"1", 0,				1, 1,                                       },
	{	"-1", 0,			-1, 2,                                      },
	{	"2", 0,				2, 1,                                       },
	{	"-2", 0,			-2, 2,                                      },
	{	"10", 0,			10, 2,                                      },
	{	"-10", 0,			-10, 3,                                     },
	{	"16", 0,			16, 2,                                      },
	{	"-16", 0,			-16, 3,                                     },
		/* Other test cases can be added here. */
	{	NULL, 0,	0, 0 },	/* terminates the list */
		},	*sdp;

	for ( sdp = str_data; sdp->nptr != NULL ; ++sdp )
		{
		/*
			7.8.2.3	The strtoimax and strtoumax functions
		*/

		strcpy(saved, sdp->nptr);

		errno = 0;		/* shouldn't be changed */

		if ( (intmax = strtoimax(sdp->nptr, &endptr, sdp->base))
		  != sdp->exp_val
		   )	{
			int	save = errno;

			fprintf(outfile,"*** strtoimax(%s,,%d) failed; should be: %"
			       PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr,
			       sdp->base, sdp->exp_val, intmax
			      );
			status = EXIT_FAILURE;
			errno = save;
			}
		else if ( endptr != sdp->nptr + sdp->exp_len )
			{
			int	save = errno;

			fprintf(outfile,"*** strtoimax(%s,,%d) returned wrong endptr"
			       " ***\n", sdp->nptr, sdp->base
			      );
			status = EXIT_FAILURE;
			errno = save;
			}

		if ( errno != 0 )
			{
			fprintf(outfile,"*** strtoimax modified errno ***\n");
			status = EXIT_FAILURE;
			}

		if ( strcmp(sdp->nptr, saved) != 0 )
			{
			fprintf(outfile,"*** strtoimax modified its input ***\n");
			status = EXIT_FAILURE;
			strcpy(saved, sdp->nptr);
			}

		if ( sdp->exp_val >= 0 )	/* else some sign extension */
			{
			errno = 0;	/* shouldn't be changed */

			if ( (uintmax = strtoumax(sdp->nptr, &endptr, sdp->base
						 )
			     ) != sdp->exp_val
			   )	{
				int	save = errno;

				fprintf(outfile,"*** strtoumax(%s,,%d) failed; "
				       "should be: %"PRIuMAX", was: %"PRIuMAX
				       " ***\n", sdp->nptr, sdp->base,
				       sdp->exp_val, uintmax
				      );
				status = EXIT_FAILURE;
				errno = save;
				}
			else if ( endptr != sdp->nptr + sdp->exp_len )
				{
				int	save = errno;

				fprintf(outfile,"*** strtoumax(%s,,%d) returned wrong "
				       "endptr ***\n", sdp->nptr, sdp->base
				      );
				status = EXIT_FAILURE;
				errno = save;
				}

			if ( errno != 0 )
				{
				fprintf(outfile,"*** strtoumax modified errno ***\n");
				status = EXIT_FAILURE;
				}

			if ( strcmp(sdp->nptr, saved) != 0 )
				{
				fprintf(outfile,"*** strtoumax"
				       " modified its input ***\n"
				      );
				status = EXIT_FAILURE;
				strcpy(saved, sdp->nptr);
				}
			}

		/* tests for null endptr */

#define	WARN()	if (!warned) warned = 1, fprintf(outfile,"*** Using null endptr: ***\n")

		warned = 0;
		errno = 0;		/* shouldn't be changed */

		if ( (intmax = strtoimax(sdp->nptr, (char **)NULL, sdp->base))
		  != sdp->exp_val
		   )	{
			int	save = errno;

			WARN();
			fprintf(outfile,"*** strtoimax(%s,NULL,%d) failed; "
			       "should be: %"PRIdMAX", was: %"PRIdMAX" ***\n",
			       sdp->nptr, sdp->base, sdp->exp_val, intmax
			      );
			status = EXIT_FAILURE;
			errno = save;
			}

		if ( errno != 0 )
			{
			WARN();
			fprintf(outfile,"*** strtoimax modified errno ***\n");
			status = EXIT_FAILURE;
			}

		if ( strcmp(sdp->nptr, saved) != 0 )
			{
			WARN();
			fprintf(outfile,"*** strtoimax modified its input ***\n");
			status = EXIT_FAILURE;
			strcpy(saved, sdp->nptr);
			}

		if ( sdp->exp_val >= 0 )	/* else some sign extension */
			{
			errno = 0;	/* shouldn't be changed */

			if ( (uintmax = strtoumax(sdp->nptr, (char **)NULL,
						  sdp->base
						 )
			     ) != sdp->exp_val
			   )	{
				int	save = errno;

				WARN();
				fprintf(outfile,"*** strtoumax(%s,NULL,%d) failed; "
				       "should be: %"PRIuMAX", was: %"PRIuMAX
				       " ***\n", sdp->nptr, sdp->base,
				       sdp->exp_val, uintmax
				      );
				status = EXIT_FAILURE;
				errno = save;
				}

			 if ( errno != 0 )
				{
				WARN();
				fprintf(outfile,"*** strtoumax modified errno ***\n");
				status = EXIT_FAILURE;
				}

			 if ( strcmp(sdp->nptr, saved) != 0 )
				{
				WARN();
				fprintf(outfile,"*** strtoumax"
				       " modified its input ***\n"
				      );
				status = EXIT_FAILURE;
				strcpy(saved, sdp->nptr);
				}
			}

		/*
			7.8.2.4	The wcstoimax and wcstoumax functions
		*/

		for ( i = 0; i < 64; ++i )
			if ( (wnptr[i] = sdp->nptr[i]) == '\0' )
				break;

		errno = 0;		/* shouldn't be changed */

		if ( (intmax = wcstoimax(wnptr, &wendptr, sdp->base))
		  != sdp->exp_val
		   )	{
			int	save = errno;

			fprintf(outfile,"*** wcstoimax(%s,,%d) failed; should be: %"
			       PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr,
			       sdp->base, sdp->exp_val, intmax
			      );
			status = EXIT_FAILURE;
			errno = save;
			}
		else if ( wendptr != wnptr + sdp->exp_len )
			{
			int	save = errno;

			fprintf(outfile,"*** wcstoimax(%s,,%d) returned wrong endptr"
			       " ***\n", sdp->nptr, sdp->base
			      );
			status = EXIT_FAILURE;
			errno = save;
			}

		if ( errno != 0 )
			{
			fprintf(outfile,"*** wcstoimax modified errno ***\n");
			status = EXIT_FAILURE;
			}

		for ( i = 0; i < 64; ++i )
			if ( wnptr[i] != sdp->nptr[i] )
				{
				fprintf(outfile,"*** wcstoimax modified its input ***\n"
				      );
				status = EXIT_FAILURE;

				for ( ; i < 64; ++i )
					if ( (wnptr[i] = sdp->nptr[i]) == '\0' )
						break;

				break;
				}
			else if ( wnptr[i] == '\0' )
				break;

		if ( sdp->exp_val >= 0 )	/* else some sign extension */
			{
			errno = 0;	/* shouldn't be changed */

			if ( (uintmax = wcstoumax(wnptr, &wendptr, sdp->base)
			     ) != sdp->exp_val
			   )	{
				int	save = errno;

				fprintf(outfile,"*** wcstoumax(%s,,%d) failed; "
				       "should be: %"PRIuMAX", was: %"PRIuMAX
				       " ***\n", sdp->nptr, sdp->base,
				       sdp->exp_val, uintmax
				      );
				status = EXIT_FAILURE;
				errno = save;
				}
			else if ( wendptr != wnptr + sdp->exp_len )
				{
				int	save = errno;

				fprintf(outfile,"*** wcstoumax(%s,,%d) returned wrong "
				       "endptr ***\n", sdp->nptr, sdp->base
				      );
				status = EXIT_FAILURE;
				errno = save;
				}

			if ( errno != 0 )
				{
				fprintf(outfile,"*** wcstoumax modified errno ***\n");
				status = EXIT_FAILURE;
				}

			for ( i = 0; i < 64; ++i )
				if ( wnptr[i] != sdp->nptr[i] )
					{
					fprintf(outfile,"*** wcstoumax"
					       " modified its input ***\n"
					      );
					status = EXIT_FAILURE;

					for ( ; i < 64; ++i )
						if ( (wnptr[i] = sdp->nptr[i])
						  == '\0'
						   )
							break;

					break;
					}
				else if ( wnptr[i] == '\0' )
					break;
			}

		/* tests for null endptr */

		warned = 0;
		errno = 0;		/* shouldn't be changed */

		if ( (intmax = wcstoimax(wnptr, (wchar_t **)NULL, sdp->base))
		  != sdp->exp_val
		   )	{
			int	save = errno;

			WARN();
			fprintf(outfile,"*** wcstoimax(%s,NULL,%d) failed; should be: %"
			       PRIdMAX", was: %"PRIdMAX" ***\n", sdp->nptr,
			       sdp->base, sdp->exp_val, intmax
			      );
			status = EXIT_FAILURE;
			errno = save;
			}

		if ( errno != 0 )
			{
			WARN();
			fprintf(outfile,"*** wcstoimax modified errno ***\n");
			status = EXIT_FAILURE;
			}

		for ( i = 0; i < 64; ++i )
			if ( wnptr[i] != sdp->nptr[i] )
				{
				WARN();
				fprintf(outfile,"*** wcstoimax modified its input ***\n"
				      );
				status = EXIT_FAILURE;

				for ( ; i < 64; ++i )
					if ( (wnptr[i] = sdp->nptr[i])
					  == '\0'
					   )
						break;

				break;
				}
			else if ( wnptr[i] == '\0' )
				break;

		if ( sdp->exp_val >= 0 )	/* else some sign extension */
			{
			errno = 0;	/* shouldn't be changed */

			if ( (uintmax = wcstoumax(wnptr, (wchar_t **)NULL,
						  sdp->base
						 )
			     ) != sdp->exp_val
			   )	{
				int	save = errno;

				WARN();
				fprintf(outfile,"*** wcstoumax(%s,NULL,%d) failed; "
				       "should be: %"PRIuMAX", was: %"PRIuMAX
				       " ***\n", sdp->nptr, sdp->base,
				       sdp->exp_val, uintmax
				      );
				status = EXIT_FAILURE;
				errno = save;
				}

			 if ( errno != 0 )
				{
				WARN();
				fprintf(outfile,"*** wcstoumax modified errno ***\n");
				status = EXIT_FAILURE;
				}

			for ( i = 0; i < 64; ++i )
				if ( wnptr[i] != sdp->nptr[i] )
					{
					WARN();
					fprintf(outfile,"*** wcstoumax"
					       " modified its input ***\n"
					      );
					status = EXIT_FAILURE;

					for ( ; i < 64; ++i )
						if ( (wnptr[i] = sdp->nptr[i])
						  == '\0'
						   )
							break;

					break;
					}
				else if ( wnptr[i] == '\0' )
					break;
			}
		}

	/*
		7.8.2.3	The strtoimax and strtoumax functions (continued)
	*/

	if ( (intmax = strtoimax("1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890",
				 &endptr, 0
				)
	     ) != INTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** strtoimax failed overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (intmax = strtoimax("+1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890",
				 &endptr, 0
				)
	     ) != INTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** strtoimax failed +overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (intmax = strtoimax("-1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890",
				 &endptr, 0
				)
	     ) != INTMAX_MIN || errno != ERANGE
	   )	{
		fprintf(outfile,"*** strtoimax failed -overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (uintmax = strtoumax("1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890",
				 &endptr, 0
				)
	     ) != UINTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** strtoumax failed overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (uintmax = strtoumax("+1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890",
				 &endptr, 0
				)
	     ) != UINTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** strtoumax failed +overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (uintmax = strtoumax("-1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890"
				 "1234567890123456789012345678901234567890",
				 &endptr, 0
				)
	     ) != UINTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** strtoumax failed -overflow test ***\n");
		status = EXIT_FAILURE;
		}

	/*
		7.8.2.4	The wcstoimax and wcstoumax functions (continued)
	*/

#ifdef NO_INTERNAL_WCHAR
		fprintf(outfile,"NO_INTERNAL_WCHAR\n");
#else

	if ( (intmax = wcstoimax(L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890",
				 &wendptr, 0
				)
	     ) != INTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** wcstoimax failed overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (intmax = wcstoimax(L"+1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890",
				 &wendptr, 0
				)
	     ) != INTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** wcstoimax failed +overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (intmax = wcstoimax(L"-1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890",
				 &wendptr, 0
				)
	     ) != INTMAX_MIN || errno != ERANGE
	   )	{
		fprintf(outfile,"*** wcstoimax failed -overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (uintmax = wcstoumax(L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890",
				 &wendptr, 0
				)
	     ) != UINTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** wcstoumax failed overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (uintmax = wcstoumax(L"+1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890",
				 &wendptr, 0
				)
	     ) != UINTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** wcstoumax failed +overflow test ***\n");
		status = EXIT_FAILURE;
		}

	if ( (uintmax = wcstoumax(L"-1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890"
				 L"1234567890123456789012345678901234567890",
				 &wendptr, 0
				)
	     ) != UINTMAX_MAX || errno != ERANGE
	   )	{
		fprintf(outfile,"*** wcstoumax failed -overflow test ***\n");
		status = EXIT_FAILURE;
		}
#endif // NO_INTERNAL_WCHAR
	}
#endif	/* defined(INTMAX_MAX) */

	if ( status != 0 )
		fprintf(outfile, "sitest failed.\n");

    CLOSETEST();
	
	return status;
}
Exemple #12
0
uint32_t FNV32_init() {
  return UINT32_C(2166136261);
}
Exemple #13
0
int64_t a4[3] = { INT64_C (17), INT64_MIN, INT64_MAX };
verify (TYPE_MINIMUM (int64_t) == INT64_MIN);
verify (TYPE_MAXIMUM (int64_t) == INT64_MAX);
verify_same_types (INT64_MIN, (int64_t) 0 + 0);
verify_same_types (INT64_MAX, (int64_t) 0 + 0);
#endif

uint8_t b1[2] = { UINT8_C (17), UINT8_MAX };
verify (TYPE_MAXIMUM (uint8_t) == UINT8_MAX);
verify_same_types (UINT8_MAX, (uint8_t) 0 + 0);

uint16_t b2[2] = { UINT16_C (17), UINT16_MAX };
verify (TYPE_MAXIMUM (uint16_t) == UINT16_MAX);
verify_same_types (UINT16_MAX, (uint16_t) 0 + 0);

uint32_t b3[2] = { UINT32_C (17), UINT32_MAX };
verify (TYPE_MAXIMUM (uint32_t) == UINT32_MAX);
verify_same_types (UINT32_MAX, (uint32_t) 0 + 0);

#ifdef UINT64_MAX
uint64_t b4[2] = { UINT64_C (17), UINT64_MAX };
verify (TYPE_MAXIMUM (uint64_t) == UINT64_MAX);
verify_same_types (UINT64_MAX, (uint64_t) 0 + 0);
#endif

#if INT8_MIN && INT8_MAX && INT16_MIN && INT16_MAX && INT32_MIN && INT32_MAX
/* ok */
#else
err or;
#endif
Exemple #14
0
*******************************************************************************/
/** Allocation size alignment. */
#define RTMEMSAFER_ALIGN        16
/** Padding after the block to avoid small overruns. */
#define RTMEMSAFER_PAD_BEFORE   96
/** Padding after the block to avoid small underruns. */
#define RTMEMSAFER_PAD_AFTER    32


/*******************************************************************************
*   Global Variables                                                           *
*******************************************************************************/
/** XOR scrabler value.
 * @todo determine this at runtime */
#if ARCH_BITS == 32
static uintptr_t g_uScramblerXor = UINT32_C(0x867af88d);
#elif ARCH_BITS == 64
static uintptr_t g_uScramblerXor = UINT64_C(0xed95ecc99416d312);
#else
# error "Bad ARCH_BITS value"
#endif



RTDECL(int) RTMemSaferScramble(void *pv, size_t cb)
{

    AssertMsg(*(size_t *)((char *)pv - RTMEMSAFER_PAD_BEFORE) == cb,
              ("*pvStart=%#zx cb=%#zx\n", *(size_t *)((char *)pv- RTMEMSAFER_PAD_BEFORE), cb));

    /* Note! This isn't supposed to be safe, just less obvious. */
void gen_interupt(void)
{
    if (stop == 1)
    {
        g_gs_vi_counter = 0; // debug
        dyna_stop();
    }

    if (!interupt_unsafe_state)
    {
        if (savestates_get_job() == savestates_job_load)
        {
            savestates_load();
            return;
        }

        if (reset_hard_job)
        {
            reset_hard();
            reset_hard_job = 0;
            return;
        }
    }

    if (skip_jump)
    {
        uint32_t dest = skip_jump;
        skip_jump = 0;

        next_interupt = (q.first->data.count > g_cp0_regs[CP0_COUNT_REG]
                         || (g_cp0_regs[CP0_COUNT_REG] - q.first->data.count) < UINT32_C(0x80000000))
                        ? q.first->data.count
                        : 0;

        last_addr = dest;
        generic_jump_to(dest);
        return;
    }

    switch(q.first->data.type)
    {
    case SPECIAL_INT:
        special_int_handler();
        break;

    case VI_INT:
        remove_interupt_event();
        vi_vertical_interrupt_event(&g_vi);
        break;

    case COMPARE_INT:
        compare_int_handler();
        break;

    case CHECK_INT:
        remove_interupt_event();
        wrapped_exception_general();
        break;

    case SI_INT:
        remove_interupt_event();
        si_end_of_dma_event(&g_si);
        break;

    case PI_INT:
        remove_interupt_event();
        pi_end_of_dma_event(&g_pi);
        break;

    case AI_INT:
        remove_interupt_event();
        ai_end_of_dma_event(&g_ai);
        break;

    case SP_INT:
        remove_interupt_event();
        rsp_interrupt_event(&g_sp);
        break;

    case DP_INT:
        remove_interupt_event();
        rdp_interrupt_event(&g_dp);
        break;

    case HW2_INT:
        hw2_int_handler();
        break;

    case NMI_INT:
        nmi_int_handler();
        break;

    default:
        DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q.first->data.type);
        remove_interupt_event();
        wrapped_exception_general();
        break;
    }

    if (!interupt_unsafe_state)
    {
        if (savestates_get_job() == savestates_job_save)
        {
            savestates_save();
            return;
        }
    }
}
static void setupStruct(struct capn *ctx) {
  struct capn_ptr root = capn_root(ctx);
  ASSERT_EQ(CAPN_PTR_LIST, root.type);
  ASSERT_EQ(1, root.len);

  struct capn_ptr ptr = capn_new_struct(root.seg, 16, 6);
  ASSERT_EQ(CAPN_STRUCT, ptr.type);
  EXPECT_EQ(16, ptr.datasz);
  EXPECT_EQ(6, ptr.ptrs);
  EXPECT_EQ(0, capn_setp(root, 0, ptr));

  EXPECT_EQ(0, capn_write64(ptr, 0, UINT64_C(0x1011121314151617)));
  EXPECT_EQ(0, capn_write32(ptr, 8, UINT32_C(0x20212223)));
  EXPECT_EQ(0, capn_write16(ptr, 12, UINT16_C(0x3031)));
  EXPECT_EQ(0, capn_write8(ptr, 14, 0x40));
  EXPECT_EQ(0, capn_write8(ptr, 15, (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2)));

  capn_ptr subStruct = capn_new_struct(ptr.seg, 8, 0);
  ASSERT_EQ(CAPN_STRUCT, subStruct.type);
  EXPECT_EQ(8, subStruct.datasz);
  EXPECT_EQ(0, subStruct.ptrs);
  EXPECT_EQ(0, capn_write32(subStruct, 0, 123));
  EXPECT_NE(0, capn_write32(subStruct, 8, 124));
  EXPECT_EQ(0, capn_setp(ptr, 0, subStruct));

  capn_list32 list32 = capn_new_list32(ptr.seg, 3);
  capn_list64 list64 = {list32.p};
  ASSERT_EQ(CAPN_LIST, list32.p.type);
  EXPECT_EQ(3, list32.p.len);
  EXPECT_EQ(4, list32.p.datasz);
  EXPECT_EQ(0, capn_set32(list32, 0, 200));
  EXPECT_EQ(0, capn_set32(list32, 1, 201));
  EXPECT_EQ(0, capn_set32(list32, 2, 202));
  EXPECT_NE(0, capn_set32(list32, 3, 203));
  EXPECT_NE(0, capn_set64(list64, 0, 405));
  EXPECT_EQ(0, capn_setp(ptr, 1, list32.p));

  capn_ptr list = capn_new_list(ptr.seg, 4, 4, 1);
  ASSERT_EQ(CAPN_LIST, list.type);
  ASSERT_EQ(1, list.is_composite_list);
  EXPECT_EQ(4, list.len);
  EXPECT_EQ(8, list.datasz);
  EXPECT_EQ(1, list.ptrs);
  EXPECT_EQ(0, capn_setp(ptr, 2, list));
  for (int i = 0; i < 4; i++) {
    capn_ptr element = capn_getp(list, i, 1);
    ASSERT_EQ(CAPN_STRUCT, element.type);
    EXPECT_EQ(1, element.is_list_member);
    EXPECT_EQ(8, element.datasz);
    EXPECT_EQ(1, element.ptrs);
    EXPECT_EQ(0, capn_write32(element, 0, 300+i));

    capn_ptr subelement = capn_new_struct(element.seg, 8, 0);
    ASSERT_EQ(CAPN_STRUCT, subelement.type);
    EXPECT_EQ(8, subelement.datasz);
    EXPECT_EQ(0, subelement.ptrs);
    EXPECT_EQ(0, capn_write32(subelement, 0, 400+i));
    EXPECT_EQ(0, capn_setp(element, 0, subelement));
  }

  list = capn_new_ptr_list(ptr.seg, 5);
  ASSERT_EQ(CAPN_PTR_LIST, list.type);
  EXPECT_EQ(5, list.len);
  EXPECT_EQ(0, capn_setp(ptr, 3, list));
  for (int i = 0; i < 5; i++) {
    capn_list16 element = capn_new_list16(list.seg, i+1);
    ASSERT_EQ(CAPN_LIST, element.p.type);
    EXPECT_EQ(i+1, element.p.len);
    EXPECT_EQ(2, element.p.datasz);
    EXPECT_EQ(0, element.p.ptrs);
    EXPECT_EQ(0, capn_setp(list, i, element.p));
    for (int j = 0; j <= i; j++) {
      EXPECT_EQ(0, capn_set16(element, j, 500+j));
    }
  }

  capn_ptr recurse = capn_new_struct(ptr.seg, 0, 2);
  EXPECT_EQ(CAPN_STRUCT, recurse.type);
  EXPECT_EQ(0, recurse.datasz);
  EXPECT_EQ(2, recurse.ptrs);
  EXPECT_EQ(0, capn_setp(recurse, 0, recurse));
  EXPECT_EQ(0, capn_setp(ptr, 4, recurse));

}
Exemple #17
0
/**
 * Enables the KVM VCPU system-time structure.
 *
 * @returns VBox status code.
 * @param   pVM                Pointer to the VM.
 * @param   pVCpu              Pointer to the VMCPU.
 *
 * @remarks Don't do any release assertions here, these can be triggered by
 *          guest R0 code.
 */
VMMR3_INT_DECL(int) gimR3KvmEnableSystemTime(PVM pVM, PVMCPU pVCpu)
{
    PGIMKVM    pKvm    = &pVM->gim.s.u.Kvm;
    PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu;

    /*
     * Validate the mapping address first.
     */
    if (!PGMPhysIsGCPhysNormal(pVM, pKvmCpu->GCPhysSystemTime))
    {
        LogRel(("GIM: KVM: VCPU%3d: Invalid physical addr requested for mapping system-time struct. GCPhysSystemTime=%#RGp\n",
               pVCpu->idCpu, pKvmCpu->GCPhysSystemTime));
        return VERR_GIM_OPERATION_FAILED;
    }

    /*
     * Construct the system-time struct.
     */
    GIMKVMSYSTEMTIME SystemTime;
    RT_ZERO(SystemTime);
    SystemTime.u32Version  = pKvmCpu->u32SystemTimeVersion;
    SystemTime.u64NanoTS   = pKvmCpu->uVirtNanoTS;
    SystemTime.u64Tsc      = pKvmCpu->uTsc;
    SystemTime.fFlags      = pKvmCpu->fSystemTimeFlags | GIM_KVM_SYSTEM_TIME_FLAGS_TSC_STABLE;

    /*
     * How the guest calculates the system time (nanoseconds):
     *
     * tsc = rdtsc - SysTime.u64Tsc
     * if (SysTime.i8TscShift >= 0)
     *     tsc <<= i8TscShift;
     * else
     *     tsc >>= -i8TscShift;
     * time = ((tsc * SysTime.u32TscScale) >> 32) + SysTime.u64NanoTS
     */
    uint64_t u64TscFreq   = pKvm->cTscTicksPerSecond;
    SystemTime.i8TscShift = 0;
    while (u64TscFreq > 2 * RT_NS_1SEC_64)
    {
        u64TscFreq >>= 1;
        SystemTime.i8TscShift--;
    }
    uint32_t uTscFreqLo = (uint32_t)u64TscFreq;
    while (uTscFreqLo <= RT_NS_1SEC)
    {
        uTscFreqLo <<= 1;
        SystemTime.i8TscShift++;
    }
    SystemTime.u32TscScale = ASMDivU64ByU32RetU32(RT_NS_1SEC_64 << 32, uTscFreqLo);

    /*
     * Update guest memory with the system-time struct.
     */
    Assert(!(SystemTime.u32Version & UINT32_C(1)));
    int rc = PGMPhysSimpleWriteGCPhys(pVM, pKvmCpu->GCPhysSystemTime, &SystemTime, sizeof(GIMKVMSYSTEMTIME));
    if (RT_SUCCESS(rc))
    {
        LogRel(("GIM: KVM: VCPU%3d: Enabled system-time struct. at %#RGp - u32TscScale=%#RX32 i8TscShift=%d uVersion=%#RU32 "
                "fFlags=%#x uTsc=%#RX64 uVirtNanoTS=%#RX64\n", pVCpu->idCpu, pKvmCpu->GCPhysSystemTime, SystemTime.u32TscScale,
                SystemTime.i8TscShift, SystemTime.u32Version, SystemTime.fFlags, pKvmCpu->uTsc, pKvmCpu->uVirtNanoTS));
        TMR3CpuTickParavirtEnable(pVM);
    }
    else
        LogRel(("GIM: KVM: VCPU%3d: Failed to write system-time struct. at %#RGp. rc=%Rrc\n",
                pVCpu->idCpu, pKvmCpu->GCPhysSystemTime, rc));

    return rc;
}
Exemple #18
0
/* Get and put routines for GB-18030. This uses the internal gb18030table. */

#include "unicode.h"

/** @internal
    @struct gb_range_map_t
    @brief A structure to hold a mapping from a range in GB-18030 format to a Unicode range.
*/
typedef struct {
	uint_fast32_t low, high, unicode_low, unicode_high;
} gb_range_map_t;

/** Mappings from ranges in GB-18030 format to Unicode ranges. */
static const gb_range_map_t gb_range_map[] = {
	{ UINT32_C(0x0334), UINT32_C(0x1ef1), UINT32_C(0x0452), UINT32_C(0x200f) },
	{ UINT32_C(0x2403), UINT32_C(0x2c40), UINT32_C(0x2643), UINT32_C(0x2e80) },
	{ UINT32_C(0x32ad), UINT32_C(0x35a9), UINT32_C(0x361b), UINT32_C(0x3917) },
	{ UINT32_C(0x396a), UINT32_C(0x3cde), UINT32_C(0x3ce1), UINT32_C(0x4055) },
	{ UINT32_C(0x3de7), UINT32_C(0x3fbd), UINT32_C(0x4160), UINT32_C(0x4336) },
	{ UINT32_C(0x4159), UINT32_C(0x42cd), UINT32_C(0x44d7), UINT32_C(0x464b) },
	{ UINT32_C(0x440a), UINT32_C(0x45c2), UINT32_C(0x478e), UINT32_C(0x4946) },
	{ UINT32_C(0x4629), UINT32_C(0x48e7), UINT32_C(0x49b8), UINT32_C(0x4c76) },
	{ UINT32_C(0x4a63), UINT32_C(0x82bc), UINT32_C(0x9fa6), UINT32_C(0xd7ff) },
	{ UINT32_C(0x830e), UINT32_C(0x93d4), UINT32_C(0xe865), UINT32_C(0xf92b) },
	{ UINT32_C(0x94be), UINT32_C(0x98c3), UINT32_C(0xfa2a), UINT32_C(0xfe2f) },
	{ UINT32_C(0x99e2), UINT32_C(0x99fb), UINT32_C(0xffe6), UINT32_C(0xffff) },
	{ UINT32_C(0x2e248), UINT32_C(0x12e247), UINT32_C(0x10000), UINT32_C(0x10ffff) }};

/** @internal
    @brief Write a Unicode codepoint in GB-18030 encoding to a buffer.
Exemple #19
0
int main(int argc, char *argv[]) {
    uint32_t outlen = OUTLEN_DEF;
    uint32_t m_cost = 1 << LOG_M_COST_DEF;
    uint32_t t_cost = T_COST_DEF;
    uint32_t lanes = LANES_DEF;
    uint32_t threads = THREADS_DEF;
    argon2_type type = Argon2_i;
    int i;
    size_t n;
    char pwd[128], *salt;

    if (argc < 2) {
        usage(argv[0]);
        return ARGON2_MISSING_ARGS;
    }

    salt = argv[1];

    /* get password from stdin */
    while ((n = fread(pwd, 1, sizeof pwd - 1, stdin)) > 0) {
        pwd[n] = '\0';
        if (pwd[n - 1] == '\n')
            pwd[n - 1] = '\0';
    }

    /* parse options */
    for (i = 2; i < argc; i++) {
        const char *a = argv[i];
        unsigned long input = 0;
        if (!strcmp(a, "-m")) {
            if (i < argc - 1) {
                i++;
                input = strtoul(argv[i], NULL, 10);
                if (input == 0 || input == ULONG_MAX ||
                    input > ARGON2_MAX_MEMORY_BITS) {
                    fatal("bad numeric input for -m");
                }
                m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF));
                if (m_cost > ARGON2_MAX_MEMORY) {
                    fatal("m_cost overflow");
                }
                continue;
            } else {
                fatal("missing -m argument");
            }
        } else if (!strcmp(a, "-t")) {
            if (i < argc - 1) {
                i++;
                input = strtoul(argv[i], NULL, 10);
                if (input == 0 || input == ULONG_MAX ||
                    input > ARGON2_MAX_TIME) {
                    fatal("bad numeric input for -t");
                }
                t_cost = input;
                continue;
            } else {
                fatal("missing -t argument");
            }
        } else if (!strcmp(a, "-p")) {
            if (i < argc - 1) {
                i++;
                input = strtoul(argv[i], NULL, 10);
                if (input == 0 || input == ULONG_MAX ||
                    input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) {
                    fatal("bad numeric input for -p");
                }
                threads = input;
                lanes = threads;
                continue;
            } else {
                fatal("missing -p argument");
            }
        } else if (!strcmp(a, "-h")) {
            if (i < argc - 1) {
                i++;
                input = strtoul(argv[i], NULL, 10);
                outlen = input;
                continue;
            } else {
                fatal("missing -h argument");
            }
        } else if (!strcmp(a, "-d")) {
            type = Argon2_d;
        } else {
            fatal("unknown argument");
        }
    }
    if (type == Argon2_i) {
        printf("Type:\t\tArgon2i\n");
    } else {
        printf("Type:\t\tArgon2d\n");
    }
    printf("Iterations:\t%" PRIu32 " \n", t_cost);
    printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost);
    printf("Parallelism:\t%" PRIu32 " \n", lanes);
    run(outlen, pwd, salt, t_cost, m_cost, lanes, threads, type);

    return ARGON2_OK;
}
Exemple #20
0
int main()
{
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  integral_constant_checker::check();
#endif
  //
  // verify the types of the integral constants:
  //
  integral_constant_type_check(boost::int8_t(0), INT8_C(0));
  integral_constant_type_check(boost::uint8_t(0), UINT8_C(0));
  integral_constant_type_check(boost::int16_t(0), INT16_C(0));
  integral_constant_type_check(boost::uint16_t(0), UINT16_C(0));
  integral_constant_type_check(boost::int32_t(0), INT32_C(0));
  integral_constant_type_check(boost::uint32_t(0), UINT32_C(0));
#ifndef BOOST_NO_INT64_T
  integral_constant_type_check(boost::int64_t(0), INT64_C(0));
  integral_constant_type_check(boost::uint64_t(0), UINT64_C(0));
#endif
  //
  boost::int8_t          int8          = INT8_C(-127);
  boost::int_least8_t    int_least8    = INT8_C(-127);
  boost::int_fast8_t     int_fast8     = INT8_C(-127);

  boost::uint8_t         uint8         = UINT8_C(255);
  boost::uint_least8_t   uint_least8   = UINT8_C(255);
  boost::uint_fast8_t    uint_fast8    = UINT8_C(255);

  boost::int16_t         int16         = INT16_C(-32767);
  boost::int_least16_t   int_least16   = INT16_C(-32767);
  boost::int_fast16_t    int_fast16    = INT16_C(-32767);

  boost::uint16_t        uint16         = UINT16_C(65535);
  boost::uint_least16_t  uint_least16   = UINT16_C(65535);
  boost::uint_fast16_t   uint_fast16    = UINT16_C(65535);

  boost::int32_t         int32         = INT32_C(-2147483647);
  boost::int_least32_t   int_least32   = INT32_C(-2147483647);
  boost::int_fast32_t    int_fast32    = INT32_C(-2147483647);

  boost::uint32_t        uint32        = UINT32_C(4294967295);
  boost::uint_least32_t  uint_least32  = UINT32_C(4294967295);
  boost::uint_fast32_t   uint_fast32   = UINT32_C(4294967295);

#ifndef BOOST_NO_INT64_T
  boost::int64_t         int64         = INT64_C(-9223372036854775807);
  boost::int_least64_t   int_least64   = INT64_C(-9223372036854775807);
  boost::int_fast64_t    int_fast64    = INT64_C(-9223372036854775807);

  boost::uint64_t        uint64        = UINT64_C(18446744073709551615);
  boost::uint_least64_t  uint_least64  = UINT64_C(18446744073709551615);
  boost::uint_fast64_t   uint_fast64   = UINT64_C(18446744073709551615);

  boost::intmax_t        intmax        = INTMAX_C(-9223372036854775807);
  boost::uintmax_t       uintmax       = UINTMAX_C(18446744073709551615);
#else
  boost::intmax_t        intmax        = INTMAX_C(-2147483647);
  boost::uintmax_t       uintmax       = UINTMAX_C(4294967295);
#endif

  assert( int8 == -127 );
  assert( int_least8 == -127 );
  assert( int_fast8 == -127 );
  assert( uint8 == 255u );
  assert( uint_least8 == 255u );
  assert( uint_fast8 == 255u );
  assert( int16 == -32767 );
  assert( int_least16 == -32767 );
  assert( int_fast16 == -32767 );
  assert( uint16 == 65535u );
  assert( uint_least16 == 65535u );
  assert( uint_fast16 == 65535u );
  assert( int32 == -2147483647 );
  assert( int_least32 == -2147483647 );
  assert( int_fast32 == -2147483647 );
  assert( uint32 == 4294967295u );
  assert( uint_least32 == 4294967295u );
  assert( uint_fast32 == 4294967295u );

#ifndef BOOST_NO_INT64_T
  assert( int64 == INT64_C(-9223372036854775807) );
  assert( int_least64 == INT64_C(-9223372036854775807) );
  assert( int_fast64 == INT64_C(-9223372036854775807) );
  assert( uint64 == UINT64_C(18446744073709551615) );
  assert( uint_least64 == UINT64_C(18446744073709551615) );
  assert( uint_fast64 == UINT64_C(18446744073709551615) );
  assert( intmax == INT64_C(-9223372036854775807) );
  assert( uintmax == UINT64_C(18446744073709551615) );
#else
  assert( intmax == -2147483647 );
  assert( uintmax == 4294967295u );
#endif


  std::cout << "OK\n";
  return 0;
}
Exemple #21
0
DECLINLINE(int) rtSemEventLnxMultiWait(struct RTSEMEVENTMULTIINTERNAL *pThis, uint32_t fFlags, uint64_t uTimeout,
                                       PCRTLOCKVALSRCPOS pSrcPos)
{
    /*
     * Validate input.
     */
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);

    /*
     * Quickly check whether it's signaled.
     */
    int32_t iCur = ASMAtomicUoReadS32(&pThis->iState);
    Assert(iCur == 0 || iCur == -1 || iCur == 1);
    if (iCur == -1)
        return VINF_SUCCESS;

    /*
     * Check and convert the timeout value.
     */
    struct timespec ts;
    struct timespec *pTimeout = NULL;
    uint64_t u64Deadline = 0; /* shut up gcc */
    if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE))
    {
        /* If the timeout is zero, then we're done. */
        if (!uTimeout)
            return VERR_TIMEOUT;

        /* Convert it to a deadline + interval timespec. */
        if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
            uTimeout = uTimeout < UINT64_MAX / UINT32_C(1000000) * UINT32_C(1000000)
                     ? uTimeout * UINT32_C(1000000)
                     : UINT64_MAX;
        if (uTimeout != UINT64_MAX) /* unofficial way of indicating an indefinite wait */
        {
            if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
                u64Deadline = RTTimeSystemNanoTS() + uTimeout;
            else
            {
                uint64_t u64Now = RTTimeSystemNanoTS();
                if (uTimeout <= u64Now)
                    return VERR_TIMEOUT;
                u64Deadline = uTimeout;
                uTimeout   -= u64Now;
            }
            if (   sizeof(ts.tv_sec) >= sizeof(uint64_t)
                || uTimeout <= UINT64_C(1000000000) * UINT32_MAX)
            {
                ts.tv_nsec = uTimeout % UINT32_C(1000000000);
                ts.tv_sec  = uTimeout / UINT32_C(1000000000);
                pTimeout = &ts;
            }
        }
    }

    /*
     * The wait loop.
     */
#ifdef RTSEMEVENTMULTI_STRICT
    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
#else
    RTTHREAD hThreadSelf = RTThreadSelf();
#endif
    for (unsigned i = 0;; i++)
    {
        /*
         * Start waiting. We only account for there being or having been
         * threads waiting on the semaphore to keep things simple.
         */
        iCur = ASMAtomicUoReadS32(&pThis->iState);
        Assert(iCur == 0 || iCur == -1 || iCur == 1);
        if (    iCur == 1
            ||  ASMAtomicCmpXchgS32(&pThis->iState, 1, 0))
        {
            /* adjust the relative timeout */
            if (pTimeout)
            {
                int64_t i64Diff = u64Deadline - RTTimeSystemNanoTS();
                if (i64Diff < 1000)
                    return VERR_TIMEOUT;
                ts.tv_sec  = (uint64_t)i64Diff / UINT32_C(1000000000);
                ts.tv_nsec = (uint64_t)i64Diff % UINT32_C(1000000000);
            }
#ifdef RTSEMEVENTMULTI_STRICT
            if (pThis->fEverHadSignallers)
            {
                int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
                                                                uTimeout / UINT32_C(1000000), RTTHREADSTATE_EVENT_MULTI, true);
                if (RT_FAILURE(rc9))
                    return rc9;
            }
#endif
            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
            long rc = sys_futex(&pThis->iState, FUTEX_WAIT, 1, pTimeout, NULL, 0);
            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
            if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC))
                return VERR_SEM_DESTROYED;
            if (rc == 0)
                return VINF_SUCCESS;

            /*
             * Act on the wakup code.
             */
            if (rc == -ETIMEDOUT)
            {
/** @todo something is broken here. shows up every now and again in the ata
 *        code. Should try to run the timeout against RTTimeMilliTS to
 *        check that it's doing the right thing... */
                Assert(pTimeout);
                return VERR_TIMEOUT;
            }
            if (rc == -EWOULDBLOCK)
                /* retry, the value changed. */;
            else if (rc == -EINTR)
            {
                if (fFlags & RTSEMWAIT_FLAGS_NORESUME)
                    return VERR_INTERRUPTED;
            }
            else
            {
                /* this shouldn't happen! */
                AssertMsgFailed(("rc=%ld errno=%d\n", rc, errno));
                return RTErrConvertFromErrno(rc);
            }
        }
        else if (iCur == -1)
            return VINF_SUCCESS;
    }
}
/**
 * Opens the IDC interface of the support driver.
 *
 * This will perform basic version negotiations and fail if the
 * minimum requirements aren't met.
 *
 * @returns VBox status code.
 * @param   pHandle             The handle structure (output).
 * @param   uReqVersion         The requested version. Pass 0 for default.
 * @param   uMinVersion         The minimum required version. Pass 0 for default.
 * @param   puSessionVersion    Where to store the session version. Optional.
 * @param   puDriverVersion     Where to store the session version. Optional.
 * @param   puDriverRevision    Where to store the SVN revision of the driver. Optional.
 */
SUPR0DECL(int) SUPR0IdcOpen(PSUPDRVIDCHANDLE pHandle, uint32_t uReqVersion, uint32_t uMinVersion,
                            uint32_t *puSessionVersion, uint32_t *puDriverVersion, uint32_t *puDriverRevision)
{
    unsigned uDefaultMinVersion;
    SUPDRVIDCREQCONNECT Req;
    int rc;

    /*
     * Validate and set failure return values.
     */
    AssertPtrReturn(pHandle, VERR_INVALID_POINTER);
    pHandle->s.pSession = NULL;

    AssertPtrNullReturn(puSessionVersion, VERR_INVALID_POINTER);
    if (puSessionVersion)
        *puSessionVersion = 0;

    AssertPtrNullReturn(puDriverVersion, VERR_INVALID_POINTER);
    if (puDriverVersion)
        *puDriverVersion = 0;

    AssertPtrNullReturn(puDriverRevision, VERR_INVALID_POINTER);
    if (puDriverRevision)
        *puDriverRevision = 0;

    AssertReturn(!uMinVersion || (uMinVersion & UINT32_C(0xffff0000)) == (SUPDRV_IDC_VERSION & UINT32_C(0xffff0000)), VERR_INVALID_PARAMETER);
    AssertReturn(!uReqVersion || (uReqVersion & UINT32_C(0xffff0000)) == (SUPDRV_IDC_VERSION & UINT32_C(0xffff0000)), VERR_INVALID_PARAMETER);

    /*
     * Handle default version input and enforce minimum requirements made
     * by this library.
     *
     * The clients will pass defaults (0), and only in the case that some
     * special API feature was just added will they set an actual version.
     * So, this is the place where can easily enforce a minimum IDC version
     * on bugs and similar. It corresponds a bit to what SUPR3Init is
     * responsible for.
     */
    uDefaultMinVersion = SUPDRV_IDC_VERSION & UINT32_C(0xffff0000);
    if (!uMinVersion || uMinVersion < uDefaultMinVersion)
        uMinVersion = uDefaultMinVersion;
    if (!uReqVersion || uReqVersion < uDefaultMinVersion)
        uReqVersion = uDefaultMinVersion;

    /*
     * Setup the connect request packet and call the OS specific function.
     */
    Req.Hdr.cb = sizeof(Req);
    Req.Hdr.rc = VERR_WRONG_ORDER;
    Req.Hdr.pSession = NULL;
    Req.u.In.u32MagicCookie = SUPDRVIDCREQ_CONNECT_MAGIC_COOKIE;
    Req.u.In.uMinVersion = uMinVersion;
    Req.u.In.uReqVersion = uReqVersion;
    rc = supR0IdcNativeOpen(pHandle, &Req);
    if (RT_SUCCESS(rc))
    {
        pHandle->s.pSession = Req.u.Out.pSession;
        if (puSessionVersion)
            *puSessionVersion = Req.u.Out.uSessionVersion;
        if (puDriverVersion)
            *puDriverVersion = Req.u.Out.uDriverVersion;
        if (puDriverRevision)
            *puDriverRevision = Req.u.Out.uDriverRevision;

        /*
         * We don't really trust anyone, make sure the returned
         * session and version values actually makes sense.
         */
        if (    VALID_PTR(Req.u.Out.pSession)
            &&  Req.u.Out.uSessionVersion >= uMinVersion
            &&  (Req.u.Out.uSessionVersion & UINT32_C(0xffff0000)) == (SUPDRV_IDC_VERSION & UINT32_C(0xffff0000)))
        {
            ASMAtomicCmpXchgPtr(&g_pMainHandle, pHandle, NULL);
            return rc;
        }

        AssertMsgFailed(("pSession=%p uSessionVersion=0x%x (r%u)\n", Req.u.Out.pSession, Req.u.Out.uSessionVersion, Req.u.Out.uDriverRevision));
        rc = VERR_VERSION_MISMATCH;
        SUPR0IdcClose(pHandle);
    }

    return rc;
}
Exemple #23
0
/**
 * Deals with complicated MMIO writes.
 *
 * Complicated means unaligned or non-dword/qword sized accesses depending on
 * the MMIO region's access mode flags.
 *
 * @returns Strict VBox status code. Any EM scheduling status code,
 *          VINF_IOM_R3_MMIO_WRITE, VINF_IOM_R3_MMIO_READ_WRITE or
 *          VINF_IOM_R3_MMIO_READ may be returned.
 *
 * @param   pVM         The cross context VM structure.
 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
 * @param   pRange      The range to write to.
 * @param   GCPhys      The physical address to start writing.
 * @param   pvValue     Where to store the value.
 * @param   cbValue     The size of the value to write.
 */
static VBOXSTRICTRC iomMMIODoComplicatedWrite(PVM pVM, PVMCPU pVCpu, PIOMMMIORANGE pRange, RTGCPHYS GCPhys,
                                              void const *pvValue, unsigned cbValue)
{
    AssertReturn(   (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) != IOMMMIO_FLAGS_WRITE_PASSTHRU
                 && (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) <= IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING,
                 VERR_IOM_MMIO_IPE_1);
    AssertReturn(cbValue != 0 && cbValue <= 16, VERR_IOM_MMIO_IPE_2);
    RTGCPHYS const GCPhysStart  = GCPhys; NOREF(GCPhysStart);
    bool const     fReadMissing = (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING
                               || (pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING;

    /*
     * Do debug stop if requested.
     */
    int rc = VINF_SUCCESS; NOREF(pVM);
#ifdef VBOX_STRICT
    if (pRange->fFlags & IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_WRITE)
    {
# ifdef IN_RING3
        LogRel(("IOM: Complicated write %#x byte at %RGp to %s, initiating debugger intervention\n", cbValue, GCPhys,
                R3STRING(pRange->pszDesc)));
        rc = DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, RT_SRC_POS,
                            "Complicated write %#x byte at %RGp to %s\n", cbValue, GCPhys, R3STRING(pRange->pszDesc));
        if (rc == VERR_DBGF_NOT_ATTACHED)
            rc = VINF_SUCCESS;
# else
        return VINF_IOM_R3_MMIO_WRITE;
# endif
    }
#endif

    /*
     * Check if we should ignore the write.
     */
    if ((pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_ONLY_DWORD)
    {
        Assert(cbValue != 4 || (GCPhys & 3));
        return VINF_SUCCESS;
    }
    if ((pRange->fFlags & IOMMMIO_FLAGS_WRITE_MODE) == IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD)
    {
        Assert((cbValue != 4 && cbValue != 8) || (GCPhys & (cbValue - 1)));
        return VINF_SUCCESS;
    }

    /*
     * Split and conquer.
     */
    for (;;)
    {
        unsigned const  offAccess  = GCPhys & 3;
        unsigned        cbThisPart = 4 - offAccess;
        if (cbThisPart > cbValue)
            cbThisPart = cbValue;

        /*
         * Get the missing bits (if any).
         */
        uint32_t u32MissingValue = 0;
        if (fReadMissing && cbThisPart != 4)
        {
            int rc2 = pRange->CTX_SUFF(pfnReadCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
                                                        GCPhys & ~(RTGCPHYS)3, &u32MissingValue, sizeof(u32MissingValue));
            switch (rc2)
            {
                case VINF_SUCCESS:
                    break;
                case VINF_IOM_MMIO_UNUSED_FF:
                    u32MissingValue = UINT32_C(0xffffffff);
                    break;
                case VINF_IOM_MMIO_UNUSED_00:
                    u32MissingValue = 0;
                    break;
#ifndef IN_RING3
                case VINF_IOM_R3_MMIO_READ:
                case VINF_IOM_R3_MMIO_READ_WRITE:
                case VINF_IOM_R3_MMIO_WRITE:
                    LogFlow(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [read]\n", GCPhys, GCPhysStart, cbValue, rc2));
                    rc2 = VBOXSTRICTRC_TODO(iomMmioRing3WritePending(pVCpu, GCPhys, pvValue, cbValue, pRange));
                    if (rc == VINF_SUCCESS || rc2 < rc)
                        rc = rc2;
                    return rc;
#endif
                default:
                    if (RT_FAILURE(rc2))
                    {
                        Log(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [read]\n", GCPhys, GCPhysStart, cbValue, rc2));
                        return rc2;
                    }
                    AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS);
                    if (rc == VINF_SUCCESS || rc2 < rc)
                        rc = rc2;
                    break;
            }
        }

        /*
         * Merge missing and given bits.
         */
        uint32_t u32GivenMask;
        uint32_t u32GivenValue;
        switch (cbThisPart)
        {
            case 1:
                u32GivenValue = *(uint8_t  const *)pvValue;
                u32GivenMask  = UINT32_C(0x000000ff);
                break;
            case 2:
                u32GivenValue = *(uint16_t const *)pvValue;
                u32GivenMask  = UINT32_C(0x0000ffff);
                break;
            case 3:
                u32GivenValue = RT_MAKE_U32_FROM_U8(((uint8_t const *)pvValue)[0], ((uint8_t const *)pvValue)[1],
                                                    ((uint8_t const *)pvValue)[2], 0);
                u32GivenMask  = UINT32_C(0x00ffffff);
                break;
            case 4:
                u32GivenValue = *(uint32_t const *)pvValue;
                u32GivenMask  = UINT32_C(0xffffffff);
                break;
            default:
                AssertFailedReturn(VERR_IOM_MMIO_IPE_3);
        }
        if (offAccess)
        {
            u32GivenValue <<= offAccess * 8;
            u32GivenMask  <<= offAccess * 8;
        }

        uint32_t u32Value = (u32MissingValue & ~u32GivenMask)
                          | (u32GivenValue & u32GivenMask);

        /*
         * Do DWORD write to the device.
         */
        int rc2 = pRange->CTX_SUFF(pfnWriteCallback)(pRange->CTX_SUFF(pDevIns), pRange->CTX_SUFF(pvUser),
                                                     GCPhys & ~(RTGCPHYS)3, &u32Value, sizeof(u32Value));
        switch (rc2)
        {
            case VINF_SUCCESS:
                break;
#ifndef IN_RING3
            case VINF_IOM_R3_MMIO_READ:
            case VINF_IOM_R3_MMIO_READ_WRITE:
            case VINF_IOM_R3_MMIO_WRITE:
                Log3(("iomMMIODoComplicatedWrite: deferring GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [write]\n", GCPhys, GCPhysStart, cbValue, rc2));
                AssertReturn(pVCpu->iom.s.PendingMmioWrite.cbValue == 0, VERR_IOM_MMIO_IPE_1);
                AssertReturn(cbValue + (GCPhys & 3) <= sizeof(pVCpu->iom.s.PendingMmioWrite.abValue), VERR_IOM_MMIO_IPE_2);
                pVCpu->iom.s.PendingMmioWrite.GCPhys  = GCPhys & ~(RTGCPHYS)3;
                pVCpu->iom.s.PendingMmioWrite.cbValue = cbValue + (GCPhys & 3);
                *(uint32_t *)pVCpu->iom.s.PendingMmioWrite.abValue = u32Value;
                if (cbValue > cbThisPart)
                    memcpy(&pVCpu->iom.s.PendingMmioWrite.abValue[4],
                           (uint8_t const *)pvValue + cbThisPart, cbValue - cbThisPart);
                VMCPU_FF_SET(pVCpu, VMCPU_FF_IOM);
                if (rc == VINF_SUCCESS)
                    rc = VINF_IOM_R3_MMIO_COMMIT_WRITE;
                return rc2;
#endif
            default:
                if (RT_FAILURE(rc2))
                {
                    Log(("iomMMIODoComplicatedWrite: GCPhys=%RGp GCPhysStart=%RGp cbValue=%u rc=%Rrc [write]\n", GCPhys, GCPhysStart, cbValue, rc2));
                    return rc2;
                }
                AssertMsgReturn(rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST, ("%Rrc\n", rc2), VERR_IPE_UNEXPECTED_INFO_STATUS);
                if (rc == VINF_SUCCESS || rc2 < rc)
                    rc = rc2;
                break;
        }

        /*
         * Advance.
         */
        cbValue -= cbThisPart;
        if (!cbValue)
            break;
        GCPhys += cbThisPart;
        pvValue = (uint8_t const *)pvValue + cbThisPart;
    }

    return rc;
}
int main()
{
   boost::int8_t i8 = INT8_C(0);
   (void)i8;
   boost::uint8_t ui8 = UINT8_C(0);
   (void)ui8;
   boost::int16_t i16 = INT16_C(0);
   (void)i16;
   boost::uint16_t ui16 = UINT16_C(0);
   (void)ui16;
   boost::int32_t i32 = INT32_C(0);
   (void)i32;
   boost::uint32_t ui32 = UINT32_C(0);
   (void)ui32;
#ifndef BOOST_NO_INT64_T
   boost::int64_t i64 = 0;
   (void)i64;
   boost::uint64_t ui64 = 0;
   (void)ui64;
#endif
   boost::int_least8_t i8least = INT8_C(0);
   (void)i8least;
   boost::uint_least8_t ui8least = UINT8_C(0);
   (void)ui8least;
   boost::int_least16_t i16least = INT16_C(0);
   (void)i16least;
   boost::uint_least16_t ui16least = UINT16_C(0);
   (void)ui16least;
   boost::int_least32_t i32least = INT32_C(0);
   (void)i32least;
   boost::uint_least32_t ui32least = UINT32_C(0);
   (void)ui32least;
#ifndef BOOST_NO_INT64_T
   boost::int_least64_t i64least = 0;
   (void)i64least;
   boost::uint_least64_t ui64least = 0;
   (void)ui64least;
#endif
   boost::int_fast8_t i8fast = INT8_C(0);
   (void)i8fast;
   boost::uint_fast8_t ui8fast = UINT8_C(0);
   (void)ui8fast;
   boost::int_fast16_t i16fast = INT16_C(0);
   (void)i16fast;
   boost::uint_fast16_t ui16fast = UINT16_C(0);
   (void)ui16fast;
   boost::int_fast32_t i32fast = INT32_C(0);
   (void)i32fast;
   boost::uint_fast32_t ui32fast = UINT32_C(0);
   (void)ui32fast;
#ifndef BOOST_NO_INT64_T
   boost::int_fast64_t i64fast = 0;
   (void)i64fast;
   boost::uint_fast64_t ui64fast = 0;
   (void)ui64fast;
#endif
   boost::intmax_t im = 0;
   (void)im;
   boost::uintmax_t uim = 0;
   (void)uim;
}
/**
 * Worker for RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug.
 *
 * @returns VBox status code.
 * @param   pThis           The event semaphore.
 * @param   fFlags          See RTSemEventMultiWaitEx.
 * @param   uTimeout        See RTSemEventMultiWaitEx.
 * @param   pSrcPos         The source code position of the wait.
 */
static int rtR0SemEventMultiDarwinWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
                                       PCRTLOCKVALSRCPOS pSrcPos)
{
    /*
     * Validate input.
     */
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
    if (uTimeout != 0 || (fFlags & RTSEMWAIT_FLAGS_INDEFINITE))
        RT_ASSERT_PREEMPTIBLE();

    rtR0SemEventMultiDarwinRetain(pThis);
    lck_spin_lock(pThis->pSpinlock);

    /*
     * Is the event already signalled or do we have to wait?
     */
    int rc;
    uint32_t const fOrgStateAndGen = ASMAtomicUoReadU32(&pThis->fStateAndGen);
    if (fOrgStateAndGen & RTSEMEVENTMULTIDARWIN_STATE_MASK)
        rc = VINF_SUCCESS;
    else
    {
        /*
         * We have to wait. So, we'll need to convert the timeout and figure
         * out if it's indefinite or not.
         */
        uint64_t uNsAbsTimeout = 1;
        if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE))
        {
            if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
                uTimeout = uTimeout < UINT64_MAX / UINT32_C(1000000) * UINT32_C(1000000)
                         ? uTimeout * UINT32_C(1000000)
                         : UINT64_MAX;
            if (uTimeout == UINT64_MAX)
                fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
            else
            {
                uint64_t u64Now;
                if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
                {
                    if (uTimeout != 0)
                    {
                        u64Now = RTTimeSystemNanoTS();
                        uNsAbsTimeout = u64Now + uTimeout;
                        if (uNsAbsTimeout < u64Now) /* overflow */
                            fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
                    }
                }
                else
                {
                    uNsAbsTimeout = uTimeout;
                    u64Now        = RTTimeSystemNanoTS();
                    uTimeout      = u64Now < uTimeout ? uTimeout - u64Now : 0;
                }
            }
        }

        if (   !(fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
            && uTimeout == 0)
        {
            /*
             * Poll call, we already checked the condition above so no need to
             * wait for anything.
             */
            rc = VERR_TIMEOUT;
        }
        else
        {
            for (;;)
            {
                /*
                 * Do the actual waiting.
                 */
                ASMAtomicWriteBool(&pThis->fHaveBlockedThreads, true);
                wait_interrupt_t fInterruptible = fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE ? THREAD_ABORTSAFE : THREAD_UNINT;
                wait_result_t    rcWait;
                if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
                    rcWait = lck_spin_sleep(pThis->pSpinlock, LCK_SLEEP_DEFAULT, (event_t)pThis, fInterruptible);
                else
                {
                    uint64_t u64AbsTime;
                    nanoseconds_to_absolutetime(uNsAbsTimeout, &u64AbsTime);
                    rcWait = lck_spin_sleep_deadline(pThis->pSpinlock, LCK_SLEEP_DEFAULT,
                                                     (event_t)pThis, fInterruptible, u64AbsTime);
                }

                /*
                 * Deal with the wait result.
                 */
                if (RT_LIKELY(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC))
                {
                    switch (rcWait)
                    {
                        case THREAD_AWAKENED:
                            if (RT_LIKELY(ASMAtomicUoReadU32(&pThis->fStateAndGen) != fOrgStateAndGen))
                                rc = VINF_SUCCESS;
                            else if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
                                rc = VERR_INTERRUPTED;
                            else
                                continue; /* Seen this happen after fork/exec/something. */
                            break;

                        case THREAD_TIMED_OUT:
                            Assert(!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE));
                            rc = VERR_TIMEOUT;
                            break;

                        case THREAD_INTERRUPTED:
                            Assert(fInterruptible != THREAD_UNINT);
                            rc = VERR_INTERRUPTED;
                            break;

                        case THREAD_RESTART:
                            AssertMsg(pThis->u32Magic == ~RTSEMEVENTMULTI_MAGIC, ("%#x\n", pThis->u32Magic));
                            rc = VERR_SEM_DESTROYED;
                            break;

                        default:
                            AssertMsgFailed(("rcWait=%d\n", rcWait));
                            rc = VERR_INTERNAL_ERROR_3;
                            break;
                    }
                }
                else
                    rc = VERR_SEM_DESTROYED;
                break;
            }
        }
    }

    lck_spin_unlock(pThis->pSpinlock);
    rtR0SemEventMultiDarwinRelease(pThis);
    return rc;
}
Exemple #26
0
#  define ENDIAN_FROM_BE64(x) ENDIAN_BSWAP64(x)
#elif defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
#  define ENDIAN_FROM_LE16(x) ENDIAN_BSWAP16(x)
#  define ENDIAN_FROM_LE32(x) ENDIAN_BSWAP32(x)
#  define ENDIAN_FROM_LE64(x) ENDIAN_BSWAP64(x)
#  define ENDIAN_FROM_BE16(x) (x)
#  define ENDIAN_FROM_BE32(x) (x)
#  define ENDIAN_FROM_BE64(x) (x)
#else /* Can't determine endianness at compile time */
#  include <stdint.h>
#  if defined(__cplusplus)
extern "C"
#  endif

enum {
  ENDIAN_RT_LITTLE_ENDIAN = UINT32_C(0x03020100),
  ENDIAN_RT_BIG_ENDIAN    = UINT32_C(0x00010203)
};

#define ENDIAN_RT_BYTE_ORDER (((union { unsigned char bytes[4]; uint32_t value; }) { { 0, 1, 2, 3 } }).value)

#  if defined(__cplusplus)
}
#  endif

#  define ENDIAN_FROM_LE16(v) ((ENDIAN_RT_BYTE_ORDER == ENDIAN_RT_LITTLE_ENDIAN) ? (v) : ENDIAN_BSWAP16(v))
#  define ENDIAN_FROM_BE16(v) ((ENDIAN_RT_BYTE_ORDER == ENDIAN_RT_BIG_ENDIAN)    ? (v) : ENDIAN_BSWAP16(v))
#  define ENDIAN_FROM_LE32(v) ((ENDIAN_RT_BYTE_ORDER == ENDIAN_RT_LITTLE_ENDIAN) ? (v) : ENDIAN_BSWAP32(v))
#  define ENDIAN_FROM_BE32(v) ((ENDIAN_RT_BYTE_ORDER == ENDIAN_RT_BIG_ENDIAN)    ? (v) : ENDIAN_BSWAP32(v))
#  define ENDIAN_FROM_LE64(v) ((ENDIAN_RT_BYTE_ORDER == ENDIAN_RT_LITTLE_ENDIAN) ? (v) : ENDIAN_BSWAP64(v))
#  define ENDIAN_FROM_BE64(v) ((ENDIAN_RT_BYTE_ORDER == ENDIAN_RT_BIG_ENDIAN)    ? (v) : ENDIAN_BSWAP64(v))
/**
 * Generates a kind of report of the hardware, software and whatever else we
 * think might be useful to know about the testbox.
 */
static RTEXITCODE handlerReport(int argc, char **argv)
{
    NOREF(argc); NOREF(argv);

#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    /*
     * For now, a simple CPUID dump.  Need to figure out how to share code
     * like this with other bits, putting it in IPRT.
     */
    RTPrintf("CPUID Dump\n"
             "Leaf      eax      ebx      ecx      edx\n"
             "---------------------------------------------\n");
    static uint32_t const s_auRanges[] =
    {
        UINT32_C(0x00000000),
        UINT32_C(0x80000000),
        UINT32_C(0x80860000),
        UINT32_C(0xc0000000),
        UINT32_C(0x40000000),
    };
    for (uint32_t iRange = 0; iRange < RT_ELEMENTS(s_auRanges); iRange++)
    {
        uint32_t const uFirst = s_auRanges[iRange];

        uint32_t uEax, uEbx, uEcx, uEdx;
        ASMCpuIdExSlow(uFirst, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
        if (uEax >= uFirst && uEax < uFirst + 100)
        {
            uint32_t const cLeafs = RT_MIN(uEax - uFirst + 1, 32);
            for (uint32_t iLeaf = 0; iLeaf < cLeafs; iLeaf++)
            {
                uint32_t uLeaf = uFirst + iLeaf;
                ASMCpuIdExSlow(uLeaf, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);

                /* Clear APIC IDs to avoid submitting new reports all the time. */
                if (uLeaf == 1)
                    uEbx &= UINT32_C(0x00ffffff);
                if (uLeaf == 0xb)
                    uEdx  = 0;
                if (uLeaf == 0x8000001e)
                    uEax  = 0;

                /* Clear some other node/cpu/core/thread ids. */
                if (uLeaf == 0x8000001e)
                {
                    uEbx &= UINT32_C(0xffffff00);
                    uEcx &= UINT32_C(0xffffff00);
                }

                RTPrintf("%08x: %08x %08x %08x %08x\n", uLeaf, uEax, uEbx, uEcx, uEdx);
            }
        }
    }
    RTPrintf("\n");

    /*
     * DMI info.
     */
    RTPrintf("DMI Info\n"
             "--------\n");
    static const struct { const char *pszName; RTSYSDMISTR enmDmiStr; } s_aDmiStrings[] =
    {
        { "Product Name",           RTSYSDMISTR_PRODUCT_NAME },
        { "Product version",        RTSYSDMISTR_PRODUCT_VERSION },
        { "Product UUID",           RTSYSDMISTR_PRODUCT_UUID },
        { "Product Serial",         RTSYSDMISTR_PRODUCT_SERIAL },
        { "System Manufacturer",    RTSYSDMISTR_MANUFACTURER },
    };
    for (uint32_t iDmiString = 0; iDmiString < RT_ELEMENTS(s_aDmiStrings); iDmiString++)
    {
        char szTmp[4096];
        RT_ZERO(szTmp);
        int rc = RTSystemQueryDmiString(s_aDmiStrings[iDmiString].enmDmiStr, szTmp, sizeof(szTmp) - 1);
        if (RT_SUCCESS(rc))
            RTPrintf("%25s: %s\n", s_aDmiStrings[iDmiString].pszName, RTStrStrip(szTmp));
        else
            RTPrintf("%25s: %s [rc=%Rrc]\n", s_aDmiStrings[iDmiString].pszName, RTStrStrip(szTmp), rc);
    }
    RTPrintf("\n");

#else
#endif

    /*
     * Dump the environment.
     */
    RTPrintf("Environment\n"
             "-----------\n");
    RTENV hEnv;
    int rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
    if (RT_SUCCESS(rc))
    {
        uint32_t cVars = RTEnvCountEx(hEnv);
        for (uint32_t iVar = 0; iVar < cVars; iVar++)
        {
            char szVar[1024];
            char szValue[16384];
            rc = RTEnvGetByIndexEx(hEnv, iVar, szVar, sizeof(szVar), szValue, sizeof(szValue));

            /* zap the value of variables that are subject to change. */
            if (   (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW)
                && (   !strcmp(szVar, "TESTBOX_SCRIPT_REV")
                    || !strcmp(szVar, "TESTBOX_ID")
                    || !strcmp(szVar, "TESTBOX_SCRATCH_SIZE")
                    || !strcmp(szVar, "TESTBOX_TIMEOUT")
                    || !strcmp(szVar, "TESTBOX_TIMEOUT_ABS")
                    || !strcmp(szVar, "TESTBOX_TEST_SET_ID")
                   )
               )
               strcpy(szValue, "<volatile>");

            if (RT_SUCCESS(rc))
                RTPrintf("%25s=%s\n", szVar, szValue);
            else if (rc == VERR_BUFFER_OVERFLOW)
                RTPrintf("%25s=%s [VERR_BUFFER_OVERFLOW]\n", szVar, szValue);
            else
                RTPrintf("rc=%Rrc\n", rc);
        }
        RTEnvDestroy(hEnv);
    }

    /** @todo enumerate volumes and whatnot.  */

    int cch = RTPrintf("\n");
    return cch > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
void add_interupt_event_count(int type, unsigned int count)
{
    struct node* event;
    struct node* e;
    int special;

    special = (type == SPECIAL_INT);

    if(g_cp0_regs[CP0_COUNT_REG] > UINT32_C(0x80000000)) SPECIAL_done = 0;

    if (get_event(type)) {
        DebugMessage(M64MSG_WARNING, "two events of type 0x%x in interrupt queue", type);
        /* FIXME: hack-fix for freezing in Perfect Dark
         * http://code.google.com/p/mupen64plus/issues/detail?id=553
         * https://github.com/mupen64plus-ae/mupen64plus-ae/commit/802d8f81d46705d64694d7a34010dc5f35787c7d
         */
        return;
    }

    event = alloc_node(&q.pool);
    if (event == NULL)
    {
        DebugMessage(M64MSG_ERROR, "Failed to allocate node for new interrupt event");
        return;
    }

    event->data.count = count;
    event->data.type = type;

    if (q.first == NULL)
    {
        q.first = event;
        event->next = NULL;
        next_interupt = q.first->data.count;
    }
    else if (before_event(count, q.first->data.count, q.first->data.type) && !special)
    {
        event->next = q.first;
        q.first = event;
        next_interupt = q.first->data.count;
    }
    else
    {
        for(e = q.first;
                e->next != NULL &&
                (!before_event(count, e->next->data.count, e->next->data.type) || special);
                e = e->next);

        if (e->next == NULL)
        {
            e->next = event;
            event->next = NULL;
        }
        else
        {
            if (!special)
                for(; e->next != NULL && e->next->data.count == count; e = e->next);

            event->next = e->next;
            e->next = event;
        }
    }
}
Exemple #29
0
int main()
{
    int rc = 0;
    printf("tstVMStructSize: TESTING\n");

    printf("info: struct VM: %d bytes\n", (int)sizeof(VM));

#define CHECK_PADDING_VM(align, member) \
    do \
    { \
        CHECK_PADDING(VM, member, align); \
        CHECK_MEMBER_ALIGNMENT(VM, member, align); \
        VM *p = NULL; NOREF(p); \
        if (sizeof(p->member.padding) >= (ssize_t)sizeof(p->member.s) + 128 + sizeof(p->member.s) / 20) \
            printf("warning: VM::%-8s: padding=%-5d s=%-5d -> %-4d  suggest=%-5u\n", \
                   #member, (int)sizeof(p->member.padding), (int)sizeof(p->member.s), \
                   (int)sizeof(p->member.padding) - (int)sizeof(p->member.s), \
                   (int)RT_ALIGN_Z(sizeof(p->member.s), (align))); \
    } while (0)


#define CHECK_PADDING_VMCPU(align, member) \
    do \
    { \
        CHECK_PADDING(VMCPU, member, align); \
        CHECK_MEMBER_ALIGNMENT(VMCPU, member, align); \
        VMCPU *p = NULL; NOREF(p); \
        if (sizeof(p->member.padding) >= (ssize_t)sizeof(p->member.s) + 128 + sizeof(p->member.s) / 20) \
            printf("warning: VMCPU::%-8s: padding=%-5d s=%-5d -> %-4d  suggest=%-5u\n", \
                   #member, (int)sizeof(p->member.padding), (int)sizeof(p->member.s), \
                   (int)sizeof(p->member.padding) - (int)sizeof(p->member.s), \
                   (int)RT_ALIGN_Z(sizeof(p->member.s), (align))); \
    } while (0)

#define CHECK_CPUMCTXCORE(member) \
    do { \
        unsigned off1 = RT_OFFSETOF(CPUMCTX, member) - RT_OFFSETOF(CPUMCTX, rax); \
        unsigned off2 = RT_OFFSETOF(CPUMCTXCORE, member); \
        if (off1 != off2) \
        { \
            printf("error! CPUMCTX/CORE:: %s! (%#x vs %#x (ctx))\n", #member, off1, off2); \
            rc++; \
        } \
    } while (0)

#define CHECK_PADDING_UVM(align, member) \
    do \
    { \
        CHECK_PADDING(UVM, member, align); \
        CHECK_MEMBER_ALIGNMENT(UVM, member, align); \
        UVM *p = NULL; NOREF(p); \
        if (sizeof(p->member.padding) >= (ssize_t)sizeof(p->member.s) + 128 + sizeof(p->member.s) / 20) \
            printf("warning: UVM::%-8s: padding=%-5d s=%-5d -> %-4d  suggest=%-5u\n", \
                   #member, (int)sizeof(p->member.padding), (int)sizeof(p->member.s), \
                   (int)sizeof(p->member.padding) - (int)sizeof(p->member.s), \
                   (int)RT_ALIGN_Z(sizeof(p->member.s), (align))); \
    } while (0)

#define CHECK_PADDING_UVMCPU(align, member) \
    do \
    { \
        CHECK_PADDING(UVMCPU, member, align); \
        CHECK_MEMBER_ALIGNMENT(UVMCPU, member, align); \
        UVMCPU *p = NULL; NOREF(p); \
        if (sizeof(p->member.padding) >= (ssize_t)sizeof(p->member.s) + 128 + sizeof(p->member.s) / 20) \
            printf("warning: UVMCPU::%-8s: padding=%-5d s=%-5d -> %-4d  suggest=%-5u\n", \
                   #member, (int)sizeof(p->member.padding), (int)sizeof(p->member.s), \
                   (int)sizeof(p->member.padding) - (int)sizeof(p->member.s), \
                   (int)RT_ALIGN_Z(sizeof(p->member.s), (align))); \
    } while (0)

#define CHECK_PADDING_GVM(align, member) \
    do \
    { \
        CHECK_PADDING(GVM, member, align); \
        CHECK_MEMBER_ALIGNMENT(GVM, member, align); \
        GVM *p = NULL; NOREF(p); \
        if (sizeof(p->member.padding) >= (ssize_t)sizeof(p->member.s) + 128 + sizeof(p->member.s) / 20) \
            printf("warning: GVM::%-8s: padding=%-5d s=%-5d -> %-4d  suggest=%-5u\n", \
                   #member, (int)sizeof(p->member.padding), (int)sizeof(p->member.s), \
                   (int)sizeof(p->member.padding) - (int)sizeof(p->member.s), \
                   (int)RT_ALIGN_Z(sizeof(p->member.s), (align))); \
    } while (0)

#define CHECK_PADDING_GVMCPU(align, member) \
    do \
    { \
        CHECK_PADDING(GVMCPU, member, align); \
        CHECK_MEMBER_ALIGNMENT(GVMCPU, member, align); \
        GVMCPU *p = NULL; NOREF(p); \
        if (sizeof(p->member.padding) >= (ssize_t)sizeof(p->member.s) + 128 + sizeof(p->member.s) / 20) \
            printf("warning: GVMCPU::%-8s: padding=%-5d s=%-5d -> %-4d  suggest=%-5u\n", \
                   #member, (int)sizeof(p->member.padding), (int)sizeof(p->member.s), \
                   (int)sizeof(p->member.padding) - (int)sizeof(p->member.s), \
                   (int)RT_ALIGN_Z(sizeof(p->member.s), (align))); \
    } while (0)

#define PRINT_OFFSET(strct, member) \
    do \
    { \
        printf("info: %10s::%-24s offset %#6x (%6d) sizeof %4d\n",  #strct, #member, (int)RT_OFFSETOF(strct, member), (int)RT_OFFSETOF(strct, member), (int)RT_SIZEOFMEMB(strct, member)); \
    } while (0)


    CHECK_SIZE(uint128_t, 128/8);
    CHECK_SIZE(int128_t, 128/8);
    CHECK_SIZE(uint64_t, 64/8);
    CHECK_SIZE(int64_t, 64/8);
    CHECK_SIZE(uint32_t, 32/8);
    CHECK_SIZE(int32_t, 32/8);
    CHECK_SIZE(uint16_t, 16/8);
    CHECK_SIZE(int16_t, 16/8);
    CHECK_SIZE(uint8_t, 8/8);
    CHECK_SIZE(int8_t, 8/8);

    CHECK_SIZE(X86DESC, 8);
    CHECK_SIZE(X86DESC64, 16);
    CHECK_SIZE(VBOXIDTE, 8);
    CHECK_SIZE(VBOXIDTR, 10);
    CHECK_SIZE(VBOXGDTR, 10);
    CHECK_SIZE(VBOXTSS, 136);
    CHECK_SIZE(X86FXSTATE, 512);
    CHECK_SIZE(RTUUID, 16);
    CHECK_SIZE(X86PTE, 4);
    CHECK_SIZE(X86PD, PAGE_SIZE);
    CHECK_SIZE(X86PDE, 4);
    CHECK_SIZE(X86PT, PAGE_SIZE);
    CHECK_SIZE(X86PTEPAE, 8);
    CHECK_SIZE(X86PTPAE, PAGE_SIZE);
    CHECK_SIZE(X86PDEPAE, 8);
    CHECK_SIZE(X86PDPAE, PAGE_SIZE);
    CHECK_SIZE(X86PDPE, 8);
    CHECK_SIZE(X86PDPT, PAGE_SIZE);
    CHECK_SIZE(X86PML4E, 8);
    CHECK_SIZE(X86PML4, PAGE_SIZE);

    PRINT_OFFSET(VM, cpum);
    CHECK_PADDING_VM(64, cpum);
    CHECK_PADDING_VM(64, vmm);
    PRINT_OFFSET(VM, pgm);
    PRINT_OFFSET(VM, pgm.s.CritSectX);
    CHECK_PADDING_VM(64, pgm);
    PRINT_OFFSET(VM, hm);
    CHECK_PADDING_VM(64, hm);
    CHECK_PADDING_VM(64, trpm);
    CHECK_PADDING_VM(64, selm);
    CHECK_PADDING_VM(64, mm);
    CHECK_PADDING_VM(64, pdm);
    CHECK_PADDING_VM(64, iom);
#ifdef VBOX_WITH_RAW_MODE
    CHECK_PADDING_VM(64, patm);
    CHECK_PADDING_VM(64, csam);
#endif
    CHECK_PADDING_VM(64, em);
    /*CHECK_PADDING_VM(64, iem);*/
    CHECK_PADDING_VM(64, tm);
    CHECK_PADDING_VM(64, dbgf);
    CHECK_PADDING_VM(64, ssm);
    CHECK_PADDING_VM(64, rem);
    CHECK_PADDING_VM(8, vm);
    CHECK_PADDING_VM(8, cfgm);

    PRINT_OFFSET(VMCPU, cpum);
    CHECK_PADDING_VMCPU(64, cpum);
    CHECK_PADDING_VMCPU(64, hm);
    CHECK_PADDING_VMCPU(64, em);
    CHECK_PADDING_VMCPU(64, iem);
    CHECK_PADDING_VMCPU(64, trpm);
    CHECK_PADDING_VMCPU(64, tm);
    CHECK_PADDING_VMCPU(64, vmm);
    CHECK_PADDING_VMCPU(64, pdm);
    CHECK_PADDING_VMCPU(64, iom);
    CHECK_PADDING_VMCPU(64, dbgf);
#if 0
    PRINT_OFFSET(VMCPU, abAlignment2);
#endif
    PRINT_OFFSET(VMCPU, pgm);
    CHECK_PADDING_VMCPU(4096, pgm);
#ifdef VBOX_WITH_STATISTICS
    PRINT_OFFSET(VMCPU, pgm.s.pStatTrap0eAttributionRC);
#endif

    CHECK_MEMBER_ALIGNMENT(VM, selm.s.Tss, 16);
    PRINT_OFFSET(VM, selm.s.Tss);
    PVM pVM = NULL; NOREF(pVM);
    if ((RT_OFFSETOF(VM, selm.s.Tss) & PAGE_OFFSET_MASK) > PAGE_SIZE - sizeof(pVM->selm.s.Tss))
    {
        printf("error! SELM:Tss is crossing a page!\n");
        rc++;
    }
    PRINT_OFFSET(VM, selm.s.TssTrap08);
    if ((RT_OFFSETOF(VM, selm.s.TssTrap08) & PAGE_OFFSET_MASK) > PAGE_SIZE - sizeof(pVM->selm.s.TssTrap08))
    {
        printf("error! SELM:TssTrap08 is crossing a page!\n");
        rc++;
    }
    CHECK_MEMBER_ALIGNMENT(VM, trpm.s.aIdt, 16);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[0], PAGE_SIZE);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[1], PAGE_SIZE);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[0].cpum.s.Host, 64);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[0].cpum.s.Guest, 64);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[1].cpum.s.Host, 64);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[1].cpum.s.Guest, 64);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[0].cpum.s.Hyper, 64);
    CHECK_MEMBER_ALIGNMENT(VM, aCpus[1].cpum.s.Hyper, 64);
#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
    CHECK_MEMBER_ALIGNMENT(VM, cpum.s.pvApicBase, 8);
#endif

    CHECK_MEMBER_ALIGNMENT(VMCPU, vmm.s.u64CallRing3Arg, 8);
#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
    CHECK_MEMBER_ALIGNMENT(VMCPU, vmm.s.CallRing3JmpBufR0, 16);
    CHECK_MEMBER_ALIGNMENT(VMCPU, vmm.s.CallRing3JmpBufR0.xmm6, 16);
#endif
    CHECK_MEMBER_ALIGNMENT(VM, vmm.s.u64LastYield, 8);
    CHECK_MEMBER_ALIGNMENT(VM, vmm.s.StatRunRC, 8);
    CHECK_MEMBER_ALIGNMENT(VM, StatTotalQemuToGC, 8);
    CHECK_MEMBER_ALIGNMENT(VM, rem.s.uPendingExcptCR2, 8);
    CHECK_MEMBER_ALIGNMENT(VM, rem.s.StatsInQEMU, 8);
    CHECK_MEMBER_ALIGNMENT(VM, rem.s.Env, 64);

    /* the VMCPUs are page aligned TLB hit reasons. */
    CHECK_MEMBER_ALIGNMENT(VM, aCpus, 4096);
    CHECK_SIZE_ALIGNMENT(VMCPU, 4096);

    /* cpumctx */
    CHECK_MEMBER_ALIGNMENT(CPUMCTX, fpu, 32);
    CHECK_MEMBER_ALIGNMENT(CPUMCTX, rax, 32);
    CHECK_MEMBER_ALIGNMENT(CPUMCTX, idtr.pIdt, 8);
    CHECK_MEMBER_ALIGNMENT(CPUMCTX, gdtr.pGdt, 8);
    CHECK_MEMBER_ALIGNMENT(CPUMCTX, SysEnter, 8);
    CHECK_CPUMCTXCORE(rax);
    CHECK_CPUMCTXCORE(rcx);
    CHECK_CPUMCTXCORE(rdx);
    CHECK_CPUMCTXCORE(rbx);
    CHECK_CPUMCTXCORE(rsp);
    CHECK_CPUMCTXCORE(rbp);
    CHECK_CPUMCTXCORE(rsi);
    CHECK_CPUMCTXCORE(rdi);
    CHECK_CPUMCTXCORE(r8);
    CHECK_CPUMCTXCORE(r9);
    CHECK_CPUMCTXCORE(r10);
    CHECK_CPUMCTXCORE(r11);
    CHECK_CPUMCTXCORE(r12);
    CHECK_CPUMCTXCORE(r13);
    CHECK_CPUMCTXCORE(r14);
    CHECK_CPUMCTXCORE(r15);
    CHECK_CPUMCTXCORE(es);
    CHECK_CPUMCTXCORE(ss);
    CHECK_CPUMCTXCORE(cs);
    CHECK_CPUMCTXCORE(ds);
    CHECK_CPUMCTXCORE(fs);
    CHECK_CPUMCTXCORE(gs);
    CHECK_CPUMCTXCORE(rip);
    CHECK_CPUMCTXCORE(rflags);

#if HC_ARCH_BITS == 32
    /* CPUMHOSTCTX - lss pair */
    if (RT_OFFSETOF(CPUMHOSTCTX, esp) + 4 != RT_OFFSETOF(CPUMHOSTCTX, ss))
    {
        printf("error! CPUMHOSTCTX lss has been split up!\n");
        rc++;
    }
#endif
    CHECK_SIZE_ALIGNMENT(CPUMCTX, 64);
    CHECK_SIZE_ALIGNMENT(CPUMHOSTCTX, 64);
    CHECK_SIZE_ALIGNMENT(CPUMCTXMSRS, 64);

    /* pdm */
    PRINT_OFFSET(PDMDEVINS, Internal);
    PRINT_OFFSET(PDMDEVINS, achInstanceData);
    CHECK_MEMBER_ALIGNMENT(PDMDEVINS, achInstanceData, 64);
    CHECK_PADDING(PDMDEVINS, Internal, 1);

    PRINT_OFFSET(PDMUSBINS, Internal);
    PRINT_OFFSET(PDMUSBINS, achInstanceData);
    CHECK_MEMBER_ALIGNMENT(PDMUSBINS, achInstanceData, 32);
    CHECK_PADDING(PDMUSBINS, Internal, 1);

    PRINT_OFFSET(PDMDRVINS, Internal);
    PRINT_OFFSET(PDMDRVINS, achInstanceData);
    CHECK_MEMBER_ALIGNMENT(PDMDRVINS, achInstanceData, 32);
    CHECK_PADDING(PDMDRVINS, Internal, 1);

    CHECK_PADDING2(PDMCRITSECT);
    CHECK_PADDING2(PDMCRITSECTRW);

    /* pgm */
#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE)  || defined(VBOX_WITH_RAW_MODE)
    CHECK_MEMBER_ALIGNMENT(PGMCPU, AutoSet, 8);
#endif
    CHECK_MEMBER_ALIGNMENT(PGMCPU, GCPhysCR3, sizeof(RTGCPHYS));
    CHECK_MEMBER_ALIGNMENT(PGMCPU, aGCPhysGstPaePDs, sizeof(RTGCPHYS));
    CHECK_MEMBER_ALIGNMENT(PGMCPU, DisState, 8);
    CHECK_MEMBER_ALIGNMENT(PGMCPU, cPoolAccessHandler, 8);
    CHECK_MEMBER_ALIGNMENT(PGMPOOLPAGE, idx, sizeof(uint16_t));
    CHECK_MEMBER_ALIGNMENT(PGMPOOLPAGE, pvPageR3, sizeof(RTHCPTR));
    CHECK_MEMBER_ALIGNMENT(PGMPOOLPAGE, GCPhys, sizeof(RTGCPHYS));
    CHECK_SIZE(PGMPAGE, 16);
    CHECK_MEMBER_ALIGNMENT(PGMRAMRANGE, aPages, 16);
    CHECK_MEMBER_ALIGNMENT(PGMMMIO2RANGE, RamRange, 16);

    /* rem */
    CHECK_MEMBER_ALIGNMENT(REM, aGCPtrInvalidatedPages, 8);
    CHECK_PADDING3(REMHANDLERNOTIFICATION, u.PhysicalRegister, u.padding);
    CHECK_PADDING3(REMHANDLERNOTIFICATION, u.PhysicalDeregister, u.padding);
    CHECK_PADDING3(REMHANDLERNOTIFICATION, u.PhysicalModify, u.padding);
    CHECK_SIZE_ALIGNMENT(REMHANDLERNOTIFICATION, 8);
    CHECK_MEMBER_ALIGNMENT(REMHANDLERNOTIFICATION, u.PhysicalDeregister.GCPhys, 8);

    /* TM */
    CHECK_MEMBER_ALIGNMENT(TM, TimerCritSect, sizeof(uintptr_t));
    CHECK_MEMBER_ALIGNMENT(TM, VirtualSyncLock, sizeof(uintptr_t));

    /* misc */
    CHECK_PADDING3(EMCPU, u.FatalLongJump, u.achPaddingFatalLongJump);
    CHECK_SIZE_ALIGNMENT(VMMR0JMPBUF, 8);
#ifdef VBOX_WITH_RAW_MODE
    CHECK_SIZE_ALIGNMENT(PATCHINFO, 8);
#endif
#if 0
    PRINT_OFFSET(VM, fForcedActions);
    PRINT_OFFSET(VM, StatQemuToGC);
    PRINT_OFFSET(VM, StatGCToQemu);
#endif

    CHECK_MEMBER_ALIGNMENT(IOM, CritSect, sizeof(uintptr_t));
#ifdef VBOX_WITH_REM
    CHECK_MEMBER_ALIGNMENT(EM, CritSectREM, sizeof(uintptr_t));
#endif
    CHECK_MEMBER_ALIGNMENT(PGM, CritSectX, sizeof(uintptr_t));
    CHECK_MEMBER_ALIGNMENT(PDM, CritSect, sizeof(uintptr_t));
    CHECK_MEMBER_ALIGNMENT(MMHYPERHEAP, Lock, sizeof(uintptr_t));

    /* hm - 32-bit gcc won't align uint64_t naturally, so check. */
    CHECK_MEMBER_ALIGNMENT(HM, u64RegisterMask, 8);
    CHECK_MEMBER_ALIGNMENT(HM, vmx.hostCR4, 8);
    CHECK_MEMBER_ALIGNMENT(HM, vmx.msr.feature_ctrl, 8);
    CHECK_MEMBER_ALIGNMENT(HM, StatTprPatchSuccess, 8);
    CHECK_MEMBER_ALIGNMENT(HMCPU, StatEntry, 8);
    CHECK_MEMBER_ALIGNMENT(HMCPU, vmx.HCPhysVmcs, sizeof(RTHCPHYS));
    CHECK_MEMBER_ALIGNMENT(HMCPU, vmx.u32PinCtls, 8);
    CHECK_MEMBER_ALIGNMENT(HMCPU, DisState, 8);
    CHECK_MEMBER_ALIGNMENT(HMCPU, Event.u64IntrInfo, 8);

    /* Make sure the set is large enough and has the correct size. */
    CHECK_SIZE(VMCPUSET, 32);
    if (sizeof(VMCPUSET) * 8 < VMM_MAX_CPU_COUNT)
    {
        printf("error! VMCPUSET is too small for VMM_MAX_CPU_COUNT=%u!\n", VMM_MAX_CPU_COUNT);
        rc++;
    }

    printf("info: struct UVM: %d bytes\n", (int)sizeof(UVM));

    CHECK_PADDING_UVM(32, vm);
    CHECK_PADDING_UVM(32, mm);
    CHECK_PADDING_UVM(32, pdm);
    CHECK_PADDING_UVM(32, stam);

    printf("info: struct UVMCPU: %d bytes\n", (int)sizeof(UVMCPU));
    CHECK_PADDING_UVMCPU(32, vm);

#ifdef VBOX_WITH_RAW_MODE
    /*
     * Compare HC and RC.
     */
    printf("tstVMStructSize: Comparing HC and RC...\n");
# include "tstVMStructRC.h"
#endif /* VBOX_WITH_RAW_MODE */

    CHECK_PADDING_GVM(4, gvmm);
    CHECK_PADDING_GVM(4, gmm);
    CHECK_PADDING_GVMCPU(4, gvmm);

    /*
     * Check that the optimized access macros for PGMPAGE works correctly.
     */
    PGMPAGE Page;
    PGM_PAGE_CLEAR(&Page);

    CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_NONE);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == false);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == false);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);

    PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_ALL);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_ALL);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);

    PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);

    PGM_PAGE_CLEAR(&Page);
    PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_ALL);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_ALL);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);

    PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);


    PGM_PAGE_CLEAR(&Page);
    PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_ALL);
    PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_ALL);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);

    PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_WRITE);
    PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_ALL);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_ALL);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == true);

    PGM_PAGE_SET_HNDL_PHYS_STATE(&Page, PGM_PAGE_HNDL_PHYS_STATE_WRITE);
    PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);

    PGM_PAGE_SET_HNDL_VIRT_STATE(&Page, PGM_PAGE_HNDL_VIRT_STATE_NONE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_PHYS_STATE(&Page) == PGM_PAGE_HNDL_PHYS_STATE_WRITE);
    CHECK_EXPR(PGM_PAGE_GET_HNDL_VIRT_STATE(&Page) == PGM_PAGE_HNDL_VIRT_STATE_NONE);
    CHECK_EXPR(PGM_PAGE_HAS_ANY_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_HANDLERS(&Page) == true);
    CHECK_EXPR(PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(&Page) == false);

#undef AssertFatal
#define AssertFatal(expr) do { } while (0)
#undef Assert
#define Assert(expr)      do { } while (0)

    PGM_PAGE_CLEAR(&Page);
    CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == 0);
    PGM_PAGE_SET_HCPHYS(NULL, &Page, UINT64_C(0x0000fffeff1ff000));
    CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == UINT64_C(0x0000fffeff1ff000));
    PGM_PAGE_SET_HCPHYS(NULL, &Page, UINT64_C(0x0000000000001000));
    CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == UINT64_C(0x0000000000001000));

    PGM_PAGE_INIT(&Page, UINT64_C(0x0000feedfacef000), UINT32_C(0x12345678), PGMPAGETYPE_RAM, PGM_PAGE_STATE_ALLOCATED);
    CHECK_EXPR(PGM_PAGE_GET_HCPHYS_NA(&Page) == UINT64_C(0x0000feedfacef000));
    CHECK_EXPR(PGM_PAGE_GET_PAGEID(&Page) == UINT32_C(0x12345678));
    CHECK_EXPR(PGM_PAGE_GET_TYPE_NA(&Page)   == PGMPAGETYPE_RAM);
    CHECK_EXPR(PGM_PAGE_GET_STATE_NA(&Page)  == PGM_PAGE_STATE_ALLOCATED);


    /*
     * Report result.
     */
    if (rc)
        printf("tstVMStructSize: FAILURE - %d errors\n", rc);
    else
        printf("tstVMStructSize: SUCCESS\n");
    return rc;
}
Exemple #30
0
int main(int argc, char **argv)
{
    const char *infile_name = NULL;
    const char *outfile_name = NULL;
    if (argc != 3) {
        fprintf(stderr, "build GENH from Taiko no Tatsukin Atsumete Tomodachi Daisakusen .nus3bank\n");
        fprintf(stderr, "usage: ttatd SONG_YUGEN.nus3bank SONG_YUGEN.genh\n");
        return -1;
    }

    infile_name = argv[1];
    outfile_name = argv[2];

    FILE *infile = fopen(infile_name, "rb");
    CHECK_ERRNO(NULL == infile, "input file open failed");

    const long nus3_offset = 0;
    EXPECT_32_BE(nus3_offset, infile, 0x4E555333, "NUS3");
    const long nus3_size = get_32_le_seek(nus3_offset + 4, infile) + 8;
    const long nus3_end = nus3_offset + nus3_size;

    EXPECT_32_BE(nus3_offset + 8, infile, 0x42414E4B, "BANK");

    long chunk_offset = nus3_offset + 12;

    long PACK_offset = -1;
    uint32_t PACK_size = 0;

    /* scan to find PACK */
    while (chunk_offset < nus3_end)
    {
        uint32_t chunk_type = get_32_be_seek(chunk_offset, infile);
        long     chunk_size = get_32_le(infile);

        //printf("offset: %"PRIx32" type: %"PRIx32" size: %"PRIx32"\n", (uint32_t)chunk_offset, chunk_type, (uint32_t)chunk_size);

        switch (chunk_type)
        {
            case UINT32_C(0x544F4320):  /* TOC  */
            case UINT32_C(0x50524F50):  /* PROP */
            case UINT32_C(0x42494E46):  /* BINF */
            case UINT32_C(0x47525020):  /* GRP  */
            case UINT32_C(0x44544F4E):  /* DTON */
            case UINT32_C(0x544F4E45):  /* TONE */
            case UINT32_C(0x4A554E4B):  /* JUNK */
                break;

            case UINT32_C(0x5041434B):  /* PACK */
                CHECK_ERROR(PACK_offset != -1, "expected only one PACK");
                PACK_offset = chunk_offset + 8;
                PACK_size = chunk_size;
                break;

            default:
                fprintf(stderr, "unexpected chunk %"PRIx32" at 0x%lx\n", chunk_type, chunk_offset);
                CHECK_ERROR(1, "who knows?");
                break;
        }
        chunk_offset += 8 + chunk_size;
        CHECK_ERROR(chunk_offset > nus3_end, "truncated chunk");
    }

    CHECK_ERROR(PACK_offset == -1, "missing PACK");

    const long IDSP_offset = PACK_offset;
    EXPECT_32_BE(IDSP_offset, infile, 0x49445350, "IDSP");

    EXPECT_32_BE(IDSP_offset + 4, infile, 0, "0 at IDSP+4");
    const uint32_t channels    = get_32_be_seek(IDSP_offset + 0x08, infile);
    CHECK_ERROR(channels != 1 && channels != 2,
        "only mono and stereo supported in GENH");

    const uint32_t sample_rate = get_32_be_seek(IDSP_offset + 0x0c, infile);
    const uint32_t sample_count= get_32_be_seek(IDSP_offset + 0x10, infile);
    EXPECT_32_BE(IDSP_offset + 0x14, infile, 0, "0 at IDSP+0x14");
    EXPECT_32_BE(IDSP_offset + 0x18, infile, 0, "0 at IDSP+0x18");
    EXPECT_32_BE(IDSP_offset + 0x1c, infile, 0, "0 at IDSP+0x1c");
    const uint32_t ch_head_offset = get_32_be_seek(IDSP_offset + 0x20, infile);
    const uint32_t ch_head_size   = get_32_be_seek(IDSP_offset + 0x24, infile);
    const uint32_t ch_body_offset = get_32_be_seek(IDSP_offset + 0x28, infile);
    const uint32_t ch_body_size   = get_32_be_seek(IDSP_offset + 0x2c, infile);

    CHECK_ERROR(ch_head_size != 0x60, "expected 0x60 header per channel");

    int loop_flag = 0;
    int loop_start = 0;
    int loop_end = 0;

    /* read header for checking and loop info */
    for (unsigned int c = 0; c < channels; c++) {
        struct dsp_header h;
        read_dsp_header(&h, infile, IDSP_offset + ch_head_offset + ch_head_size * c);

        CHECK_ERROR(h.sample_count != sample_count, "sample count mismatch");
        CHECK_ERROR(dsp_nibbles_to_samples(h.nibble_count) != sample_count, "nibble count mismatch");
        CHECK_ERROR(h.sample_rate  != sample_rate,  "sample rate mismatch");
        CHECK_ERROR(h.format != 0, "not DSP format?");

        CHECK_ERROR(c > 0 && ((h.loop_flag && !loop_flag) || (!h.loop_flag && loop_flag)), "loop flag mismatch");

        if (h.loop_flag) {
            loop_flag = 1;
            uint32_t new_loop_start = dsp_nibbles_to_samples(h.loop_start_offset);
            uint32_t new_loop_end   = dsp_nibbles_to_samples(h.loop_end_offset);
            if (c > 0) {
                CHECK_ERROR(loop_start != new_loop_start || loop_end != new_loop_end, "loop point mismatch");
            }

            loop_start = new_loop_start;
            loop_end = new_loop_end;
        }
    }


    long IDSP_size = ch_head_offset + (ch_head_size + ch_body_size) * channels;
    CHECK_ERROR(IDSP_size != PACK_size, "IDSP size does not match PACK size");

    /* build GENH */
    unsigned char genh_head[0x38];
    memset(genh_head, 0, sizeof(genh_head));

    /* header magic */
    memcpy(&genh_head[0x00], "GENH", 4);

    /* channel count */
    write_32_le(channels, &genh_head[0x04]);

    /* interleave */
    if (channels == 1)
    {
      write_32_le(0, &genh_head[0x08]);
    }
    else if (channels == 2)
    {
      // no interleave, but GENH does split data like this
      write_32_le(ch_body_size, &genh_head[0x08]);
    }

    /* sample rate */
    write_32_le(sample_rate, &genh_head[0x0c]);

    /* loop start */
    if (loop_flag) {
        write_32_le(loop_start, &genh_head[0x10]);
    } else {
        write_32_le(~UINT32_C(0), &genh_head[0x10]);
    }

    /* loop end */
    if (loop_flag) {
        write_32_le(loop_end, &genh_head[0x14]);
    } else {
        write_32_le(sample_count, &genh_head[0x14]);
    }

    /* coding type, coding_NGC_DSP */
    write_32_le(12, &genh_head[0x18]);

    /* start_offset */
    write_32_le(0x38 + IDSP_offset + ch_body_offset, &genh_head[0x1c]);

    /* header_size */
    write_32_le(0x38, &genh_head[0x20]);

    /* dsp coefs */
    write_32_le(0x38 + IDSP_offset + ch_head_offset + 0x1c, &genh_head[0x24]);
    if (channels == 2) {
        write_32_le(0x38 + IDSP_offset + ch_head_offset + ch_head_size + 0x1c, &genh_head[0x28]);
    }

    /* dsp interleave type */
    if (channels == 1) {
        /* no interleave */
          write_32_le(2, &genh_head[0x2c]);
    }

    /* normal coefs */
    //write_32_le(0, &genh_head[0x30]);

    FILE *outfile = fopen(outfile_name, "wb");
    CHECK_ERRNO(NULL == outfile, "output file open failed");

    put_bytes(outfile, genh_head, sizeof(genh_head));
    dump(infile, outfile, nus3_offset, nus3_size);

    CHECK_ERRNO(EOF == fclose(outfile), "fclose of output file");
}