diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-02-17 03:18:02 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-02-17 03:18:02 +0000 |
commit | ff725d8f795ca9b9ee7166c11d109871f580c21e (patch) | |
tree | 64dda3dc1b9868886bda68ed11dda63c123c0e75 | |
parent | 6adf7f8e7f8b42b877eb8b97de028915985618cf (diff) | |
download | xine-lib-ff725d8f795ca9b9ee7166c11d109871f580c21e.tar.gz xine-lib-ff725d8f795ca9b9ee7166c11d109871f580c21e.tar.bz2 |
- fix LDT clash with linuxthreads
- comment useless calls. some people really don't know what this thing does,
they probably think that lots of Setup_FS_Segment() all over will make
win32 gods happy. :)
- fix vfw (indeo) and quicktime segfaults
in short: xine now plays indeo, animatrix and the hulk trailers.
CVS patchset: 4178
CVS date: 2003/02/17 03:18:02
-rw-r--r-- | src/libw32dll/dmo/DMO_AudioDecoder.c | 2 | ||||
-rw-r--r-- | src/libw32dll/dmo/DMO_VideoDecoder.c | 4 | ||||
-rw-r--r-- | src/libw32dll/wine/driver.c | 8 | ||||
-rw-r--r-- | src/libw32dll/wine/ldt_keeper.c | 70 | ||||
-rw-r--r-- | src/libw32dll/wine/ldt_keeper.h | 1 | ||||
-rw-r--r-- | src/libw32dll/wine/win32.c | 42 |
6 files changed, 73 insertions, 54 deletions
diff --git a/src/libw32dll/dmo/DMO_AudioDecoder.c b/src/libw32dll/dmo/DMO_AudioDecoder.c index 6df84c38e..faf49e266 100644 --- a/src/libw32dll/dmo/DMO_AudioDecoder.c +++ b/src/libw32dll/dmo/DMO_AudioDecoder.c @@ -129,7 +129,7 @@ int DMO_AudioDecoder_Convert(DMO_AudioDecoder *this, const void* in_data, unsign #ifdef LDT_paranoia Setup_FS_Segment(); #endif - + //m_pDMO_Filter->m_pMedia->vt->Lock(m_pDMO_Filter->m_pMedia, 1); bufferin = CMediaBufferCreate(in_size, (void*)in_data, in_size, 1); r = this->m_pDMO_Filter->m_pMedia->vt->ProcessInput(this->m_pDMO_Filter->m_pMedia, 0, diff --git a/src/libw32dll/dmo/DMO_VideoDecoder.c b/src/libw32dll/dmo/DMO_VideoDecoder.c index d32653edd..aba62ee63 100644 --- a/src/libw32dll/dmo/DMO_VideoDecoder.c +++ b/src/libw32dll/dmo/DMO_VideoDecoder.c @@ -320,7 +320,9 @@ int DMO_VideoDecoder_DecodeInternal(DMO_VideoDecoder *this, const void* src, int // return -1; // } +#ifdef LDT_paranoia Setup_FS_Segment(); +#endif bufferin = CMediaBufferCreate(size, (void*)src, size, 0); result = this->m_pDMO_Filter->m_pMedia->vt->ProcessInput(this->m_pDMO_Filter->m_pMedia, 0, @@ -507,7 +509,9 @@ int DMO_VideoDecoder_SetDestFmt(DMO_VideoDecoder *this, int bits, unsigned int c break; } +#ifdef LDT_paranoia Setup_FS_Segment(); +#endif // if(should_test) // result = this->m_pDMO_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDMO_Filter->m_pOutputPin, &this->m_sDestType); diff --git a/src/libw32dll/wine/driver.c b/src/libw32dll/wine/driver.c index 8dea4b85f..7720a4975 100644 --- a/src/libw32dll/wine/driver.c +++ b/src/libw32dll/wine/driver.c @@ -85,7 +85,9 @@ LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT message, __asm__ __volatile__ ("fsave (%0)\n\t": :"r"(&qw)); #endif +#ifdef LDT_paranoia Setup_FS_Segment(); +#endif STORE_ALL; result=module->DriverProc(module->dwDriverID, hDriver, message, lParam1, lParam2); @@ -108,7 +110,9 @@ void DrvClose(HDRVR hDriver) DRVR* d = (DRVR*)hDriver; if (d->hDriverModule) { +#ifdef LDT_paranoia Setup_FS_Segment(); +#endif if (d->DriverProc) { SendDriverMessage(hDriver, DRV_CLOSE, 0, 0); @@ -130,7 +134,9 @@ HDRVR DrvOpen(LPARAM lParam2) char unknown[0x124]; const char* filename = (const char*) ((ICOPEN*) lParam2)->pV1Reserved; +#ifdef LDT_paranoia Setup_LDT_Keeper(); +#endif printf("Loading codec DLL: '%s'\n",filename); hDriver = (NPDRVR) malloc(sizeof(DRVR)); @@ -139,7 +145,9 @@ HDRVR DrvOpen(LPARAM lParam2) memset((void*)hDriver, 0, sizeof(DRVR)); CodecAlloc(); +#ifdef LDT_paranoia Setup_FS_Segment(); +#endif hDriver->hDriverModule = LoadLibraryA(filename); if (!hDriver->hDriverModule) diff --git a/src/libw32dll/wine/ldt_keeper.c b/src/libw32dll/wine/ldt_keeper.c index fef86c6bd..61a8fa186 100644 --- a/src/libw32dll/wine/ldt_keeper.c +++ b/src/libw32dll/wine/ldt_keeper.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: ldt_keeper.c,v 1.5 2002/12/18 04:00:53 guenter Exp $ + * $Id: ldt_keeper.c,v 1.6 2003/02/17 03:18:03 miguelfreitas Exp $ * * * contents: @@ -124,67 +124,39 @@ struct modify_ldt_ldt_s { /* user level (privilege level: 3) ldt (1<<2) segment selector */ #define LDT_SEL(idx) ((idx) << 3 | 1 << 2 | 3) -/* i got this value from wine sources, it's the first free LDT entry */ +/* i got value 17 from wine sources, it's the first free LDT entry */ +/* unfortunately it clashes with linuxthreads. lets try another one. */ #ifndef TEB_SEL_IDX -#define TEB_SEL_IDX 17 +#define TEB_SEL_IDX 27 #endif #define TEB_SEL LDT_SEL(TEB_SEL_IDX) -/** - * here is a small logical problem with Restore for multithreaded programs - - * in C++ we use static class for this... - */ - #ifdef __cplusplus extern "C" #endif void Setup_FS_Segment(void) { __asm__ __volatile__( - "movl %0,%%eax; movw %%ax, %%fs" : : "i" (TEB_SEL) + "movl %0,%%eax; movw %%ax, %%fs" : : "i" (TEB_SEL) : "%eax" ); } -/* (just in case someday we need dynamic entry indexes) -__ASM_GLOBAL_FUNC( __set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" ) -*/ - -/* we don't need this - use modify_ldt instead */ -#if 0 -#ifdef __linux__ -/* XXX: why is this routine from libc redefined here? */ -/* NOTE: the redefined version ignores the count param, count is hardcoded as 16 */ -static int LDT_Modify( int func, struct modify_ldt_ldt_s *ptr, - unsigned long count ) +void Check_FS_Segment(void) { - int res; -#ifdef __PIC__ - __asm__ __volatile__( "pushl %%ebx\n\t" - "movl %2,%%ebx\n\t" - "int $0x80\n\t" - "popl %%ebx" - : "=a" (res) - : "0" (__NR_modify_ldt), - "r" (func), - "c" (ptr), - "d"(16)//sizeof(*ptr) from kernel point of view - :"esi" ); -#else - __asm__ __volatile__("int $0x80" - : "=a" (res) - : "0" (__NR_modify_ldt), - "b" (func), - "c" (ptr), - "d"(16) - :"esi"); -#endif /* __PIC__ */ - if (res >= 0) return res; - errno = -res; - return -1; + int fs; + __asm__ __volatile__( + "movw %%fs,%%ax; mov %%eax,%0" : "=r" (fs) :: "%eax" + ); + fs = fs & 0xffff; + + if( fs != TEB_SEL ) { + printf("ldt_keeper: FS segment is not set or has being lost!\n"); + printf(" Please report this error to xine-devel@sourceforge.net\n"); + printf(" Aborting....\n"); + abort(); + } } -#endif -#endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) @@ -202,8 +174,6 @@ static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt } #endif -void* fs_seg=0; - ldt_fs_t* Setup_LDT_Keeper(void) { struct modify_ldt_ldt_s array; @@ -218,7 +188,7 @@ ldt_fs_t* Setup_LDT_Keeper(void) perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: "); return NULL; } - fs_seg= + ldt_fs->fs_seg = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, ldt_fs->fd, 0); if (ldt_fs->fs_seg == (void*)-1) @@ -281,7 +251,7 @@ ldt_fs_t* Setup_LDT_Keeper(void) #endif Setup_FS_Segment(); - + ldt_fs->prev_struct = (char*)malloc(sizeof(char) * 8); *(void**)array.base_addr = ldt_fs->prev_struct; diff --git a/src/libw32dll/wine/ldt_keeper.h b/src/libw32dll/wine/ldt_keeper.h index d36ebb892..ca084d885 100644 --- a/src/libw32dll/wine/ldt_keeper.h +++ b/src/libw32dll/wine/ldt_keeper.h @@ -14,6 +14,7 @@ typedef struct { void Setup_FS_Segment(void); ldt_fs_t* Setup_LDT_Keeper(void); +void Check_FS_Segment(void); void Restore_LDT_Keeper(ldt_fs_t* ldt_fs); #ifdef __cplusplus } diff --git a/src/libw32dll/wine/win32.c b/src/libw32dll/wine/win32.c index 8f4ca3ba1..88766dcc8 100644 --- a/src/libw32dll/wine/win32.c +++ b/src/libw32dll/wine/win32.c @@ -1423,10 +1423,9 @@ static int WINAPI expGetCurrentProcess() // this version is required for Quicktime codecs (.qtx/.qts) to work. // (they assume some pointers at FS: segment) -extern void* fs_seg; - //static int tls_count; static int tls_use_map[64]; +static void *tls_minus_one; static int WINAPI expTlsAlloc() { int i; @@ -1448,16 +1447,53 @@ static int WINAPI expTlsSetValue(int index, void* value) // if((index<0) || (index>64)) if((index>=64)) return 0; + + /* qt passes -1 here. probably a side effect of some bad patching */ + if( index < 0 ) { + tls_minus_one = value; + return 1; + } + +#if 0 *(void**)((char*)fs_seg+0x88+4*index) = value; +#else + /* does not require fs_seg memory, if everything is right + * we can access FS:xxxx like any win32 code would do. + */ + index = 0x88+4*index; + __asm__ __volatile__( + "movl %0,%%fs:(%1)" :: "r" (value), "r" (index) + ); +#endif return 1; } static void* WINAPI expTlsGetValue(DWORD index) { + void *ret; + dbgprintf("TlsGetValue(%d)\n",index); // if((index<0) || (index>64)) - if((index>=64)) return NULL; + if((index>=64)) + return NULL; + + /* qt passes -1 here. probably a side effect of some bad patching */ + if( index < 0 ) { + return tls_minus_one; + } + +#if 0 return *(void**)((char*)fs_seg+0x88+4*index); +#else + /* does not require fs_seg memory, if everything is right + * we can access FS:xxxx like any win32 code would do. + */ + index = 0x88+4*index; + __asm__ __volatile__( + "movl %%fs:(%1),%0" : "=r" (ret) : "r" (index) + ); + return ret; +#endif } static int WINAPI expTlsFree(int idx) |