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
     181
    262182    /** Pointer to the file provider operations. */
    263183    PCKLDRRDROPS pOps;
    264184} KLDRRDR;
     185
     186
     187
    265188
    266189void    kLdrRdrAddProvider(PKLDRRDROPS pAdd);
     
    274197off_t   kLdrRdrTell(    PKLDRRDR pRdr);
    275198const char *kLdrRdrName(PKLDRRDR pRdr);
     199
     200
     201
     202
     203
     204
     205
     206
    276207
    277208/** @} */
     
    399330    /** The usual invalid enum value. */
    400331    KLDRDBGINFOTYPE_INVALID = 0,
     332
     333
    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
     401
     402
     403
     404
     405
     406
     407
     408
    468409} KLDRSEG;
    469410/** Pointer to a loader segment. */
     
    563504typedef struct KLDRMOD
    564505{
    565     /** Magic number. */
     506    /** Magic number. */
    566507    uint32_t            u32Magic;
    567508    /** The format of this module. */
     
    696637 *
    697638 * @param   pMod        The module.
     639
    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   e.
     646 * .
    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);
     683int     kLdrModCallTerm(PKLDRMOD pMod);
     684int     kLdrModCallThread(PKLDRMOD pMod, unsigned fAttachingOrDetaching);
    742685/** @} */
    743686
    744687/** @name Operations On The Externally Managed Mappings
    745688 * @{ */
    746 size_t kLdrModSize(PKLDRMOD pMod);
     689 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);
    821764    /** @copydoc kLdrModCallTerm */
    822     int (* pfnCallTerm)(PKLDRMOD pMod);
     765    int (* pfnCallTerm)(PKLDRMOD pMod);
    823766    /** @copydoc kLdrModCallThread */
    824     int (* pfnCallThread)(PKLDRMOD pMod, unsigned fAttachingOrDetaching);
     767    int (* pfnCallThread)(PKLDRMOD pMod, unsigned fAttachingOrDetaching);
    825768    /** @copydoc kLdrModSize */
    826     size_t (* pfnSize)(PKLDRMOD pMod);
     769    (* 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
     998
     999
     1000
     1001
     1002
     1003
     1004
    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);
    10051005    if (!rc)
    10061006        pMod->enmState = KLDRSTATE_GOOD;
     
    10231023    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_TERMINATING);
    10241024
    1025     kLdrModCallTerm(pMod->pMod);
     1025    kLdrModCallTerm(pMod->pMod);
    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, 1 /* attach */);
    10411041}
    10421042
     
    10521052    KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_GOOD);
    10531053
    1054     kLdrModCallThread(pMod->pMod, 0 /* detach */);
     1054    kLdrModCallThread(pMod->pMod, 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
    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)
     559{
     560    KLDRMOD_VALIDATE(pMod);
     561    return pMod->pOps->pfnCallTerm(pMod);
    560562}
    561563
     
    564566 * Call the thread attach or detach function of a mapped module (if any).
    565567 *
     568
     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
     573
    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, 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, fAttachingOrDetaching);
    576582}
    577583
     
    583589 * @param   pMod            The module.
    584590 */
    585 size_t kLdrModSize(PKLDRMOD pMod)
     591 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    /** . */
     77    ;
    7778    /** Reserved flags. */
    78     uint32_t                f31Reserved;
     79    uint32_t                f3Reserved;
    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);
     103
     104
     105
     106
     107
     108
     109
     110
    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
     484
     485
     486
     487
     488
     489
     490
     491
     492
     493
     494
     495
     496
     497
     498
     499
     500
     501
     502
     503
     504
     505
     506
     507
     508
     509
     510
     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->)
     548            *ppvBits = ;
    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
     975
    933976    rc = kldrModPEBitsAndBaseAddress(pModPE, NULL, &BaseAddress);
    934977    if (rc)
    935978        return rc;
    936979
     980
     981
     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
     157
     158
     159
     160
    154161
    155162
     
    412419typedef IMAGE_LOAD_CONFIG_DIRECTORY64 *PIMAGE_LOAD_CONFIG_DIRECTORY64;
    413420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
     458
     459
     460
     461
     462
     463
     464
     465
    414466#pragma pack()
    415467
  • trunk/kLdr/kLdrRdr.c

    r2826 r2856  
    3131#include <kLdr.h>
    3232#include "kLdrInternal.h"
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
    3377
    3478
     
    82126int kLdrRdrClose(PKLDRRDR pRdr)
    83127{
     128
    84129    return pRdr->pOps->pfnDestroy(pRdr);
    85130}
     
    96141int kLdrRdrRead(PKLDRRDR pRdr, void *pvBuf, size_t cb, off_t off)
    97142{
     143
    98144    return pRdr->pOps->pfnRead(pRdr, pvBuf, cb, off);
    99145}
     
    109155int kLdrRdrAllMap(PKLDRRDR pRdr, const void **ppvBits)
    110156{
     157
    111158    return pRdr->pOps->pfnAllMap(pRdr, ppvBits);
    112159}
     
    121168int kLdrRdrAllUnmap(PKLDRRDR pRdr, const void *pvBits)
    122169{
     170
    123171    return pRdr->pOps->pfnAllUnmap(pRdr, pvBits);
    124172}
     
    132180off_t kLdrRdrSize(PKLDRRDR pRdr)
    133181{
     182
    134183    return pRdr->pOps->pfnSize(pRdr);
    135184}
     
    143192off_t kLdrRdrTell(PKLDRRDR pRdr)
    144193{
     194
    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 on failure.
    152202 * @param   pRdr        The file provider instance.
    153203 */
    154204const char *kLdrRdrName(PKLDRRDR pRdr)
    155205{
     206
    156207    return pRdr->pOps->pfnName(pRdr);
    157208}
    158209
    159210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
Note: See TracChangeset for help on using the changeset viewer.