Changeset 2860
- Timestamp:
- Nov 8, 2006, 5:10:14 AM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrModPE.c
r2859 r2860 551 551 static int kldrModPEDoMap(PKLDRMODPE pModPE, unsigned fForReal) 552 552 { 553 return -1; 553 PKLDRMOD pMod = pModPE->pMod; 554 unsigned fFixed; 555 void *pvBase; 556 size_t cb; 557 int rc; 558 uint32_t i; 559 560 /* 561 * Prepare it. 562 */ 563 /* size */ 564 cb = (size_t)pMod->pOps->pfnSize(pModPE->pMod); 565 if (cb != pMod->pOps->pfnSize(pModPE->pMod)) 566 return KLDR_ERR_ADDRESS_OVERFLOW; 567 568 /* fixed image? */ 569 fFixed = fForReal 570 && ( pMod->enmType == KLDRTYPE_EXECUTABLE_FIXED 571 || pMod->enmType == KLDRTYPE_SHARED_LIBRARY_FIXED); 572 if (!fFixed) 573 pvBase = NULL; 574 else 575 { 576 pvBase = (void *)(uintptr_t)pMod->aSegments[0].LinkAddress; 577 if ((uintptr_t)pvBase != pMod->aSegments[0].LinkAddress) 578 return KLDR_ERR_ADDRESS_OVERFLOW; 579 } 580 581 /* try do the prepare */ 582 rc = kLdrRdrPrepare(pMod->pRdr, &pvBase, cb, fFixed); 583 if (rc) 584 return rc; 585 586 /* 587 * Map the segments (sub sections in PE terms). 588 */ 589 for (i = 0; i < pMod->cSegments; i++) 590 { 591 void *pvSeg; 592 593 if (!pMod->aSegments[i].Alignment) 594 continue; 595 596 pvSeg = (uint8_t *)pvBase + pMod->aSegments[i].RVA; 597 rc = kLdrRdrMap(pMod->pRdr, pvSeg, pMod->aSegments[i].cbMapped, pMod->aSegments[i].enmProt, 598 pMod->aSegments[i].offFile, pMod->aSegments[i].cbFile); 599 if (rc) 600 { 601 /* bailout */ 602 while (i-- > 0) 603 { 604 if (!pMod->aSegments[i].Alignment) 605 continue; 606 607 kLdrRdrUnmap(pMod->pRdr, (void *)pMod->aSegments[i].MapAddress, pMod->aSegments[i].cbMapped); 608 pMod->aSegments[i].MapAddress = 0; 609 } 610 break; 611 } 612 pMod->aSegments[i].MapAddress = (uintptr_t)pvSeg; 613 } 614 615 if (!rc) 616 { 617 if (fForReal) 618 pModPE->pvMapping = pvBase; 619 else 620 pModPE->pvBits = pvBase; 621 } 622 else 623 kLdrRdrUnprepare(pMod->pRdr, pvBase, cb); 624 return rc; 554 625 } 555 626 … … 567 638 static int kldrModPEDoUnmap(PKLDRMODPE pModPE, const void *pvMapping) 568 639 { 569 return -1; 640 PKLDRMOD pMod = pModPE->pMod; 641 size_t cb = (size_t)pMod->pOps->pfnSize(pModPE->pMod); 642 int rc2; 643 int rc = 0; 644 uint32_t i; 645 646 /* 647 * Unmap the segments (sub sections in PE terms). 648 */ 649 for (i = 0; i < pMod->cSegments; i++) 650 { 651 if (!pMod->aSegments[i].MapAddress) 652 continue; 653 654 rc2 = kLdrRdrUnmap(pMod->pRdr, (void *)pMod->aSegments[i].MapAddress, pMod->aSegments[i].cbMapped); 655 if (!rc2) 656 pMod->aSegments[i].MapAddress = 0; 657 else if (!rc) 658 rc = rc2; 659 } 660 661 /* 662 * 'Unprepare' the mapping region. 663 */ 664 if (!rc) 665 { 666 rc = kLdrRdrUnprepare(pMod->pRdr, (void *)pvMapping, cb); 667 if (!rc) 668 { 669 if (pModPE->pvBits == pvMapping) 670 pModPE->pvBits = NULL; 671 if (pModPE->pvMapping == pvMapping) 672 pModPE->pvMapping = NULL; 673 } 674 } 675 676 return rc; 570 677 } 571 678 -
trunk/kLdr/kLdrRdrFile.c
r2858 r2860 52 52 *******************************************************************************/ 53 53 /** 54 * Prepared stuff. 55 */ 56 typedef struct KLDRRDRFILEPREP 57 { 58 /** The address of the prepared region. */ 59 void *pv; 60 /** The size of the prepared region. */ 61 size_t cb; 62 #if defined(__WIN__) || defined(__NT__) 63 /** Handle to the section created to map the file. */ 64 HANDLE hSection; 65 #endif 66 } KLDRRDRFILEPREP, *PKLDRRDRFILEPREP; 67 68 /** 54 69 * The file provier instance for native files. 55 70 */ … … 57 72 { 58 73 /** The file reader vtable. */ 59 KLDRRDR Core;74 KLDRRDR Core; 60 75 /** The file handle. */ 61 76 #ifdef __OS2__ 62 HFILE File;77 HFILE File; 63 78 #elif defined(__WIN__) || defined(__NT__) 64 HANDLE File;79 HANDLE File; 65 80 #else 66 81 # error "Port me!" 67 82 #endif 68 83 /** The current file offset. */ 69 off_t off;84 off_t off; 70 85 /** The file size. */ 71 off_t cb; 86 off_t cb; 87 /** Array where we stuff the mapping area data. */ 88 KLDRRDRFILEPREP aPreps[4]; 89 /** The number of current preps. */ 90 uint32_t cPreps; 72 91 /** Number of mapping references. */ 73 int32_t cMappings;92 int32_t cMappings; 74 93 /** The memory mapping. */ 75 void *pvMapping;94 void *pvMapping; 76 95 /** The filename. */ 77 char szFilename[1];96 char szFilename[1]; 78 97 } KLDRRDRFILE, *PKLDRRDRFILE; 79 98 … … 133 152 } 134 153 154 155 /** 156 * Finds a prepared mapping region. 157 * 158 * @returns Pointer to the aPrep entry. 159 * @param pFile The instance data. 160 * @param pv The base of the region. 161 * @param cb The size of the region. 162 */ 163 static PKLDRRDRFILEPREP kldrRdrFileFindPrepExact(PKLDRRDRFILE pFile, void *pv, size_t cb) 164 { 165 int32_t i = pFile->cPreps; 166 while (i-- > 0) 167 if ( pFile->aPreps[i].pv == pv 168 || pFile->aPreps[i].cb == cb) 169 return &pFile->aPreps[i]; 170 return NULL; 171 } 172 173 174 /** 175 * Finds a prepared mapping region containing the specified region. 176 * 177 * @returns Pointer to the aPrep entry. 178 * @param pFile The instance data. 179 * @param pv The base of the sub region. 180 * @param cb The size of the sub region. 181 */ 182 static PKLDRRDRFILEPREP kldrRdrFileFindPrepWithin(PKLDRRDRFILE pFile, void *pv, size_t cb) 183 { 184 int32_t i = pFile->cPreps; 185 while (i-- > 0) 186 if ((uintptr_t)pv - (uintptr_t)pFile->aPreps[i].pv < pFile->aPreps[i].cb) 187 { 188 if ((uintptr_t)pv - (uintptr_t)pFile->aPreps[i].pv + cb <= pFile->aPreps[i].cb) 189 return &pFile->aPreps[i]; 190 return NULL; 191 } 192 return NULL; 193 } 194 195 135 196 /** @copydoc KLDRRDR::pfnUnprepare */ 136 197 static int kldrRdrFileUnprepare(PKLDRRDR pRdr, void *pv, size_t cb) 137 198 { 199 PKLDRRDRFILE pRdrFile = (PKLDRRDRFILE)pRdr; 200 PKLDRRDRFILEPREP pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb); 201 if (!pPrep) 202 return KLDR_ERR_INVALID_PARAMETER; 203 138 204 return -1; 139 205 } … … 143 209 static int kldrRdrFileUnmap(PKLDRRDR pRdr, void *pv, size_t cb) 144 210 { 211 PKLDRRDRFILE pRdrFile = (PKLDRRDRFILE)pRdr; 212 PKLDRRDRFILEPREP pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb); 213 if (!pPrep) 214 return KLDR_ERR_INVALID_PARAMETER; 215 145 216 return -1; 146 217 } … … 150 221 static int kldrRdrFileProtect(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt) 151 222 { 223 PKLDRRDRFILE pRdrFile = (PKLDRRDRFILE)pRdr; 224 PKLDRRDRFILEPREP pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb); 225 if (!pPrep) 226 return KLDR_ERR_INVALID_PARAMETER; 227 152 228 return -1; 153 229 } … … 157 233 static int kldrRdrFileRefreshMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile) 158 234 { 235 PKLDRRDRFILE pRdrFile = (PKLDRRDRFILE)pRdr; 236 PKLDRRDRFILEPREP pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb); 237 if (!pPrep) 238 return KLDR_ERR_INVALID_PARAMETER; 239 159 240 return -1; 160 241 } … … 164 245 static int kldrRdrFileMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile) 165 246 { 247 PKLDRRDRFILE pRdrFile = (PKLDRRDRFILE)pRdr; 248 PKLDRRDRFILEPREP pPrep = kldrRdrFileFindPrepExact(pRdrFile, pv, cb); 249 if (!pPrep) 250 return KLDR_ERR_INVALID_PARAMETER; 251 166 252 return -1; 167 253 } … … 543 629 pRdrFile->cb = cb; 544 630 pRdrFile->off = 0; 631 pRdrFile->cMappings = 0; 632 pRdrFile->cPreps = 0; 545 633 kLdrHlpMemCopy(&pRdrFile->szFilename[0], szFilename, cchFilename + 1); 546 634 -
trunk/kLdr/tstkLdrMod.c
r2859 r2860 378 378 379 379 /** 380 * Tests the mapping related api. 381 */ 382 static int BasicTestsSubMap(PKLDRMOD pMod) 383 { 384 int rc; 385 386 rc = kLdrModMap(pMod); 387 if (rc) 388 return Failure("kLdrModMap failed, rc=%d\n", rc); 389 390 return 0; 391 } 392 393 394 /** 380 395 * Performs basic module loader tests on the specified file. 381 396 */ … … 390 405 { 391 406 rc = BasicTestsSub(pMod); 407 if (!rc) 408 rc = BasicTestsSubMap(pMod); 392 409 rc2 = kLdrModClose(pMod); 393 410 if (rc2)
Note:
See TracChangeset
for help on using the changeset viewer.