Changeset 2836 for trunk/kLdr/kLdrDyld.c


Ignore:
Timestamp:
Oct 26, 2006, 5:58:53 AM (19 years ago)
Author:
bird
Message:

more prototyping. (And avoid 64-bit div/rem)

File:
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdrDyld.c

    r2833 r2836  
    3232#include "kLdrHlp.h"
    3333#include "kLdrInternal.h"
     34
     35
     36/*******************************************************************************
     37*   Defined Constants And Macros                                               *
     38*******************************************************************************/
     39/** @def KLDRDYLD_STRICT
     40 * Define KLDRDYLD_STRICT to enabled strict checks in kLdrDyld. */
     41#define KLDRDYLD_STRICT 1
     42
     43/** @def KLDRDYLD_ASSERT
     44 * Assert that an expression is true when KLDRDYLD_STRICT is defined.
     45 */
     46#ifdef KLDRDYLD_STRICT
     47# define KLDRDYLD_ASSERT(expr)  kldrHlpAssert(expr)
     48#else
     49# define KLDRDYLD_ASSERT(expr)  do {} while (0)
     50#endif
    3451
    3552
     
    4360 * (This is exported, so no prefix.) */
    4461PKLDRDYLDMOD    kLdrDyldTail = NULL;
     62/** Pointer to the head module of the termination order list. */
     63PKLDRDYLDMOD    g_pkLdrDyldTermHead;
     64/** Pointer to the tail module of the termination order list. */
     65PKLDRDYLDMOD    g_pkLdrDyldTermTail;
     66/** Pointer to the head module of the bind order list.
     67 * The modules in this list makes up the global namespace used when binding symbol unix fashion. */
     68PKLDRDYLDMOD    g_pkLdrDyldBindHead;
     69/** Pointer to the tail module of the bind order list. */
     70PKLDRDYLDMOD    g_pkLdrDyldBindTail;
     71
     72/** Stack of modules involved in the active loads.
     73 *
     74 * The main purpose is to allow module init routines to loading and unloading
     75 * modules without upsetting the init order and to assist in dereferencing
     76 * modules on load failure.
     77 *
     78 * Each call to kLdrDyldLoad and kLdrDyldLoadExe will start a load frame
     79 * when doing a fresh load. All dependant modules will be pushed on each
     80 * reference. The frame is completed when all the dependant modules has
     81 * been resolved (or a failure occurs). After doing fixups, the frame is
     82 * used to do module initialization. Should an error occur during the load
     83 * the frame will be used to dereference all the modules involved in the
     84 * load operation (it will not however, be used for termination calls as
     85 * they are postponed till the last load operation completes).
     86 *
     87 * Should any of the init calls load a module, a new frame will be created
     88 * for that operation and processed before the init call returns to the
     89 * previous frame.
     90 */
     91PPKLDRDYLDMOD   g_pakLdrDyld;
     92/** The number of used entries in the g_pakLdrDyld array. */
     93uint32_t        g_ckLdrDyld;
     94/** The number of entries allocated for the g_pakLdrDyld array. */
     95uint32_t        g_ckLdrDyldAllocated;
     96
     97/** The global error buffer. */
     98char            g_szkLdrDyldError[1024];
     99
    45100/** The Library search path. */
    46101char            kLdrDyldLibraryPath[4096];
     
    52107*   Internal Functions                                                         *
    53108*******************************************************************************/
    54 static int kldrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch,
    55                         unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr);
    56 static int kldrDyldUnload(PKLDRDYLDMOD pMod);
    57 static int kldrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PPKLDRDYLDMOD ppMod);
    58 static int kldrDyldFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment);
    59 static int kldrDyldGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName);
    60 static int kldrDyldGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename);
    61 static int kldrDyldQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind);
     109static int kldrDyldDoLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch,
     110                          unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr);
     111static int kldrDyldDoUnload(PKLDRDYLDMOD pMod);
     112static int kldrDyldDoFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch,
     113                              unsigned fFlags, PPKLDRDYLDMOD ppMod);
     114static int kldrDyldDoFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment);
     115static int kldrDyldDoGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName);
     116static int kldrDyldDoGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename);
     117static int kldrDyldDoQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind);
     118static void kldrDyldStartLoading(void);
     119static void kldrDyldStopLoading(void);
     120static int kldrDyldCopyError(int rc, char *pszErr, size_t cchErr);
    62121
    63122
     
    68127int kldrDyInit(void)
    69128{
    70     kLdrDyldHead = NULL;
    71     kLdrDyldTail = NULL;
     129    kLdrDyldHead = kLdrDyldTail = NULL;
     130    g_pkLdrDyldTermHead = g_pkLdrDyldTermTail = NULL;
     131    g_pkLdrDyldBindHead = g_pkLdrDyldBindTail = NULL;
    72132    kLdrDyldFlags = 0;
     133    g_szkLdrDyldError[0] = '\0';
    73134    return 0;
    74135}
     
    117178    {
    118179        PKLDRDYLDMOD pMod = NULL;
    119         rc = kldrDyldLoad(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, phMod, pszErr, cchErr);
     180        rc = kldrDyldDoLoad(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, phMod, pszErr, cchErr);
    120181        kldrHlpSemRelease();
    121182        *phMod = pMod;
     
    142203    if (!rc)
    143204    {
    144         rc = kldrDyldUnload(hMod);
     205        rc = kldrDyldDoUnload(hMod);
    145206        kldrHlpSemRelease();
    146207    }
     
    158219 * @returns KLDR_ERR_MODULE_NOT_FOUND on failure.
    159220 * @param   pszDll          The name of the dll to look for.
    160  * @param   pszDefPrefix    Prefix to use when searching.
    161  * @param   pszDefSuffix    Suffix to use when searching.
     221 * @param   pszDefPrefix    Prefix than can be used when searching.
     222 * @param   pszDefSuffix    Suffix than can be used when searching.
    162223 * @param   enmSearch       Method to use when locating the module.
     224 * @param   fFlags          Flags, a combintation of the KLDRYDLD_LOAD_FLAGS_* \#defines.
    163225 * @param   phMod           Where to store the handle of the module on success.
    164226 */
    165 int     kLdrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PHKLDRMOD phMod)
     227int     kLdrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch,
     228                           unsigned fFlags, PHKLDRMOD phMod)
    166229{
    167230    int rc;
     
    176239    {
    177240        PKLDRDYLDMOD pMod = NULL;
    178         rc = kldrDyldFindByName(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, phMod);
     241        rc = kldrDyldDoFindByName(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, phMod);
    179242        kldrHlpSemRelease();
    180243        *phMod = pMod;
     
    213276    {
    214277        PKLDRDYLDMOD pMod = NULL;
    215         rc = kldrDyldFindByAddress(Address, &pMod, piSegment, poffSegment);
     278        rc = kldrDyldDoFindByAddress(Address, &pMod, piSegment, poffSegment);
    216279        kldrHlpSemRelease();
    217280        *phMod = pMod;
     
    245308    if (!rc)
    246309    {
    247         rc = kldrDyldGetName(hMod, pszName, cchName);
     310        rc = kldrDyldDoGetName(hMod, pszName, cchName);
    248311        kldrHlpSemRelease();
    249312    }
     
    276339    if (!rc)
    277340    {
    278         rc = kldrDyldGetFilename(hMod, pszFilename, cchFilename);
     341        rc = kldrDyldDoGetFilename(hMod, pszFilename, cchFilename);
    279342        kldrHlpSemRelease();
    280343    }
     
    312375    if (!rc)
    313376    {
    314         rc = kldrDyldQuerySymbol(hMod, uSymbolOrdinal, pszSymbolName, pValue, pfKind);
     377        rc = kldrDyldDoQuerySymbol(hMod, uSymbolOrdinal, pszSymbolName, pValue, pfKind);
    315378        kldrHlpSemRelease();
    316379    }
     
    322385
    323386
    324 
    325 /**
    326  * Worker for kldrDyldLoad().
     387/**
     388 * Worker for kLdrDyldLoad().
    327389 * @internal
    328390 */
    329 static int kldrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch,
    330                         unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr)
    331 {
    332     /*
    333      * Open the module.
    334      */
    335 
    336 
    337     return -1;
    338 }
    339 
    340 
    341 /**
    342  * Worker for kldrDyldUnload().
     391static int kldrDyldDoLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch,
     392                          unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr)
     393{
     394    int rc;
     395
     396    /*
     397     * Try find it among the modules that's already loaded.
     398     */
     399    rc = kldrDyldFindExistingModule(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, ppMod);
     400    if (!rc)
     401    {
     402        /*
     403         * If we're in a module termination call we must check that all the modules we
     404         * depend on are loaded and initialized.
     405         */
     406//continue here        if ((*ppMod)->enmState::KLDRSTATE_LOADED)
     407        {
     408            kldrHlpAssert(!"implement me");
     409        }
     410        return kldrDyldModDynamicLoad(*ppMod);
     411    }
     412
     413    /*
     414     * Try open it.
     415     */
     416    kldrDyldStartLoading();
     417    rc = kldrDyldFindNewModule(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, ppMod);
     418    if (!rc)
     419    {
     420
     421
     422    }
     423    return kldrDyldCopyError(rc, pszErr, cchErr);
     424}
     425
     426
     427/**
     428 * Worker for kLdrDyldUnload().
    343429 * @internal
    344430 */
    345 static int kldrDyldUnload(HKLDRMOD hMod)
    346 {
    347     return -1;
     431static int kldrDyldDoUnload(PKLDRDYLDMOD pMod)
     432{
     433    return kldrDyldModDynamicUnload(pMod);
    348434}
    349435
     
    353439 * @internal
    354440 */
    355 static int kldrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PPKLDRDYLDMOD ppMod)
    356 {
    357     return -1;
     441static int kldrDyldDoFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch,
     442                                unsigned fFlags, PPKLDRDYLDMOD ppMod)
     443{
     444    return kldrDyldFindExistingModule(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, ppMod);
    358445}
    359446
     
    363450 * @internal
    364451 */
    365 static int kldrDyldFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment)
    366 {
    367     return -1;
     452static int kldrDyldDoFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment)
     453{
     454    /* Scan the segments of each module in the load list. */
     455    PKLDRDYLDMOD pMod = kLdrDyldHead;
     456    while (pMod)
     457    {
     458        uint32_t iSeg;
     459        for (iSeg = 0; iSeg < pMod->pMod->cSegments; iSeg++)
     460        {
     461            uintmax_t off = (uintmax_t)Address - pMod->pMod->aSegments[iSeg].LoadAddress;
     462            if (off < pMod->pMod->aSegments[iSeg].cb)
     463            {
     464                *ppMod = pMod->hMod;
     465                if (piSegment)
     466                    *piSegment = iSeg;
     467                if (poffSegment)
     468                    *poffSegment = (uintptr_t)off;
     469                return 0;
     470            }
     471        }
     472
     473        /* next */
     474        pMod = pMod->Load.pNext;
     475    }
     476
     477    return KLDR_ERR_MODULE_NOT_FOUND;
    368478}
    369479
     
    373483 * @internal
    374484 */
    375 static int kldrDyldGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName)
    376 {
    377     return -1;
     485static int kldrDyldDoGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName)
     486{
     487    return kldrDyldModGetName(pMod, pszName, cchName);
    378488}
    379489
     
    383493 * @internal
    384494 */
    385 static int kldrDyldGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename)
    386 {
    387     return -1;
     495static int kldrDyldDoGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename)
     496{
     497    return kldrDyldModGetFilename(pMod, pszFilename, cchFilename);
    388498}
    389499
     
    393503 * @internal
    394504 */
    395 static int kldrDyldQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind)
    396 {
    397     return -1;
     505static int kldrDyldDoQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind)
     506{
     507    return kldrDyldModQuerySymbol(pMod, uSymbolOrdinal, pszSymbolName, pValue, pfKind);
    398508}
    399509
     
    482592}
    483593
     594#endif
     595
     596/**
     597 * Starts loading a new module and its dependencies.
     598 */
     599static void kldrDyldStartLoading(void)
     600{
     601#ifdef KLDRDYLD_STRICT
     602    /* check that all modules are in the correct state */
     603    PKLDRDYLDMOD pMod = kLdrDyldHead;
     604    while (pMod)
     605    {
     606        //KLDRDYLD_ASSERT(pMod->enmState == KLDRSTATE_LOADED);
     607
     608        /* next */
     609        pMod = pMod->Load.pNext;
     610    }
     611#endif
     612}
     613
     614
     615/**
     616 * Records the loading of the module.
     617 *
     618 * @return 0 on success, KLDR_ERR_NO_MEMORY if we can't expand the table.
     619 * @param   pMod        The module to record.
     620 */
     621static int kldrDyldRecord(PKLDRDYLDMOD pMod)
     622{
     623
     624}
     625
     626
     627
     628/**
     629 * Done loading a module and its dependencies.
     630 *
     631 * If the load failed, unload all the modules involved.
     632 * If the load succeeded,
     633 *
     634 * @returns rc.
     635 * @param   rc  The status code.
     636 */
     637static void kldrDyldDoneLoading(int rc)
     638{
     639
     640}
     641
     642
    484643
    485644/**
     
    493652int kldrFailure(int rc, const char *pszFormat, ...)
    494653{
    495     kldrExit(1);
    496     return rc;
    497 }
    498 
    499 #endif
    500 
     654    kldrHlpExit(1);
     655    return rc;
     656}
     657
     658
     659/**
     660 * Copies the error string to the user buffer.
     661 *
     662 * @returns rc.
     663 * @param   rc      The status code.
     664 * @param   pszErr  Where to copy the error string to.
     665 * @param   cchErr  The size of the destination buffer.
     666 */
     667static int kldrDyldCopyError(int rc, char *pszErr, size_t cchErr)
     668{
     669    size_t cchToCopy;
     670
     671    /* if no error string, format the rc into a string. */
     672    if (!g_szkLdrDyldError[0] && rc)
     673        kldrHlpInt2Ascii(g_szkLdrDyldError, sizeof(g_szkLdrDyldError), rc, 10);
     674
     675    /* copy it if we got something. */
     676    if (cchErr && pszErr && g_szkLdrDyldError[0])
     677    {
     678        cchToCopy = kLdrHlpStrLen(g_szkLdrDyldError);
     679        if (cchToCopy >= cchErr)
     680            cchToCopy = cchErr - 1;
     681        kLdrHlpMemCopy(pszErr, g_szkLdrDyldError, cchToCopy);
     682        pszErr[cchToCopy] = '\0';
     683    }
     684
     685    return rc;
     686}
     687
Note: See TracChangeset for help on using the changeset viewer.