Changeset 2856
- Timestamp:
- Nov 4, 2006, 11:19:33 PM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 6 edited
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 /** Magic number (KLDRRDR_MAGIC). */ 181 uint32_t u32Magic; 262 182 /** Pointer to the file provider operations. */ 263 183 PCKLDRRDROPS pOps; 264 184 } KLDRRDR; 185 186 /** The magic for KLDRRDR::u32Magic. (Katsu Aki (Katsuaki Nakamura)) */ 187 #define KLDRRDR_MAGIC 0x19610919 265 188 266 189 void kLdrRdrAddProvider(PKLDRRDROPS pAdd); … … 274 197 off_t kLdrRdrTell( PKLDRRDR pRdr); 275 198 const char *kLdrRdrName(PKLDRRDR pRdr); 199 size_t kLdrRdrPageSize(PKLDRRDR pRdr); 200 int kLdrRdrPrepare( PKLDRRDR pRdr, void **ppv, size_t cb, unsigned fFixed); 201 int kLdrRdrMap( PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile); 202 int kLdrRdrRefreshMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile); 203 int kLdrRdrProtect( PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt); 204 int kLdrRdrUnmap( PKLDRRDR pRdr, void *pv, size_t cb); 205 int kLdrRdrUnprepare(PKLDRRDR pRdr, void *pv, size_t cb); 206 void kLdrRdrDone( PKLDRRDR pRdr); 276 207 277 208 /** @} */ … … 399 330 /** The usual invalid enum value. */ 400 331 KLDRDBGINFOTYPE_INVALID = 0, 332 /** Unknown debug info format. */ 333 KLDRDBGINFOTYPE_UNKNOWN, 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 /** 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; 468 409 } KLDRSEG; 469 410 /** Pointer to a loader segment. */ … … 563 504 typedef struct KLDRMOD 564 505 { 565 /** Magic number . */506 /** Magic number (KLDRMOD_MAGIC). */ 566 507 uint32_t u32Magic; 567 508 /** The format of this module. */ … … 696 637 * 697 638 * @param pMod The module. 639 * @param iDbgInfo The debug info ordinal number / id. 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 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. 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, uintptr_t uHandle); 683 int kLdrModCallTerm(PKLDRMOD pMod, uintptr_t uHandle); 684 int kLdrModCallThread(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching); 742 685 /** @} */ 743 686 744 687 /** @name Operations On The Externally Managed Mappings 745 688 * @{ */ 746 size_tkLdrModSize(PKLDRMOD pMod);689 KLDRADDR 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, uintptr_t uHandle); 821 764 /** @copydoc kLdrModCallTerm */ 822 int (* pfnCallTerm)(PKLDRMOD pMod );765 int (* pfnCallTerm)(PKLDRMOD pMod, uintptr_t uHandle); 823 766 /** @copydoc kLdrModCallThread */ 824 int (* pfnCallThread)(PKLDRMOD pMod, u nsigned fAttachingOrDetaching);767 int (* pfnCallThread)(PKLDRMOD pMod, uintptr_t uHandle, unsigned fAttachingOrDetaching); 825 768 /** @copydoc kLdrModSize */ 826 size_t(* pfnSize)(PKLDRMOD pMod);769 KLDRADDR (* 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 /** 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) 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, (uintptr_t)pMod->hMod); 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, (uintptr_t)pMod->hMod); 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, (uintptr_t)pMod->hMod, 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, (uintptr_t)pMod->hMod, 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 * @param uHandle The module handle to use if any of the term functions requires the module handle. 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, uintptr_t uHandle) 559 { 560 KLDRMOD_VALIDATE(pMod); 561 return pMod->pOps->pfnCallTerm(pMod, uHandle); 560 562 } 561 563 … … 564 566 * Call the thread attach or detach function of a mapped module (if any). 565 567 * 568 * Any per-thread TLS initialization/termination will have to be done at this time too. 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 * @param uHandle The module handle to use if any of the thread attach/detach functions 573 * requires the module handle. 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, uintptr_t uHandle, 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, uHandle, fAttachingOrDetaching); 576 582 } 577 583 … … 583 589 * @param pMod The module. 584 590 */ 585 size_tkLdrModSize(PKLDRMOD pMod)591 KLDRADDR 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 /** Pointer to the user mapping. */ 77 const void *pvMapping; 77 78 /** Reserved flags. */ 78 uint32_t f3 1Reserved;79 uint32_t f32Reserved; 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 static int kldrModPEUnprotect(PKLDRMODPE pModPE, const void *pvMapping); 104 static int kldrModPEProtect(PKLDRMODPE pModPE, const void *pvMapping); 105 static int kldrModPEDoFixups(PKLDRMODPE pModPE, void *pvMapping, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress); 106 static int kldrModPEDoImports(PKLDRMODPE pModPE, void *pvMapping, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 107 static int kldrModPEDoCallDLL(PKLDRMODPE pModPE, unsigned uOp, uintptr_t uHandle); 108 static int kldrModPEDoCallTLS(PKLDRMODPE pModPE, unsigned uOp, uintptr_t uHandle); 109 static int kldrModPERelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress, 110 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser); 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 * 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 */ 492 static 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 */ 508 static int kldrModPEDoUnmap(PKLDRMODPE pModPE, unsigned fForReal) 509 { 510 return -1; 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->pvMapping) 548 *ppvBits = pModPE->pvMapping; 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 * Resolve base address alias if any. 975 */ 933 976 rc = kldrModPEBitsAndBaseAddress(pModPE, NULL, &BaseAddress); 934 977 if (rc) 935 978 return rc; 936 979 980 /* 981 * Convert the address from the header. 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 /* 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 154 161 155 162 … … 412 419 typedef IMAGE_LOAD_CONFIG_DIRECTORY64 *PIMAGE_LOAD_CONFIG_DIRECTORY64; 413 420 421 typedef 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; 432 typedef 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 443 typedef 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; 452 typedef IMAGE_TLS_DIRECTORY32 *PIMAGE_TLS_DIRECTORY32; 453 454 typedef 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; 463 typedef IMAGE_TLS_DIRECTORY64 *PIMAGE_TLS_DIRECTORY64; 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 * 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 33 77 34 78 … … 82 126 int kLdrRdrClose(PKLDRRDR pRdr) 83 127 { 128 KLDRRDR_VALIDATE(pRdr); 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 KLDRRDR_VALIDATE(pRdr); 98 144 return pRdr->pOps->pfnRead(pRdr, pvBuf, cb, off); 99 145 } … … 109 155 int kLdrRdrAllMap(PKLDRRDR pRdr, const void **ppvBits) 110 156 { 157 KLDRRDR_VALIDATE(pRdr); 111 158 return pRdr->pOps->pfnAllMap(pRdr, ppvBits); 112 159 } … … 121 168 int kLdrRdrAllUnmap(PKLDRRDR pRdr, const void *pvBits) 122 169 { 170 KLDRRDR_VALIDATE(pRdr); 123 171 return pRdr->pOps->pfnAllUnmap(pRdr, pvBits); 124 172 } … … 132 180 off_t kLdrRdrSize(PKLDRRDR pRdr) 133 181 { 182 KLDRRDR_VALIDATE(pRdr); 134 183 return pRdr->pOps->pfnSize(pRdr); 135 184 } … … 143 192 off_t kLdrRdrTell(PKLDRRDR pRdr) 144 193 { 194 KLDRRDR_VALIDATE(pRdr); 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 name. Returns NULL on failure. 152 202 * @param pRdr The file provider instance. 153 203 */ 154 204 const char *kLdrRdrName(PKLDRRDR pRdr) 155 205 { 206 KLDRRDR_VALIDATE_EX(pRdr, NULL); 156 207 return pRdr->pOps->pfnName(pRdr); 157 208 } 158 209 159 210 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 */ 217 size_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 */ 238 int 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 */ 256 int 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 */ 274 int 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 */ 292 int 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 */ 307 int 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 */ 324 int 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 */ 339 void 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.