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

More code.

File:
1 edited

Legend:

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