Moved FILE_dommap() to memory/virtual.c (and renamed it VIRTUAL_mmap).
This commit is contained in:
parent
7b7c32c801
commit
6dbf67e566
91
files/file.c
91
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)
|
||||
*/
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
132
memory/virtual.c
132
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue