Description: map_image now sets up the protections in the view of the memory-mapped executable image according to the protections for each section in the image. Before the patch, running an app under WinDbg on W2K/VMware showed a protection violation at a certain address, which Wine did not fault at that address. After the patch, the app faults in the same place in Wine as it does in W2K. Contact info: Robert Baruch autophile@starband.net
diff -Naurb wine-cvs-orig/memory/virtual.c wine-cvs/memory/virtual.c --- wine-cvs-orig/memory/virtual.c Fri Nov 30 22:15:32 2001 +++ wine-cvs/memory/virtual.c Thu Dec 13 15:22:07 2001 @@ -492,6 +492,7 @@ FILE_VIEW *view; char *ptr; int shared_fd = -1; + BYTE prot; SetLastError( ERROR_BAD_EXE_FORMAT ); /* generic error */ @@ -584,8 +585,24 @@ continue; } - if (sec->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) continue; - if (!sec->PointerToRawData || !sec->SizeOfRawData) continue; + if (sec->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) + { + TRACE_(module)("section %.8s uninitialized data at " + "%p size %lx flags %lx\n", + sec->Name, ptr + sec->VirtualAddress, + sec->Misc.VirtualSize, + sec->Characteristics); + continue; + } + if (!sec->PointerToRawData || !sec->SizeOfRawData) + { + TRACE_(module)("section %.8s not represented in file at " + "%p size %lx flags %lx\n", + sec->Name, ptr + sec->VirtualAddress, + sec->Misc.VirtualSize, + sec->Characteristics); + continue; + } TRACE_(module)( "mapping section %.8s at %p off %lx size %lx flags %lx\n", sec->Name, ptr + sec->VirtualAddress, @@ -617,11 +634,44 @@ if (removable) hmapping = 0; /* don't keep handle open on removable media */ if (!(view = VIRTUAL_CreateView( ptr, total_size, 0, - VPROT_COMMITTED|VPROT_READ|VPROT_WRITE|VPROT_WRITECOPY, + VPROT_COMMITTED|VPROT_READ, hmapping ))) { SetLastError( ERROR_OUTOFMEMORY ); goto error; + } + + // Alter protections on the view according to each section's + // protections + + // reset sec to beginning + + sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader); + for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) + { + prot = VPROT_COMMITTED; + if (sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) + prot |= VPROT_EXEC; + if (sec->Characteristics & IMAGE_SCN_MEM_READ) + prot |= VPROT_READ; + if (sec->Characteristics & IMAGE_SCN_MEM_WRITE) + prot |= VPROT_WRITE; + if (sec->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) + prot |= VPROT_WRITECOPY; + + TRACE("Set protection for section %.8s to %02x.\n", + sec->Name, (unsigned int)prot); + + // Set protections rounded to nearest page + + if ( FALSE == VIRTUAL_SetProt(view, ptr + sec->VirtualAddress, + ROUND_SIZE(ptr + sec->VirtualAddress, sec->Misc.VirtualSize), + prot)) + { + ERR_(module)("Setting protection for section %.8s to %02x failed.\n", + sec->Name, (unsigned int)prot); + goto error; + } } SetLastError( err ); /* restore last error */