mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 11:32:08 +00:00
Improved the selector get/set functions.
Support ANSI-compatible inline asm (with the help of Patrik Stridvall).
This commit is contained in:
parent
e1d78899ea
commit
916f975624
|
@ -19,6 +19,7 @@
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "combo.h"
|
#include "combo.h"
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
#include "callback.h"
|
#include "callback.h"
|
||||||
#include "tweak.h"
|
#include "tweak.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "spy.h"
|
#include "spy.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "combo.h"
|
#include "combo.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
|
@ -257,8 +257,8 @@ BOOL DEBUG_ValidateRegisters(void)
|
||||||
return FALSE; \
|
return FALSE; \
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_CS(cs);
|
cs = __get_cs();
|
||||||
GET_DS(ds);
|
ds = __get_ds();
|
||||||
if (CS_reg(&DEBUG_context) != cs) CHECK_SEG(CS_reg(&DEBUG_context), "CS");
|
if (CS_reg(&DEBUG_context) != cs) CHECK_SEG(CS_reg(&DEBUG_context), "CS");
|
||||||
if (SS_reg(&DEBUG_context) != ds) CHECK_SEG(SS_reg(&DEBUG_context), "SS");
|
if (SS_reg(&DEBUG_context) != ds) CHECK_SEG(SS_reg(&DEBUG_context), "SS");
|
||||||
if (DS_reg(&DEBUG_context) != ds) CHECK_SEG(DS_reg(&DEBUG_context), "DS");
|
if (DS_reg(&DEBUG_context) != ds) CHECK_SEG(DS_reg(&DEBUG_context), "DS");
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "selectors.h"
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* signal context platform-specific definitions
|
* signal context platform-specific definitions
|
||||||
*/
|
*/
|
||||||
|
@ -309,13 +311,13 @@ static inline void handler_init( CONTEXT *context, const SIGCONTEXT *sigcontext
|
||||||
#ifdef FS_sig
|
#ifdef FS_sig
|
||||||
fs = FS_sig(sigcontext);
|
fs = FS_sig(sigcontext);
|
||||||
#else
|
#else
|
||||||
GET_FS(fs);
|
fs = __get_fs();
|
||||||
#endif
|
#endif
|
||||||
context->SegFs = fs;
|
context->SegFs = fs;
|
||||||
/* now restore a proper %fs for the fault handler */
|
/* now restore a proper %fs for the fault handler */
|
||||||
if (!IS_SELECTOR_SYSTEM(CS_sig(sigcontext))) fs = SYSLEVEL_Win16CurrentTeb;
|
if (!IS_SELECTOR_SYSTEM(CS_sig(sigcontext))) fs = SYSLEVEL_Win16CurrentTeb;
|
||||||
if (!fs) fs = SYSLEVEL_EmergencyTeb;
|
if (!fs) fs = SYSLEVEL_EmergencyTeb;
|
||||||
SET_FS(fs);
|
__set_fs(fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -357,8 +359,7 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
|
||||||
#ifdef GS_sig
|
#ifdef GS_sig
|
||||||
context->SegGs = LOWORD(GS_sig(sigcontext));
|
context->SegGs = LOWORD(GS_sig(sigcontext));
|
||||||
#else
|
#else
|
||||||
GET_GS( context->SegGs );
|
context->SegGs = __get_gs();
|
||||||
context->SegGs &= 0xffff;
|
|
||||||
#endif
|
#endif
|
||||||
if (ISV86(context)) V86BASE(context) = (DWORD)DOSMEM_MemoryBase(0);
|
if (ISV86(context)) V86BASE(context) = (DWORD)DOSMEM_MemoryBase(0);
|
||||||
}
|
}
|
||||||
|
@ -388,12 +389,12 @@ static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
|
||||||
#ifdef FS_sig
|
#ifdef FS_sig
|
||||||
FS_sig(sigcontext) = context->SegFs;
|
FS_sig(sigcontext) = context->SegFs;
|
||||||
#else
|
#else
|
||||||
SET_FS( context->SegFs );
|
__set_fs( context->SegFs );
|
||||||
#endif
|
#endif
|
||||||
#ifdef GS_sig
|
#ifdef GS_sig
|
||||||
GS_sig(sigcontext) = context->SegGs;
|
GS_sig(sigcontext) = context->SegGs;
|
||||||
#else
|
#else
|
||||||
SET_GS( context->SegGs );
|
__set_gs( context->SegGs );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
|
||||||
snr[0].realfun = (DWORD)SNOOP16_Entry;
|
snr[0].realfun = (DWORD)SNOOP16_Entry;
|
||||||
snr[0].lcall = 0x9a;
|
snr[0].lcall = 0x9a;
|
||||||
snr[0].callfromregs = (DWORD)CallFrom16Register;
|
snr[0].callfromregs = (DWORD)CallFrom16Register;
|
||||||
GET_CS(snr[0].seg);
|
snr[0].seg = __get_cs();
|
||||||
snr[0].lret = 0xcb66;
|
snr[0].lret = 0xcb66;
|
||||||
|
|
||||||
snr[1].pushbp = 0x5566;
|
snr[1].pushbp = 0x5566;
|
||||||
|
@ -110,7 +110,7 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
|
||||||
snr[1].realfun = (DWORD)SNOOP16_Return;
|
snr[1].realfun = (DWORD)SNOOP16_Return;
|
||||||
snr[1].lcall = 0x9a;
|
snr[1].lcall = 0x9a;
|
||||||
snr[1].callfromregs = (DWORD)CallFrom16Register;
|
snr[1].callfromregs = (DWORD)CallFrom16Register;
|
||||||
GET_CS(snr[1].seg);
|
snr[1].seg = __get_cs();
|
||||||
snr[1].lret = 0xcb66;
|
snr[1].lret = 0xcb66;
|
||||||
}
|
}
|
||||||
while (*dll) {
|
while (*dll) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "flatthunk.h"
|
#include "flatthunk.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
||||||
|
@ -498,9 +499,8 @@ UINT WINAPI ThunkConnect16(
|
||||||
void WINAPI C16ThkSL(CONTEXT86 *context)
|
void WINAPI C16ThkSL(CONTEXT86 *context)
|
||||||
{
|
{
|
||||||
LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub;
|
LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub;
|
||||||
WORD cs, ds;
|
WORD cs = __get_cs();
|
||||||
GET_CS(cs);
|
WORD ds = __get_ds();
|
||||||
GET_DS(ds);
|
|
||||||
|
|
||||||
/* We produce the following code:
|
/* We produce the following code:
|
||||||
*
|
*
|
||||||
|
@ -551,8 +551,7 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
|
||||||
struct ThunkDataSL *td = SL16->fpData;
|
struct ThunkDataSL *td = SL16->fpData;
|
||||||
|
|
||||||
DWORD procAddress = (DWORD)GetProcAddress16(GetModuleHandle16("KERNEL"), 631);
|
DWORD procAddress = (DWORD)GetProcAddress16(GetModuleHandle16("KERNEL"), 631);
|
||||||
WORD cs;
|
WORD cs = __get_cs();
|
||||||
GET_CS(cs);
|
|
||||||
|
|
||||||
if (!td)
|
if (!td)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,25 +18,28 @@ extern void SELECTOR_MoveBlock( WORD sel, const void *new_base );
|
||||||
extern void SELECTOR_FreeBlock( WORD sel, WORD count );
|
extern void SELECTOR_FreeBlock( WORD sel, WORD count );
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
# define __GET_SEG(seg,res) __asm__( "movw %%" seg ",%w0" : "=r" (res) )
|
# ifdef __GNUC__
|
||||||
# define __SET_SEG(seg,val) __asm__( "movw %w0,%%" seg : : "r" (val) )
|
# define __DEFINE_GET_SEG(seg) \
|
||||||
|
extern inline unsigned short __get_##seg(void) \
|
||||||
|
{ unsigned short res; __asm__("movw %%" #seg ",%w0" : "=r"(res)); return res; }
|
||||||
|
# define __DEFINE_SET_SEG(seg) \
|
||||||
|
extern inline void __set_##seg(int val) { __asm__("movl %0,%%" #seg : : "r" (val)); }
|
||||||
|
# else /* __GNUC__ */
|
||||||
|
# define __DEFINE_GET_SEG(seg) extern unsigned short __get_##seg(void);
|
||||||
|
# define __DEFINE_SET_SEG(seg) extern void __set_##seg(unsigned int);
|
||||||
|
# endif /* __GNUC__ */
|
||||||
#else /* __i386__ */
|
#else /* __i386__ */
|
||||||
# define __GET_SEG(seg,res) ((res) = 0)
|
# define __DEFINE_GET_SEG(seg) static inline unsigned short __get_##seg(void) { return 0; }
|
||||||
# define __SET_SEG(seg,val) /* nothing */
|
# define __DEFINE_SET_SEG(seg) /* nothing */
|
||||||
#endif /* __i386__ */
|
#endif /* __i386__ */
|
||||||
|
|
||||||
#define GET_CS(cs) __GET_SEG("cs",cs)
|
__DEFINE_GET_SEG(cs)
|
||||||
#define GET_DS(ds) __GET_SEG("ds",ds)
|
__DEFINE_GET_SEG(ds)
|
||||||
#define GET_ES(es) __GET_SEG("es",es)
|
__DEFINE_GET_SEG(es)
|
||||||
#define GET_FS(fs) __GET_SEG("fs",fs)
|
__DEFINE_GET_SEG(fs)
|
||||||
#define GET_GS(gs) __GET_SEG("gs",gs)
|
__DEFINE_GET_SEG(gs)
|
||||||
#define GET_SS(ss) __GET_SEG("ss",ss)
|
__DEFINE_GET_SEG(ss)
|
||||||
|
__DEFINE_SET_SEG(fs)
|
||||||
#define SET_CS(cs) __SET_SEG("cs",cs)
|
__DEFINE_SET_SEG(gs)
|
||||||
#define SET_DS(ds) __SET_SEG("ds",ds)
|
|
||||||
#define SET_ES(es) __SET_SEG("es",es)
|
|
||||||
#define SET_FS(fs) __SET_SEG("fs",fs)
|
|
||||||
#define SET_GS(gs) __SET_SEG("gs",gs)
|
|
||||||
#define SET_SS(ss) __SET_SEG("ss",ss)
|
|
||||||
|
|
||||||
#endif /* __WINE_SELECTORS_H */
|
#endif /* __WINE_SELECTORS_H */
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "syslevel.h"
|
#include "syslevel.h"
|
||||||
#include "selectors.h" /* for SET_FS */
|
|
||||||
#include "ntdef.h" /* UNICODE_STRING */
|
#include "ntdef.h" /* UNICODE_STRING */
|
||||||
|
|
||||||
struct _PDB;
|
struct _PDB;
|
||||||
|
|
|
@ -671,15 +671,36 @@ typedef HANDLE *PHANDLE;
|
||||||
/* Macros to retrieve the current context */
|
/* Macros to retrieve the current context */
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
#define _DEFINE_REGS_ENTRYPOINT( name, fn, args ) \
|
|
||||||
__asm__(".align 4\n\t" \
|
|
||||||
".globl " #name "\n\t" \
|
|
||||||
".type " #name ",@function\n\t" \
|
|
||||||
#name ":\n\t" \
|
|
||||||
"call CALL32_Regs\n\t" \
|
|
||||||
".long " #fn "\n\t" \
|
|
||||||
".byte " #args ", " #args "\n\t");
|
|
||||||
|
|
||||||
|
#ifdef NEED_UNDERSCORE_PREFIX
|
||||||
|
# define __ASM_NAME(name) "_" name
|
||||||
|
#else
|
||||||
|
# define __ASM_NAME(name) name
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define __ASM_GLOBAL_FUNC(name,code) \
|
||||||
|
__asm__( ".align 4\n\t" \
|
||||||
|
".globl " __ASM_NAME(#name) "\n\t" \
|
||||||
|
".type " __ASM_NAME(#name) ",@function\n" \
|
||||||
|
__ASM_NAME(#name) ":\n\t" \
|
||||||
|
code );
|
||||||
|
#else /* __GNUC__ */
|
||||||
|
# define __ASM_GLOBAL_FUNC(name,code) \
|
||||||
|
void __asm_dummy_##name(void) { \
|
||||||
|
asm( ".align 4\n\t" \
|
||||||
|
".globl " __ASM_NAME(#name) "\n\t" \
|
||||||
|
".type " __ASM_NAME(#name) ",@function\n" \
|
||||||
|
__ASM_NAME(#name) ":\n\t" \
|
||||||
|
code ); \
|
||||||
|
}
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
#define _DEFINE_REGS_ENTRYPOINT( name, fn, args ) \
|
||||||
|
__ASM_GLOBAL_FUNC( name, \
|
||||||
|
"call " __ASM_NAME("CALL32_Regs") "\n\t" \
|
||||||
|
".long " __ASM_NAME(#fn) "\n\t" \
|
||||||
|
".byte " #args ", " #args )
|
||||||
#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \
|
#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \
|
||||||
_DEFINE_REGS_ENTRYPOINT( name, fn, 0 )
|
_DEFINE_REGS_ENTRYPOINT( name, fn, 0 )
|
||||||
#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \
|
#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \
|
||||||
|
@ -1046,28 +1067,14 @@ typedef struct _NT_TIB
|
||||||
|
|
||||||
struct _TEB;
|
struct _TEB;
|
||||||
|
|
||||||
#ifdef __WINE__
|
#if defined(__i386__) && defined(__GNUC__)
|
||||||
|
extern inline struct _TEB * WINAPI NtCurrentTeb(void)
|
||||||
#if defined(__i386__)
|
|
||||||
static inline struct _TEB * WINE_UNUSED __get_teb(void)
|
|
||||||
{
|
{
|
||||||
struct _TEB *teb;
|
struct _TEB *teb;
|
||||||
__asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb));
|
__asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb));
|
||||||
return teb;
|
return teb;
|
||||||
}
|
}
|
||||||
#elif defined(HAVE__LWP_CREATE)
|
|
||||||
extern void *_lwp_getprivate(void);
|
|
||||||
static inline struct _TEB * WINE_UNUSED __get_teb(void)
|
|
||||||
{
|
|
||||||
return (struct _TEB *)_lwp_getprivate();
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
#error NtCurrentTeb() not defined for this architecture!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NtCurrentTeb() __get_teb()
|
|
||||||
|
|
||||||
#else /* __WINE__ */
|
|
||||||
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "syslevel.h"
|
#include "syslevel.h"
|
||||||
#include "services.h"
|
#include "services.h"
|
||||||
#include "winsock.h"
|
#include "winsock.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
@ -129,15 +130,12 @@ BOOL WINAPI MAIN_KernelInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReser
|
||||||
hModule = GetModuleHandle16( "KERNEL" );
|
hModule = GetModuleHandle16( "KERNEL" );
|
||||||
if ( hModule )
|
if ( hModule )
|
||||||
{
|
{
|
||||||
WORD cs, ds;
|
|
||||||
|
|
||||||
/* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
|
/* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
|
||||||
NE_SetEntryPoint( hModule, 178, GetWinFlags16() );
|
NE_SetEntryPoint( hModule, 178, GetWinFlags16() );
|
||||||
|
|
||||||
/* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
|
/* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
|
||||||
GET_CS(cs); GET_DS(ds);
|
NE_SetEntryPoint( hModule, 454, __get_cs() );
|
||||||
NE_SetEntryPoint( hModule, 454, cs );
|
NE_SetEntryPoint( hModule, 455, __get_ds() );
|
||||||
NE_SetEntryPoint( hModule, 455, ds );
|
|
||||||
|
|
||||||
/* Initialize KERNEL.THHOOK */
|
/* Initialize KERNEL.THHOOK */
|
||||||
TASK_InstallTHHook((THHOOK *)PTR_SEG_TO_LIN(
|
TASK_InstallTHHook((THHOOK *)PTR_SEG_TO_LIN(
|
||||||
|
|
|
@ -176,16 +176,12 @@ void SELECTOR_FreeBlock( WORD sel, WORD count )
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
{
|
{
|
||||||
/* Check if we are freeing current %fs or %gs selector */
|
/* Check if we are freeing current %fs or %gs selector */
|
||||||
|
if ((__get_fs() >= sel) && (__get_fs() < nextsel))
|
||||||
WORD fs, gs;
|
|
||||||
GET_FS(fs);
|
|
||||||
if ((fs >= sel) && (fs < nextsel))
|
|
||||||
{
|
{
|
||||||
WARN("Freeing %%fs selector (%04x), not good.\n", fs );
|
WARN("Freeing %%fs selector (%04x), not good.\n", __get_fs() );
|
||||||
SET_FS( 0 );
|
__set_fs( 0 );
|
||||||
}
|
}
|
||||||
GET_GS(gs);
|
if ((__get_gs() >= sel) && (__get_gs() < nextsel)) __set_gs( 0 );
|
||||||
if ((gs >= sel) && (gs < nextsel)) SET_GS( 0 );
|
|
||||||
}
|
}
|
||||||
#endif /* __i386__ */
|
#endif /* __i386__ */
|
||||||
|
|
||||||
|
@ -614,7 +610,6 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten
|
||||||
|
|
||||||
if (!(sel & 4)) /* GDT selector */
|
if (!(sel & 4)) /* GDT selector */
|
||||||
{
|
{
|
||||||
WORD seg;
|
|
||||||
sel &= ~3; /* ignore RPL */
|
sel &= ~3; /* ignore RPL */
|
||||||
if (!sel) /* null selector */
|
if (!sel) /* null selector */
|
||||||
{
|
{
|
||||||
|
@ -633,12 +628,9 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten
|
||||||
ldtent->HighWord.Bits.Default_Big = 1;
|
ldtent->HighWord.Bits.Default_Big = 1;
|
||||||
ldtent->HighWord.Bits.Type = 0x12;
|
ldtent->HighWord.Bits.Type = 0x12;
|
||||||
/* it has to be one of the system GDT selectors */
|
/* it has to be one of the system GDT selectors */
|
||||||
GET_DS(seg);
|
if (sel == (__get_ds() & ~3)) return TRUE;
|
||||||
if (sel == (seg & ~3)) return TRUE;
|
if (sel == (__get_ss() & ~3)) return TRUE;
|
||||||
GET_SS(seg);
|
if (sel == (__get_cs() & ~3))
|
||||||
if (sel == (seg & ~3)) return TRUE;
|
|
||||||
GET_CS(seg);
|
|
||||||
if (sel == (seg & ~3))
|
|
||||||
{
|
{
|
||||||
ldtent->HighWord.Bits.Type |= 8; /* code segment */
|
ldtent->HighWord.Bits.Type |= 8; /* code segment */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -826,3 +818,14 @@ SEGPTR WINAPI UTLinearToSelectorOffset16(LPVOID lptr)
|
||||||
{
|
{
|
||||||
return (SEGPTR)lptr;
|
return (SEGPTR)lptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
__ASM_GLOBAL_FUNC( __get_cs, "movl %cs,%eax\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __get_ds, "movl %ds,%eax\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __get_es, "movl %es,%eax\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __get_fs, "movl %fs,%eax\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __get_gs, "movl %gs,%eax\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __get_ss, "movl %ss,%eax\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __set_fs, "movl 4(%esp),%eax\n\tmovl %eax,%fs\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __set_gs, "movl 4(%esp),%eax\n\tmovl %eax,%gs\n\tret" );
|
||||||
|
#endif
|
||||||
|
|
|
@ -28,7 +28,6 @@ SEGPTR WINAPI Get16DLLAddress(HMODULE handle, LPSTR func_name) {
|
||||||
LPVOID tmpheap = HeapAlloc(ThunkHeap, 0, 32);
|
LPVOID tmpheap = HeapAlloc(ThunkHeap, 0, 32);
|
||||||
SEGPTR thunk = HEAP_GetSegptr(ThunkHeap, 0, tmpheap);
|
SEGPTR thunk = HEAP_GetSegptr(ThunkHeap, 0, tmpheap);
|
||||||
DWORD proc_16;
|
DWORD proc_16;
|
||||||
WORD cs;
|
|
||||||
|
|
||||||
if (!handle) handle=GetModuleHandle16("WIN32S16");
|
if (!handle) handle=GetModuleHandle16("WIN32S16");
|
||||||
proc_16 = (DWORD)WIN32_GetProcAddress16(handle, func_name);
|
proc_16 = (DWORD)WIN32_GetProcAddress16(handle, func_name);
|
||||||
|
@ -36,6 +35,6 @@ SEGPTR WINAPI Get16DLLAddress(HMODULE handle, LPSTR func_name) {
|
||||||
x=PTR_SEG_TO_LIN(thunk);
|
x=PTR_SEG_TO_LIN(thunk);
|
||||||
*x++=0xba; *(DWORD*)x=proc_16;x+=4; /* movl proc_16, $edx */
|
*x++=0xba; *(DWORD*)x=proc_16;x+=4; /* movl proc_16, $edx */
|
||||||
*x++=0xea; *(DWORD*)x=(DWORD)GetProcAddress(GetModuleHandleA("KERNEL32"),"QT_Thunk");x+=4; /* jmpl QT_Thunk */
|
*x++=0xea; *(DWORD*)x=(DWORD)GetProcAddress(GetModuleHandleA("KERNEL32"),"QT_Thunk");x+=4; /* jmpl QT_Thunk */
|
||||||
GET_CS(cs); *(WORD*)x=(WORD)cs;
|
*(WORD*)x=__get_cs();
|
||||||
return thunk;
|
return thunk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,7 +495,7 @@ static RMCB *DPMI_AllocRMCB( void )
|
||||||
*p++ = 0x9a; /* lcall */
|
*p++ = 0x9a; /* lcall */
|
||||||
*(FARPROC16 *)p = (FARPROC16)RMCallbackProc; /* FIXME: register relay */
|
*(FARPROC16 *)p = (FARPROC16)RMCallbackProc; /* FIXME: register relay */
|
||||||
p+=4;
|
p+=4;
|
||||||
GET_CS(*(WORD *)p);
|
*(WORD *)p = __get_cs();
|
||||||
p+=2;
|
p+=2;
|
||||||
*p++=0xc3; /* lret (FIXME?) */
|
*p++=0xc3; /* lret (FIXME?) */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -100,7 +100,6 @@ int RELAY_CallFrom32( int ret_addr, ... )
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
unsigned int typemask;
|
unsigned int typemask;
|
||||||
FARPROC func;
|
FARPROC func;
|
||||||
WORD fs;
|
|
||||||
|
|
||||||
int *args = &ret_addr + 1;
|
int *args = &ret_addr + 1;
|
||||||
/* Relay addr is the return address for this function */
|
/* Relay addr is the return address for this function */
|
||||||
|
@ -111,8 +110,7 @@ int RELAY_CallFrom32( int ret_addr, ... )
|
||||||
func = (FARPROC)BUILTIN32_GetEntryPoint( buffer, relay_addr - 5, &typemask );
|
func = (FARPROC)BUILTIN32_GetEntryPoint( buffer, relay_addr - 5, &typemask );
|
||||||
DPRINTF( "Call %s(", buffer );
|
DPRINTF( "Call %s(", buffer );
|
||||||
RELAY_PrintArgs( args, nb_args, typemask );
|
RELAY_PrintArgs( args, nb_args, typemask );
|
||||||
GET_FS( fs );
|
DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, __get_fs() );
|
||||||
DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, fs );
|
|
||||||
|
|
||||||
SYSLEVEL_CheckNotLevel( 2 );
|
SYSLEVEL_CheckNotLevel( 2 );
|
||||||
|
|
||||||
|
@ -202,7 +200,7 @@ int RELAY_CallFrom32( int ret_addr, ... )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DPRINTF( "Ret %s() retval=%08x ret=%08x fs=%04x\n",
|
DPRINTF( "Ret %s() retval=%08x ret=%08x fs=%04x\n",
|
||||||
buffer, ret, ret_addr, fs );
|
buffer, ret, ret_addr, __get_fs() );
|
||||||
|
|
||||||
SYSLEVEL_CheckNotLevel( 2 );
|
SYSLEVEL_CheckNotLevel( 2 );
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ static int *ph_errno = &h_errno;
|
||||||
#endif
|
#endif
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "wine/exception.h"
|
#include "wine/exception.h"
|
||||||
|
@ -108,7 +109,7 @@ void SYSDEPS_SetCurThread( TEB *teb )
|
||||||
{
|
{
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
/* On the i386, the current thread is in the %fs register */
|
/* On the i386, the current thread is in the %fs register */
|
||||||
SET_FS( teb->teb_sel );
|
__set_fs( teb->teb_sel );
|
||||||
#elif defined(HAVE__LWP_CREATE)
|
#elif defined(HAVE__LWP_CREATE)
|
||||||
/* On non-i386 Solaris, we use the LWP private pointer */
|
/* On non-i386 Solaris, we use the LWP private pointer */
|
||||||
_lwp_setprivate( teb );
|
_lwp_setprivate( teb );
|
||||||
|
@ -206,10 +207,9 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
||||||
*/
|
*/
|
||||||
void SYSDEPS_ExitThread(void)
|
void SYSDEPS_ExitThread(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE__LWP_CREATE
|
#if !defined(__i386__) && defined(HAVE__LWP_CREATE)
|
||||||
_lwp_exit();
|
_lwp_exit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_exit( 0 );
|
_exit( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,14 +219,14 @@ void SYSDEPS_ExitThread(void)
|
||||||
*
|
*
|
||||||
* This will crash and burn if called before threading is initialized
|
* This will crash and burn if called before threading is initialized
|
||||||
*/
|
*/
|
||||||
|
#ifdef __i386__
|
||||||
/* if it was defined as a macro, we need to do some magic */
|
__ASM_GLOBAL_FUNC( NtCurrentTeb, ".byte 0x64\n\tmovl 0x18,%eax\n\tret" );
|
||||||
#ifdef NtCurrentTeb
|
#elif defined(HAVE__LWP_CREATE)
|
||||||
#undef NtCurrentTeb
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct _TEB * WINAPI NtCurrentTeb(void)
|
struct _TEB * WINAPI NtCurrentTeb(void)
|
||||||
{
|
{
|
||||||
return __get_teb();
|
extern void *_lwp_getprivate(void);
|
||||||
|
return (struct _TEB *)_lwp_getprivate();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
# error NtCurrentTeb not defined for this architecture
|
||||||
|
#endif /* __i386__ */
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "syslevel.h"
|
#include "syslevel.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ VOID WINAPI _EnterSysLevel(SYSLEVEL *lock)
|
||||||
teb->sys_count[lock->level] );
|
teb->sys_count[lock->level] );
|
||||||
|
|
||||||
if (lock == &Win16Mutex)
|
if (lock == &Win16Mutex)
|
||||||
GET_FS( SYSLEVEL_Win16CurrentTeb );
|
SYSLEVEL_Win16CurrentTeb = __get_fs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "neexe.h"
|
#include "neexe.h"
|
||||||
#include "selectors.h"
|
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
#include "builtin16.h"
|
#include "builtin16.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
@ -43,6 +42,16 @@
|
||||||
# undef USE_STABS
|
# undef USE_STABS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
extern WORD __get_cs(void);
|
||||||
|
extern WORD __get_ds(void);
|
||||||
|
__ASM_GLOBAL_FUNC( __get_cs, "movl %cs,%eax\n\tret" );
|
||||||
|
__ASM_GLOBAL_FUNC( __get_ds, "movl %ds,%eax\n\tret" );
|
||||||
|
#else
|
||||||
|
static inline WORD __get_cs(void) { return 0; }
|
||||||
|
static inline WORD __get_ds(void) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TYPE_BYTE, /* byte variable (Win16) */
|
TYPE_BYTE, /* byte variable (Win16) */
|
||||||
|
@ -3182,8 +3191,8 @@ int main(int argc, char **argv)
|
||||||
* the asm files on the platform that will also run them. Probably
|
* the asm files on the platform that will also run them. Probably
|
||||||
* a safe assumption to make.
|
* a safe assumption to make.
|
||||||
*/
|
*/
|
||||||
GET_CS( Code_Selector );
|
Code_Selector = __get_cs();
|
||||||
GET_DS( Data_Selector );
|
Data_Selector = __get_ds();
|
||||||
|
|
||||||
if (!strcmp( argv[1], "-spec" )) BuildSpecFile( outfile, open_input( argv[2] ) );
|
if (!strcmp( argv[1], "-spec" )) BuildSpecFile( outfile, open_input( argv[2] ) );
|
||||||
else if (!strcmp( argv[1], "-glue" )) BuildGlue( outfile, open_input( argv[2] ) );
|
else if (!strcmp( argv[1], "-glue" )) BuildGlue( outfile, open_input( argv[2] ) );
|
||||||
|
|
|
@ -968,7 +968,7 @@ FreeSLCallback(
|
||||||
*/
|
*/
|
||||||
void WINAPI GetTEBSelectorFS16(void)
|
void WINAPI GetTEBSelectorFS16(void)
|
||||||
{
|
{
|
||||||
GET_FS( CURRENT_STACK16->fs );
|
CURRENT_STACK16->fs = __get_fs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "winproc.h"
|
#include "winproc.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
#include "selectors.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "struct32.h"
|
#include "struct32.h"
|
||||||
|
|
|
@ -301,7 +301,7 @@ static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
|
||||||
(void(*)())WINPROC_Thunk16To32W;
|
(void(*)())WINPROC_Thunk16To32W;
|
||||||
proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
|
proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
|
||||||
proc->thunk.t_from16.glue = (void*)CallFrom16Long;
|
proc->thunk.t_from16.glue = (void*)CallFrom16Long;
|
||||||
GET_CS(proc->thunk.t_from16.cs);
|
proc->thunk.t_from16.cs = __get_cs();
|
||||||
proc->thunk.t_from16.lret = 0xca66;
|
proc->thunk.t_from16.lret = 0xca66;
|
||||||
proc->thunk.t_from16.nArgs = 10;
|
proc->thunk.t_from16.nArgs = 10;
|
||||||
proc->jmp.jmp = 0xe9;
|
proc->jmp.jmp = 0xe9;
|
||||||
|
|
Loading…
Reference in a new issue