Moved FILE_dommap() to memory/virtual.c (and renamed it VIRTUAL_mmap).

This commit is contained in:
Alexandre Julliard 2000-09-18 01:44:08 +00:00
parent 7b7c32c801
commit 6dbf67e566
5 changed files with 107 additions and 128 deletions

View File

@ -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) * GetFileType (KERNEL32.222)
*/ */

View File

@ -41,11 +41,6 @@ extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
DWORD attributes, HANDLE template, BOOL fail_read_only ); DWORD attributes, HANDLE template, BOOL fail_read_only );
extern HFILE FILE_CreateDevice( int client_id, DWORD access, extern HFILE FILE_CreateDevice( int client_id, DWORD access,
LPSECURITY_ATTRIBUTES sa ); 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 HFILE16 FILE_AllocDosHandle( HANDLE handle );
extern HANDLE FILE_GetHandle( HFILE16 hfile ); extern HANDLE FILE_GetHandle( HFILE16 hfile );

View File

@ -23,6 +23,8 @@ extern HGLOBAL16 GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL16 hOwner,
extern DWORD VIRTUAL_GetPageSize(void); extern DWORD VIRTUAL_GetPageSize(void);
extern DWORD VIRTUAL_GetGranularity(void); extern DWORD VIRTUAL_GetGranularity(void);
extern LPVOID VIRTUAL_MapFileW( LPCWSTR name ); 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); typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID);
extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg); extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg);

View File

