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 "combo.h"
|
||||
#include "local.h"
|
||||
#include "selectors.h"
|
||||
#include "debugtools.h"
|
||||
#include "callback.h"
|
||||
#include "tweak.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "drive.h"
|
||||
#include "heap.h"
|
||||
#include "spy.h"
|
||||
#include "selectors.h"
|
||||
#include "win.h"
|
||||
#include "combo.h"
|
||||
#include "debugtools.h"
|
||||
|
|
|
@ -257,8 +257,8 @@ BOOL DEBUG_ValidateRegisters(void)
|
|||
return FALSE; \
|
||||
}
|
||||
|
||||
GET_CS(cs);
|
||||
GET_DS(ds);
|
||||
cs = __get_cs();
|
||||
ds = __get_ds();
|
||||
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 (DS_reg(&DEBUG_context) != ds) CHECK_SEG(DS_reg(&DEBUG_context), "DS");
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#include "selectors.h"
|
||||
|
||||
/***********************************************************************
|
||||
* signal context platform-specific definitions
|
||||
*/
|
||||
|
@ -309,13 +311,13 @@ static inline void handler_init( CONTEXT *context, const SIGCONTEXT *sigcontext
|
|||
#ifdef FS_sig
|
||||
fs = FS_sig(sigcontext);
|
||||
#else
|
||||
GET_FS(fs);
|
||||
fs = __get_fs();
|
||||
#endif
|
||||
context->SegFs = fs;
|
||||
/* now restore a proper %fs for the fault handler */
|
||||
if (!IS_SELECTOR_SYSTEM(CS_sig(sigcontext))) fs = SYSLEVEL_Win16CurrentTeb;
|
||||
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
|
||||
context->SegGs = LOWORD(GS_sig(sigcontext));
|
||||
#else
|
||||
GET_GS( context->SegGs );
|
||||
context->SegGs &= 0xffff;
|
||||
context->SegGs = __get_gs();
|
||||
#endif
|
||||
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
|
||||
FS_sig(sigcontext) = context->SegFs;
|
||||
#else
|
||||
SET_FS( context->SegFs );
|
||||
__set_fs( context->SegFs );
|
||||
#endif
|
||||
#ifdef GS_sig
|
||||
GS_sig(sigcontext) = context->SegGs;
|
||||
#else
|
||||
SET_GS( context->SegGs );
|
||||
__set_gs( context->SegGs );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
|
|||
snr[0].realfun = (DWORD)SNOOP16_Entry;
|
||||
snr[0].lcall = 0x9a;
|
||||
snr[0].callfromregs = (DWORD)CallFrom16Register;
|
||||
GET_CS(snr[0].seg);
|
||||
snr[0].seg = __get_cs();
|
||||
snr[0].lret = 0xcb66;
|
||||
|
||||
snr[1].pushbp = 0x5566;
|
||||
|
@ -110,7 +110,7 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
|
|||
snr[1].realfun = (DWORD)SNOOP16_Return;
|
||||
snr[1].lcall = 0x9a;
|
||||
snr[1].callfromregs = (DWORD)CallFrom16Register;
|
||||
GET_CS(snr[1].seg);
|
||||
snr[1].seg = __get_cs();
|
||||
snr[1].lret = 0xcb66;
|
||||
}
|
||||
while (*dll) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "win.h"
|
||||
#include "flatthunk.h"
|
||||
#include "mouse.h"
|
||||
#include "selectors.h"
|
||||
#include "keyboard.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
|
@ -498,9 +499,8 @@ UINT WINAPI ThunkConnect16(
|
|||
void WINAPI C16ThkSL(CONTEXT86 *context)
|
||||
{
|
||||
LPBYTE stub = PTR_SEG_TO_LIN(EAX_reg(context)), x = stub;
|
||||
WORD cs, ds;
|
||||
GET_CS(cs);
|
||||
GET_DS(ds);
|
||||
WORD cs = __get_cs();
|
||||
WORD ds = __get_ds();
|
||||
|
||||
/* We produce the following code:
|
||||
*
|
||||
|
@ -551,8 +551,7 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
|
|||
struct ThunkDataSL *td = SL16->fpData;
|
||||
|
||||
DWORD procAddress = (DWORD)GetProcAddress16(GetModuleHandle16("KERNEL"), 631);
|
||||
WORD cs;
|
||||
GET_CS(cs);
|
||||
WORD cs = __get_cs();
|
||||
|
||||
if (!td)
|
||||
{
|
||||
|
|
|
@ -18,25 +18,28 @@ extern void SELECTOR_MoveBlock( WORD sel, const void *new_base );
|
|||
extern void SELECTOR_FreeBlock( WORD sel, WORD count );
|
||||
|
||||
#ifdef __i386__
|
||||
# define __GET_SEG(seg,res) __asm__( "movw %%" seg ",%w0" : "=r" (res) )
|
||||
# define __SET_SEG(seg,val) __asm__( "movw %w0,%%" seg : : "r" (val) )
|
||||
# ifdef __GNUC__
|
||||
# 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__ */
|
||||
# define __GET_SEG(seg,res) ((res) = 0)
|
||||
# define __SET_SEG(seg,val) /* nothing */
|
||||
# define __DEFINE_GET_SEG(seg) static inline unsigned short __get_##seg(void) { return 0; }
|
||||
# define __DEFINE_SET_SEG(seg) /* nothing */
|
||||
#endif /* __i386__ */
|
||||
|
||||
#define GET_CS(cs) __GET_SEG("cs",cs)
|
||||
#define GET_DS(ds) __GET_SEG("ds",ds)
|
||||
#define GET_ES(es) __GET_SEG("es",es)
|
||||
#define GET_FS(fs) __GET_SEG("fs",fs)
|
||||
#define GET_GS(gs) __GET_SEG("gs",gs)
|
||||
#define GET_SS(ss) __GET_SEG("ss",ss)
|
||||
|
||||
#define SET_CS(cs) __SET_SEG("cs",cs)
|
||||
#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)
|
||||
__DEFINE_GET_SEG(cs)
|
||||
__DEFINE_GET_SEG(ds)
|
||||
__DEFINE_GET_SEG(es)
|
||||
__DEFINE_GET_SEG(fs)
|
||||
__DEFINE_GET_SEG(gs)
|
||||
__DEFINE_GET_SEG(ss)
|
||||
__DEFINE_SET_SEG(fs)
|
||||
__DEFINE_SET_SEG(gs)
|
||||
|
||||
#endif /* __WINE_SELECTORS_H */
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "config.h"
|
||||
#include "winbase.h"
|
||||
#include "syslevel.h"
|
||||
#include "selectors.h" /* for SET_FS */
|
||||
#include "ntdef.h" /* UNICODE_STRING */
|
||||
|
||||
struct _PDB;
|
||||
|
|
|
@ -671,15 +671,36 @@ typedef HANDLE *PHANDLE;
|
|||
/* Macros to retrieve the current context */
|
||||
|
||||
#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_REGS_ENTRYPOINT( name, fn, 0 )
|
||||
#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \
|
||||
|
@ -1046,28 +1067,14 @@ typedef struct _NT_TIB
|
|||
|
||||
struct _TEB;
|
||||
|
||||
#ifdef __WINE__
|
||||
|
||||
#if defined(__i386__)
|
||||
static inline struct _TEB * WINE_UNUSED __get_teb(void)
|
||||
#if defined(__i386__) && defined(__GNUC__)
|
||||
extern inline struct _TEB * WINAPI NtCurrentTeb(void)
|
||||
{
|
||||
struct _TEB *teb;
|
||||
__asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (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
|
||||
#error NtCurrentTeb() not defined for this architecture!
|
||||
#endif
|
||||
|
||||
#define NtCurrentTeb() __get_teb()
|
||||
|
||||
#else /* __WINE__ */
|
||||
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "syslevel.h"
|
||||
#include "services.h"
|
||||
#include "winsock.h"
|
||||
#include "selectors.h"
|
||||
#include "thread.h"
|
||||
#include "task.h"
|
||||
#include "debugtools.h"
|
||||
|
@ -129,15 +130,12 @@ BOOL WINAPI MAIN_KernelInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReser
|
|||
hModule = GetModuleHandle16( "KERNEL" );
|
||||
if ( hModule )
|
||||
{
|
||||
WORD cs, ds;
|
||||
|
||||
/* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
|
||||
NE_SetEntryPoint( hModule, 178, GetWinFlags16() );
|
||||
|
||||
/* Initialize KERNEL.454/455 (__FLATCS/__FLATDS) */
|
||||
GET_CS(cs); GET_DS(ds);
|
||||
NE_SetEntryPoint( hModule, 454, cs );
|
||||
NE_SetEntryPoint( hModule, 455, ds );
|
||||
NE_SetEntryPoint( hModule, 454, __get_cs() );
|
||||
NE_SetEntryPoint( hModule, 455, __get_ds() );
|
||||
|
||||
/* Initialize KERNEL.THHOOK */
|
||||
TASK_InstallTHHook((THHOOK *)PTR_SEG_TO_LIN(
|
||||
|
|
|
@ -176,16 +176,12 @@ void SELECTOR_FreeBlock( WORD sel, WORD count )
|
|||
#ifdef __i386__
|
||||
{
|
||||
/* Check if we are freeing current %fs or %gs selector */
|
||||
|
||||
WORD fs, gs;
|
||||
GET_FS(fs);
|
||||
if ((fs >= sel) && (fs < nextsel))
|
||||
if ((__get_fs() >= sel) && (__get_fs() < nextsel))
|
||||
{
|
||||
WARN("Freeing %%fs selector (%04x), not good.\n", fs );
|
||||
SET_FS( 0 );
|
||||
WARN("Freeing %%fs selector (%04x), not good.\n", __get_fs() );
|
||||
__set_fs( 0 );
|
||||
}
|
||||
GET_GS(gs);
|
||||
if ((gs >= sel) && (gs < nextsel)) SET_GS( 0 );
|
||||
if ((__get_gs() >= sel) && (__get_gs() < nextsel)) __set_gs( 0 );
|
||||
}
|
||||
#endif /* __i386__ */
|
||||
|
||||
|
@ -614,7 +610,6 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten
|
|||
|
||||
if (!(sel & 4)) /* GDT selector */
|
||||
{
|
||||
WORD seg;
|
||||
sel &= ~3; /* ignore RPL */
|
||||
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.Type = 0x12;
|
||||
/* it has to be one of the system GDT selectors */
|
||||
GET_DS(seg);
|
||||
if (sel == (seg & ~3)) return TRUE;
|
||||
GET_SS(seg);
|
||||
if (sel == (seg & ~3)) return TRUE;
|
||||
GET_CS(seg);
|
||||
if (sel == (seg & ~3))
|
||||
if (sel == (__get_ds() & ~3)) return TRUE;
|
||||
if (sel == (__get_ss() & ~3)) return TRUE;
|
||||
if (sel == (__get_cs() & ~3))
|
||||
{
|
||||
ldtent->HighWord.Bits.Type |= 8; /* code segment */
|
||||
return TRUE;
|
||||
|
@ -826,3 +818,14 @@ SEGPTR WINAPI UTLinearToSelectorOffset16(LPVOID 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);
|
||||
SEGPTR thunk = HEAP_GetSegptr(ThunkHeap, 0, tmpheap);
|
||||
DWORD proc_16;
|
||||
WORD cs;
|
||||
|
||||
if (!handle) handle=GetModuleHandle16("WIN32S16");
|
||||
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++=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 */
|
||||
GET_CS(cs); *(WORD*)x=(WORD)cs;
|
||||
*(WORD*)x=__get_cs();
|
||||
return thunk;
|
||||
}
|
||||
|
|
|
@ -495,7 +495,7 @@ static RMCB *DPMI_AllocRMCB( void )
|
|||
*p++ = 0x9a; /* lcall */
|
||||
*(FARPROC16 *)p = (FARPROC16)RMCallbackProc; /* FIXME: register relay */
|
||||
p+=4;
|
||||
GET_CS(*(WORD *)p);
|
||||
*(WORD *)p = __get_cs();
|
||||
p+=2;
|
||||
*p++=0xc3; /* lret (FIXME?) */
|
||||
#endif
|
||||
|
|
|
@ -100,7 +100,6 @@ int RELAY_CallFrom32( int ret_addr, ... )
|
|||
char buffer[80];
|
||||
unsigned int typemask;
|
||||
FARPROC func;
|
||||
WORD fs;
|
||||
|
||||
int *args = &ret_addr + 1;
|
||||
/* 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 );
|
||||
DPRINTF( "Call %s(", buffer );
|
||||
RELAY_PrintArgs( args, nb_args, typemask );
|
||||
GET_FS( fs );
|
||||
DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, fs );
|
||||
DPRINTF( ") ret=%08x fs=%04x\n", ret_addr, __get_fs() );
|
||||
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
|
||||
|
@ -202,7 +200,7 @@ int RELAY_CallFrom32( int ret_addr, ... )
|
|||
}
|
||||
}
|
||||
DPRINTF( "Ret %s() retval=%08x ret=%08x fs=%04x\n",
|
||||
buffer, ret, ret_addr, fs );
|
||||
buffer, ret, ret_addr, __get_fs() );
|
||||
|
||||
SYSLEVEL_CheckNotLevel( 2 );
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ static int *ph_errno = &h_errno;
|
|||
#endif
|
||||
#include "wine/port.h"
|
||||
#include "thread.h"
|
||||
#include "selectors.h"
|
||||
#include "server.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/exception.h"
|
||||
|
@ -108,7 +109,7 @@ void SYSDEPS_SetCurThread( TEB *teb )
|
|||
{
|
||||
#if defined(__i386__)
|
||||
/* 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)
|
||||
/* On non-i386 Solaris, we use the LWP private pointer */
|
||||
_lwp_setprivate( teb );
|
||||
|
@ -206,10 +207,9 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
|||
*/
|
||||
void SYSDEPS_ExitThread(void)
|
||||
{
|
||||
#ifdef HAVE__LWP_CREATE
|
||||
#if !defined(__i386__) && defined(HAVE__LWP_CREATE)
|
||||
_lwp_exit();
|
||||
#endif
|
||||
|
||||
_exit( 0 );
|
||||
}
|
||||
|
||||
|
@ -219,14 +219,14 @@ void SYSDEPS_ExitThread(void)
|
|||
*
|
||||
* This will crash and burn if called before threading is initialized
|
||||
*/
|
||||
|
||||
/* if it was defined as a macro, we need to do some magic */
|
||||
#ifdef NtCurrentTeb
|
||||
#undef NtCurrentTeb
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
__ASM_GLOBAL_FUNC( NtCurrentTeb, ".byte 0x64\n\tmovl 0x18,%eax\n\tret" );
|
||||
#elif defined(HAVE__LWP_CREATE)
|
||||
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 "syslevel.h"
|
||||
#include "heap.h"
|
||||
#include "selectors.h"
|
||||
#include "stackframe.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
|
@ -94,7 +95,7 @@ VOID WINAPI _EnterSysLevel(SYSLEVEL *lock)
|
|||
teb->sys_count[lock->level] );
|
||||
|
||||
if (lock == &Win16Mutex)
|
||||
GET_FS( SYSLEVEL_Win16CurrentTeb );
|
||||
SYSLEVEL_Win16CurrentTeb = __get_fs();
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "winnt.h"
|
||||
#include "module.h"
|
||||
#include "neexe.h"
|
||||
#include "selectors.h"
|
||||
#include "stackframe.h"
|
||||
#include "builtin16.h"
|
||||
#include "thread.h"
|
||||
|
@ -43,6 +42,16 @@
|
|||
# undef USE_STABS
|
||||
#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
|
||||
{
|
||||
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
|
||||
* a safe assumption to make.
|
||||
*/
|
||||
GET_CS( Code_Selector );
|
||||
GET_DS( Data_Selector );
|
||||
Code_Selector = __get_cs();
|
||||
Data_Selector = __get_ds();
|
||||
|
||||
if (!strcmp( argv[1], "-spec" )) BuildSpecFile( 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)
|
||||
{
|
||||
GET_FS( CURRENT_STACK16->fs );
|
||||
CURRENT_STACK16->fs = __get_fs();
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "winproc.h"
|
||||
#include "task.h"
|
||||
#include "process.h"
|
||||
#include "selectors.h"
|
||||
#include "thread.h"
|
||||
#include "options.h"
|
||||
#include "struct32.h"
|
||||
|
|
|
@ -301,7 +301,7 @@ static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
|
|||
(void(*)())WINPROC_Thunk16To32W;
|
||||
proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
|
||||
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.nArgs = 10;
|
||||
proc->jmp.jmp = 0xe9;
|
||||
|
|
Loading…
Reference in New Issue