Commit 916f9756 authored by Alexandre Julliard's avatar Alexandre Julliard

Improved the selector get/set functions.

Support ANSI-compatible inline asm (with the help of Patrik Stridvall).
parent e1d78899
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment