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

Roughly done with kldrDyldMod now.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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    }
Note: See TracChangeset for help on using the changeset viewer.