Changeset 2860


Ignore:
Timestamp:
Nov 8, 2006, 5:10:14 AM (19 years ago)
Author:
bird
Message:

Working on the mapping stuff (windows is gonna be a headache).

Location:
trunk/kLdr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdrModPE.c

    r2859 r2860  
    551551static int kldrModPEDoMap(PKLDRMODPE pModPE, unsigned fForReal)
    552552{
    553     return -1;
     553    PKLDRMOD    pMod = pModPE->pMod;
     554    unsigned    fFixed;
     555    void       *pvBase;
     556    size_t      cb;
     557    int         rc;
     558    uint32_t    i;
     559
     560    /*
     561     * Prepare it.
     562     */
     563    /* size */
     564    cb = (size_t)pMod->pOps->pfnSize(pModPE->pMod);
     565    if (cb != pMod->pOps->pfnSize(pModPE->pMod))
     566        return KLDR_ERR_ADDRESS_OVERFLOW;
     567
     568    /* fixed image? */
     569    fFixed = fForReal
     570          && (   pMod->enmType == KLDRTYPE_EXECUTABLE_FIXED
     571              || pMod->enmType == KLDRTYPE_SHARED_LIBRARY_FIXED);
     572    if (!fFixed)
     573        pvBase = NULL;
     574    else
     575    {
     576        pvBase = (void *)(uintptr_t)pMod->aSegments[0].LinkAddress;
     577        if ((uintptr_t)pvBase != pMod->aSegments[0].LinkAddress)
     578            return KLDR_ERR_ADDRESS_OVERFLOW;
     579    }
     580
     581    /* try do the prepare */
     582    rc = kLdrRdrPrepare(pMod->pRdr, &pvBase, cb, fFixed);
     583    if (rc)
     584        return rc;
     585
     586    /*
     587     * Map the segments (sub sections in PE terms).
     588     */
     589    for (i = 0; i < pMod->cSegments; i++)
     590    {
     591        void *pvSeg;
     592
     593        if (!pMod->aSegments[i].Alignment)
     594            continue;
     595
     596        pvSeg = (uint8_t *)pvBase + pMod->aSegments[i].RVA;
     597        rc = kLdrRdrMap(pMod->pRdr, pvSeg, pMod->aSegments[i].cbMapped, pMod->aSegments[i].enmProt,
     598                        pMod->aSegments[i].offFile, pMod->aSegments[i].cbFile);
     599        if (rc)
     600        {
     601            /* bailout */
     602            while (i-- > 0)
     603            {
     604                if (!pMod->aSegments[i].Alignment)
     605                    continue;
     606
     607                kLdrRdrUnmap(pMod->pRdr, (void *)pMod->aSegments[i].MapAddress, pMod->aSegments[i].cbMapped);
     608                pMod->aSegments[i].MapAddress = 0;
     609            }
     610            break;
     611        }
     612        pMod->aSegments[i].MapAddress = (uintptr_t)pvSeg;
     613    }
     614
     615    if (!rc)
     616    {
     617        if (fForReal)
     618            pModPE->pvMapping = pvBase;
     619        else
     620            pModPE->pvBits = pvBase;
     621    }
     622    else
     623        kLdrRdrUnprepare(pMod->pRdr, pvBase, cb);
     624    return rc;
    554625}
    555626
     
    567638static int kldrModPEDoUnmap(PKLDRMODPE pModPE, const void *pvMapping)
    568639{
    569     return -1;
     640    PKLDRMOD    pMod = pModPE->pMod;
     641    size_t      cb = (size_t)pMod->pOps->pfnSize(pModPE->pMod);
     642    int         rc2;
     643    int         rc = 0;
     644    uint32_t    i;
     645
     646    /*
     647     * Unmap the segments (sub sections in PE terms).
     648     */
     649    for (i = 0; i < pMod->cSegments; i++)
     650    {
     651        if (!pMod->aSegments[i].MapAddress)
     652            continue;
     653
     654        rc2 = kLdrRdrUnmap(pMod->pRdr, (void *)pMod->aSegments[i].MapAddress, pMod->aSegments[i].cbMapped);
     655        if (!rc2)
     656            pMod->aSegments[i].MapAddress = 0;
     657        else if (!rc)
     658            rc = rc2;
     659    }
     660
     661    /*
     662     * 'Unprepare' the mapping region.
     663     */
     664    if (!rc)
     665    {
     666        rc = kLdrRdrUnprepare(pMod->pRdr, (void *)pvMapping, cb);
     667        if (!rc)
     668        {
     669            if (pModPE->pvBits == pvMapping)
     670                pModPE->pvBits = NULL;
     671            if (pModPE->pvMapping == pvMapping)
     672                pModPE->pvMapping = NULL;
     673        }
     674    }
     675
     676    return rc;
    570677}
    571678
  • trunk/kLdr/kLdrRdrFile.c

    r2858 r2860  
    5252*******************************************************************************/
    5353/**
     54 * Prepared stuff.
     55 */
     56typedef struct KLDRRDRFILEPREP
     57{
     58    /** The address of the prepared region. */
     59    void           *pv;
     60    /** The size of the prepared region. */
     61    size_t          cb;
     62#if defined(__WIN__) || defined(__NT__)
     63    /** Handle to the section created to map the file. */
     64    HANDLE          hSection;
     65#endif
     66} KLDRRDRFILEPREP, *PKLDRRDRFILEPREP;
     67
     68/**
    5469 * The file provier instance for native files.
    5570 */
     
    5772{
    5873    /** The file reader vtable. */
    59     KLDRRDR     Core;
     74    KLDRRDR             Core;
    6075    /** The file handle. */
    6176#ifdef __OS2__
    62     HFILE       File;
     77    HFILE               File;
    6378#elif defined(__WIN__) || defined(__NT__)
    64     HANDLE      File;
     79    HANDLE              File;
    6580#else
    6681# error "Port me!"
    6782#endif
    6883    /** The current file offset. */
    69     off_t       off;
     84    off_t               off;
    7085    /** The file size. */
    71     off_t       cb;
     86    off_t               cb;
     87    /** Array where we stuff the mapping area data. */
     88    KLDRRDRFILEPREP     aPreps[4];
     89    /** The number of current preps. */
     90    uint32_t            cPreps;
    7291    /** Number of mapping references. */
    73     int32_t     cMappings;
     92    int32_t             cMappings;
    7493    /** The memory mapping. */
    75     void       *pvMapping;
     94    void               *pvMapping;
    7695    /** The filename. */
    77     char        szFilename[1];
     96    char                szFilename[1];
    7897} KLDRRDRFILE, *PKLDRRDRFILE;
    7998
     
    133152}
    134153
     154
     155/**
     156 * Finds a prepared mapping region.
     157 *
     158 * @returns Pointer to the aPrep entry.
     159 * @param   pFile   The instance data.
     160 * @param   pv      The base of the region.
     161 * @param   cb      The size of the region.
     162 */
     163static PKLDRRDRFILEPREP kldrRdrFileFindPrepExact(PKLDRRDRFILE pFile, void *pv, size_t cb)
     164{
     165    int32_t i = pFile->cPreps;
     166    while (i-- > 0)
     167        if (    pFile->aPreps[i].pv == pv
     168            ||  pFile->aPreps[i].cb == cb)
     169            return &pFile->aPreps[i];
     170    return NULL;
     171}
     172
     173
     174/**
     175 * Finds a prepared mapping region containing the specified region.
     176 *
     177 * @returns Pointer to the aPrep entry.
     178 * @param   pFile   The instance data.
     179 * @param   pv      The base of the sub region.
     180 * @param   cb      The size of the sub region.
     181 */
     182static PKLDRRDRFILEPREP kldrRdrFileFindPrepWithin(PKLDRRDRFILE pFile, void *pv, size_t cb)
     183{
     184    int32_t i = pFile->cPreps;
     185    while (i-- > 0)
     186        if ((uintptr_t)pv - (uintptr_t)pFile->aPreps[i].pv < pFile->aPreps[i].cb)
     187        {
     188            if ((uintptr_t)pv - (uintptr_t)pFile->aPreps[i].pv + cb <= pFile->aPreps[i].cb)
     189                return &pFile->aPreps[i];
     190            return NULL;
     191        }
     192    return NULL;
     193}
     194
     195
    135196/** @copydoc KLDRRDR::pfnUnprepare */
    136197static int      kldrRdrFileUnprepare(PKLDRRDR pRdr, void *pv, size_t cb)
    137198{
     199    PKLDRRDRFILE        pRdrFile = (PKLDRRDRFILE)pRdr;
     200    PKLDRRDRFILEPREP    pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb);
     201    if (!pPrep)
     202        return KLDR_ERR_INVALID_PARAMETER;
     203
    138204    return -1;
    139205}
     
    143209static int      kldrRdrFileUnmap(PKLDRRDR pRdr, void *pv, size_t cb)
    144210{
     211    PKLDRRDRFILE        pRdrFile = (PKLDRRDRFILE)pRdr;
     212    PKLDRRDRFILEPREP    pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb);
     213    if (!pPrep)
     214        return KLDR_ERR_INVALID_PARAMETER;
     215
    145216    return -1;
    146217}
     
    150221static int      kldrRdrFileProtect(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt)
    151222{
     223    PKLDRRDRFILE        pRdrFile = (PKLDRRDRFILE)pRdr;
     224    PKLDRRDRFILEPREP    pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb);
     225    if (!pPrep)
     226        return KLDR_ERR_INVALID_PARAMETER;
     227
    152228    return -1;
    153229}
     
    157233static int      kldrRdrFileRefreshMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile)
    158234{
     235    PKLDRRDRFILE        pRdrFile = (PKLDRRDRFILE)pRdr;
     236    PKLDRRDRFILEPREP    pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb);
     237    if (!pPrep)
     238        return KLDR_ERR_INVALID_PARAMETER;
     239
    159240    return -1;
    160241}
     
    164245static int      kldrRdrFileMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile)
    165246{
     247    PKLDRRDRFILE        pRdrFile = (PKLDRRDRFILE)pRdr;
     248    PKLDRRDRFILEPREP    pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb);
     249    if (!pPrep)
     250        return KLDR_ERR_INVALID_PARAMETER;
     251
    166252    return -1;
    167253}
     
    543629    pRdrFile->cb = cb;
    544630    pRdrFile->off = 0;
     631    pRdrFile->cMappings = 0;
     632    pRdrFile->cPreps = 0;
    545633    kLdrHlpMemCopy(&pRdrFile->szFilename[0], szFilename, cchFilename + 1);
    546634
  • trunk/kLdr/tstkLdrMod.c

    r2859 r2860  
    378378
    379379/**
     380 * Tests the mapping related api.
     381 */
     382static int BasicTestsSubMap(PKLDRMOD pMod)
     383{
     384    int rc;
     385
     386    rc = kLdrModMap(pMod);
     387    if (rc)
     388        return Failure("kLdrModMap failed, rc=%d\n", rc);
     389
     390    return 0;
     391}
     392
     393
     394/**
    380395 * Performs basic module loader tests on the specified file.
    381396 */
     
    390405    {
    391406        rc = BasicTestsSub(pMod);
     407        if (!rc)
     408            rc = BasicTestsSubMap(pMod);
    392409        rc2 = kLdrModClose(pMod);
    393410        if (rc2)
Note: See TracChangeset for help on using the changeset viewer.