From 6dbf67e56662b0aa95d5e576e618d5eeb0c83d9a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 18 Sep 2000 01:44:08 +0000 Subject: [PATCH] Moved FILE_dommap() to memory/virtual.c (and renamed it VIRTUAL_mmap). --- files/file.c | 91 ------------------------------ include/file.h | 5 -- include/global.h | 2 + memory/virtual.c | 132 ++++++++++++++++++++++++++++++++++---------- relay32/builtin32.c | 5 +- 5 files changed, 107 insertions(+), 128 deletions(-) diff --git a/files/file.c b/files/file.c index 18750944850..889ec75d82c 100644 --- a/files/file.c +++ b/files/file.c @@ -1617,97 +1617,6 @@ BOOL WINAPI DeleteFileW( LPCWSTR path ) } -/*********************************************************************** - * FILE_dommap - */ -LPVOID FILE_dommap( int unix_handle, LPVOID start, - DWORD size_high, DWORD size_low, - DWORD offset_high, DWORD offset_low, - int prot, int flags ) -{ - int fd = -1; - int pos; - LPVOID ret; - - if (size_high || offset_high) - FIXME("offsets larger than 4Gb not supported\n"); - - if (unix_handle == -1) - { -#ifdef MAP_ANON - flags |= MAP_ANON; -#else - static int fdzero = -1; - - if (fdzero == -1) - { - if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1) - { - perror( "/dev/zero: open" ); - exit(1); - } - } - fd = fdzero; -#endif /* MAP_ANON */ - /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */ -#ifdef MAP_SHARED - flags &= ~MAP_SHARED; -#endif -#ifdef MAP_PRIVATE - flags |= MAP_PRIVATE; -#endif - } - else fd = unix_handle; - - if ((ret = mmap( start, size_low, prot, - flags, fd, offset_low )) != (LPVOID)-1) - return ret; - - /* mmap() failed; if this is because the file offset is not */ - /* page-aligned (EINVAL), or because the underlying filesystem */ - /* does not support mmap() (ENOEXEC,ENODEV), we do it by hand. */ - - if (unix_handle == -1) return ret; - if ((errno != ENOEXEC) && (errno != EINVAL) && (errno != ENODEV)) return ret; - if (prot & PROT_WRITE) - { - /* We cannot fake shared write mappings */ -#ifdef MAP_SHARED - if (flags & MAP_SHARED) return ret; -#endif -#ifdef MAP_PRIVATE - if (!(flags & MAP_PRIVATE)) return ret; -#endif - } -/* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/ - /* Reserve the memory with an anonymous mmap */ - ret = FILE_dommap( -1, start, size_high, size_low, 0, 0, - PROT_READ | PROT_WRITE, flags ); - if (ret == (LPVOID)-1) return ret; - /* Now read in the file */ - if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1) - { - FILE_munmap( ret, size_high, size_low ); - return (LPVOID)-1; - } - read( fd, ret, size_low ); - lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */ - mprotect( ret, size_low, prot ); /* Set the right protection */ - return ret; -} - - -/*********************************************************************** - * FILE_munmap - */ -int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ) -{ - if (size_high) - FIXME("offsets larger than 4Gb not supported\n"); - return munmap( start, size_low ); -} - - /*********************************************************************** * GetFileType (KERNEL32.222) */ diff --git a/include/file.h b/include/file.h index 6303c74f948..c39d7511550 100644 --- a/include/file.h +++ b/include/file.h @@ -41,11 +41,6 @@ extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, DWORD attributes, HANDLE template, BOOL fail_read_only ); extern HFILE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa ); -extern LPVOID FILE_dommap( int unix_handle, LPVOID start, - DWORD size_high, DWORD size_low, - DWORD offset_high, DWORD offset_low, - int prot, int flags ); -extern int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ); extern HFILE16 FILE_AllocDosHandle( HANDLE handle ); extern HANDLE FILE_GetHandle( HFILE16 hfile ); diff --git a/include/global.h b/include/global.h index b1e530f4400..690fb1b01a5 100644 --- a/include/global.h +++ b/include/global.h @@ -23,6 +23,8 @@ extern HGLOBAL16 GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL16 hOwner, extern DWORD VIRTUAL_GetPageSize(void); extern DWORD VIRTUAL_GetGranularity(void); extern LPVOID VIRTUAL_MapFileW( LPCWSTR name ); +extern LPVOID VIRTUAL_mmap( int unix_handle, LPVOID start, DWORD size, + DWORD offset, int prot, int flags ); typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID); extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg); diff --git a/memory/virtual.c b/memory/virtual.c index 67a5da52a09..9027e3f931e 100644 --- a/memory/virtual.c +++ b/memory/virtual.c @@ -265,7 +265,7 @@ static void VIRTUAL_DeleteView( FILE_VIEW *view /* [in] View */ ) { if (!(view->flags & VFLAG_SYSTEM)) - FILE_munmap( (void *)view->base, 0, view->size ); + munmap( (void *)view->base, view->size ); if (view->next) view->next->prev = view->prev; if (view->prev) view->prev->next = view->next; else VIRTUAL_FirstView = view->next; @@ -414,11 +414,11 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size, /* zero-map the whole range */ - if ((ptr = FILE_dommap( -1, base, 0, total_size, 0, 0, PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE )) == (char *)-1) + if ((ptr = VIRTUAL_mmap( -1, base, total_size, 0, + PROT_READ | PROT_WRITE | PROT_EXEC, 0 )) == (char *)-1) { - ptr = FILE_dommap( -1, NULL, 0, total_size, 0, 0, - PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE ); + ptr = VIRTUAL_mmap( -1, NULL, total_size, 0, + PROT_READ | PROT_WRITE | PROT_EXEC, 0 ); if (ptr == (char *)-1) { ERR_(module)("Not enough memory for module (%ld bytes)\n", total_size); @@ -431,15 +431,15 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size, VPROT_COMMITTED|VPROT_READ|VPROT_WRITE|VPROT_WRITECOPY, hmapping ))) { - FILE_munmap( ptr, 0, total_size ); + munmap( ptr, total_size ); SetLastError( ERROR_OUTOFMEMORY ); goto error; } /* map the header */ - if (FILE_dommap( fd, ptr, 0, header_size, 0, 0, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED ) == (char *)-1) goto error; + if (VIRTUAL_mmap( fd, ptr, header_size, 0, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED ) == (char *)-1) goto error; dos = (IMAGE_DOS_HEADER *)ptr; nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew); if ((char *)(nt + 1) > ptr + header_size) goto error; @@ -499,9 +499,9 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size, sec->Name, (char *)ptr + sec->VirtualAddress, sec->PointerToRawData, pos, sec->SizeOfRawData, size, sec->Characteristics ); - if (FILE_dommap( shared_fd, (char *)ptr + sec->VirtualAddress, 0, size, - 0, pos, PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_SHARED|MAP_FIXED ) == (void *)-1) + if (VIRTUAL_mmap( shared_fd, (char *)ptr + sec->VirtualAddress, size, + pos, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_SHARED|MAP_FIXED ) == (void *)-1) { ERR_(module)( "Could not map shared section %.8s\n", sec->Name ); goto error; @@ -518,12 +518,12 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size, sec->PointerToRawData, sec->SizeOfRawData, sec->Characteristics ); - /* Note: if the section is not aligned properly FILE_dommap will magically + /* Note: if the section is not aligned properly VIRTUAL_mmap will magically * fall back to read(), so we don't need to check anything here. */ - if (FILE_dommap( fd, (char *)ptr + sec->VirtualAddress, 0, sec->SizeOfRawData, - 0, sec->PointerToRawData, PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_PRIVATE | MAP_FIXED ) == (void *)-1) + if (VIRTUAL_mmap( fd, (char *)ptr + sec->VirtualAddress, sec->SizeOfRawData, + sec->PointerToRawData, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE | MAP_FIXED ) == (void *)-1) { ERR_(module)( "Could not map section %.8s, file probably truncated\n", sec->Name ); goto error; @@ -645,6 +645,82 @@ DWORD VIRTUAL_HandleFault( LPCVOID addr ) } +/*********************************************************************** + * VIRTUAL_mmap + * + * Wrapper for mmap() that handles anonymous mappings portably, + * and falls back to read if mmap of a file fails. + */ +LPVOID VIRTUAL_mmap( int unix_handle, LPVOID start, DWORD size, + DWORD offset, int prot, int flags ) +{ + int fd = -1; + int pos; + LPVOID ret; + + if (unix_handle == -1) + { +#ifdef MAP_ANON + flags |= MAP_ANON; +#else + static int fdzero = -1; + + if (fdzero == -1) + { + if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1) + { + perror( "/dev/zero: open" ); + ExitProcess(1); + } + } + fd = fdzero; +#endif /* MAP_ANON */ + /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */ +#ifdef MAP_SHARED + flags &= ~MAP_SHARED; +#endif +#ifdef MAP_PRIVATE + flags |= MAP_PRIVATE; +#endif + } + else fd = unix_handle; + + if ((ret = mmap( start, size, prot, flags, fd, offset )) != (LPVOID)-1) + return ret; + + /* mmap() failed; if this is because the file offset is not */ + /* page-aligned (EINVAL), or because the underlying filesystem */ + /* does not support mmap() (ENOEXEC,ENODEV), we do it by hand. */ + + if (unix_handle == -1) return ret; + if ((errno != ENOEXEC) && (errno != EINVAL) && (errno != ENODEV)) return ret; + if (prot & PROT_WRITE) + { + /* We cannot fake shared write mappings */ +#ifdef MAP_SHARED + if (flags & MAP_SHARED) return ret; +#endif +#ifdef MAP_PRIVATE + if (!(flags & MAP_PRIVATE)) return ret; +#endif + } + + /* Reserve the memory with an anonymous mmap */ + ret = VIRTUAL_mmap( -1, start, size, 0, PROT_READ | PROT_WRITE, flags ); + if (ret == (LPVOID)-1) return ret; + /* Now read in the file */ + if ((pos = lseek( fd, offset, SEEK_SET )) == -1) + { + munmap( ret, size ); + return (LPVOID)-1; + } + read( fd, ret, size ); + lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */ + mprotect( ret, size, prot ); /* Set the right protection */ + return ret; +} + + /*********************************************************************** * VirtualAlloc (KERNEL32.548) * Reserves or commits a region of pages in virtual address space @@ -721,8 +797,8 @@ LPVOID WINAPI VirtualAlloc( if (type & MEM_SYSTEM) ptr = base; else - ptr = (UINT)FILE_dommap( -1, (LPVOID)base, 0, view_size, 0, 0, - VIRTUAL_GetUnixProt( vprot ), MAP_PRIVATE ); + ptr = (UINT)VIRTUAL_mmap( -1, (LPVOID)base, view_size, 0, + VIRTUAL_GetUnixProt( vprot ), 0 ); if (ptr == (UINT)-1) { SetLastError( ERROR_OUTOFMEMORY ); @@ -736,28 +812,27 @@ LPVOID WINAPI VirtualAlloc( if (ptr & granularity_mask) { UINT extra = granularity_mask + 1 - (ptr & granularity_mask); - FILE_munmap( (void *)ptr, 0, extra ); + munmap( (void *)ptr, extra ); ptr += extra; view_size -= extra; } if (view_size > size) - FILE_munmap( (void *)(ptr + size), 0, view_size - size ); + munmap( (void *)(ptr + size), view_size - size ); } else if (ptr != base) { /* We couldn't get the address we wanted */ - FILE_munmap( (void *)ptr, 0, view_size ); + munmap( (void *)ptr, view_size ); SetLastError( ERROR_INVALID_ADDRESS ); return NULL; } if (!(view = VIRTUAL_CreateView( ptr, size, (type & MEM_SYSTEM) ? VFLAG_SYSTEM : 0, vprot, -1 ))) { - FILE_munmap( (void *)ptr, 0, size ); + munmap( (void *)ptr, size ); SetLastError( ERROR_OUTOFMEMORY ); return NULL; } - VIRTUAL_DEBUG_DUMP_VIEW( view ); return (LPVOID)ptr; } @@ -849,9 +924,8 @@ BOOL WINAPI VirtualFree( /* Decommit the pages by remapping zero-pages instead */ - if (FILE_dommap( -1, (LPVOID)base, 0, size, 0, 0, - VIRTUAL_GetUnixProt( 0 ), MAP_PRIVATE|MAP_FIXED ) - != (LPVOID)base) + if (VIRTUAL_mmap( -1, (LPVOID)base, size, 0, VIRTUAL_GetUnixProt( 0 ), + MAP_FIXED ) != (LPVOID)base) ERR( "Could not remap pages, expect trouble\n" ); return VIRTUAL_SetProt( view, base, size, 0 ); } @@ -940,7 +1014,7 @@ BOOL WINAPI VirtualProtect( } } - VIRTUAL_GetWin32Prot( view->prot[0], old_prot, NULL ); + if (old_prot) VIRTUAL_GetWin32Prot( view->prot[0], old_prot, NULL ); vprot = VIRTUAL_GetProt( new_prot ) | VPROT_COMMITTED; return VIRTUAL_SetProt( view, base, size, vprot ); } @@ -1492,8 +1566,8 @@ LPVOID WINAPI MapViewOfFileEx( TRACE("handle=%x size=%x offset=%lx\n", handle, size, offset_low ); - ptr = (UINT)FILE_dommap( unix_handle, addr, 0, size, 0, offset_low, - VIRTUAL_GetUnixProt( prot ), flags ); + ptr = (UINT)VIRTUAL_mmap( unix_handle, addr, size, offset_low, + VIRTUAL_GetUnixProt( prot ), flags ); if (ptr == (UINT)-1) { /* KB: Q125713, 25-SEP-1995, "Common File Mapping Problems and * Platform Differences": @@ -1518,7 +1592,7 @@ LPVOID WINAPI MapViewOfFileEx( error: if (unix_handle != -1) close( unix_handle ); - if (ptr != (UINT)-1) FILE_munmap( (void *)ptr, 0, size ); + if (ptr != (UINT)-1) munmap( (void *)ptr, size ); return NULL; } diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 38ca10935f2..d2c265e3c25 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -22,7 +22,6 @@ #include "wine/winbase16.h" #include "builtin32.h" #include "elfdll.h" -#include "file.h" #include "global.h" #include "neexe.h" #include "heap.h" @@ -130,8 +129,8 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr ) if (descr->pe_header) { - if ((addr = FILE_dommap( -1, descr->pe_header, 0, page_size, 0, 0, - PROT_READ|PROT_WRITE, MAP_FIXED )) != descr->pe_header) + if ((addr = VIRTUAL_mmap( -1, descr->pe_header, page_size, 0, + PROT_READ|PROT_WRITE, MAP_FIXED )) != descr->pe_header) { ERR("failed to map over PE header for %s at %p\n", descr->filename, descr->pe_header ); return 0;