@ -265,7 +265,7 @@ static void VIRTUAL_DeleteView(
FILE_VIEW *view /* [in] View */ FILE_VIEW *view /* [in] View */
) { ) {
if (!(view->flags & VFLAG_SYSTEM)) 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->next) view->next->prev = view->prev;
if (view->prev) view->prev->next = view->next; if (view->prev) view->prev->next = view->next;
else VIRTUAL_FirstView = 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 */ /* zero-map the whole range */
if ((ptr = FILE_dommap( -1, base, 0, total_size, 0, 0, PROT_READ|PROT_WRITE|PROT_EXEC, if ((ptr = VIRTUAL_mmap( -1, base, total_size, 0,
MAP_PRIVATE )) == (char *)-1) PROT_READ | PROT_WRITE | PROT_EXEC, 0 )) == (char *)-1)
{ {
ptr = FILE_dommap( -1, NULL, 0, total_size, 0, 0, ptr = VIRTUAL_mmap( -1, NULL, total_size, 0,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE ); PROT_READ | PROT_WRITE | PROT_EXEC, 0 );
if (ptr == (char *)-1) if (ptr == (char *)-1)
{ {
ERR_(module)("Not enough memory for module (%ld bytes)\n", total_size); 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, VPROT_COMMITTED|VPROT_READ|VPROT_WRITE|VPROT_WRITECOPY,
hmapping ))) hmapping )))
{ {
FILE_munmap( ptr, 0, total_size ); munmap( ptr, total_size );
SetLastError( ERROR_OUTOFMEMORY ); SetLastError( ERROR_OUTOFMEMORY );
goto error; goto error;
} }
/* map the header */ /* map the header */
if (FILE_dommap( fd, ptr, 0, header_size, 0, 0, if (VIRTUAL_mmap( fd, ptr, header_size, 0, PROT_READ | PROT_WRITE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED ) == (char *)-1) goto error; MAP_PRIVATE | MAP_FIXED ) == (char *)-1) goto error;
dos = (IMAGE_DOS_HEADER *)ptr; dos = (IMAGE_DOS_HEADER *)ptr;
nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew); nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew);
if ((char *)(nt + 1) > ptr + header_size) goto error; 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->Name, (char *)ptr + sec->VirtualAddress,
sec->PointerToRawData, pos, sec->SizeOfRawData, sec->PointerToRawData, pos, sec->SizeOfRawData,
size, sec->Characteristics ); size, sec->Characteristics );
if (FILE_dommap( shared_fd, (char *)ptr + sec->VirtualAddress, 0, size, if (VIRTUAL_mmap( shared_fd, (char *)ptr + sec->VirtualAddress, size,
0, pos, PROT_READ|PROT_WRITE|PROT_EXEC, pos, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_SHARED|MAP_FIXED ) == (void *)-1) MAP_SHARED|MAP_FIXED ) == (void *)-1)
{ {
ERR_(module)( "Could not map shared section %.8s\n", sec->Name ); ERR_(module)( "Could not map shared section %.8s\n", sec->Name );
goto error; goto error;
@ -518,12 +518,12 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size,
sec->PointerToRawData, sec->SizeOfRawData, sec->PointerToRawData, sec->SizeOfRawData,
sec->Characteristics ); 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. * fall back to read(), so we don't need to check anything here.
*/ */
if (FILE_dommap( fd, (char *)ptr + sec->VirtualAddress, 0, sec->SizeOfRawData, if (VIRTUAL_mmap( fd, (char *)ptr + sec->VirtualAddress, sec->SizeOfRawData,
0, sec->PointerToRawData, PROT_READ|PROT_WRITE|PROT_EXEC, sec->PointerToRawData, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE | MAP_FIXED ) == (void *)-1) MAP_PRIVATE | MAP_FIXED ) == (void *)-1)
{ {
ERR_(module)( "Could not map section %.8s, file probably truncated\n", sec->Name ); ERR_(module)( "Could not map section %.8s, file probably truncated\n", sec->Name );
goto error; 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) * VirtualAlloc (KERNEL32.548)
* Reserves or commits a region of pages in virtual address space * Reserves or commits a region of pages in virtual address space
@ -721,8 +797,8 @@ LPVOID WINAPI VirtualAlloc(
if (type & MEM_SYSTEM) if (type & MEM_SYSTEM)
ptr = base; ptr = base;
else else
ptr = (UINT)FILE_dommap( -1, (LPVOID)base, 0, view_size, 0, 0, ptr = (UINT)VIRTUAL_mmap( -1, (LPVOID)base, view_size, 0,
VIRTUAL_GetUnixProt( vprot ), MAP_PRIVATE ); VIRTUAL_GetUnixProt( vprot ), 0 );
if (ptr == (UINT)-1) if (ptr == (UINT)-1)
{ {
SetLastError( ERROR_OUTOFMEMORY ); SetLastError( ERROR_OUTOFMEMORY );
@ -736,28 +812,27 @@ LPVOID WINAPI VirtualAlloc(
if (ptr & granularity_mask) if (ptr & granularity_mask)
{ {
UINT extra = granularity_mask + 1 - (ptr & granularity_mask); UINT extra = granularity_mask + 1 - (ptr & granularity_mask);
FILE_munmap( (void *)ptr, 0, extra ); munmap( (void *)ptr, extra );
ptr += extra; ptr += extra;
view_size -= extra; view_size -= extra;
} }
if (view_size > size) if (view_size > size)
FILE_munmap( (void *)(ptr + size), 0, view_size - size ); munmap( (void *)(ptr + size), view_size - size );
} }
else if (ptr != base) else if (ptr != base)
{ {
/* We couldn't get the address we wanted */ /* We couldn't get the address we wanted */
FILE_munmap( (void *)ptr, 0, view_size ); munmap( (void *)ptr, view_size );
SetLastError( ERROR_INVALID_ADDRESS ); SetLastError( ERROR_INVALID_ADDRESS );
return NULL; return NULL;
} }
if (!(view = VIRTUAL_CreateView( ptr, size, (type & MEM_SYSTEM) ? if (!(view = VIRTUAL_CreateView( ptr, size, (type & MEM_SYSTEM) ?
VFLAG_SYSTEM : 0, vprot, -1 ))) VFLAG_SYSTEM : 0, vprot, -1 )))
{ {
FILE_munmap( (void *)ptr, 0, size ); munmap( (void *)ptr, size );
SetLastError( ERROR_OUTOFMEMORY ); SetLastError( ERROR_OUTOFMEMORY );
return NULL; return NULL;
} }
VIRTUAL_DEBUG_DUMP_VIEW( view );
return (LPVOID)ptr; return (LPVOID)ptr;
} }
@ -849,9 +924,8 @@ BOOL WINAPI VirtualFree(
/* Decommit the pages by remapping zero-pages instead */ /* Decommit the pages by remapping zero-pages instead */
if (FILE_dommap( -1, (LPVOID)base, 0, size, 0, 0, if (VIRTUAL_mmap( -1, (LPVOID)base, size, 0, VIRTUAL_GetUnixProt( 0 ),
VIRTUAL_GetUnixProt( 0 ), MAP_PRIVATE|MAP_FIXED ) MAP_FIXED ) != (LPVOID)base)
!= (LPVOID)base)
ERR( "Could not remap pages, expect trouble\n" ); ERR( "Could not remap pages, expect trouble\n" );
return VIRTUAL_SetProt( view, base, size, 0 ); 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; vprot = VIRTUAL_GetProt( new_prot ) | VPROT_COMMITTED;
return VIRTUAL_SetProt( view, base, size, vprot ); 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 ); TRACE("handle=%x size=%x offset=%lx\n", handle, size, offset_low );
ptr = (UINT)FILE_dommap( unix_handle, addr, 0, size, 0, offset_low, ptr = (UINT)VIRTUAL_mmap( unix_handle, addr, size, offset_low,
VIRTUAL_GetUnixProt( prot ), flags ); VIRTUAL_GetUnixProt( prot ), flags );
if (ptr == (UINT)-1) { if (ptr == (UINT)-1) {
/* KB: Q125713, 25-SEP-1995, "Common File Mapping Problems and /* KB: Q125713, 25-SEP-1995, "Common File Mapping Problems and
* Platform Differences": * Platform Differences":
@ -1518,7 +1592,7 @@ LPVOID WINAPI MapViewOfFileEx(
error: error:
if (unix_handle != -1) close( unix_handle ); 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; return NULL;
} }

View File

@ -22,7 +22,6 @@
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "builtin32.h" #include "builtin32.h"
#include "elfdll.h" #include "elfdll.h"
#include "file.h"
#include "global.h" #include "global.h"
#include "neexe.h" #include "neexe.h"
#include "heap.h" #include "heap.h"
@ -130,8 +129,8 @@ static HMODULE BUILTIN32_DoLoadImage( const BUILTIN32_DESCRIPTOR *descr )
if (descr->pe_header) if (descr->pe_header)
{ {
if ((addr = FILE_dommap( -1, descr->pe_header, 0, page_size, 0, 0, if ((addr = VIRTUAL_mmap( -1, descr->pe_header, page_size, 0,
PROT_READ|PROT_WRITE, MAP_FIXED )) != descr->pe_header) 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 ); ERR("failed to map over PE header for %s at %p\n", descr->filename, descr->pe_header );
return 0; return 0;