Changeset 2856


Ignore:
Timestamp:
Nov 4, 2006, 11:19:33 PM (19 years ago)
Author:
bird
Message:

More code.

Location:
trunk/kLdr
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.h

    r2855 r2856  
    136136     */
    137137    int     (* pfnDestroy)( PKLDRRDR pRdr);
    138     /** Read bits from the file.
    139      *
    140      * @returns 0 on success, OS specific error code on failure.
    141      * @param   pRdr        The file provider instance.
    142      * @param   pvBuf       Where to put the bits.
    143      * @param   cb          The number of bytes to read.
    144      * @param   off         Where to start reading.
    145      */
     138    /** @copydoc kLdrRdrRead */
    146139    int     (* pfnRead)(    PKLDRRDR pRdr, void *pvBuf, size_t cb, off_t off);
    147     /** Map all the file bits into memory (read only).
    148      *
    149      * @returns 0 on success, OS specific error code on failure.
    150      * @param   pRdr        The file provider instance.
    151      * @param   ppvBits     Where to store the address of the mapping.
    152      *                      The size can be obtained using pfnSize.
    153      */
     140    /** @copydoc kLdrRdrAllMap */
    154141    int     (* pfnAllMap)(  PKLDRRDR pRdr, const void **ppvBits);
    155     /** Unmap a file bits mapping obtained by KLDRRDROPS::pfnAllMap.
    156      *
    157      * @returns 0 on success, OS specific error code on failure.
    158      * @param   pRdr        The file provider instance.
    159      * @param   pvBits      The mapping address.
    160      */
     142    /** @copydoc kLdrRdrAllUnmap */
    161143    int     (* pfnAllUnmap)(PKLDRRDR pRdr, const void *pvBits);
    162     /** Get the file size.
    163      *
    164      * @returns The file size. Returns -1 on failure.
    165      * @param   pRdr        The file provider instance.
    166      */
     144    /** @copydoc kLdrRdrSize */
    167145    off_t   (* pfnSize)(    PKLDRRDR pRdr);
    168     /** Get the file pointer offset.
    169      *
    170      * @returns The file pointer offset. Returns -1 on failure.
    171      * @param   pRdr        The file provider instance.
    172      */
     146    /** @copydoc kLdrRdrTell */
    173147    off_t   (* pfnTell)(    PKLDRRDR pRdr);
    174     /** Get the file name.
    175      *
    176      * @returns The file size. Returns -1 on failure.
    177      * @param   pRdr        The file provider instance.
    178      */
     148    /** @copydoc kLdrRdrName */
    179149    const char * (* pfnName)(PKLDRRDR pRdr);
    180     /**
    181      * Prepares a memory region to map file sections into.
    182      *
    183      * @returns 0 on success, OS specific error code on failure.
    184      * @param   pRdr        The file provider instance.
    185      * @param   ppv         If fFixed is set, *ppv contains the memory location which
    186      *                      the region should be based at. If fFixed is clear the OS
    187      *                      is free to choose the location.
    188      *                      On successful return *ppv contains address of the prepared
    189      *                      memory region.
    190      * @param   cb          The size of the memory region to prepare.
    191      * @param   fFixed      When set *ppv will contain the desired region address.
    192      *
    193      */
     150    /** @copydoc kLdrRdrPageSize */
     151    size_t  (* pfnPageSize)(PKLDRRDR pRdr);
     152    /** @copydoc kLdrRdrPrepare */
    194153    int     (* pfnPrepare)(PKLDRRDR pRdr, void **ppv, size_t cb, unsigned fFixed);
    195     /**
    196      * Maps a section of the file into the memory region reserved by pfnPrepare.
    197      *
    198      * @returns 0 on success, OS specific error code on failure.
    199      * @param   pRdr        The file provider instance.
    200      * @param   pv          The address in the prepared region.
    201      * @param   cb          The size of the memory mapping.
    202      * @param   enmProt     The desired memory protection.
    203      * @param   offFile     The start of the raw file bytes.
    204      * @param   cbFile      The number of raw file bytes. This must be less or equal to cb.
    205      */
     154    /** @copydoc kLdrRdrMap */
    206155    int     (* pfnMap)(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile);
    207     /**
    208      * Changes the page protection of a section mapped using pfnMap.
    209      *
    210      * This is typically used for applying fixups and similar.
    211      *
    212      * @returns 0 on success, OS specific error code on failure.
    213      * @param   pRdr        The file provider instance.
    214      * @param   pv          The address passed to pfnMap.
    215      * @param   cb          The size passed to pfnMap.
    216      * @param   enmProt     The desired memory protection.
    217      */
     156    /** @copydoc kLdrRdrRefreshMap */
     157    int     (* pfnRefreshMap)(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile);
     158    /** @copydoc kLdrRdrProtect */
    218159    int     (* pfnProtect)(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt);
    219     /**
    220      * Unmaps a section of the file previously mapped using pfnMap.
    221      *
    222      * @returns 0 on success, OS specific error code on failure.
    223      * @param   pRdr        The file provider instance.
    224      * @param   pv          The address passed to pfnMap.
    225      * @param   cb          The size passed to pfnMap.
    226      */
     160    /** @copydoc kLdrRdrUnmap */
    227161    int     (* pfnUnmap)(PKLDRRDR pRdr, void *pv, size_t cb);
    228     /**
    229      * Releases the memory region prepared by pfnPrepare().
    230      *
    231      * Before calling this function, all sections mapped by pfnMap must first be unmapped by calling pfnUnmap.
    232      *
    233      * @returns 0 on success, OS specific error code on failure.
    234      * @param   pRdr        The file provider instance.
    235      * @param   pv          The address of the prepared region.
    236      * @param   cb          The size of the prepared region.
    237      */
     162    /** @copydoc kLdrRdrUnprepare */
    238163    int     (* pfnUnprepare)(PKLDRRDR pRdr, void *pv, size_t cb);
    239     /**
    240      * We're done reading from the file but would like to keep file mappings.
    241      *
    242      * If the OS support closing the file handle while the file is mapped,
    243      * the reader should do so.
    244      *
    245      * @param   pRdr        The file provider instance.
    246      */
     164    /** @copydoc kLdrRdrDone */
    247165    void    (* pfnDone)(PKLDRRDR pRdr);
    248166    /** The usual non-zero dummy that makes sure we've initialized all members. */
     
    260178typedef struct KLDRRDR
    261179{
     180    /** Magic number (KLDRRDR_MAGIC). */
     181    uint32_t     u32Magic;
    262182    /** Pointer to the file provider operations. */
    263183    PCKLDRRDROPS pOps;
    264184} KLDRRDR;
     185
     186/** The magic for KLDRRDR::u32Magic. (Katsu Aki (Katsuaki Nakamura)) */
     187#define KLDRRDR_MAGIC   0x19610919
    265188
    266189void    kLdrRdrAddProvider(PKLDRRDROPS pAdd);
     
    274197off_t   kLdrRdrTell(    PKLDRRDR pRdr);
    275198const char *kLdrRdrName(PKLDRRDR pRdr);
     199size_t  kLdrRdrPageSize(PKLDRRDR pRdr);
     200int     kLdrRdrPrepare( PKLDRRDR pRdr, void **ppv, size_t cb, unsigned fFixed);
     201int     kLdrRdrMap(     PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile);
     202int     kLdrRdrRefreshMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile);
     203int     kLdrRdrProtect( PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt);
     204int     kLdrRdrUnmap(   PKLDRRDR pRdr, void *pv, size_t cb);
     205int     kLdrRdrUnprepare(PKLDRRDR pRdr, void *pv, size_t cb);
     206void    kLdrRdrDone(    PKLDRRDR pRdr);
    276207
    277208/** @} */
     
    399330    /** The usual invalid enum value. */
    400331    KLDRDBGINFOTYPE_INVALID = 0,
     332    /** Unknown debug info format. */
     333    KLDRDBGINFOTYPE_UNKNOWN,
    401334    /** Stabs. */
    402335    KLDRDBGINFOTYPE_STABS,
     
    456389    /** The size of the segment. */
    457390    KLDRSIZE        cb;
    458     /** The required segment alignment. */
     391    /** The required segment alignment.
     392     * The to 0 if the segment isn't supposed to be mapped. */
    459393    KLDRADDR        Alignment;
    460394    /** The link address.
    461      * Set to NIL_KLDRADDR if the segment isn't supposed to be mapped. */
     395     * Set to NIL_KLDRADDR if the segment isn't supposed to be
     396     * mapped or if the image doesn't have link addresses. */
    462397    KLDRADDR        LinkAddress;
    463     /** The address the segment was mapped at by kLdrModMap().
    464      * Set to NIL_KLDRADDR if not mapped. */
    465     KLDRADDR        MapAddress;
    466398    /** The segment protection. */
    467399    KLDRPROT        enmProt;
     400    /** The address the segment was mapped at by kLdrModMap().
     401     * Set to 0 if not mapped. */
     402    uintptr_t       MapAddress;
     403    /** File offset of the segment.
     404     * Set to -1 if no file backing (like BSS). */
     405    off_t           offFile;
     406    /** Size of the file bits of the segment.
     407     * Set to -1 if no file backing (like BSS). */
     408    off_t           cbFile;
    468409} KLDRSEG;
    469410/** Pointer to a loader segment. */
     
    563504typedef struct KLDRMOD
    564505{
    565     /** Magic number. */
     506    /** Magic number (KLDRMOD_MAGIC). */
    566507    uint32_t            u32Magic;
    567508    /** The format of this module. */
     
    696637 *
    697638 * @param   pMod        The module.
     639 * @param   iDbgInfo    The debug info ordinal number / id.
    698640 * @param   enmType     The debug info type.
    699  * @param   iDbgInfo    The debug info ordinal number / id.
     641 * @param   iMajorVer   The major version number of the debug info format. -1 if unknow - implies invalid iMinorVer.
     642 * @param   iMinorVer   The minor version number of the debug info format. -1 when iMajorVer is -1.
    700643 * @param   offFile     The file offset *if* this type has one specific location in the executable image file.
    701644 *                      This is -1 if there isn't any specific file location.
    702  * @param   cbFile      The file size.
    703  *                      This is 0 if there isn't any specific file location.
     645 * @param   LinkAddress The link address of the debug info if it's loadable. NIL_KLDRADDR if not loadable.
     646 * @param   cb          The size of the debug information. -1 is used if this isn't applicable.
    704647 * @param   pszExtFile  This points to the name of an external file containing the debug info.
    705648 *                      This is NULL if there isn't any external file.
    706649 * @param   pvUser      The user parameter specified to kLdrModEnumDbgInfo.
    707650 */
    708 typedef int FNKLDRENUMDBG(PKLDRMOD pMod, KLDRDBGINFOTYPE enmType, uint32_t iDbgInfo, off_t offFile, off_t cbFile,
    709                           const char *pszExtFile, void *pvUser);
     651typedef int FNKLDRENUMDBG(PKLDRMOD pMod, uint32_t iDbgInfo, KLDRDBGINFOTYPE enmType, int16_t iMajorVer, int16_t iMinorVer,
     652                          off_t offFile, KLDRADDR LinkAddress, off_t cb, const char *pszExtFile, void *pvUser);
     653/** Pointer to a debug info enumberator callback. */
     654typedef FNKLDRENUMDBG *PFNKLDRENUMDBG;
    710655
    711656int     kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod);
     
    724669int     kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
    725670int     kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
    726 /** Pointer to a debug info enumberator callback. */
    727 typedef FNKLDRENUMDBG *PFNKLDRENUMDBG;
    728671int     kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
    729672int     kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits);
     
    737680int     kLdrModReload(PKLDRMOD pMod);
    738681int     kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    739 int     kLdrModCallInit(PKLDRMOD pMod);
    740 int     kLdrModCallTerm(PKLDRMOD pMod);
    741 int     kLdrModCallThread(PKLDRMOD pMod, unsigned fAttachingOrDetaching);
     682int     kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle);
     683int     kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle);
     684int     kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching);
    742685/** @} */
    743686
    744687/** @name Operations On The Externally Managed Mappings
    745688 * @{ */
    746 size_t kLdrModSize(PKLDRMOD pMod);
     689KLDRADDR kLdrModSize(PKLDRMOD pMod);
    747690int     kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    748691int     kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
     
    818761    int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    819762    /** @copydoc kLdrModCallInit */
    820     int (* pfnCallInit)(PKLDRMOD pMod);
     763    int (* pfnCallInit)(PKLDRMOD pMod, uintptr_t uHandle);
    821764    /** @copydoc kLdrModCallTerm */
    822     int (* pfnCallTerm)(PKLDRMOD pMod);
     765    int (* pfnCallTerm)(PKLDRMOD pMod, uintptr_t uHandle);
    823766    /** @copydoc kLdrModCallThread */
    824     int (* pfnCallThread)(PKLDRMOD pMod, unsigned fAttachingOrDetaching);
     767    int (* pfnCallThread)(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching);
    825768    /** @copydoc kLdrModSize */
    826     size_t (* pfnSize)(PKLDRMOD pMod);
     769    KLDRADDR (* pfnSize)(PKLDRMOD pMod);
    827770    /** @copydoc kLdrModGetBits */
    828771    int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     
    1052995/** A forwarder chain was too long. */
    1053996#define KLDR_ERR_TOO_LONG_FORWARDER_CHAIN                   (KLDR_ERR_BASE + 51)
     997/** The module has no debug info. */
     998#define KLDR_ERR_NO_DEBUG_INFO                              (KLDR_ERR_BASE + 52)
     999/** The module is already mapped.
     1000 * kLdrModMap() can only be called once (without kLdrModUnmap() in between). */
     1001#define KLDR_ERR_ALREADY_MAPPED                             (KLDR_ERR_BASE + 53)
     1002/** The module was not mapped.
     1003 * kLdrModUnmap() should not called without being preceeded by a kLdrModMap(). */
     1004#define KLDR_ERR_NOT_MAPPED                                 (KLDR_ERR_BASE + 54)
    10541005
    10551006/** @name kLdrModPE status codes
  • trunk/kLdr/kLdrDyldMod.c

    r2855 r2856  
    10021002    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_INITIALIZING);
    10031003
    1004     rc = kLdrModCallInit(pMod->pMod);
     1004    rc = kLdrModCallInit(pMod->pMod, (uintptr_t)pMod->hMod);
    10051005    if (!rc)
    10061006        pMod->enmState = KLDRSTATE_GOOD;
     
    10231023    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_TERMINATING);
    10241024
    1025     kLdrModCallTerm(pMod->pMod);
     1025    kLdrModCallTerm(pMod->pMod, (uintptr_t)pMod->hMod);
    10261026    pMod->enmState = KLDRSTATE_PENDING_GC;
    10271027}
     
    10381038    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_GOOD);
    10391039
    1040     return kLdrModCallThread(pMod->pMod, 1 /* attach */);
     1040    return kLdrModCallThread(pMod->pMod, (uintptr_t)pMod->hMod, 1 /* attach */);
    10411041}
    10421042
     
    10521052    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_GOOD);
    10531053
    1054     kLdrModCallThread(pMod->pMod, 0 /* detach */);
     1054    kLdrModCallThread(pMod->pMod, (uintptr_t)pMod->hMod, 0 /* detach */);
    10551055}
    10561056
  • trunk/kLdr/kLdrMod.c

    r2855 r2856  
    538538 * @returns 0 on success or no init function, non-zero on init function failure or invalid pMod.
    539539 * @param   pMod            The module.
    540  */
    541 int     kLdrModCallInit(PKLDRMOD pMod)
    542 {
    543     KLDRMOD_VALIDATE(pMod);
    544     return pMod->pOps->pfnCallInit(pMod);
     540 * @param   uHandle         The module handle to use if any of the init functions requires the module handle.
     541 */
     542int     kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle)
     543{
     544    KLDRMOD_VALIDATE(pMod);
     545    return pMod->pOps->pfnCallInit(pMod, uHandle);
    545546}
    546547
     
    551552 * @returns 0 on success or no term function, non-zero on invalid pMod.
    552553 * @param   pMod            The module.
     554 * @param   uHandle         The module handle to use if any of the term functions requires the module handle.
    553555 *
    554556 * @remark  Termination function failure will be ignored by the module interpreter.
    555557 */
    556 int     kLdrModCallTerm(PKLDRMOD pMod)
    557 {
    558     KLDRMOD_VALIDATE(pMod);
    559     return pMod->pOps->pfnCallTerm(pMod);
     558int     kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle)
     559{
     560    KLDRMOD_VALIDATE(pMod);
     561    return pMod->pOps->pfnCallTerm(pMod, uHandle);
    560562}
    561563
     
    564566 * Call the thread attach or detach function of a mapped module (if any).
    565567 *
     568 * Any per-thread TLS initialization/termination will have to be done at this time too.
     569 *
    566570 * @returns 0 on success or no attach/detach function, non-zero on attach failure or invalid pMod.
    567571 * @param   pMod            The module.
     572 * @param   uHandle         The module handle to use if any of the thread attach/detach functions
     573 *                          requires the module handle.
    568574 *
    569575 * @remark  Detach function failure will be ignored by the module interpreter.
    570576 */
    571 int     kLdrModCallThread(PKLDRMOD pMod, unsigned fAttachingOrDetaching)
     577int     kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching)
    572578{
    573579    KLDRMOD_VALIDATE(pMod);
    574580    KLDRHLP_VALIDATE_FLAGS(fAttachingOrDetaching, 1);
    575     return pMod->pOps->pfnCallThread(pMod, fAttachingOrDetaching);
     581    return pMod->pOps->pfnCallThread(pMod, uHandle, fAttachingOrDetaching);
    576582}
    577583
     
    583589 * @param   pMod            The module.
    584590 */
    585 size_t kLdrModSize(PKLDRMOD pMod)
     591KLDRADDR kLdrModSize(PKLDRMOD pMod)
    586592{
    587593    KLDRMOD_VALIDATE_EX(pMod, 0);
  • trunk/kLdr/kLdrModPE.c

    r2855 r2856  
    3333#include "kLdrInternal.h"
    3434#include "kLdrModPE.h"
     35
    3536
    3637/*******************************************************************************
     
    7374    /** Pointer to the RDR mapping of the raw file bits. NULL if not mapped. */
    7475    const void             *pvBits;
    75     /** Whether we've mapped the image or not. */
    76     uint32_t                fMapped : 1;
     76    /** Pointer to the user mapping. */
     77    const void             *pvMapping;
    7778    /** Reserved flags. */
    78     uint32_t                f31Reserved;
     79    uint32_t                f32Reserved;
    7980    /** The number of imported modules.
    8081     * If ~(uint32_t)0 this hasn't been determined yet. */
     
    100101                                   PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind);
    101102static int32_t kldrModPENumberOfImports(PKLDRMOD pMod, const void *pvBits);
     103static int kldrModPEUnprotect(PKLDRMODPE pModPE, const void *pvMapping);
     104static int kldrModPEProtect(PKLDRMODPE pModPE, const void *pvMapping);
     105static int kldrModPEDoFixups(PKLDRMODPE pModPE, void *pvMapping, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress);
     106static int kldrModPEDoImports(PKLDRMODPE pModPE, void *pvMapping, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     107static int kldrModPEDoCallDLL(PKLDRMODPE pModPE, unsigned uOp, uintptr_t uHandle);
     108static int kldrModPEDoCallTLS(PKLDRMODPE pModPE, unsigned uOp, uintptr_t uHandle);
     109static int kldrModPERelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
     110                                 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    102111
    103112
     
    221230    pModPE->pMod = pMod;
    222231    pModPE->pvBits = NULL;
    223     pModPE->fMapped = 0;
    224     pModPE->f31Reserved = 0;
     232    pModPE->f32Reserved = 0;
    225233    pModPE->cImportModules = ~(uint32_t)0;
    226234    pModPE->offHdrs = offNewHdr >= 0 ? offNewHdr : 0;
     
    473481
    474482/**
     483 * Performs the mapping of the image.
     484 *
     485 * This can be used to do the internal mapping as well as the
     486 * user requested mapping. fForReal indicates which is desired.
     487 *
     488 * @returns 0 on success, non-zero OS or kLdr status code on failure.
     489 * @param   pModPE          The interpreter module instance
     490 * @param   fForReal        If set, do the user mapping. if clear, do the internal mapping.
     491 */
     492static int kldrModPEDoMap(PKLDRMODPE pModPE, unsigned fForReal)
     493{
     494    return -1;
     495}
     496
     497
     498/**
     499 * Unmaps a image mapping.
     500 *
     501 * This can be used to do the internal mapping as well as the
     502 * user requested mapping. fForReal indicates which is desired.
     503 *
     504 * @returns 0 on success, non-zero OS or kLdr status code on failure.
     505 * @param   pModPE          The interpreter module instance
     506 * @param   fForReal        If set, unmap the user mapping. if clear, unmap the internal mapping.
     507 */
     508static int kldrModPEDoUnmap(PKLDRMODPE pModPE, unsigned fForReal)
     509{
     510    return -1;
     511}
     512
     513
     514/**
    475515 * Gets usable bits and the right base address.
    476516 *
     
    505545    if (!*ppvBits)
    506546    {
    507         if (pModPE->fMapped)
    508             *ppvBits = (void *)(uintptr_t)pModPE->pMod->aSegments[0].MapAddress;
     547        if (pModPE->pvMapping)
     548            *ppvBits = pModPE->pvMapping;
    509549        else if (pModPE->pvBits)
    510550            *ppvBits = pModPE->pvBits;
     
    888928        /*
    889929         * We'll have to walk the import descriptors to figure out their number.
    890          * First, make sure we've got mapped bits and resolve any base address aliases.
     930         * First, make sure we've got mapped bits.
    891931         */
    892932        if (kldrModPEBitsAndBaseAddress(pModPE, &pvBits, NULL))
     
    931971    int rc;
    932972
     973    /*
     974     * Resolve base address alias if any.
     975     */
    933976    rc = kldrModPEBitsAndBaseAddress(pModPE, NULL, &BaseAddress);
    934977    if (rc)
    935978        return rc;
    936979
     980    /*
     981     * Convert the address from the header.
     982     */
    937983    *pMainEPAddress = pModPE->Hdrs.OptionalHeader.AddressOfEntryPoint
    938984        ? BaseAddress + pModPE->Hdrs.OptionalHeader.AddressOfEntryPoint
     
    943989
    944990/** @copydoc kLdrModEnumDbgInfo */
    945 int (* pfnEnumDbgInfo)(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
     991static int kldrModPEEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
     992{
     993    PKLDRMODPE                      pModPE = (PKLDRMODPE)pMod->pvData;
     994    const IMAGE_DEBUG_DIRECTORY    *pDbgDir;
     995    uint32_t                        iDbgInfo;
     996    uint32_t                        cb;
     997    int                             rc;
     998
     999    /*
     1000     * Check that there is a debug directory first.
     1001     */
     1002    cb = pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
     1003    if (    cb < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
     1004        ||  !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
     1005        return 0;
     1006
     1007    /*
     1008     * Make sure we've got mapped bits.
     1009     */
     1010    rc = kldrModPEBitsAndBaseAddress(pModPE, &pvBits, NULL);
     1011    if (rc)
     1012        return rc;
     1013
     1014    /*
     1015     * Enumerate the debug directory.
     1016     */
     1017    pDbgDir = KLDRMODPE_RVA2TYPE(pvBits,
     1018                                 pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
     1019                                 const IMAGE_DEBUG_DIRECTORY *);
     1020    for (iDbgInfo = 0;; iDbgInfo++, pDbgDir++, cb -= sizeof(IMAGE_DEBUG_DIRECTORY))
     1021    {
     1022        KLDRDBGINFOTYPE     enmDbgInfoType;
     1023
     1024        /* convert the type. */
     1025        switch (pDbgDir->Type)
     1026        {
     1027            case IMAGE_DEBUG_TYPE_UNKNOWN:
     1028            case IMAGE_DEBUG_TYPE_FPO:
     1029            case IMAGE_DEBUG_TYPE_COFF: //stabs dialect??
     1030            case IMAGE_DEBUG_TYPE_MISC:
     1031            case IMAGE_DEBUG_TYPE_EXCEPTION:
     1032            case IMAGE_DEBUG_TYPE_FIXUP:
     1033            case IMAGE_DEBUG_TYPE_BORLAND:
     1034            default:
     1035                enmDbgInfoType = KLDRDBGINFOTYPE_UNKNOWN;
     1036                break;
     1037            case IMAGE_DEBUG_TYPE_CODEVIEW:
     1038                enmDbgInfoType = KLDRDBGINFOTYPE_CODEVIEW;
     1039                break;
     1040        }
     1041
     1042        rc = pfnCallback(pMod, iDbgInfo,
     1043                         enmDbgInfoType, pDbgDir->MajorVersion, pDbgDir->MinorVersion,
     1044                         pDbgDir->PointerToRawData ? pDbgDir->PointerToRawData : -1,
     1045                         pDbgDir->AddressOfRawData ? pDbgDir->AddressOfRawData : NIL_KLDRADDR,
     1046                         pDbgDir->SizeOfData,
     1047                         NULL,
     1048                         pvUser);
     1049        if (rc)
     1050            break;
     1051
     1052        /* next */
     1053        if (cb <= sizeof(IMAGE_DEBUG_DIRECTORY))
     1054            break;
     1055    }
     1056
     1057    return rc;
     1058}
     1059
    9461060
    9471061/** @copydoc kLdrModHasDbgInfo */
    948 int (* pfnHasDbgInfo)(PKLDRMOD pMod, const void *pvBits);
     1062static int kldrModPEHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
     1063{
     1064    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     1065
     1066    /*
     1067     * Base this entirely on the presence of a debug directory.
     1068     */
     1069    if (    pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size
     1070            < sizeof(IMAGE_DEBUG_DIRECTORY) /* screw borland linkers */
     1071        ||  !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress)
     1072        return KLDR_ERR_NO_DEBUG_INFO;
     1073    return 0;
     1074}
     1075
     1076
    9491077/** @copydoc kLdrModMap */
    950 int (* pfnMap)(PKLDRMOD pMod);
     1078static int kldrModPEMap(PKLDRMOD pMod)
     1079{
     1080    PKLDRMODPE  pModPE = (PKLDRMODPE)pMod->pvData;
     1081    int         rc;
     1082
     1083    /*
     1084     * Already mapped?
     1085     */
     1086    if (pModPE->pvMapping)
     1087        return KLDR_ERR_ALREADY_MAPPED;
     1088
     1089    /*
     1090     * We've got a common worker which does this.
     1091     */
     1092    rc = kldrModPEDoMap(pModPE, 1 /* the real thing */);
     1093    if (rc)
     1094        return rc;
     1095    KLDRMODPE_ASSERT(pModPE->pvMapping);
     1096    return 0;
     1097}
     1098
     1099
    9511100/** @copydoc kLdrModUnmap */
    952 int (* pfnUnmap)(PKLDRMOD pMod);
     1101static int kldrModPEUnmap(PKLDRMOD pMod)
     1102{
     1103    PKLDRMODPE  pModPE = (PKLDRMODPE)pMod->pvData;
     1104    int         rc;
     1105
     1106    /*
     1107     * Mapped?
     1108     */
     1109    if (!pModPE->pvMapping)
     1110        return KLDR_ERR_NOT_MAPPED;
     1111
     1112    /*
     1113     * We've got a common worker which does this.
     1114     */
     1115    rc = kldrModPEDoMap(pModPE, 1 /* the real thing */);
     1116    if (rc)
     1117        return rc;
     1118    KLDRMODPE_ASSERT(pModPE->pvMapping);
     1119    return 0;
     1120
     1121}
     1122
     1123
    9531124/** @copydoc kLdrModAllocTLS */
    954 int (* pfnAllocTLS)(PKLDRMOD pMod);
     1125static int kldrModPEAllocTLS(PKLDRMOD pMod)
     1126{
     1127    PKLDRMODPE  pModPE = (PKLDRMODPE)pMod->pvData;
     1128
     1129    /*
     1130     * Mapped?
     1131     */
     1132    if (!pModPE->pvMapping)
     1133        return KLDR_ERR_NOT_MAPPED;
     1134
     1135    /*
     1136     * If no TLS directory then there is nothing to do.
     1137     */
     1138    if (    !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size
     1139        ||  !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress)
     1140        return 0;
     1141    /** @todo implement TLS. */
     1142    return -1;
     1143}
     1144
     1145
    9551146/** @copydoc kLdrModFreeTLS */
    956 void (* pfnFreeTLS)(PKLDRMOD pMod);
     1147static void kldrModPEFreeTLS(PKLDRMOD pMod)
     1148{
     1149    PKLDRMODPE  pModPE = (PKLDRMODPE)pMod->pvData;
     1150
     1151    /*
     1152     * Mapped?
     1153     */
     1154    if (!pModPE->pvMapping)
     1155        return;
     1156
     1157    /*
     1158     * If no TLS directory then there is nothing to do.
     1159     */
     1160    if (    !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size
     1161        ||  !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress)
     1162        return;
     1163    /** @todo implement TLS. */
     1164    return;
     1165}
     1166
     1167
    9571168/** @copydoc kLdrModReload */
    958 int (* pfnReload)(PKLDRMOD pMod);
     1169static int kldrModPEReload(PKLDRMOD pMod)
     1170{
     1171    PKLDRMODPE      pModPE = (PKLDRMODPE)pMod->pvData;
     1172    uint32_t        i;
     1173    int             rc;
     1174    const size_t    cbPage = kLdrRdrPageSize(pMod->pRdr);
     1175
     1176    /*
     1177     * Mapped?
     1178     */
     1179    if (!pModPE->pvMapping)
     1180        return KLDR_ERR_NOT_MAPPED;
     1181
     1182    /*
     1183     * Iterate the objects and ask the file provider to undo all the changes.
     1184     */
     1185    for (i = rc = 0; !rc && i < pMod->cSegments; i++)
     1186        rc = kLdrRdrRefreshMap(pMod->pRdr,
     1187                               (void *)pMod->aSegments[i].MapAddress,
     1188                               (size_t)pMod->aSegments[i].cb,
     1189                               pMod->aSegments[i].enmProt,
     1190                               pMod->aSegments[i].offFile,
     1191                               pMod->aSegments[i].cbFile);
     1192
     1193    return rc;
     1194}
     1195
     1196
    9591197/** @copydoc kLdrModFixupMapping */
    960 int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     1198static int kldrModPEFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
     1199{
     1200    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     1201    int rc, rc2;
     1202
     1203    /*
     1204     * Mapped?
     1205     */
     1206    if (!pModPE->pvMapping)
     1207        return KLDR_ERR_NOT_MAPPED;
     1208
     1209    /*
     1210     * Before doing anything we'll have to make all pages writable.
     1211     */
     1212    rc = kldrModPEUnprotect(pModPE, pModPE->pvMapping);
     1213    if (rc)
     1214        return rc;
     1215
     1216    /*
     1217     * Do we need to apply base relocations?
     1218     */
     1219    if (pModPE->Hdrs.OptionalHeader.ImageBase != (uintptr_t)pModPE->pvMapping)
     1220        rc = kldrModPEDoFixups(pModPE, (void *)pModPE->pvMapping, (uintptr_t)pModPE->pvMapping,
     1221                               pModPE->Hdrs.OptionalHeader.ImageBase);
     1222
     1223    /*
     1224     * Resolve imports.
     1225     */
     1226    if (!rc)
     1227        rc = kldrModPEDoImports(pModPE, (void *)pModPE->pvMapping, pfnGetImport, pvUser);
     1228
     1229    /*
     1230     * Restore protection.
     1231     */
     1232    rc2 = kldrModPEProtect(pModPE, pModPE->pvMapping);
     1233    if (!rc && rc2)
     1234        rc = rc2;
     1235    return rc;
     1236}
     1237
     1238
    9611239/** @copydoc kLdrModCallInit */
    962 int (* pfnCallInit)(PKLDRMOD pMod);
     1240static int kldrModPECallInit(PKLDRMOD pMod, uintptr_t uHandle)
     1241{
     1242    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     1243    int rc;
     1244
     1245    /*
     1246     * Mapped?
     1247     */
     1248    if (!pModPE->pvMapping)
     1249        return KLDR_ERR_NOT_MAPPED;
     1250
     1251    /*
     1252     * Do TLS callbacks first and then call the init/term function if it's a DLL.
     1253     */
     1254    rc = kldrModPEDoCallTLS(pModPE, DLL_PROCESS_ATTACH, uHandle);
     1255    if (    !rc
     1256        &&  (pModPE->Hdrs.FileHeader.Characteristics & IMAGE_FILE_DLL))
     1257    {
     1258        rc = kldrModPEDoCallDLL(pModPE, DLL_PROCESS_ATTACH, uHandle);
     1259        if (rc)
     1260            kldrModPEDoCallTLS(pModPE, DLL_PROCESS_DETACH, uHandle);
     1261    }
     1262
     1263    return rc;
     1264}
     1265
     1266
    9631267/** @copydoc kLdrModCallTerm */
    964 int (* pfnCallTerm)(PKLDRMOD pMod);
     1268static int kldrModPECallTerm(PKLDRMOD pMod, uintptr_t uHandle)
     1269{
     1270    PKLDRMODPE  pModPE = (PKLDRMODPE)pMod->pvData;
     1271
     1272    /*
     1273     * Mapped?
     1274     */
     1275    if (!pModPE->pvMapping)
     1276        return KLDR_ERR_NOT_MAPPED;
     1277
     1278    /*
     1279     * Do TLS callbacks first.
     1280     */
     1281    kldrModPEDoCallTLS(pModPE, DLL_PROCESS_DETACH, uHandle);
     1282    if (pModPE->Hdrs.FileHeader.Characteristics & IMAGE_FILE_DLL)
     1283        kldrModPEDoCallDLL(pModPE, DLL_PROCESS_DETACH, uHandle);
     1284
     1285    return 0;
     1286}
     1287
     1288
    9651289/** @copydoc kLdrModCallThread */
    966 int (* pfnCallThread)(PKLDRMOD pMod, unsigned fAttachingOrDetaching);
     1290static int kldrModPECallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching)
     1291{
     1292    PKLDRMODPE  pModPE = (PKLDRMODPE)pMod->pvData;
     1293    unsigned    uOp = fAttachingOrDetaching ? DLL_THREAD_ATTACH : DLL_THREAD_DETACH;
     1294    int         rc;
     1295
     1296    /*
     1297     * Do TLS callbacks first and then call the init/term function if it's a DLL.
     1298     */
     1299    rc = kldrModPEDoCallTLS(pModPE, uOp, uHandle);
     1300    if (!fAttachingOrDetaching)
     1301        rc = 0;
     1302    if (    !rc
     1303        &&  (pModPE->Hdrs.FileHeader.Characteristics & IMAGE_FILE_DLL))
     1304    {
     1305        rc = kldrModPEDoCallDLL(pModPE, uOp, uHandle);
     1306        if (!fAttachingOrDetaching)
     1307            rc = 0;
     1308        if (rc)
     1309            kldrModPEDoCallTLS(pModPE, uOp, uHandle);
     1310    }
     1311
     1312    return rc;
     1313}
     1314
     1315
    9671316/** @copydoc kLdrModSize */
    968 size_t (* pfnSize)(PKLDRMOD pMod);
     1317static KLDRADDR kldrModPESize(PKLDRMOD pMod)
     1318{
     1319    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     1320    return pModPE->Hdrs.OptionalHeader.SizeOfImage;
     1321}
     1322
     1323
    9691324/** @copydoc kLdrModGetBits */
    970 int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
     1325static int kldrModPEGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
     1326{
     1327    PKLDRMODPE  pModPE = (PKLDRMODPE)pMod->pvData;
     1328    uint32_t    i;
     1329    int         rc;
     1330
     1331    /*
     1332     * Iterate the segments and read the data within them.
     1333     */
     1334    for (i = 0; i < pMod->cSegments; i++)
     1335    {
     1336        /// @todo
     1337        rc = 0;
     1338    }
     1339
     1340    /*
     1341     * Perform relocations.
     1342     */
     1343    return kldrModPERelocateBits(pMod, pvBits, BaseAddress, pModPE->Hdrs.OptionalHeader.ImageBase, pfnGetImport, pvUser);
     1344
     1345}
     1346
     1347
    9711348/** @copydoc kLdrModRelocateBits */
    972 int (* pfnRelocateBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
    973                         PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    974 
     1349static int kldrModPERelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
     1350                                 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
     1351{
     1352    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     1353    int rc;
     1354
     1355    /*
     1356     * Call workers to do the jobs.
     1357     */
     1358    rc = kldrModPEDoFixups(pModPE, pvBits, NewBaseAddress, OldBaseAddress);
     1359    if (!rc)
     1360        rc = kldrModPEDoImports(pModPE, pvBits, pfnGetImport, pvUser);
     1361
     1362    return rc;
     1363}
     1364
  • trunk/kLdr/kLdrModPE.h

    r2834 r2856  
    152152#define  IMAGE_ORDINAL64(ord)  ((ord) &  0xffff)
    153153#define  IMAGE_SNAP_BY_ORDINAL64(ord)  (!!((ord) & IMAGE_ORDINAL_FLAG64))
     154
     155
     156/* dll/tls entry points argument */
     157#define DLL_PROCESS_DETACH      0
     158#define DLL_PROCESS_ATTACH      1
     159#define DLL_THREAD_ATTACH       2
     160#define DLL_THREAD_DETACH       3
    154161
    155162
     
    412419typedef IMAGE_LOAD_CONFIG_DIRECTORY64 *PIMAGE_LOAD_CONFIG_DIRECTORY64;
    413420
     421typedef struct _IMAGE_DEBUG_DIRECTORY
     422{
     423    uint32_t  Characteristics;
     424        uint32_t  TimeDateStamp;
     425    uint16_t  MajorVersion;
     426    uint16_t  MinorVersion;
     427    uint32_t  Type;
     428    uint32_t  SizeOfData;
     429    uint32_t  AddressOfRawData;
     430    uint32_t  PointerToRawData;
     431} IMAGE_DEBUG_DIRECTORY;
     432typedef IMAGE_DEBUG_DIRECTORY *PIMAGE_DEBUG_DIRECTORY;
     433
     434#define IMAGE_DEBUG_TYPE_UNKNOWN  0
     435#define IMAGE_DEBUG_TYPE_COFF 1
     436#define IMAGE_DEBUG_TYPE_CODEVIEW 2 /* 4.0 */
     437#define IMAGE_DEBUG_TYPE_FPO 3 /* FPO = frame pointer omission */
     438#define IMAGE_DEBUG_TYPE_MISC 4
     439#define IMAGE_DEBUG_TYPE_EXCEPTION 5
     440#define IMAGE_DEBUG_TYPE_FIXUP 6
     441#define IMAGE_DEBUG_TYPE_BORLAND 9
     442
     443typedef struct _IMAGE_TLS_DIRECTORY32
     444{
     445    uint32_t  StartAddressOfRawData;
     446    uint32_t  EndAddressOfRawData;
     447    uint32_t  AddressOfIndex;
     448    uint32_t  AddressOfCallBacks;
     449    uint32_t  SizeOfZeroFill;
     450    uint32_t  Characteristics;
     451} IMAGE_TLS_DIRECTORY32;
     452typedef IMAGE_TLS_DIRECTORY32 *PIMAGE_TLS_DIRECTORY32;
     453
     454typedef struct _IMAGE_TLS_DIRECTORY64
     455{
     456    uint64_t  StartAddressOfRawData;
     457    uint64_t  EndAddressOfRawData;
     458    uint64_t  AddressOfIndex;
     459    uint64_t  AddressOfCallBacks;
     460    uint32_t  SizeOfZeroFill;
     461    uint32_t  Characteristics;
     462} IMAGE_TLS_DIRECTORY64;
     463typedef IMAGE_TLS_DIRECTORY64 *PIMAGE_TLS_DIRECTORY64;
     464
     465
    414466#pragma pack()
    415467
  • trunk/kLdr/kLdrRdr.c

    r2826 r2856  
    3131#include <kLdr.h>
    3232#include "kLdrInternal.h"
     33
     34
     35/*******************************************************************************
     36*   Defined Constants And Macros                                               *
     37*******************************************************************************/
     38/** @def KLDRRDR_STRICT
     39 * Define KLDRRDR_STRICT to enabled strict checks in KLDRMOD. */
     40#define KLDRRDR_STRICT 1
     41
     42/** @def KLDRRDR_ASSERT
     43 * Assert that an expression is true when KLDR_STRICT is defined.
     44 */
     45#ifdef KLDRRDR_STRICT
     46# define KLDRRDR_ASSERT(expr)  kldrHlpAssert(expr)
     47#else
     48# define KLDRRDR_ASSERT(expr)  do {} while (0)
     49#endif
     50
     51/** Return / crash validation of a reader argument. */
     52#define KLDRRDR_VALIDATE_EX(pRdr, rc) \
     53    do  { \
     54        if (    (pRdr)->u32Magic != KLDRRDR_MAGIC \
     55            ||  (pRdr)->pOps == NULL \
     56           )\
     57        { \
     58            return (rc); \
     59        } \
     60    } while (0)
     61
     62/** Return / crash validation of a reader argument. */
     63#define KLDRRDR_VALIDATE(pRdr) \
     64    KLDRRDR_VALIDATE_EX(pRdr, KLDR_ERR_INVALID_PARAMETER)
     65
     66/** Return / crash validation of a reader argument. */
     67#define KLDRRDR_VALIDATE_VOID(pRdr) \
     68    do  { \
     69        if (    (pRdr)->u32Magic != KLDRRDR_MAGIC \
     70            ||  (pRdr)->pOps == NULL \
     71           )\
     72        { \
     73            return; \
     74        } \
     75    } while (0)
     76
    3377
    3478
     
    82126int kLdrRdrClose(PKLDRRDR pRdr)
    83127{
     128    KLDRRDR_VALIDATE(pRdr);
    84129    return pRdr->pOps->pfnDestroy(pRdr);
    85130}
     
    96141int kLdrRdrRead(PKLDRRDR pRdr, void *pvBuf, size_t cb, off_t off)
    97142{
     143    KLDRRDR_VALIDATE(pRdr);
    98144    return pRdr->pOps->pfnRead(pRdr, pvBuf, cb, off);
    99145}
     
    109155int kLdrRdrAllMap(PKLDRRDR pRdr, const void **ppvBits)
    110156{
     157    KLDRRDR_VALIDATE(pRdr);
    111158    return pRdr->pOps->pfnAllMap(pRdr, ppvBits);
    112159}
     
    121168int kLdrRdrAllUnmap(PKLDRRDR pRdr, const void *pvBits)
    122169{
     170    KLDRRDR_VALIDATE(pRdr);
    123171    return pRdr->pOps->pfnAllUnmap(pRdr, pvBits);
    124172}
     
    132180off_t kLdrRdrSize(PKLDRRDR pRdr)
    133181{
     182    KLDRRDR_VALIDATE(pRdr);
    134183    return pRdr->pOps->pfnSize(pRdr);
    135184}
     
    143192off_t kLdrRdrTell(PKLDRRDR pRdr)
    144193{
     194    KLDRRDR_VALIDATE(pRdr);
    145195    return pRdr->pOps->pfnTell(pRdr);
    146196}
     
    149199/** Get the file name.
    150200 *
    151  * @returns The file size. Returns -1 on failure.
     201 * @returns The file name. Returns NULL on failure.
    152202 * @param   pRdr        The file provider instance.
    153203 */
    154204const char *kLdrRdrName(PKLDRRDR pRdr)
    155205{
     206    KLDRRDR_VALIDATE_EX(pRdr, NULL);
    156207    return pRdr->pOps->pfnName(pRdr);
    157208}
    158209
    159210
     211/**
     212 * Gets the page size used when mapping sections of the file.
     213 *
     214 * @returns The page size.
     215 * @param   pRdr        The file provider instance.
     216 */
     217size_t  kLdrRdrPageSize(PKLDRRDR pRdr)
     218{
     219    KLDRRDR_VALIDATE_EX(pRdr, 0x10000);
     220    return pRdr->pOps->pfnPageSize(pRdr);
     221}
     222
     223
     224/**
     225 * Prepares a memory region to map file sections into.
     226 *
     227 * @returns 0 on success, OS specific error code on failure.
     228 * @param   pRdr        The file provider instance.
     229 * @param   ppv         If fFixed is set, *ppv contains the memory location which
     230 *                      the region should be based at. If fFixed is clear the OS
     231 *                      is free to choose the location.
     232 *                      On successful return *ppv contains address of the prepared
     233 *                      memory region.
     234 * @param   cb          The size of the memory region to prepare.
     235 * @param   fFixed      When set *ppv will contain the desired region address.
     236 *
     237 */
     238int kLdrRdrPrepare(PKLDRRDR pRdr, void **ppv, size_t cb, unsigned fFixed)
     239{
     240    KLDRRDR_VALIDATE(pRdr);
     241    return pRdr->pOps->pfnPrepare(pRdr, ppv, cb, fFixed);
     242}
     243
     244
     245/**
     246 * Maps a section of the file into the memory region reserved by pfnPrepare.
     247 *
     248 * @returns 0 on success, OS specific error code on failure.
     249 * @param   pRdr        The file provider instance.
     250 * @param   pv          The address in the prepared region.
     251 * @param   cb          The size of the memory mapping.
     252 * @param   enmProt     The desired memory protection.
     253 * @param   offFile     The start of the raw file bytes.
     254 * @param   cbFile      The number of raw file bytes. This must be less or equal to cb.
     255 */
     256int kLdrRdrMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile)
     257{
     258    KLDRRDR_VALIDATE(pRdr);
     259    return pRdr->pOps->pfnMap(pRdr, pv, cb, enmProt, offFile, cbFile);
     260}
     261
     262
     263/**
     264 * Reloads dirty pages in mapped section.
     265 *
     266 * @returns 0 on success, OS specific error code on failure.
     267 * @param   pRdr        The file provider instance.
     268 * @param   pv          The address in the prepared region.
     269 * @param   cb          The size of the memory mapping.
     270 * @param   enmProt     The desired memory protection.
     271 * @param   offFile     The start of the raw file bytes.
     272 * @param   cbFile      The number of raw file bytes. This must be less or equal to cb.
     273 */
     274int kLdrRdrRefreshMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile)
     275{
     276    KLDRRDR_VALIDATE(pRdr);
     277    return pRdr->pOps->pfnRefreshMap(pRdr, pv, cb, enmProt, offFile, cbFile);
     278}
     279
     280
     281/**
     282 * Changes the page protection of a section mapped using pfnMap.
     283 *
     284 * This is typically used for applying fixups and similar.
     285 *
     286 * @returns 0 on success, OS specific error code on failure.
     287 * @param   pRdr        The file provider instance.
     288 * @param   pv          The address passed to pfnMap.
     289 * @param   cb          The size passed to pfnMap.
     290 * @param   enmProt     The desired memory protection.
     291 */
     292int kLdrRdrProtect(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt)
     293{
     294    KLDRRDR_VALIDATE(pRdr);
     295    return pRdr->pOps->pfnProtect(pRdr, pv, cb, enmProt);
     296}
     297
     298
     299/**
     300 * Unmaps a section of the file previously mapped using pfnMap.
     301 *
     302 * @returns 0 on success, OS specific error code on failure.
     303 * @param   pRdr        The file provider instance.
     304 * @param   pv          The address passed to pfnMap.
     305 * @param   cb          The size passed to pfnMap.
     306 */
     307int kLdrRdrUnmap(PKLDRRDR pRdr, void *pv, size_t cb)
     308{
     309    KLDRRDR_VALIDATE(pRdr);
     310    return pRdr->pOps->pfnUnmap(pRdr, pv, cb);
     311}
     312
     313
     314/**
     315 * Releases the memory region prepared by pfnPrepare().
     316 *
     317 * Before calling this function, all sections mapped by pfnMap must first be unmapped by calling pfnUnmap.
     318 *
     319 * @returns 0 on success, OS specific error code on failure.
     320 * @param   pRdr        The file provider instance.
     321 * @param   pv          The address of the prepared region.
     322 * @param   cb          The size of the prepared region.
     323 */
     324int kLdrRdrUnprepare(PKLDRRDR pRdr, void *pv, size_t cb)
     325{
     326    KLDRRDR_VALIDATE(pRdr);
     327    return pRdr->pOps->pfnUnprepare(pRdr, pv, cb);
     328}
     329
     330
     331/**
     332 * We're done reading from the file but would like to keep file mappings.
     333 *
     334 * If the OS support closing the file handle while the file is mapped,
     335 * the reader should do so.
     336 *
     337 * @param   pRdr        The file provider instance.
     338 */
     339void kLdrRdrDone(PKLDRRDR pRdr)
     340{
     341    KLDRRDR_VALIDATE_VOID(pRdr);
     342    pRdr->pOps->pfnDone(pRdr);
     343}
     344
Note: See TracChangeset for help on using the changeset viewer.