Ignore:
Timestamp:
Nov 10, 2006, 4:04:42 AM (19 years ago)
Author:
bird
Message:

Put the PE module interpreter thru the wringer and learnt how much the window file mapping API sucks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/tstkLdrMod.c

    r2860 r2861  
    4040*******************************************************************************/
    4141/** The default base address used in the tests. */
    42 #define MY_BASEADDRESS      0x4200000
     42#define MY_BASEADDRESS      0x2400000
    4343
    4444
     
    6969
    7070
     71/** Dummy import resolver callback. */
     72static int BasicTestsGetImport(PKLDRMOD pMod, uint32_t iImport, uint32_t iSymbol, const char *pszSymbol,
     73                               PKLDRADDR puValue, uint32_t *pfKind, void *pvUser)
     74{
     75    *puValue = 0xdeadface;
     76    *pfKind = KLDRSYMKIND_NO_BIT | KLDRSYMKIND_NO_TYPE;
     77    return 0;
     78}
     79
     80
     81
     82/**
     83 * Performs basic relocation tests.
     84 */
     85static int BasicTestsRelocate(PKLDRMOD pMod, void *pvBits, void *pvBits2)
     86{
     87    const size_t cbImage = (size_t)kLdrModSize(pMod);
     88    int rc;
     89
     90    printf("* Relocation test...\n");
     91
     92    /*
     93     * Get the same bits again to check that we get the same result.
     94     */
     95    memset(pvBits2, 0xfe, cbImage);
     96    rc = kLdrModGetBits(pMod, pvBits2, (uintptr_t)pvBits, BasicTestsGetImport, NULL);
     97    if (rc)
     98        return Failure("failed to get image bits, rc=%d (a)", rc);
     99    if (memcmp(pvBits2, pvBits, cbImage))
     100        return Failure("relocation test failed, mismatching bits (a)");
     101
     102    /*
     103     * Short relocation round trip.
     104     */
     105    rc = kLdrModRelocateBits(pMod, pvBits2, 0x1000, (uintptr_t)pvBits, BasicTestsGetImport, NULL);
     106    if (rc)
     107        return Failure("failed to relocate, rc=%d (b1)");
     108    rc = kLdrModRelocateBits(pMod, pvBits2, (uintptr_t)pvBits, 0x1000, BasicTestsGetImport, NULL);
     109    if (rc)
     110        return Failure("failed to relocate, rc=%d (b2)");
     111    if (memcmp(pvBits2, pvBits, cbImage))
     112        return Failure("relocation test failed, mismatching bits (b)");
     113
     114    /*
     115     * Longer trip where we also check the intermediate results.
     116     */
     117    /* stage one */
     118    rc = kLdrModRelocateBits(pMod, pvBits, 0x1000000, (uintptr_t)pvBits, BasicTestsGetImport, NULL);
     119    if (rc)
     120        return Failure("failed to relocate, rc=%d (c1)");
     121    memset(pvBits2, 0xfe, cbImage);
     122    rc = kLdrModGetBits(pMod, pvBits2, 0x1000000, BasicTestsGetImport, NULL);
     123    if (rc)
     124        return Failure("failed to get image bits, rc=%d (c1)", rc);
     125    if (memcmp(pvBits2, pvBits, cbImage))
     126        return Failure("relocation test failed, mismatching bits (c1)");
     127
     128    /* stage two */
     129    rc = kLdrModRelocateBits(pMod, pvBits, ~(uintptr_t)0x1010000, 0x1000000, BasicTestsGetImport, NULL);
     130    if (rc)
     131        return Failure("failed to relocate, rc=%d (c2)");
     132    memset(pvBits2, 0xef, cbImage);
     133    rc = kLdrModGetBits(pMod, pvBits2, ~(uintptr_t)0x1010000, BasicTestsGetImport, NULL);
     134    if (rc)
     135        return Failure("failed to get image bits, rc=%d (c2)", rc);
     136    if (memcmp(pvBits2, pvBits, cbImage))
     137        return Failure("relocation test failed, mismatching bits (c2)");
     138
     139    /* stage three */
     140    rc = kLdrModRelocateBits(pMod, pvBits, MY_BASEADDRESS, ~(uintptr_t)0x1010000, BasicTestsGetImport, NULL);
     141    if (rc)
     142        return Failure("failed to relocate, rc=%d (c3)");
     143    memset(pvBits2, 0xef, cbImage);
     144    rc = kLdrModGetBits(pMod, pvBits2, MY_BASEADDRESS, BasicTestsGetImport, NULL);
     145    if (rc)
     146        return Failure("failed to get image bits, rc=%d (c3)", rc);
     147    if (memcmp(pvBits2, pvBits, cbImage))
     148        return Failure("relocation test failed, mismatching bits (c3)");
     149
     150    /* stage four */
     151    rc = kLdrModRelocateBits(pMod, pvBits, ~(uintptr_t)0 / 2 - 0x10000, MY_BASEADDRESS, BasicTestsGetImport, NULL);
     152    if (rc)
     153        return Failure("failed to relocate, rc=%d (c4)");
     154    memset(pvBits2, 0xdc, cbImage);
     155    rc = kLdrModGetBits(pMod, pvBits2, ~(uintptr_t)0 / 2 - 0x10000, BasicTestsGetImport, NULL);
     156    if (rc)
     157        return Failure("failed to get image bits, rc=%d (c4)", rc);
     158    if (memcmp(pvBits2, pvBits, cbImage))
     159        return Failure("relocation test failed, mismatching bits (c4)");
     160
     161    /* return */
     162    rc = kLdrModRelocateBits(pMod, pvBits, (uintptr_t)pvBits, ~(uintptr_t)0 / 2 - 0x10000, BasicTestsGetImport, NULL);
     163    if (rc)
     164        return Failure("failed to relocate, rc=%d (c5)");
     165    memset(pvBits2, 0xcd, cbImage);
     166    rc = kLdrModGetBits(pMod, pvBits2, (uintptr_t)pvBits, BasicTestsGetImport, NULL);
     167    if (rc)
     168        return Failure("failed to get image bits, rc=%d (c5)", rc);
     169    if (memcmp(pvBits2, pvBits, cbImage))
     170        return Failure("relocation test failed, mismatching bits (c5)");
     171
     172    return 0;
     173}
     174
     175
    71176/**
    72177 * Dump symbols and check that we can query each of them recursivly.
     
    91196                                &uValue2, &fKind2);
    92197        if (rc)
    93             return Failure("Couldn't find symbol %#x (%s) by ordinal. rc=%d\n", iSymbol, pszSymbol, rc);
     198            return Failure("Couldn't find symbol %#x (%s) by ordinal. rc=%d", iSymbol, pszSymbol, rc);
    94199        if (uValue != uValue2)
    95             return Failure("Symbol %#x (%s): Value mismatch %016" PRI_KLDRADDR " != %016" PRI_KLDRADDR " (enum!=query/ord)  pvBits=%p\n",
     200            return Failure("Symbol %#x (%s): Value mismatch %016" PRI_KLDRADDR " != %016" PRI_KLDRADDR " (enum!=query/ord)  pvBits=%p",
    96201                           iSymbol, pszSymbol, uValue, uValue2, pvUser);
    97202        if (fKind != fKind2)
    98             return Failure("Symbol %#x (%s): Kind mismatch %#x != %#x (enum!=query/ord) pvBits=%p\n",
     203            return Failure("Symbol %#x (%s): Kind mismatch %#x != %#x (enum!=query/ord) pvBits=%p",
    99204                           iSymbol, pszSymbol, fKind, fKind2, pvUser);
    100205    }
     
    106211                                &uValue2, &fKind2);
    107212        if (rc)
    108             return Failure("Couldn't find symbol %#x (%s) by name. rc=%d\n", iSymbol, pszSymbol, rc);
     213            return Failure("Couldn't find symbol %#x (%s) by name. rc=%d", iSymbol, pszSymbol, rc);
    109214        if (uValue != uValue2)
    110             return Failure("Symbol %#x (%s): Value mismatch %016" PRI_KLDRADDR " != %016" PRI_KLDRADDR " (enum!=query/name) pvBits=%p\n",
     215            return Failure("Symbol %#x (%s): Value mismatch %016" PRI_KLDRADDR " != %016" PRI_KLDRADDR " (enum!=query/name) pvBits=%p",
    111216                           iSymbol, pszSymbol, uValue, uValue2, pvUser);
    112217        if (fKind != fKind2)
    113             return Failure("Symbol %#x (%s): Kind mismatch %#x != %#x (enum!=query/name) pvBits=%p\n",
     218            return Failure("Symbol %#x (%s): Kind mismatch %#x != %#x (enum!=query/name) pvBits=%p",
    114219                           iSymbol, pszSymbol, fKind, fKind2, pvUser);
    115220    }
     
    153258    KLDRSTACKINFO StackInfo;
    154259
     260    printf("* Testing queries with pvBits=%p...\n", pvBits);
     261
    155262    /*
    156263     * Get the import modules.
     
    159266    printf("cImports=%d\n", cImports);
    160267    if (cImports < 0)
    161         return Failure("failed to allocate %d bytes for the image", cImports);
     268        return Failure("failed to query the number of import, cImports=%d", cImports);
    162269    for (i = 0; i < cImports; i++)
    163270    {
     
    201308    if (MainEPAddress == ~(KLDRADDR)42)
    202309        return Failure("MainEPAddress wasn't set.");
     310    if (MainEPAddress != NIL_KLDRADDR && MainEPAddress < MY_BASEADDRESS)
     311        return Failure("Bad MainEPAddress (a).");
     312    if (MainEPAddress != NIL_KLDRADDR && MainEPAddress >= MY_BASEADDRESS + kLdrModSize(pMod))
     313        return Failure("Bad MainEPAddress (b).");
    203314
    204315    /*
     
    256367*/
    257368
    258     return 0;
    259 }
    260 
    261 
    262 /** Dummy import resolver callback. */
    263 static int BasicTestsGetImport(PKLDRMOD pMod, uint32_t iImport, uint32_t iSymbol, const char *pszSymbol,
    264                                PKLDRADDR puValue, uint32_t *pfKind, void *pvUser)
    265 {
    266     *puValue = 0xdeadface;
    267     *pfKind = KLDRSYMKIND_NO_BIT | KLDRSYMKIND_NO_TYPE;
    268369    return 0;
    269370}
     
    354455    }
    355456
     457
    356458    /*
    357459     * Get image the size and query the image bits.
    358460     */
     461    printf("* Testing user mapping...\n");
     462
    359463    cbImage = (size_t)kLdrModSize(pMod);
    360464    if (cbImage != kLdrModSize(pMod))
    361         return Failure("aborting test because the image is too huge!\n");
     465        return Failure("aborting test because the image is too huge!");
    362466    pvBits = malloc((size_t)cbImage);
    363467    if (!pvBits)
    364         return Failure("failed to allocate %d bytes for the image\n", cbImage);
     468        return Failure("failed to allocate %d bytes for the image", cbImage);
    365469
    366470    rc = kLdrModGetBits(pMod, pvBits, (uintptr_t)pvBits, BasicTestsGetImport, NULL);
    367471    if (rc)
    368         return Failure("failed to allocate %d bytes for the image\n", cbImage);
     472        return Failure("failed to get image bits, rc=%d", rc);
    369473
    370474    /*
     
    372476     */
    373477    rc = BasicTestsSub2(pMod, pvBits);
     478    if (!rc)
     479    {
     480        /*
     481         * Test relocating the bits in a few different ways before we're done with them.
     482         */
     483        void *pvBits2 = malloc((size_t)cbImage);
     484        if (pvBits2)
     485        {
     486            rc = BasicTestsRelocate(pMod, pvBits, pvBits2);
     487            free(pvBits2);
     488        }
     489        else
     490            rc = Failure("failed to allocate %d bytes for the 2nd image", cbImage);
     491    }
     492
    374493    free(pvBits);
    375494    return rc;
     
    378497
    379498/**
     499 * Tests the mapping related api, after mapping.
     500 */
     501static int BasicTestsSubMap2(PKLDRMOD pMod)
     502{
     503    int rc;
     504
     505    rc = kLdrModFixupMapping(pMod, BasicTestsGetImport, NULL);
     506    if (rc)
     507        return Failure("kLdrModFixupMapping (a) failed, rc=%d", rc);
     508
     509    rc = kLdrModReload(pMod);
     510    if (rc)
     511        return Failure("kLdrModReload (a) failed, rc=%d", rc);
     512
     513    rc = kLdrModReload(pMod);
     514    if (rc)
     515        return Failure("kLdrModReload (b) failed, rc=%d", rc);
     516
     517    rc = kLdrModFixupMapping(pMod, BasicTestsGetImport, NULL);
     518    if (rc)
     519        return Failure("kLdrModFixupMapping (b) failed, rc=%d", rc);
     520
     521    rc = kLdrModAllocTLS(pMod);
     522    if (rc)
     523        return Failure("kLdrModAllocTLS (a) failed, rc=%d", rc);
     524    kLdrModFreeTLS(pMod);
     525
     526    rc = kLdrModAllocTLS(pMod);
     527    if (rc)
     528        return Failure("kLdrModAllocTLS (b) failed, rc=%d", rc);
     529    kLdrModFreeTLS(pMod);
     530
     531    /*
     532     * Repeat the BasicTestsSub2 with pvBits as NULL to test module
     533     * interpreters that can utilize the mapping.
     534     */
     535    rc = BasicTestsSub2(pMod, NULL);
     536    if (rc)
     537        return Failure("BasicTestsSub2 in Map2 failed, rc=%d", rc);
     538    return 0;
     539}
     540
     541
     542/**
    380543 * Tests the mapping related api.
    381544 */
    382545static int BasicTestsSubMap(PKLDRMOD pMod)
    383546{
    384     int rc;
     547    int rc, rc2;
     548    printf("* Mapping tests...\n");
    385549
    386550    rc = kLdrModMap(pMod);
    387551    if (rc)
    388         return Failure("kLdrModMap failed, rc=%d\n", rc);
    389 
    390     return 0;
     552        return Failure("kLdrModMap failed, rc=%d", rc);
     553    rc = BasicTestsSubMap2(pMod);
     554    rc2 = kLdrModUnmap(pMod);
     555    if (rc2)
     556    {
     557        Failure("kLdrModUnmap failed, rc=%d", rc2);
     558        rc = rc ? rc : rc2;
     559    }
     560
     561    printf("* Mapping tests done.\n");
     562    return rc;
    391563}
    392564
     
    400572    int rc, rc2;
    401573
    402     printf("tstLdrMod: Testing '%s'\n", pszFilename);
     574    printf("tstLdrMod: Testing '%s'", pszFilename);
    403575    rc = kLdrModOpen(pszFilename, &pMod);
    404576    if (!rc)
     
    407579        if (!rc)
    408580            rc = BasicTestsSubMap(pMod);
     581        if (!rc)
     582            rc = BasicTestsSub2(pMod, NULL);
    409583        rc2 = kLdrModClose(pMod);
    410584        if (rc2)
    411             Failure("failed to close '%s', rc=%d\n", pszFilename, rc);
     585            Failure("failed to close '%s', rc=%d", pszFilename, rc);
    412586        if (rc2 && !rc)
    413587            rc = rc2;
    414588    }
    415589    else
    416         Failure("Failed to open '%s', rc=%d\n", pszFilename, rc);
     590        Failure("Failed to open '%s', rc=%d", pszFilename, rc);
    417591    return rc ? 1 : 0;
    418592}
Note: See TracChangeset for help on using the changeset viewer.