Changeset 2856
- Timestamp:
- Nov 4, 2006, 11:19:33 PM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 6 edited
-
kLdr.h (modified) (11 diffs)
-
kLdrDyldMod.c (modified) (4 diffs)
-
kLdrMod.c (modified) (4 diffs)
-
kLdrModPE.c (modified) (9 diffs)
-
kLdrModPE.h (modified) (2 diffs)
-
kLdrRdr.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdr.h
r2855 r2856 136 136 */ 137 137 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 */ 146 139 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 */ 154 141 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 */ 161 143 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 */ 167 145 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 */ 173 147 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 */ 179 149 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 */ 194 153 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 */ 206 155 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 */ 218 159 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 */ 227 161 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 */ 238 163 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 */ 247 165 void (* pfnDone)(PKLDRRDR pRdr); 248 166 /** The usual non-zero dummy that makes sure we've initialized all members. */ … … 260 178 typedef struct KLDRRDR 261 179 { 180 181 262 182 /** Pointer to the file provider operations. */ 263 183 PCKLDRRDROPS pOps; 264 184 } KLDRRDR; 185 186 187 265 188 266 189 void kLdrRdrAddProvider(PKLDRRDROPS pAdd); … … 274 197 off_t kLdrRdrTell( PKLDRRDR pRdr); 275 198 const char *kLdrRdrName(PKLDRRDR pRdr); 199 200 201 202 203 204 205 206 276 207 277 208 /** @} */ … … 399 330 /** The usual invalid enum value. */ 400 331 KLDRDBGINFOTYPE_INVALID = 0, 332 333 401 334 /** Stabs. */ 402 335 KLDRDBGINFOTYPE_STABS, … … 456 389 /** The size of the segment. */ 457 390 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. */ 459 393 KLDRADDR Alignment; 460 394 /** 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. */ 462 397 KLDRADDR LinkAddress; 463 /** The address the segment was mapped at by kLdrModMap().464 * Set to NIL_KLDRADDR if not mapped. */465 KLDRADDR MapAddress;466 398 /** The segment protection. */ 467 399 KLDRPROT enmProt; 400 401 402 403 404 405 406 407 408 468 409 } KLDRSEG; 469 410 /** Pointer to a loader segment. */ … … 563 504 typedef struct KLDRMOD 564 505 { 565 /** Magic number . */506 /** Magic number. */ 566 507 uint32_t u32Magic; 567 508 /** The format of this module. */ … … 696 637 * 697 638 * @param pMod The module. 639 698 640 * @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. 700 643 * @param offFile The file offset *if* this type has one specific location in the executable image file. 701 644 * 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 * . 704 647 * @param pszExtFile This points to the name of an external file containing the debug info. 705 648 * This is NULL if there isn't any external file. 706 649 * @param pvUser The user parameter specified to kLdrModEnumDbgInfo. 707 650 */ 708 typedef int FNKLDRENUMDBG(PKLDRMOD pMod, KLDRDBGINFOTYPE enmType, uint32_t iDbgInfo, off_t offFile, off_t cbFile, 709 const char *pszExtFile, void *pvUser); 651 typedef 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. */ 654 typedef FNKLDRENUMDBG *PFNKLDRENUMDBG; 710 655 711 656 int kLdrModOpen(const char *pszFilename, PPKLDRMOD ppMod); … … 724 669 int kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo); 725 670 int kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress); 726 /** Pointer to a debug info enumberator callback. */727 typedef FNKLDRENUMDBG *PFNKLDRENUMDBG;728 671 int kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser); 729 672 int kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits); … … 737 680 int kLdrModReload(PKLDRMOD pMod); 738 681 int kLdrModFixupMapping(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 739 int kLdrModCallInit(PKLDRMOD pMod );740 int kLdrModCallTerm(PKLDRMOD pMod );741 int kLdrModCallThread(PKLDRMOD pMod, u nsigned fAttachingOrDetaching);682 int kLdrModCallInit(PKLDRMOD pMod); 683 int kLdrModCallTerm(PKLDRMOD pMod); 684 int kLdrModCallThread(PKLDRMOD pMod, unsigned fAttachingOrDetaching); 742 685 /** @} */ 743 686 744 687 /** @name Operations On The Externally Managed Mappings 745 688 * @{ */ 746 size_tkLdrModSize(PKLDRMOD pMod);689 kLdrModSize(PKLDRMOD pMod); 747 690 int kLdrModGetBits(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 748 691 int kLdrModRelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress, … … 818 761 int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 819 762 /** @copydoc kLdrModCallInit */ 820 int (* pfnCallInit)(PKLDRMOD pMod );763 int (* pfnCallInit)(PKLDRMOD pMod); 821 764 /** @copydoc kLdrModCallTerm */ 822 int (* pfnCallTerm)(PKLDRMOD pMod );765 int (* pfnCallTerm)(PKLDRMOD pMod); 823 766 /** @copydoc kLdrModCallThread */ 824 int (* pfnCallThread)(PKLDRMOD pMod, u nsigned fAttachingOrDetaching);767 int (* pfnCallThread)(PKLDRMOD pMod, unsigned fAttachingOrDetaching); 825 768 /** @copydoc kLdrModSize */ 826 size_t(* pfnSize)(PKLDRMOD pMod);769 (* pfnSize)(PKLDRMOD pMod); 827 770 /** @copydoc kLdrModGetBits */ 828 771 int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); … … 1052 995 /** A forwarder chain was too long. */ 1053 996 #define KLDR_ERR_TOO_LONG_FORWARDER_CHAIN (KLDR_ERR_BASE + 51) 997 998 999 1000 1001 1002 1003 1004 1054 1005 1055 1006 /** @name kLdrModPE status codes -
trunk/kLdr/kLdrDyldMod.c
r2855 r2856 1002 1002 KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_INITIALIZING); 1003 1003 1004 rc = kLdrModCallInit(pMod->pMod );1004 rc = kLdrModCallInit(pMod->pMod); 1005 1005 if (!rc) 1006 1006 pMod->enmState = KLDRSTATE_GOOD; … … 1023 1023 KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_TERMINATING); 1024 1024 1025 kLdrModCallTerm(pMod->pMod );1025 kLdrModCallTerm(pMod->pMod); 1026 1026 pMod->enmState = KLDRSTATE_PENDING_GC; 1027 1027 } … … 1038 1038 KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_GOOD); 1039 1039 1040 return kLdrModCallThread(pMod->pMod, 1 /* attach */);1040 return kLdrModCallThread(pMod->pMod, 1 /* attach */); 1041 1041 } 1042 1042 … … 1052 1052 KLDRDYLDMOD_ASSERT(pMod->enmState == KLDRSTATE_GOOD); 1053 1053 1054 kLdrModCallThread(pMod->pMod, 0 /* detach */);1054 kLdrModCallThread(pMod->pMod, 0 /* detach */); 1055 1055 } 1056 1056 -
trunk/kLdr/kLdrMod.c
r2855 r2856 538 538 * @returns 0 on success or no init function, non-zero on init function failure or invalid pMod. 539 539 * @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 */ 542 int kLdrModCallInit(PKLDRMOD pMod, uintptr_t uHandle) 543 { 544 KLDRMOD_VALIDATE(pMod); 545 return pMod->pOps->pfnCallInit(pMod, uHandle); 545 546 } 546 547 … … 551 552 * @returns 0 on success or no term function, non-zero on invalid pMod. 552 553 * @param pMod The module. 554 553 555 * 554 556 * @remark Termination function failure will be ignored by the module interpreter. 555 557 */ 556 int kLdrModCallTerm(PKLDRMOD pMod )557 { 558 KLDRMOD_VALIDATE(pMod); 559 return pMod->pOps->pfnCallTerm(pMod );558 int kLdrModCallTerm(PKLDRMOD pMod) 559 { 560 KLDRMOD_VALIDATE(pMod); 561 return pMod->pOps->pfnCallTerm(pMod); 560 562 } 561 563 … … 564 566 * Call the thread attach or detach function of a mapped module (if any). 565 567 * 568 569 566 570 * @returns 0 on success or no attach/detach function, non-zero on attach failure or invalid pMod. 567 571 * @param pMod The module. 572 573 568 574 * 569 575 * @remark Detach function failure will be ignored by the module interpreter. 570 576 */ 571 int kLdrModCallThread(PKLDRMOD pMod, u nsigned fAttachingOrDetaching)577 int kLdrModCallThread(PKLDRMOD pMod, unsigned fAttachingOrDetaching) 572 578 { 573 579 KLDRMOD_VALIDATE(pMod); 574 580 KLDRHLP_VALIDATE_FLAGS(fAttachingOrDetaching, 1); 575 return pMod->pOps->pfnCallThread(pMod, fAttachingOrDetaching);581 return pMod->pOps->pfnCallThread(pMod, fAttachingOrDetaching); 576 582 } 577 583 … … 583 589 * @param pMod The module. 584 590 */ 585 size_tkLdrModSize(PKLDRMOD pMod)591 kLdrModSize(PKLDRMOD pMod) 586 592 { 587 593 KLDRMOD_VALIDATE_EX(pMod, 0); -
trunk/kLdr/kLdrModPE.c
r2855 r2856 33 33 #include "kLdrInternal.h" 34 34 #include "kLdrModPE.h" 35 35 36 36 37 /******************************************************************************* … … 73 74 /** Pointer to the RDR mapping of the raw file bits. NULL if not mapped. */ 74 75 const void *pvBits; 75 /** Whether we've mapped the image or not. */76 uint32_t fMapped : 1;76 /** . */ 77 ; 77 78 /** Reserved flags. */ 78 uint32_t f3 1Reserved;79 uint32_t f3Reserved; 79 80 /** The number of imported modules. 80 81 * If ~(uint32_t)0 this hasn't been determined yet. */ … … 100 101 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind); 101 102 static int32_t kldrModPENumberOfImports(PKLDRMOD pMod, const void *pvBits); 103 104 105 106 107 108 109 110 102 111 103 112 … … 221 230 pModPE->pMod = pMod; 222 231 pModPE->pvBits = NULL; 223 pModPE->fMapped = 0; 224 pModPE->f31Reserved = 0; 232 pModPE->f32Reserved = 0; 225 233 pModPE->cImportModules = ~(uint32_t)0; 226 234 pModPE->offHdrs = offNewHdr >= 0 ? offNewHdr : 0; … … 473 481 474 482 /** 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 475 515 * Gets usable bits and the right base address. 476 516 * … … 505 545 if (!*ppvBits) 506 546 { 507 if (pModPE-> fMapped)508 *ppvBits = (void *)(uintptr_t)pModPE->pMod->aSegments[0].MapAddress;547 if (pModPE->) 548 *ppvBits = ; 509 549 else if (pModPE->pvBits) 510 550 *ppvBits = pModPE->pvBits; … … 888 928 /* 889 929 * 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. 891 931 */ 892 932 if (kldrModPEBitsAndBaseAddress(pModPE, &pvBits, NULL)) … … 931 971 int rc; 932 972 973 974 975 933 976 rc = kldrModPEBitsAndBaseAddress(pModPE, NULL, &BaseAddress); 934 977 if (rc) 935 978 return rc; 936 979 980 981 982 937 983 *pMainEPAddress = pModPE->Hdrs.OptionalHeader.AddressOfEntryPoint 938 984 ? BaseAddress + pModPE->Hdrs.OptionalHeader.AddressOfEntryPoint … … 943 989 944 990 /** @copydoc kLdrModEnumDbgInfo */ 945 int (* pfnEnumDbgInfo)(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser); 991 static 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 946 1060 947 1061 /** @copydoc kLdrModHasDbgInfo */ 948 int (* pfnHasDbgInfo)(PKLDRMOD pMod, const void *pvBits); 1062 static 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 949 1077 /** @copydoc kLdrModMap */ 950 int (* pfnMap)(PKLDRMOD pMod); 1078 static 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 951 1100 /** @copydoc kLdrModUnmap */ 952 int (* pfnUnmap)(PKLDRMOD pMod); 1101 static 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 953 1124 /** @copydoc kLdrModAllocTLS */ 954 int (* pfnAllocTLS)(PKLDRMOD pMod); 1125 static 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 955 1146 /** @copydoc kLdrModFreeTLS */ 956 void (* pfnFreeTLS)(PKLDRMOD pMod); 1147 static 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 957 1168 /** @copydoc kLdrModReload */ 958 int (* pfnReload)(PKLDRMOD pMod); 1169 static 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 959 1197 /** @copydoc kLdrModFixupMapping */ 960 int (* pfnFixupMapping)(PKLDRMOD pMod, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 1198 static 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 961 1239 /** @copydoc kLdrModCallInit */ 962 int (* pfnCallInit)(PKLDRMOD pMod); 1240 static 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 963 1267 /** @copydoc kLdrModCallTerm */ 964 int (* pfnCallTerm)(PKLDRMOD pMod); 1268 static 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 965 1289 /** @copydoc kLdrModCallThread */ 966 int (* pfnCallThread)(PKLDRMOD pMod, unsigned fAttachingOrDetaching); 1290 static 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 967 1316 /** @copydoc kLdrModSize */ 968 size_t (* pfnSize)(PKLDRMOD pMod); 1317 static KLDRADDR kldrModPESize(PKLDRMOD pMod) 1318 { 1319 PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData; 1320 return pModPE->Hdrs.OptionalHeader.SizeOfImage; 1321 } 1322 1323 969 1324 /** @copydoc kLdrModGetBits */ 970 int (* pfnGetBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 1325 static 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 971 1348 /** @copydoc kLdrModRelocateBits */ 972 int (* pfnRelocateBits)(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress, 973 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 974 1349 static 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 152 152 #define IMAGE_ORDINAL64(ord) ((ord) & 0xffff) 153 153 #define IMAGE_SNAP_BY_ORDINAL64(ord) (!!((ord) & IMAGE_ORDINAL_FLAG64)) 154 155 156 157 158 159 160 154 161 155 162 … … 412 419 typedef IMAGE_LOAD_CONFIG_DIRECTORY64 *PIMAGE_LOAD_CONFIG_DIRECTORY64; 413 420 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 414 466 #pragma pack() 415 467 -
trunk/kLdr/kLdrRdr.c
r2826 r2856 31 31 #include <kLdr.h> 32 32 #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 33 77 34 78 … … 82 126 int kLdrRdrClose(PKLDRRDR pRdr) 83 127 { 128 84 129 return pRdr->pOps->pfnDestroy(pRdr); 85 130 } … … 96 141 int kLdrRdrRead(PKLDRRDR pRdr, void *pvBuf, size_t cb, off_t off) 97 142 { 143 98 144 return pRdr->pOps->pfnRead(pRdr, pvBuf, cb, off); 99 145 } … … 109 155 int kLdrRdrAllMap(PKLDRRDR pRdr, const void **ppvBits) 110 156 { 157 111 158 return pRdr->pOps->pfnAllMap(pRdr, ppvBits); 112 159 } … … 121 168 int kLdrRdrAllUnmap(PKLDRRDR pRdr, const void *pvBits) 122 169 { 170 123 171 return pRdr->pOps->pfnAllUnmap(pRdr, pvBits); 124 172 } … … 132 180 off_t kLdrRdrSize(PKLDRRDR pRdr) 133 181 { 182 134 183 return pRdr->pOps->pfnSize(pRdr); 135 184 } … … 143 192 off_t kLdrRdrTell(PKLDRRDR pRdr) 144 193 { 194 145 195 return pRdr->pOps->pfnTell(pRdr); 146 196 } … … 149 199 /** Get the file name. 150 200 * 151 * @returns The file size. Returns -1on failure.201 * @returns The file on failure. 152 202 * @param pRdr The file provider instance. 153 203 */ 154 204 const char *kLdrRdrName(PKLDRRDR pRdr) 155 205 { 206 156 207 return pRdr->pOps->pfnName(pRdr); 157 208 } 158 209 159 210 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.
