Changeset 2847 for trunk/kLdr


Ignore:
Timestamp:
Nov 1, 2006, 8:17:21 PM (19 years ago)
Author:
bird
Message:

Roughly done with kldrDyldMod now.

Location:
trunk/kLdr
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.h

    r2846 r2847  
    551551                               uintmax_t *pValue, uint32_t *pfKind, void *pvModuleUser, void *pvUser);
    552552typedef FNKLDRMODGETIMPORT *PFNKLDRMODGETIMPORT;
    553 typedef int FNKLDRMODENUMIMPMODS(PKLDRMOD pMod, const char *pszImpMod, unsigned fFlags, void *pvUser);
    554 typedef FNKLDRMODENUMIMPMODS *PFNKLDRMODENUMIMPMODS;
    555553typedef int FNKLDRMODENUMSYMS(PKLDRMOD pMod, const char *pszSymbol, unsigned uSymbol, uintmax_t Value, uint32_t fKind, void *pvUser);
    556554typedef FNKLDRMODENUMSYMS *PFNKLDRMODENUMSYMS;
     
    562560int     kLdrModQuerySymbol(PKLDRMOD pMod, const void *pvBits, uintmax_t BaseAddress, const char *pszSymbol, uintmax_t *pValue, uint32_t *pfKind);
    563561int     kLdrModEnumSymbols(PKLDRMOD pMod, unsigned fFlags, const void *pvBits, uintmax_t BaseAddress, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
    564 int     kLdrModEnumImportModules(PKLDRMOD pMod, unsigned fFlags, const void *pvBits, FNKLDRMODENUMIMPMODS pfnCallback, void *pvUser);
     562int     kLdrModGetImport(PKLDRMOD pMod, uint32_t iImport, const char *pszName, size_t cchName);
     563int32_t kLdrModNumberOfImports(PKLDRMOD pMod);
    565564int     kLdrModMap(PKLDRMOD pMod);
    566565int     kLdrModUnmap(PKLDRMOD pMod);
     
    573572int     kLdrModQueryMainEntrypoint(PKLDRMOD pMod, void *pvBits, uintmax_t uBaseAddress, uintmax_t *puValue);
    574573int     kLdrModAllocTLS(PKLDRMOD pMod);
    575 int     kLdrModFreeTLS(PKLDRMOD pMod);
     574void    kLdrModFreeTLS(PKLDRMOD pMod);
    576575int     kLdrModReload(PKLDRMOD pMod);
    577576int     kLdrModCallInit(PKLDRMOD pMod);
  • trunk/kLdr/kLdrDyld.c

    r2846 r2847  
    754754 * @returns 0 on success, non-zero error code on failure.
    755755 * @param   pMod            The module to start at.
    756  * @param   pszPrefix    Prefix to use when searching.
    757  * @param   pszSuffix    Suffix to use when searching.
     756 * @param   pszPrefix       Prefix to use when searching.
     757 * @param   pszSuffix       Suffix to use when searching.
    758758 * @param   enmSearch       Method to use when locating the module and any modules it may depend on.
    759759 * @param   fFlags          Flags, a combintation of the KLDRYDLD_LOAD_FLAGS_* \#defines.
  • trunk/kLdr/kLdrDyldMod.c

    r2846 r2847  
    5050# define KLDRDYLDMOD_ASSERT(expr)  do {} while (0)
    5151#endif
     52
     53/*******************************************************************************
     54*   Internal Functions                                                         *
     55*******************************************************************************/
     56static void kldrDyldModUnlink(PKLDRDYLDMOD pMod);
    5257
    5358
     
    175180void kldrDyldModDestroy(PKLDRDYLDMOD pMod)
    176181{
     182    int rc;
     183
    177184    /*
    178185     * Validate the state.
     
    191198    KLDRDYLDMOD_ASSERT(!pMod->cDepRefs);
    192199
    193 
    194200    /*
    195201     * Ensure that the module is unmapped.
    196202     */
     203    if (pMod->fAllocatedTLS)
     204    {
     205        kLdrModFreeTLS(pMod->pMod);
     206        pMod->fAllocatedTLS = 0;
     207    }
    197208    if (pMod->fMapped)
    198         kldrDyldModUnmap(pMod);
     209    {
     210        rc = kLdrModUnmap(pMod->pMod); KLDRDYLDMOD_ASSERT(!rc);
     211        pMod->fMapped = 0;
     212    }
     213
     214    /*
     215     * Ensure it's unlinked from all chains.
     216     */
     217    if (pMod->enmState < KLDRSTATE_PENDING_DESTROY)
     218        kldrDyldModUnlink(pMod);
     219
     220    /*
     221     * Free everything associated with the module.
     222     */
     223    /* the prerequisite array. */
     224    if (pMod->papPrereqs)
     225    {
     226        uint32_t i = pMod->cPrereqs;
     227        while (i-- > 0)
     228        {
     229            KLDRDYLDMOD_ASSERT(pMod->papPrereqs[i] == NULL);
     230            pMod->papPrereqs[i] = NULL;
     231        }
     232
     233        kldrHlpFree(pMod->papPrereqs);
     234        pMod->papPrereqs = NULL;
     235        pMod->cPrereqs = 0;
     236    }
     237
     238    /* the module interpreter.  */
     239    if (pMod->pMod)
     240    {
     241        rc = kLdrModClose(pMod->pMod); KLDRDYLDMOD_ASSERT(!rc);
     242        pMod->pMod = NULL;
     243    }
     244
     245
     246    /*
     247     * Finally, change the module state and free the module if
     248     * there are not more references to it. If somebody is still
     249     * referencing it, postpone the freeing to Deref.
     250     */
     251    pMod->enmState = KLDRSTATE_DESTROYED;
     252    if (!pMod->cRefs)
     253    {
     254        pMod->u32MagicHead = 1;
     255        pMod->u32MagicTail = 2;
     256        kldrHlpFree(pMod);
     257    }
    199258}
    200259
     
    377436    if (    pMod->enmState == KLDRSTATE_DESTROYED
    378437        &&  !pMod->cRefs)
     438    {
     439        pMod->u32MagicHead = 1;
     440        pMod->u32MagicTail = 2;
    379441        kldrHlpFree(pMod);
     442    }
    380443}
    381444
     
    511574        if (pMod2)
    512575        {
     576            pMod->papPrereqs[i] = NULL;
     577
    513578            /* do the derefering ourselves or we'll end up in a recursive loop here. */
    514579            KLDRDYLDMOD_ASSERT(pMod2->cDepRefs > 0);
     
    603668
    604669
     670/**
     671 * Loads the prerequisite modules this module depends on.
     672 *
     673 * To find each of the prerequisite modules this method calls
     674 * kldrDyldGetPrerequisite() and it will make sure the modules
     675 * are added to the load stack frame.
     676 *
     677 * @returns 0 on success, non-zero native OS or kLdr status code on failure.
     678 *          The state is changed to LOADED_PREREQUISITES or RELOADED_LOADED_PREREQUISITES.
     679 * @param   pMod            The module.
     680 * @param   pszPrefix       Prefix to use when searching.
     681 * @param   pszSuffix       Suffix to use when searching.
     682 * @param   enmSearch       Method to use when locating the module and any modules it may depend on.
     683 * @param   fFlags          Flags, a combintation of the KLDRYDLD_LOAD_FLAGS_* \#defines.
     684 */
    605685int kldrDyldModLoadPrerequisites(PKLDRDYLDMOD pMod, const char *pszPrefix, const char *pszSuffix,
    606686                                 KLDRDYLDSEARCH enmSearch, unsigned fFlags)
    607687{
    608 
    609     return -1;
    610 }
    611 
    612 
    613 int kldrDyldModCheckPrerequisites(PKLDRDYLDMOD pMod)
    614 {
    615     return -1;
     688    int32_t     cPrereqs;
     689    uint32_t    i;
     690    int         rc = 0;
     691
     692    /* sanity */
     693    switch (pMod->enmState)
     694    {
     695        case KLDRSTATE_MAPPED:
     696        case KLDRSTATE_RELOADED:
     697            break;
     698        default:
     699            KLDRDYLDMOD_ASSERT(!"invalid state");
     700            return -1;
     701    }
     702
     703    /*
     704     * Query number of prerequiste modules and allocate the array.
     705     */
     706    cPrereqs = kLdrModNumberOfImports(pMod->pMod);
     707    kldrHlpAssert(cPrereqs >= 0);
     708    if (pMod->cPrereqs != cPrereqs)
     709    {
     710        KLDRDYLDMOD_ASSERT(!pMod->papPrereqs);
     711        pMod->papPrereqs = (PPKLDRDYLDMOD)kldrHlpAllocZ(sizeof(pMod->papPrereqs[0]) * cPrereqs);
     712        if (!pMod->papPrereqs)
     713            return KLDR_ERR_NO_MEMORY;
     714        pMod->cPrereqs = cPrereqs;
     715    }
     716    else
     717        KLDRDYLDMOD_ASSERT(pMod->papPrereqs || !pMod->cPrereqs);
     718
     719    /*
     720     * Iterate the prerequisites and load them.
     721     */
     722    for (i = 0; i < pMod->cPrereqs; i++)
     723    {
     724        static char s_szPrereq[260];
     725        PKLDRDYLDMOD pPrereqMod;
     726
     727        KLDRDYLDMOD_ASSERT(pMod->papPrereqs[i] == NULL);
     728        rc = kLdrModGetImport(pMod->pMod, i, s_szPrereq, sizeof(s_szPrereq));
     729        if (rc)
     730            break;
     731        rc = kldrDyldGetPrerequisite(s_szPrereq, pszPrefix, pszSuffix, enmSearch, fFlags, pMod, &pPrereqMod);
     732        if (rc)
     733            break;
     734        pMod->papPrereqs[i] = pPrereqMod;
     735    }
     736
     737    /* change the state regardless of what happend. */
     738    if (pMod->enmState == KLDRSTATE_MAPPED)
     739        pMod->enmState = KLDRSTATE_LOADED_PREREQUISITES;
     740    else
     741        pMod->enmState = KLDRSTATE_RELOADED_LOADED_PREREQUISITES;
     742    return rc;
    616743}
    617744
     
    679806
    680807    /* do the job. */
    681     rc = kLdrModFreeTLS(pMod->pMod);
     808    if (pMod->fAllocatedTLS)
     809    {
     810        kLdrModFreeTLS(pMod->pMod);
     811        pMod->fAllocatedTLS = 0;
     812    }
     813    rc = kLdrModUnmap(pMod->pMod);
    682814    if (!rc)
    683815    {
    684         rc = kLdrModUnmap(pMod->pMod);
    685         if (!rc)
     816        pMod->fMapped = 0;
     817        if (pMod->enmState < KLDRSTATE_PENDING_DESTROY)
    686818        {
    687             pMod->fMapped = 0;
    688             if (pMod->enmState < KLDRSTATE_PENDING_DESTROY)
    689             {
    690                 pMod->enmState = KLDRSTATE_PENDING_DESTROY;
    691                 kldrDyldModUnlink(pMod);
    692             }
     819            pMod->enmState = KLDRSTATE_PENDING_DESTROY;
     820            kldrDyldModUnlink(pMod);
    693821        }
    694         else
    695             kLdrModAllocTLS(pMod->pMod);
    696     }
     822    }
     823
    697824    return rc;
    698825}
     
    716843    KLDRDYLDMOD_ASSERT(pMod->cRefs > 0);
    717844    KLDRDYLDMOD_ASSERT(pMod->fMapped);
    718     KLDRDYLDMOD_ASSERT(pMod->fAllocatedTLS);
    719845
    720846    switch (pMod->enmState)
     
    729855    }
    730856
     857    /* Free TLS before reloading. */
     858    if (pMod->fAllocatedTLS)
     859    {
     860        kLdrModFreeTLS(pMod->pMod);
     861        pMod->fAllocatedTLS = 0;
     862    }
     863
    731864    /* Let the module interpreter do the reloading of the mapping. */
    732865    rc = kLdrModReload(pMod->pMod);
    733866    if (!rc)
    734867    {
    735         /* Free and allocate the TLS anew to ensure we get clean entries. */
    736         if (pMod->fAllocatedTLS)
    737             rc = kLdrModFreeTLS(pMod->pMod);
     868        rc = kLdrModAllocTLS(pMod->pMod);
    738869        if (!rc)
    739870        {
    740             pMod->fAllocatedTLS = 0;
    741             rc = kLdrModAllocTLS(pMod->pMod);
    742             if (!rc)
    743             {
    744                 pMod->fAllocatedTLS = 1;
    745                 pMod->enmState = KLDRSTATE_RELOADED;
    746             }
     871            pMod->fAllocatedTLS = 1;
     872            pMod->enmState = KLDRSTATE_RELOADED;
    747873        }
    748874    }
  • trunk/kLdr/kLdrHlp.h

    r2846 r2847  
    143143void    kldrHlpHeapDonate(void *pv, size_t cb);
    144144void *  kldrHlpAlloc(size_t cb);
     145void *  kldrHlpAllocZ(size_t cb);
    145146void    kldrHlpFree(void *pv);
    146147
  • trunk/kLdr/kLdrHlpHeap.c

    r2826 r2847  
    217217{
    218218    return kLdrHeapAlloc(&g_Heap, cb);
     219}
     220
     221
     222/**
     223 * Allocates zero initialized memory from the kLdr heap.
     224 *
     225 * @returns Pointer to the allocated heap block. NULL if we can't satify the request.
     226 * @param   cb      The requested heap block size.
     227 */
     228void *kldrHlpAllocZ(size_t cb)
     229{
     230    void *pv = kLdrHeapAlloc(&g_Heap, cb);
     231    if (pv)
     232        kLdrHlpMemSet(pv, 0, cb);
     233    return pv;
    219234}
    220235
  • trunk/kLdr/kLdrInternal.h

    r2846 r2847  
    318318                               KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod);
    319319
     320int kldrDyldGetPrerequisite(const char *pszDll, const char *pszPrefix, const char *pszSuffix, KLDRDYLDSEARCH enmSearch,
     321                            unsigned fFlags, PKLDRDYLDMOD pDep, PPKLDRDYLDMOD ppMod);
     322
    320323
    321324int kldrDyldModCreate(PKLDRRDR pRdr, PPKLDRDYLDMOD ppMod);
Note: See TracChangeset for help on using the changeset viewer.