Changeset 21472 for trunk/src/kernel32/mmap.cpp
- Timestamp:
- Nov 11, 2010, 1:19:13 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/mmap.cpp
r10572 r21472 35 35 #include "oslibmem.h" 36 36 #include <winimagepeldr.h> 37 #include <custombuild.h> 37 #include <custombuild.h> 38 38 #include "asmutil.h" 39 39 … … 54 54 //****************************************************************************** 55 55 //****************************************************************************** 56 void WIN32API SetCustomMMapSemName(LPSTR pszSemName) 56 void WIN32API SetCustomMMapSemName(LPSTR pszSemName) 57 57 { 58 58 pszMMapSemName = pszSemName; … … 79 79 //****************************************************************************** 80 80 Win32MemMap::Win32MemMap(HANDLE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName) 81 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0), 81 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0), 82 82 image(0), pWriteBitmap(NULL), lpszFileName(NULL) 83 83 { … … 105 105 //****************************************************************************** 106 106 Win32MemMap::Win32MemMap(Win32PeLdrImage *pImage, ULONG baseAddress, ULONG size) 107 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0), 107 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0), 108 108 image(0), pWriteBitmap(NULL), lpszFileName(NULL) 109 109 { … … 273 273 dprintf(("Win32MemMap::commitRange %x (faultaddr %x)", pageAddr, lpPageFaultAddr)); 274 274 275 if(fWriteAccess) 275 if(fWriteAccess) 276 276 {//writes are handled on a per-page basis 277 for(int i=0;i<nrpages;i++) 277 for(int i=0;i<nrpages;i++) 278 278 { 279 279 if(commitPage(ulFaultAddr, offset, TRUE, 1) == FALSE) { … … 305 305 // FALSE - failure 306 306 // 307 // NOTE: 307 // NOTE: 308 308 // We handle only one pages for write access! 309 309 // … … 327 327 } 328 328 329 if(fWriteAccess && (mProtFlags & PAGE_WRITECOPY)) 329 if(fWriteAccess && (mProtFlags & PAGE_WRITECOPY)) 330 330 {//this is a COW map, call commitGuardPage to handle write faults 331 331 return commitGuardPage(ulFaultAddr, offset, fWriteAccess); … … 340 340 if(fWriteAccess) { 341 341 Win32MemMapView *view = Win32MemMapView::findView(ulFaultAddr); 342 if(view) { 342 if(view) { 343 343 if(!(view->getAccessFlags() & MEMMAP_ACCESS_WRITE)) { 344 344 dprintf(("Write access for a readonly view!!")); … … 354 354 int faultsize = nrpages*PAGE_SIZE; 355 355 356 if(fWriteAccess) 356 if(fWriteAccess) 357 357 {//write access needs special care, so do that on a per page basis 358 358 dprintf(("Write access -> handle only one page")); … … 365 365 } 366 366 367 while(faultsize) 367 while(faultsize) 368 368 { 369 369 if(VirtualQuery((LPSTR)pageAddr, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0) { … … 386 386 updateViewPages(offset, memInfo.RegionSize, (fWriteAccess) ? PAGEVIEW_VIEW : PAGEVIEW_READONLY); 387 387 388 if(hMemFile != -1) 388 if(hMemFile != -1) 389 389 {//now read the page(s) from disk 390 390 DWORD size; … … 408 408 goto fail; 409 409 } 410 } 411 //We set the protection flags to PAGE_READONLY, unless this pagefault 410 } 411 //We set the protection flags to PAGE_READONLY, unless this pagefault 412 412 //was due to a write access 413 413 //This way we can track dirty pages which need to be flushed to 414 414 //disk when FlushViewOfFile is called or the map is closed. 415 if(!fWriteAccess) 415 if(!fWriteAccess) 416 416 { 417 417 if(VirtualProtect((LPVOID)pageAddr, memInfo.RegionSize, PAGE_READONLY, &oldProt) == FALSE) { … … 420 420 } 421 421 } 422 else 422 else 423 423 {//make these pages as dirty 424 424 ULONG startPage = (pageAddr - (ULONG)pMapping) >> PAGE_SHIFT; … … 431 431 markDirtyPages(startPage, nrPages); 432 432 433 //Write access means that the next time the corresponding COW page 433 //Write access means that the next time the corresponding COW page 434 434 //is touched, we need to reload it. So set the GUARD flags. 435 435 updateViewPages(offset, memInfo.RegionSize, PAGEVIEW_GUARD); 436 436 } 437 437 } 438 else 439 if(fWriteAccess) 438 else 439 if(fWriteAccess) 440 440 { 441 441 //mark these pages as dirty … … 457 457 updateViewPages(offset, memInfo.RegionSize, PAGEVIEW_VIEW); 458 458 459 //Write access means that the next time the corresponding COW page 459 //Write access means that the next time the corresponding COW page 460 460 //is touched, we need to reload it. So set the GUARD flags. 461 461 updateViewPages(offset, memInfo.RegionSize, PAGEVIEW_GUARD); … … 519 519 memcpy((LPVOID)pageAddr, (char *)pMapping+ulOffset, PAGE_SIZE); 520 520 521 if(fWriteAccess) 521 if(fWriteAccess) 522 522 {//copy on write; mark pages as private 523 523 DWORD startpage = (ulOffset) >> PAGE_SHIFT; … … 526 526 527 527 Win32MemMapView *view = Win32MemMapView::findView(ulFaultAddr); 528 if(view) 528 if(view) 529 529 { 530 530 view->markCOWPages(startpage, 1); … … 532 532 else DebugInt3(); //oh, oh 533 533 } 534 else 534 else 535 535 {//read access; must set the map + all views to READONLY to track write access 536 536 … … 574 574 int localmaps; 575 575 576 if(views) 576 if(views) 577 577 { 578 578 localmaps = Win32MemMapView::findViews(this, nrMappings, views); 579 if(localmaps <= nrMappings) 579 if(localmaps <= nrMappings) 580 580 { 581 for(int i=0;i<localmaps;i++) 581 for(int i=0;i<localmaps;i++) 582 582 { 583 583 views[i]->changePageFlags(offset, size, flags); 584 } 584 } 585 585 } 586 586 else { … … 619 619 dprintf(("ERROR: Win32MemMap::invalidatePages: VirtualFree failed!!")); 620 620 } 621 //invalidate all shared COW pages too by setting the GUARD flag 621 //invalidate all shared COW pages too by setting the GUARD flag 622 622 //(which forces a resync the next time the app touches them) 623 623 return updateViewPages(offset, size, PAGEVIEW_GUARD); … … 640 640 641 641 //Memory has already been allocated for executable image maps (only used internally) 642 if(!pMapping && nrMappings == 0) 642 if(!pMapping && nrMappings == 0) 643 643 {//if not mapped, reserve/commit entire view 644 644 //SvL: Always read/write access or else ReadFile will crash once we … … 648 648 // flag it will also crash) 649 649 //NOTE: If this is ever changed, then we must update setProtFlags!!!! 650 650 651 651 //All named file mappings are shared (files & memory only) 652 652 if(lpszMapName) { … … 687 687 return TRUE; 688 688 689 fail: 689 fail: 690 690 return FALSE; 691 691 } … … 702 702 // FILE_MAP_WRITE, FILE_MAP_READ, FILE_MAP_COPY 703 703 // FILE_MAP_ALL_ACCESS 704 // 704 // 705 705 // 706 706 // Returns: … … 723 723 if((fdwAccess & FILE_MAP_WRITE) && !(mProtFlags & PAGE_READWRITE)) 724 724 goto parmfail; 725 if((fdwAccess & FILE_MAP_READ) && !(mProtFlags & (PAGE_READWRITE|PAGE_READONLY))) 725 // CreateFileMapping docs say that PAGE_WRITECOPY is equivalent to PAGE_READONLY and thus 726 // is okay for FILE_MAP_READ too 727 if((fdwAccess & FILE_MAP_READ) && !(mProtFlags & (PAGE_READWRITE|PAGE_READONLY|PAGE_WRITECOPY))) 726 728 goto parmfail; 727 729 728 730 if (fdwAccess != FILE_MAP_ALL_ACCESS) 729 731 if((fdwAccess & FILE_MAP_COPY) && !(mProtFlags & PAGE_WRITECOPY)) … … 786 788 787 789 view = Win32MemMapView::findView((ULONG)addr); 788 if(view == NULL) 790 if(view == NULL) 789 791 goto fail; 790 792 … … 825 827 goto parmfail; 826 828 827 if(viewaddr != MMAP_FLUSHVIEW_ALL) 829 if(viewaddr != MMAP_FLUSHVIEW_ALL) 828 830 { 829 831 view = Win32MemMapView::findView(viewaddr); … … 854 856 855 857 //Check the write page bitmap for dirty pages and write them to disk 856 while(cbFlush) 858 while(cbFlush) 857 859 { 858 860 int startPage = offset >> PAGE_SHIFT; … … 944 946 Win32MemMap *map = memmaps; 945 947 946 if(map != NULL) 948 if(map != NULL) 947 949 { 948 950 while(map) { 949 951 //TODO: we currently don't support sharing file maps between processes 950 if(map->mProcessId == processId && map->lpszFileName) 952 if(map->mProcessId == processId && map->lpszFileName) 951 953 { 952 954 if(!strcmp(map->lpszFileName, szFileName)) … … 1020 1022 while(map) { 1021 1023 nextmap = map->next; 1022 if(map->getProcessId() == processId) 1024 if(map->getProcessId() == processId) 1023 1025 { 1024 1026 //delete map can delete multiple objects (duplicate memory map), so make
Note:
See TracChangeset
for help on using the changeset viewer.