Commit a02d2773 authored by Alexandre Julliard's avatar Alexandre Julliard

krnl386: Reimplement LDT support using NtSetLdtEntries().

parent 12c3177e
......@@ -29,6 +29,7 @@
#include "wine/windef16.h"
#include "winbase.h"
#include "winnt.h" /* for PCONTEXT */
#include "kernel16_private.h"
#define MAX_DOS_DRIVES 26
......@@ -64,7 +65,7 @@ extern WORD relay_data_sel DECLSPEC_HIDDEN;
* segmented mode is recognized by checking whether 'seg' is 32-bit
* selector which is neither system selector nor zero.
*/
#define CTX_SEG_OFF_TO_LIN(context,seg,off) (wine_ldt_get_ptr((seg),(off)))
#define CTX_SEG_OFF_TO_LIN(context,seg,off) (ldt_get_ptr((seg),(off)))
#define INT_BARF(context,num) \
ERR( "int%x: unknown/not implemented parameters:\n" \
......
......@@ -53,14 +53,14 @@ static inline void add_stack( CONTEXT *context, int offset )
static inline void *make_ptr( CONTEXT *context, DWORD seg, DWORD off, int long_addr )
{
if (wine_ldt_is_system(seg)) return (void *)off;
if (ldt_is_system(seg)) return (void *)off;
if (!long_addr) off = LOWORD(off);
return (char *) MapSL( MAKESEGPTR( seg, 0 ) ) + off;
}
static inline void *get_stack( CONTEXT *context )
{
return wine_ldt_get_ptr( context->SegSs, context->Esp );
return ldt_get_ptr( context->SegSs, context->Esp );
}
#include "pshpack1.h"
......@@ -315,9 +315,9 @@ static BYTE *INSTR_GetOperandAddr( CONTEXT *context, BYTE *instr,
if (segprefix != -1) seg = segprefix;
/* Make sure the segment and offset are valid */
if (wine_ldt_is_system(seg)) return (BYTE *)(base + (index << ss));
if (ldt_is_system(seg)) return (BYTE *)(base + (index << ss));
if ((seg & 7) != 7) return NULL;
wine_ldt_get_entry( seg, &entry );
if (!ldt_get_entry( seg, &entry )) return NULL;
if (wine_ldt_is_empty( &entry )) return NULL;
if (wine_ldt_get_limit(&entry) < (base + (index << ss))) return NULL;
return (BYTE *)wine_ldt_get_base(&entry) + base + (index << ss);
......@@ -790,7 +790,7 @@ DWORD __wine_emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT *context )
break; /* Unable to emulate it */
case 0xcf: /* iret */
if (wine_ldt_is_system(context->SegCs)) break; /* don't emulate it in 32-bit code */
if (ldt_is_system(context->SegCs)) break; /* don't emulate it in 32-bit code */
if (long_op)
{
DWORD *stack = get_stack( context );
......@@ -884,7 +884,7 @@ LONG CALLBACK INSTR_vectored_handler( EXCEPTION_POINTERS *ptrs )
EXCEPTION_RECORD *record = ptrs->ExceptionRecord;
CONTEXT *context = ptrs->ContextRecord;
if (wine_ldt_is_system(context->SegCs) &&
if (ldt_is_system(context->SegCs) &&
(record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
record->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION))
{
......
......@@ -242,9 +242,8 @@ void WINAPI DOSVM_Int31Handler( CONTEXT *context )
TRACE( "get selector base address (0x%04x)\n", BX_reg(context) );
{
LDT_ENTRY entry;
WORD sel = BX_reg(context);
wine_ldt_get_entry( sel, &entry );
if (wine_ldt_is_empty(&entry))
if (!ldt_get_entry( BX_reg(context), &entry ) || wine_ldt_is_empty(&entry))
{
context->Eax = 0x8022; /* invalid selector */
SET_CFLAG(context);
......@@ -301,7 +300,7 @@ void WINAPI DOSVM_Int31Handler( CONTEXT *context )
{
LDT_ENTRY *entry = CTX_SEG_OFF_TO_LIN( context, context->SegEs,
context->Edi );
wine_ldt_get_entry( BX_reg(context), entry );
ldt_get_entry( BX_reg(context), entry );
}
break;
......@@ -310,7 +309,7 @@ void WINAPI DOSVM_Int31Handler( CONTEXT *context )
{
LDT_ENTRY *entry = CTX_SEG_OFF_TO_LIN( context, context->SegEs,
context->Edi );
wine_ldt_set_entry( BX_reg(context), entry );
if (!ldt_is_system( BX_reg(context) )) ldt_set_entry( BX_reg(context), *entry );
}
break;
......
......@@ -280,7 +280,7 @@ BOOL DOSVM_EmulateInterruptPM( CONTEXT *context, BYTE intnum )
DOSVM_IntProcRelay,
DOSVM_GetBuiltinHandler(intnum) );
}
else if (wine_ldt_is_system(context->SegCs))
else if (ldt_is_system(context->SegCs))
{
INTPROC proc;
if (intnum >= ARRAY_SIZE(DOSVM_VectorsBuiltin)) return FALSE;
......
......@@ -71,6 +71,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
switch(reason)
{
case DLL_PROCESS_ATTACH:
init_selectors();
if (LoadLibrary16( "krnl386.exe" ) < 32) return FALSE;
/* fall through */
case DLL_THREAD_ATTACH:
......
......@@ -232,11 +232,16 @@ extern void NE_DllProcessAttach( HMODULE16 hModule ) DECLSPEC_HIDDEN;
extern void NE_CallUserSignalProc( HMODULE16 hModule, UINT16 code ) DECLSPEC_HIDDEN;
/* selector.c */
extern void init_selectors(void) DECLSPEC_HIDDEN;
extern BOOL ldt_is_system( WORD sel ) DECLSPEC_HIDDEN;
extern void *ldt_get_ptr( WORD sel, DWORD offset ) DECLSPEC_HIDDEN;
extern BOOL ldt_get_entry( WORD sel, LDT_ENTRY *entry ) DECLSPEC_HIDDEN;
extern void ldt_set_entry( WORD sel, LDT_ENTRY entry ) DECLSPEC_HIDDEN;
extern WORD SELECTOR_AllocBlock( const void *base, DWORD size, unsigned char flags ) DECLSPEC_HIDDEN;
extern WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size ) DECLSPEC_HIDDEN;
extern void SELECTOR_FreeBlock( WORD sel ) DECLSPEC_HIDDEN;
#define IS_SELECTOR_32BIT(sel) \
(wine_ldt_is_system(sel) || (wine_ldt_copy.flags[LOWORD(sel) >> 3] & WINE_LDT_FLAGS_32BIT))
(ldt_is_system(sel) || (wine_ldt_copy.flags[LOWORD(sel) >> 3] & WINE_LDT_FLAGS_32BIT))
/* relay16.c */
extern int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT *context ) DECLSPEC_HIDDEN;
......
......@@ -57,14 +57,10 @@ static SEGPTR call16_ret_addr; /* segptr to __wine_call_to_16_ret routine */
BOOL WOWTHUNK_Init(void)
{
/* allocate the code selector for CallTo16 routines */
LDT_ENTRY entry;
WORD codesel = wine_ldt_alloc_entries(1);
WORD codesel = SELECTOR_AllocBlock( __wine_call16_start,
(BYTE *)(&CallTo16_TebSelector + 1) - __wine_call16_start,
WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
if (!codesel) return FALSE;
wine_ldt_set_base( &entry, __wine_call16_start );
wine_ldt_set_limit( &entry, (BYTE *)(&CallTo16_TebSelector + 1) - __wine_call16_start - 1 );
wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
wine_ldt_set_entry( codesel, &entry );
/* Patch the return addresses for CallTo16 routines */
......@@ -116,7 +112,7 @@ static BOOL fix_selector( CONTEXT *context )
default:
return FALSE;
}
stack = wine_ldt_get_ptr( context->SegSs, context->Esp );
stack = ldt_get_ptr( context->SegSs, context->Esp );
TRACE( "fixing up selector %x for pop instruction\n", *stack );
*stack = 0;
return TRUE;
......@@ -141,7 +137,7 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE
else if (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
record->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION)
{
if (wine_ldt_is_system(context->SegCs))
if (ldt_is_system(context->SegCs))
{
if (fix_selector( context )) return ExceptionContinueExecution;
}
......@@ -155,7 +151,7 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE
/* check for Win16 __GP handler */
if ((gpHandler = HasGPHandler16( MAKESEGPTR( context->SegCs, context->Eip ) )))
{
WORD *stack = wine_ldt_get_ptr( context->SegSs, context->Esp );
WORD *stack = ldt_get_ptr( context->SegSs, context->Esp );
*--stack = context->SegCs;
*--stack = context->Eip;
......
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