mirror of https://github.com/mpv-player/mpv
added mmap_anon to osdep lib. Used in loader for now
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@21203 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
b30a399c52
commit
ac04dcd625
3
Makefile
3
Makefile
|
@ -62,7 +62,6 @@ COMMON_LIBS = libmpcodecs/libmpcodecs.a \
|
|||
stream/stream.a \
|
||||
libswscale/libswscale.a \
|
||||
libvo/libosd.a \
|
||||
osdep/libosdep.a \
|
||||
|
||||
LIBS_MPLAYER = libvo/libvo.a \
|
||||
libao2/libao2.a \
|
||||
|
@ -158,6 +157,8 @@ ifeq ($(TARGET_WIN32),yes)
|
|||
OBJS_MPLAYER += osdep/mplayer-rc.o
|
||||
endif
|
||||
|
||||
COMMON_LIBS += osdep/libosdep.a
|
||||
|
||||
COMMON_LDFLAGS += $(EXTRA_LIB)\
|
||||
$(EXTRALIBS) \
|
||||
|
||||
|
|
73
loader/ext.c
73
loader/ext.c
|
@ -26,6 +26,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "osdep/mmap_anon.h"
|
||||
#include "wine/windef.h"
|
||||
#include "wine/winbase.h"
|
||||
#include "wine/debugtools.h"
|
||||
|
@ -233,7 +234,6 @@ LPSTR HEAP_strdupWtoA(HANDLE heap, DWORD flags, LPCWSTR string)
|
|||
|
||||
//#define MAP_PRIVATE
|
||||
//#define MAP_SHARED
|
||||
#undef MAP_ANON
|
||||
LPVOID FILE_dommap( int unix_handle, LPVOID start,
|
||||
DWORD size_high, DWORD size_low,
|
||||
DWORD offset_high, DWORD offset_low,
|
||||
|
@ -248,36 +248,15 @@ LPVOID FILE_dommap( int unix_handle, LPVOID start,
|
|||
|
||||
if (unix_handle == -1)
|
||||
{
|
||||
#ifdef MAP_ANON
|
||||
// printf("Anonymous\n");
|
||||
flags |= MAP_ANON;
|
||||
#else
|
||||
static int fdzero = -1;
|
||||
|
||||
if (fdzero == -1)
|
||||
{
|
||||
if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
|
||||
{
|
||||
perror( "Cannot open /dev/zero for READ. Check permissions! error: " );
|
||||
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
|
||||
ret = mmap_anon( start, size_low, prot, flags, &fd, offset_low );
|
||||
}
|
||||
else fd = unix_handle;
|
||||
// printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot);
|
||||
// if ((ret = mmap( start, size_low, prot,
|
||||
// flags, fd, offset_low )) != (LPVOID)-1)
|
||||
if ((ret = mmap( start, size_low, prot,
|
||||
MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1)
|
||||
else
|
||||
{
|
||||
fd = unix_handle;
|
||||
ret = mmap( start, size_low, prot, flags, fd, offset_low );
|
||||
}
|
||||
|
||||
if (ret != (LPVOID)-1)
|
||||
{
|
||||
// printf("address %08x\n", *(int*)ret);
|
||||
// printf("%x\n", ret);
|
||||
|
@ -371,14 +350,8 @@ HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr,
|
|||
int anon=0;
|
||||
int mmap_access=0;
|
||||
if(hFile<0)
|
||||
{
|
||||
anon=1;
|
||||
hFile=open("/dev/zero", O_RDWR);
|
||||
if(hFile<0){
|
||||
perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
anon=1;
|
||||
|
||||
if(!anon)
|
||||
{
|
||||
len=lseek(hFile, 0, SEEK_END);
|
||||
|
@ -391,8 +364,12 @@ HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr,
|
|||
else
|
||||
mmap_access |=PROT_READ|PROT_WRITE;
|
||||
|
||||
answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0);
|
||||
if(anon)
|
||||
answer=mmap_anon(NULL, len, mmap_access, MAP_PRIVATE, &hFile, 0);
|
||||
else
|
||||
answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0);
|
||||
|
||||
if(hFile != -1)
|
||||
close(hFile);
|
||||
if(answer!=(LPVOID)-1)
|
||||
{
|
||||
|
@ -418,7 +395,7 @@ HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr,
|
|||
fm->name=NULL;
|
||||
fm->mapping_size=len;
|
||||
|
||||
if(anon)
|
||||
if(hFile != -1)
|
||||
close(hFile);
|
||||
return (HANDLE)answer;
|
||||
}
|
||||
|
@ -471,12 +448,6 @@ LPVOID WINAPI VirtualAlloc(LPVOID address, DWORD size, DWORD type, DWORD protec
|
|||
|
||||
if ((type&(MEM_RESERVE|MEM_COMMIT)) == 0) return NULL;
|
||||
|
||||
fd=open("/dev/zero", O_RDWR);
|
||||
if(fd<0){
|
||||
perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type&MEM_RESERVE && (unsigned)address&0xffff) {
|
||||
size += (unsigned)address&0xffff;
|
||||
address = (unsigned)address&~0xffff;
|
||||
|
@ -513,23 +484,23 @@ LPVOID WINAPI VirtualAlloc(LPVOID address, DWORD size, DWORD type, DWORD protec
|
|||
&& ((unsigned)address+size<=(unsigned)str->address+str->mapping_size)
|
||||
&& (type & MEM_COMMIT))
|
||||
{
|
||||
close(fd);
|
||||
return address; //returning previously reserved memory
|
||||
}
|
||||
//printf(" VirtualAlloc(...) does not commit or not entirely within reserved, and\n");
|
||||
}
|
||||
/*printf(" VirtualAlloc(...) (0x%08X, %u) overlaps with (0x%08X, %u, state=%d)\n",
|
||||
(unsigned)address, size, (unsigned)str->address, str->mapping_size, str->state);*/
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE, fd, 0);
|
||||
answer=mmap_anon(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE, &fd, 0);
|
||||
// answer=FILE_dommap(-1, address, 0, size, 0, 0,
|
||||
// PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
|
||||
close(fd);
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
if (answer != (void *)-1 && address && answer != address) {
|
||||
/* It is dangerous to try mmap() with MAP_FIXED since it does not
|
||||
always detect conflicts or non-allocation and chaos ensues after
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "osdep/mmap_anon.h"
|
||||
#ifdef __linux__
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/ldt.h>
|
||||
|
@ -200,8 +201,8 @@ ldt_fs_t* Setup_LDT_Keeper(void)
|
|||
return NULL;
|
||||
}
|
||||
fs_seg=
|
||||
ldt_fs->fs_seg = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE,
|
||||
ldt_fs->fd, 0);
|
||||
ldt_fs->fs_seg = mmap_anon(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, &ldt_fs->fd,
|
||||
0);
|
||||
if (ldt_fs->fs_seg == (void*)-1)
|
||||
{
|
||||
perror("ERROR: Couldn't allocate memory for fs segment");
|
||||
|
@ -286,6 +287,7 @@ void Restore_LDT_Keeper(ldt_fs_t* ldt_fs)
|
|||
free(ldt_fs->prev_struct);
|
||||
munmap((char*)ldt_fs->fs_seg, getpagesize());
|
||||
ldt_fs->fs_seg = 0;
|
||||
if (ldt_fs->fd != -1)
|
||||
close(ldt_fs->fd);
|
||||
free(ldt_fs);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ SRCS= shmem.c \
|
|||
fseeko.c \
|
||||
swab.c \
|
||||
setenv.c \
|
||||
mmap_anon.c \
|
||||
# timer.c \
|
||||
|
||||
getch = getch2.c
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* \file mmap_anon.c
|
||||
* \brief Provide a compatible anonymous space mapping function
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
/*
|
||||
* mmap() anonymous space, depending on the system's mmap() style. On systems
|
||||
* that use the /dev/zero mapping idiom, zerofd will be set to the file descriptor
|
||||
* of the opened /dev/zero.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief mmap() anonymous space, depending on the system's mmap() style. On systems
|
||||
* that use the /dev/zero mapping idiom, zerofd will be set to the file descriptor
|
||||
* of the opened /dev/zero.
|
||||
*
|
||||
* \param addr address to map at.
|
||||
* \param len number of bytes from addr to be mapped.
|
||||
* \param prot protections (region accessibility).
|
||||
* \param flags specifies the type of the mapped object.
|
||||
* \param offset start mapping at byte offset.
|
||||
* \param zerofd
|
||||
* \return a pointer to the mapped region upon successful completion, -1 otherwise.
|
||||
*/
|
||||
void *mmap_anon(void *addr, size_t len, int prot, int flags, int *zerofd, off_t offset)
|
||||
{
|
||||
int fd;
|
||||
void *result;
|
||||
|
||||
/* From loader/ext.c:
|
||||
* "Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap"
|
||||
* Therefore we preserve the same behavior on all platforms, ie. no
|
||||
* shared mappings of anon space (if the concepts are supported). */
|
||||
#if defined(MAP_SHARED) && defined(MAP_PRIVATE)
|
||||
flags = (flags & ~MAP_SHARED) | MAP_PRIVATE;
|
||||
#endif /* defined(MAP_SHARED) && defined(MAP_PRIVATE) */
|
||||
|
||||
#ifdef MAP_ANONYMOUS
|
||||
/* BSD-style anonymous mapping */
|
||||
fd = -1;
|
||||
result = mmap(addr, len, prot, flags | MAP_ANONYMOUS, -1, offset);
|
||||
#else
|
||||
/* SysV-style anonymous mapping */
|
||||
fd = open("/dev/zero", O_RDWR);
|
||||
if(fd < 0){
|
||||
perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: ");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = mmap(addr, len, prot, flags, fd, offset);
|
||||
#endif /* MAP_ANONYMOUS */
|
||||
|
||||
if (zerofd)
|
||||
*zerofd = fd;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _OSDEP_MMAP_ANON_H_
|
||||
#define _OSDEP_MMAP_ANON_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
void *mmap_anon(void *, size_t, int, int, int *, off_t);
|
||||
|
||||
#endif /* _OSDEP_MMAP_ANON_H_ */
|
Loading…
Reference in New Issue