Changeset 2851


Ignore:
Timestamp:
Nov 2, 2006, 4:21:54 AM (19 years ago)
Author:
bird
Message:

kLdrMod done.

Location:
trunk/kLdr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.h

    r2850 r2851  
    532532
    533533
    534 /**
    535  * Loader module.
     534/** Pointer to a module interpreter method table. */
     535typedef struct KLDRMODOPS *PKLDRMODOPS;
     536/** Pointer to const module interpreter methods table. */
     537typedef const struct KLDRMODOPS *PCKLDRMODOPS;
     538
     539/**
     540 * Module interpreter instance.
     541 * All members are read only unless you're kLdrMod or the module interpreter.
    536542 */
    537543typedef struct KLDRMOD
     
    560566    /** The number of segments in the module. */
    561567    uint32_t            cSegments;
     568    /** Pointer to the loader methods.
     569     * Not meant for calling directly thru! */
     570    PCKLDRMODOPS        pOps;
    562571    /** The module data. */
    563572    void               *pvData;
     
    565574    KLDRSEG             aSegments[1];
    566575} KLDRMOD, *PKLDRMOD, **PPKLDRMOD;
     576
     577/** The magic for KLDRMOD::u32Magic. (Kosuke Fujishima) */
     578#define KLDRMOD_MAGIC   0x19640707
    567579
    568580
     
    712724                            PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    713725/** @} */
     726
     727
     728/**
     729 * The loader module operation.
     730 */
     731typedef struct KLDRMODOPS
     732{
     733    /** The name of this module interpreter. */
     734    const char         *pszName;
     735    /** Pointer to the next module interpreter. */
     736    PCKLDRMODOPS        pNext;
     737
     738    /**
     739     * Create a loader module instance interpreting the executable image found
     740     * in the specified file provider instance.
     741     *
     742     * @returns 0 on success and *ppMod pointing to a module instance.
     743     *          On failure, a non-zero OS specific error code is returned.
     744     * @param   pOps            Pointer to the registered method table.
     745     * @param   pRdr            The file provider instance to use.
     746     * @param   offNewHdr       The offset of the new header in MZ files. -1 if not found.
     747     * @param   ppMod           Where to store the module instance pointer.
     748     */
     749    int (* pfnCreate)(PCKLDRMODOPS pOps, PKLDRRDR pRdr, off_t offNewHdr, PPKLDRMOD ppMod);
     750    /**
     751     * Destroys an loader module instance.
     752     *
     753     * The caller is responsible for calling kLdrModUnmap() and kLdrFreeTLS() first.
     754     *
     755     * @returns 0 on success, non-zero on failure. The module instance state
     756     *          is unknown on failure, it's best not to touch it.
     757     * @param   pMod    The module.
     758     */
     759    int (* pfnDestroy)(PKLDRMOD pMod);
     760
     761    /** @copydoc kLdrModQuerySymbol */
     762    int (* pfnQuerySymbol)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, uint32_t uSymbol,
     763                           const char *pszSymbol, PKLDRADDR puValue, uint32_t *pfKind);
     764    /** @copydoc kLdrModEnumSymbols */
     765    int (* pfnEnumSymbols)(PKLDRMOD pMod, uint32_t fFlags, const void *pvBits, KLDRADDR BaseAddress,
     766                           PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
     767    /** @copydoc kLdrModGetImport */
     768    int (* pfnGetImport)(PKLDRMOD pMod, void *pvBits, uint32_t iImport, const char *pszName, size_t cchName);
     769    /** @copydoc kLdrModNumberOfImports */
     770    int32_t (* pfnNumberOfImports)(PKLDRMOD pMod, void *pvBits);
     771    /** @copydoc kLdrModCanExecuteOn */
     772    int (* pfnCanExecuteOn)(PKLDRMOD pMod, void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
     773    /** @copydoc kLdrModGetStackInfo */
     774    int (* pfnGetStackInfo)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
     775    /** @copydoc kLdrModQueryMainEntrypoint */
     776    int (* pfnQueryMainEntrypoint)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
     777    /** @copydoc kLdrModEnumDbgInfo */
     778    int (* pfnEnumDbgInfo)(PKLDRMOD pMod, void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
     779    /** @copydoc kLdrModHasDbgInfo */
     780    int (* pfnHasDbgInfo)(PKLDRMOD pMod, void *pvBits);
     781    /** @copydoc kLdrModMap */
     782    int (* pfnMap)(PKLDRMOD pMod);
     783    /** @copydoc kLdrModUnmap */
     784    int (* pfnUnmap)(PKLDRMOD pMod);
     785    /** @copydoc kLdrModAllocTLS */
     786    int (* pfnAllocTLS)(PKLDRMOD pMod);
     787    /** @copydoc kLdrModFreeTLS */
     788    void (* pfnFreeTLS)(PKLDRMOD pMod);
     789    /** @copydoc kLdrModReload */
     790    int (* pfnReload)(PKLDRMOD pMod);
     791    /** @copydoc kLdrModFixupMapping */
     792    int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     793    /** @copydoc kLdrModCallInit */
     794    int (* pfnCallInit)(PKLDRMOD pMod);
     795    /** @copydoc kLdrModCallTerm */
     796    int (* pfnCallTerm)(PKLDRMOD pMod);
     797    /** @copydoc kLdrModCallThread */
     798    int (* pfnCallThread)(PKLDRMOD pMod, unsigned fAttachingOrDetaching);
     799    /** @copydoc kLdrModSize */
     800    size_t (* pfnSize)(PKLDRMOD pMod);
     801    /** @copydoc kLdrModGetBits */
     802    int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     803    /** @copydoc kLdrModRelocateBits */
     804    int (* pfnRelocateBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
     805                            PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     806    /** Dummy which should be assigned a non-zero value. */
     807    uint32_t uEndOfStructure;
     808} KLDRMODOPS;
    714809
    715810
  • trunk/kLdr/kLdrHlp.h

    r2847 r2851  
    221221    } while (0)
    222222
     223/** Return validation of a flags argument. */
     224#define KLDRHLP_VALIDATE_FLAGS(arg, AllowedMask) \
     225    do { \
     226        if ((arg) & ~(AllowedMask)) \
     227        {  \
     228            return KLDR_ERR_INVALID_PARAMETER; \
     229        } \
     230    } while (0)
     231
    223232/** @} */
    224233
  • trunk/kLdr/kLdrMod.c

    r2849 r2851  
    3939# include "kLdrModELF64.h"
    4040#endif
     41
     42
     43/*******************************************************************************
     44*   Defined Constants And Macros                                               *
     45*******************************************************************************/
     46/** @def KLDRMOD_STRICT
     47 * Define KLDRMOD_STRICT to enabled strict checks in KLDRMOD. */
     48#define KLDRMOD_STRICT 1
     49
     50/** @def KLDRMOD_ASSERT
     51 * Assert that an expression is true when KLDR_STRICT is defined.
     52 */
     53#ifdef KLDRMOD_STRICT
     54# define KLDRMOD_ASSERT(expr)  kldrHlpAssert(expr)
     55#else
     56# define KLDRMOD_ASSERT(expr)  do {} while (0)
     57#endif
     58
     59/** Return / crash validation of a module argument. */
     60#define KLDRMOD_VALIDATE_EX(pMod, rc) \
     61    do  { \
     62        if (    (pMod)->u32Magic != KLDRMOD_MAGIC \
     63            ||  (pMod)->pOps == NULL \
     64           )\
     65        { \
     66            return (rc); \
     67        } \
     68    } while (0)
     69
     70/** Return / crash validation of a module argument. */
     71#define KLDRMOD_VALIDATE(pMod) \
     72    KLDRMOD_VALIDATE_EX(pMod, KLDR_ERR_INVALID_PARAMETER)
     73
     74/** Return / crash validation of a module argument. */
     75#define KLDRMOD_VALIDATE_VOID(pMod) \
     76    do  { \
     77        if (    (pMod)->u32Magic != KLDRMOD_MAGIC \
     78            ||  (pMod)->pOps == NULL \
     79           )\
     80        { \
     81            return; \
     82        } \
     83    } while (0)
     84
     85
     86/*******************************************************************************
     87*   Global Variables                                                           *
     88*******************************************************************************/
     89/** The list of module interpreters. */
     90static PCKLDRMODOPS g_pModInterpreterHead = NULL;
     91
     92
     93
     94/*******************************************************************************
     95*   Internal Functions                                                         *
     96*******************************************************************************/
     97
    4198
    4299
     
    115172
    116173    /*
    117      * Use the magic to select the appropriate image interpreter.
     174     * Use the magic to select the appropriate image interpreter head on.
    118175     */
    119176    if (u.u16 == IMAGE_DOS_SIGNATURE)
    120         return KLDR_ERR_MZ_NOT_SUPPORTED;
     177        rc = KLDR_ERR_MZ_NOT_SUPPORTED;
    121178    else if (u.u16 == IMAGE_NE_SIGNATURE)
    122         return KLDR_ERR_NE_NOT_SUPPORTED;
     179        rc = KLDR_ERR_NE_NOT_SUPPORTED;
    123180    else if (u.u16 == IMAGE_LX_SIGNATURE)
    124         return KLDR_ERR_LX_NOT_SUPPORTED;
     181        rc = KLDR_ERR_LX_NOT_SUPPORTED;
    125182    else if (u.u16 == IMAGE_LE_SIGNATURE)
    126         return KLDR_ERR_LE_NOT_SUPPORTED;
     183        rc = KLDR_ERR_LE_NOT_SUPPORTED;
    127184    else if (u.u32 == IMAGE_NT_SIGNATURE)
    128         return KLDR_ERR_PE_NOT_SUPPORTED;
     185        rc = KLDR_ERR_PE_NOT_SUPPORTED;
    129186    else if (u.u32 == IMAGE_ELF_SIGNATURE)
    130         return KLDR_ERR_ELF_NOT_SUPPORTED;
    131     return KLDR_ERR_UNKNOWN_FORMAT;
     187        rc = KLDR_ERR_ELF_NOT_SUPPORTED;
     188    else
     189        rc = KLDR_ERR_UNKNOWN_FORMAT;
     190
     191    /*
     192     * If no head on hit, let each interpreter have a go.
     193     */
     194    if (rc)
     195    {
     196        PCKLDRMODOPS pOps;
     197        for (pOps = g_pModInterpreterHead; pOps; pOps = pOps->pNext)
     198        {
     199            int rc2 = pOps->pfnCreate(pOps, pRdr, offHdr, ppMod);
     200            if (!rc2)
     201                return rc;
     202        }
     203        *ppMod = NULL;
     204    }
     205    return rc;
    132206}
    133207
     
    162236 * before closing the module.
    163237 *
    164  * @returns 0 on success,
     238 * @returns 0 on success, non-zero on failure. The module instance state
     239 *          is unknown on failure, it's best not to touch it.
    165240 * @param   pMod    The module.
    166241 */
    167242int     kLdrModClose(PKLDRMOD pMod)
    168243{
    169     //pMod->
    170     return -1;
    171 }
    172 
     244    KLDRMOD_VALIDATE(pMod);
     245    return pMod->pOps->pfnDestroy(pMod);
     246}
    173247
    174248
     
    194268                           const char *pszSymbol, PKLDRADDR puValue, uint32_t *pfKind)
    195269{
    196     return -1;
     270    KLDRMOD_VALIDATE(pMod);
     271    if (!puValue && !pfKind)
     272        return KLDR_ERR_INVALID_PARAMETER;
     273    if (puValue)
     274        *puValue = 0;
     275    if (pfKind)
     276        *pfKind = 0;
     277    return pMod->pOps->pfnDestroy(pMod);
    197278}
    198279
     
    215296                           PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
    216297{
    217     return -1;
     298    KLDRMOD_VALIDATE(pMod);
     299    KLDRHLP_VALIDATE_FLAGS(fFlags, KLDRMOD_ENUM_SYMS_FLAGS_ALL);
     300    return pMod->pOps->pfnEnumSymbols(pMod, fFlags, pvBits, BaseAddress, pfnCallback, pvUser);
    218301}
    219302
     
    234317int     kLdrModGetImport(PKLDRMOD pMod, void *pvBits, uint32_t iImport, const char *pszName, size_t cchName)
    235318{
    236     return -1;
     319    KLDRMOD_VALIDATE(pMod);
     320    return pMod->pOps->pfnGetImport(pMod, pvBits, iImport, pszName, cchName);
    237321}
    238322
     
    248332int32_t kLdrModNumberOfImports(PKLDRMOD pMod, void *pvBits)
    249333{
    250     return -1;
     334    KLDRMOD_VALIDATE(pMod);
     335    return pMod->pOps->pfnNumberOfImports(pMod, pvBits);
    251336}
    252337
     
    263348int     kLdrModCanExecuteOn(PKLDRMOD pMod, void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu)
    264349{
    265     //return KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
    266     return 0;
     350    KLDRMOD_VALIDATE(pMod);
     351    return pMod->pOps->pfnCanExecuteOn(pMod, pvBits, enmArch, enmCpu);
    267352}
    268353
     
    282367int     kLdrModGetStackInfo(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
    283368{
    284     return -1;
     369    KLDRMOD_VALIDATE(pMod);
     370    return pMod->pOps->pfnGetStackInfo(pMod, pvBits, BaseAddress, pStackInfo);
    285371}
    286372
     
    303389int     kLdrModQueryMainEntrypoint(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
    304390{
    305     return 1;
     391    KLDRMOD_VALIDATE(pMod);
     392    *pMainEPAddress = 0;
     393    return pMod->pOps->pfnQueryMainEntrypoint(pMod, pvBits, BaseAddress, pMainEPAddress);
    306394}
    307395
     
    320408int     kLdrModEnumDbgInfo(PKLDRMOD pMod, void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
    321409{
    322     return 0;
     410    KLDRMOD_VALIDATE(pMod);
     411    return pMod->pOps->pfnEnumDbgInfo(pMod, pvBits, pfnCallback, pvUser);
    323412}
    324413
     
    335424int     kLdrModHasDbgInfo(PKLDRMOD pMod, void *pvBits)
    336425{
    337     return -1;
     426    KLDRMOD_VALIDATE(pMod);
     427    return pMod->pOps->pfnHasDbgInfo(pMod, pvBits);
    338428}
    339429
     
    351441int     kLdrModMap(PKLDRMOD pMod)
    352442{
    353     return -1;
     443    KLDRMOD_VALIDATE(pMod);
     444    return pMod->pOps->pfnMap(pMod);
    354445}
    355446
     
    363454int     kLdrModUnmap(PKLDRMOD pMod)
    364455{
    365     return -1;
     456    KLDRMOD_VALIDATE(pMod);
     457    return pMod->pOps->pfnUnmap(pMod);
    366458}
    367459
     
    378470int     kLdrModAllocTLS(PKLDRMOD pMod)
    379471{
    380     return 0;
     472    KLDRMOD_VALIDATE(pMod);
     473    return pMod->pOps->pfnAllocTLS(pMod);
    381474}
    382475
     
    393486void    kLdrModFreeTLS(PKLDRMOD pMod)
    394487{
     488    KLDRMOD_VALIDATE_VOID(pMod);
     489    pMod->pOps->pfnFreeTLS(pMod);
    395490}
    396491
     
    409504int     kLdrModReload(PKLDRMOD pMod)
    410505{
    411     return -1;
     506    KLDRMOD_VALIDATE(pMod);
     507    return pMod->pOps->pfnReload(pMod);
    412508}
    413509
     
    426522int     kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
    427523{
    428     return -1;
     524    KLDRMOD_VALIDATE(pMod);
     525    return pMod->pOps->pfnFixupMapping(pMod, pfnGetImport, pvUser);
    429526}
    430527
     
    438535int     kLdrModCallInit(PKLDRMOD pMod)
    439536{
    440     return -1;
     537    KLDRMOD_VALIDATE(pMod);
     538    return pMod->pOps->pfnCallInit(pMod);
    441539}
    442540
     
    452550int     kLdrModCallTerm(PKLDRMOD pMod)
    453551{
    454     return 0;
     552    KLDRMOD_VALIDATE(pMod);
     553    return pMod->pOps->pfnCallTerm(pMod);
    455554}
    456555
     
    466565int     kLdrModCallThread(PKLDRMOD pMod, unsigned fAttachingOrDetaching)
    467566{
    468     return 0;
     567    KLDRMOD_VALIDATE(pMod);
     568    KLDRHLP_VALIDATE_FLAGS(fAttachingOrDetaching, 1);
     569    return pMod->pOps->pfnCallThread(pMod, fAttachingOrDetaching);
    469570}
    470571
     
    478579size_t  kLdrModSize(PKLDRMOD pMod)
    479580{
    480     return 0;
     581    KLDRMOD_VALIDATE_EX(pMod, 0);
     582    return pMod->pOps->pfnSize(pMod);
    481583}
    482584
     
    498600int     kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
    499601{
    500     return -1;
     602    KLDRMOD_VALIDATE(pMod);
     603    return pMod->pOps->pfnGetBits(pMod, pvBits, BaseAddress, pfnGetImport, pvUser);
    501604}
    502605
     
    517620                            PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
    518621{
    519     return -1;
    520 }
    521 
     622    KLDRMOD_VALIDATE(pMod);
     623    return pMod->pOps->pfnRelocateBits(pMod, pvBits, NewBaseAddress, OldBaseAddress, pfnGetImport, pvUser);
     624}
     625
Note: See TracChangeset for help on using the changeset viewer.