ntdll: Avoid using the LDT definitions from libwine.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-04-01 12:41:05 +02:00
parent b644034a52
commit b8f0e32b9f
1 changed files with 41 additions and 13 deletions

View File

@ -2301,6 +2301,11 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
#define LDT_SIZE 8192
#define LDT_FLAGS_DATA 0x13 /* Data segment */
#define LDT_FLAGS_CODE 0x1b /* Code segment */
#define LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
#define LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated */
static WORD gdt_fs_sel;
static RTL_CRITICAL_SECTION ldt_section;
@ -2335,13 +2340,36 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
static inline void *ldt_get_base( LDT_ENTRY ent )
{
return (void *)(ent.BaseLow |
(ULONG_PTR)ent.HighWord.Bits.BaseMid << 16 |
(ULONG_PTR)ent.HighWord.Bits.BaseHi << 24);
}
static inline unsigned int ldt_get_limit( LDT_ENTRY ent )
{
unsigned int limit = ent.LimitLow | (ent.HighWord.Bits.LimitHi << 16);
if (ent.HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
return limit;
}
static LDT_ENTRY ldt_make_entry( void *base, unsigned int limit, unsigned char flags )
{
LDT_ENTRY entry;
wine_ldt_set_base( &entry, base );
wine_ldt_set_limit( &entry, limit );
wine_ldt_set_flags( &entry, flags );
entry.BaseLow = (WORD)(ULONG_PTR)base;
entry.HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
entry.HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
if ((entry.HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
entry.LimitLow = (WORD)limit;
entry.HighWord.Bits.LimitHi = limit >> 16;
entry.HighWord.Bits.Dpl = 3;
entry.HighWord.Bits.Pres = 1;
entry.HighWord.Bits.Type = flags;
entry.HighWord.Bits.Sys = 0;
entry.HighWord.Bits.Reserved_0 = 0;
entry.HighWord.Bits.Default_Big = (flags & LDT_FLAGS_32BIT) != 0;
return entry;
}
@ -2352,7 +2380,7 @@ static void ldt_set_entry( WORD sel, LDT_ENTRY entry )
#ifdef linux
struct modify_ldt_s ldt_info = { index };
ldt_info.base_addr = wine_ldt_get_base( &entry );
ldt_info.base_addr = ldt_get_base( entry );
ldt_info.limit = entry.LimitLow | (entry.HighWord.Bits.LimitHi << 16);
ldt_info.seg_32bit = entry.HighWord.Bits.Default_Big;
ldt_info.contents = (entry.HighWord.Bits.Type >> 2) & 3;
@ -2374,7 +2402,7 @@ static void ldt_set_entry( WORD sel, LDT_ENTRY entry )
struct ssd ldt_mod;
ldt_mod.sel = sel;
ldt_mod.bo = (unsigned long)wine_ldt_get_base(&entry);
ldt_mod.bo = (unsigned long)ldt_get_base( entry );
ldt_mod.ls = entry.LimitLow | (entry.HighWord.Bits.LimitHi << 16);
ldt_mod.acc1 = entry.HighWord.Bytes.Flags1;
ldt_mod.acc2 = entry.HighWord.Bytes.Flags2 >> 4;
@ -2389,11 +2417,11 @@ static void ldt_set_entry( WORD sel, LDT_ENTRY entry )
exit(1);
#endif
wine_ldt_copy.base[index] = wine_ldt_get_base( &entry );
wine_ldt_copy.limit[index] = wine_ldt_get_limit( &entry );
wine_ldt_copy.base[index] = ldt_get_base( entry );
wine_ldt_copy.limit[index] = ldt_get_limit( entry );
wine_ldt_copy.flags[index] = (entry.HighWord.Bits.Type |
(entry.HighWord.Bits.Default_Big ? WINE_LDT_FLAGS_32BIT : 0) |
WINE_LDT_FLAGS_ALLOCATED);
(entry.HighWord.Bits.Default_Big ? LDT_FLAGS_32BIT : 0) |
LDT_FLAGS_ALLOCATED);
}
static void ldt_init(void)
@ -2422,7 +2450,7 @@ WORD ldt_alloc_fs( TEB *teb, int first_thread )
if (gdt_fs_sel) return gdt_fs_sel;
entry = ldt_make_entry( teb, teb_size - 1, WINE_LDT_FLAGS_DATA | WINE_LDT_FLAGS_32BIT );
entry = ldt_make_entry( teb, teb_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
if (first_thread) /* no locking for first thread */
{
@ -2490,11 +2518,11 @@ NTSTATUS get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_
if (!(info->Selector & ~3))
info->Entry = null_entry;
else if ((info->Selector | 3) == wine_get_cs())
info->Entry = ldt_make_entry( 0, ~0u, WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
info->Entry = ldt_make_entry( 0, ~0u, LDT_FLAGS_CODE | LDT_FLAGS_32BIT );
else if ((info->Selector | 3) == wine_get_ds())
info->Entry = ldt_make_entry( 0, ~0u, WINE_LDT_FLAGS_DATA | WINE_LDT_FLAGS_32BIT );
info->Entry = ldt_make_entry( 0, ~0u, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
else if ((info->Selector | 3) == wine_get_fs())
info->Entry = ldt_make_entry( NtCurrentTeb(), 0xfff, WINE_LDT_FLAGS_DATA | WINE_LDT_FLAGS_32BIT );
info->Entry = ldt_make_entry( NtCurrentTeb(), 0xfff, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
else
return STATUS_UNSUCCESSFUL;
}