PKGBUILDS/wine-tkg-git/wine-tkg-git/wine-tkg-patches/game-specific/leagueoflolfix/legacy/leagueoflolfix-7f14464.patch

713 lines
28 KiB
Diff

From bff63e4de27f2ef1287e7ff3f8c0cd2e13e6875d Mon Sep 17 00:00:00 2001
From: yuiiio <atbjyk@protonmail.com>
Date: Thu, 1 Oct 2020 23:35:35 +0900
Subject: [PATCH 1/2] Revert "libwine: Remove some no longer needed helper
functions."
This reverts commit 18273d5e71e25575bdbdba1d252df72be3373f6d.
---
libs/wine/ldt.c | 55 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 40 insertions(+), 15 deletions(-)
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index 30d9b945f73..5e85c1137c8 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -45,9 +45,26 @@ struct __wine_ldt_copy
unsigned char flags[8192]; /* flags (defined below) */
} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
static inline void *wine_ldt_get_base( const LDT_ENTRY *ent )
{
return (void *)(ent->BaseLow |
@@ -60,6 +77,26 @@ static inline unsigned int wine_ldt_get_limit( const LDT_ENTRY *ent )
if (ent->HighWord.Bits.Granularity) limit = (limit << 12) | 0xfff;
return limit;
}
+static inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
#ifdef __linux__
@@ -170,21 +207,9 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
lock_ldt();
if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- ULONG_PTR base = (ULONG_PTR)wine_ldt_copy_obsolete.base[index];
- ULONG limit = wine_ldt_copy_obsolete.limit[index];
-
- entry->BaseLow = (WORD)base;
- entry->HighWord.Bits.BaseMid = (BYTE)(base >> 16);
- entry->HighWord.Bits.BaseHi = (BYTE)(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 = wine_ldt_copy_obsolete.flags[index];
- entry->HighWord.Bits.Sys = 0;
- entry->HighWord.Bits.Reserved_0 = 0;
- entry->HighWord.Bits.Default_Big = !!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT);
+ wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
--
2.28.0
From 992d96a7464b533358aa03ea1b616f5402241a99 Mon Sep 17 00:00:00 2001
From: yuiiio <atbjyk@protonmail.com>
Date: Thu, 1 Oct 2020 23:41:43 +0900
Subject: [PATCH 2/2] Revert "libwine: Make the LDT functions obsolete."
This reverts commit 3b16f35413f3a6641df42b782ead294f343e7d5e.
---
include/wine/library.h | 110 ++++++++++++++++++++++++++
libs/wine/ldt.c | 175 +++++++++++------------------------------
libs/wine/wine.map | 38 +++++----
3 files changed, 181 insertions(+), 142 deletions(-)
diff --git a/include/wine/library.h b/include/wine/library.h
index b8a4a2df576..2e0f6dc1bad 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -63,6 +63,116 @@ extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
extern int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg),
void *arg, int top_down );
+#ifdef __i386__
+
+/* LDT management */
+
+extern void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) );
+extern void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry );
+extern int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry );
+extern int wine_ldt_is_system( unsigned short sel );
+extern void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset );
+extern unsigned short wine_ldt_alloc_entries( int count );
+extern unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount );
+extern void wine_ldt_free_entries( unsigned short sel, int count );
+extern unsigned short wine_ldt_alloc_fs(void);
+extern void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry );
+extern void wine_ldt_free_fs( unsigned short sel );
+
+/* the local copy of the LDT */
+extern struct __wine_ldt_copy
+{
+ void *base[8192]; /* base address or 0 if entry is free */
+ unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
+ unsigned char flags[8192]; /* flags (defined below) */
+} wine_ldt_copy;
+
+#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
+#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
+#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
+#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
+#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
+#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+
+/* helper functions to manipulate the LDT_ENTRY structure */
+static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
+{
+ ent->BaseLow = (WORD)(ULONG_PTR)base;
+ ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
+ ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
+}
+static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
+{
+ if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
+ ent->LimitLow = (WORD)limit;
+ ent->HighWord.Bits.LimitHi = (limit >> 16);
+}
+static inline void *wine_ldt_get_base( const 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 wine_ldt_get_limit( const 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 inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
+{
+ ent->HighWord.Bits.Dpl = 3;
+ ent->HighWord.Bits.Pres = 1;
+ ent->HighWord.Bits.Type = flags;
+ ent->HighWord.Bits.Sys = 0;
+ ent->HighWord.Bits.Reserved_0 = 0;
+ ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
+}
+static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
+{
+ unsigned char ret = ent->HighWord.Bits.Type;
+ if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
+ return ret;
+}
+static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
+{
+ const DWORD *dw = (const DWORD *)ent;
+ return (dw[0] | dw[1]) == 0;
+}
+
+/* segment register access */
+
+# if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
+# define __DEFINE_GET_SEG(seg) \
+ static FORCEINLINE unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm__ __volatile__("movw %%" #seg ",%w0" : "=r"(res)); return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static FORCEINLINE void wine_set_##seg(int val) \
+ { __asm__("movw %w0,%%" #seg : : "r" (val)); }
+# elif defined(_MSC_VER)
+# define __DEFINE_GET_SEG(seg) \
+ static inline unsigned short wine_get_##seg(void) \
+ { unsigned short res; __asm { mov res, seg } return res; }
+# define __DEFINE_SET_SEG(seg) \
+ static inline void wine_set_##seg(unsigned short val) { __asm { mov seg, val } }
+# else /* __GNUC__ || _MSC_VER */
+# define __DEFINE_GET_SEG(seg) extern unsigned short wine_get_##seg(void);
+# define __DEFINE_SET_SEG(seg) extern void wine_set_##seg(unsigned int);
+# endif /* __GNUC__ || _MSC_VER */
+
+__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)
+#undef __DEFINE_GET_SEG
+#undef __DEFINE_SET_SEG
+
+#endif /* __i386__ */
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index 5e85c1137c8..15ce11f2074 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -31,73 +31,11 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/library.h"
#include "wine/asm.h"
#ifdef __i386__
-#ifdef __ASM_OBSOLETE
-
-/* the local copy of the LDT */
-struct __wine_ldt_copy
-{
- void *base[8192]; /* base address or 0 if entry is free */
- unsigned long limit[8192]; /* limit in bytes or 0 if entry is free */
- unsigned char flags[8192]; /* flags (defined below) */
-} wine_ldt_copy_obsolete = { { 0, 0, 0 } };
-
-#define WINE_LDT_FLAGS_DATA 0x13 /* Data segment */
-#define WINE_LDT_FLAGS_STACK 0x17 /* Stack segment */
-#define WINE_LDT_FLAGS_CODE 0x1b /* Code segment */
-#define WINE_LDT_FLAGS_TYPE_MASK 0x1f /* Mask for segment type */
-#define WINE_LDT_FLAGS_32BIT 0x40 /* Segment is 32-bit (code or stack) */
-#define WINE_LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
-
-/* helper functions to manipulate the LDT_ENTRY structure */
-static inline void wine_ldt_set_base( LDT_ENTRY *ent, const void *base )
-{
- ent->BaseLow = (WORD)(ULONG_PTR)base;
- ent->HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
- ent->HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
-}
-static inline void wine_ldt_set_limit( LDT_ENTRY *ent, unsigned int limit )
-{
- if ((ent->HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
- ent->LimitLow = (WORD)limit;
- ent->HighWord.Bits.LimitHi = (limit >> 16);
-}
-static inline void *wine_ldt_get_base( const 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 wine_ldt_get_limit( const 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 inline void wine_ldt_set_flags( LDT_ENTRY *ent, unsigned char flags )
-{
- ent->HighWord.Bits.Dpl = 3;
- ent->HighWord.Bits.Pres = 1;
- ent->HighWord.Bits.Type = flags;
- ent->HighWord.Bits.Sys = 0;
- ent->HighWord.Bits.Reserved_0 = 0;
- ent->HighWord.Bits.Default_Big = (flags & WINE_LDT_FLAGS_32BIT) != 0;
-}
-static inline unsigned char wine_ldt_get_flags( const LDT_ENTRY *ent )
-{
- unsigned char ret = ent->HighWord.Bits.Type;
- if (ent->HighWord.Bits.Default_Big) ret |= WINE_LDT_FLAGS_32BIT;
- return ret;
-}
-static inline int wine_ldt_is_empty( const LDT_ENTRY *ent )
-{
- const DWORD *dw = (const DWORD *)ent;
- return (dw[0] | dw[1]) == 0;
-}
-
#ifdef __linux__
#ifdef HAVE_SYS_SYSCALL_H
@@ -164,6 +102,13 @@ static inline int set_thread_area( struct modify_ldt_s *ptr )
#include <i386/user_ldt.h>
#endif
+/* local copy of the LDT */
+#ifdef __APPLE__
+struct __wine_ldt_copy wine_ldt_copy = { { 0, 0, 0 } };
+#else
+struct __wine_ldt_copy wine_ldt_copy;
+#endif
+
static const LDT_ENTRY null_entry; /* all-zeros, used to clear LDT entries */
#define LDT_FIRST_ENTRY 512
@@ -183,7 +128,7 @@ static inline int is_gdt_sel( unsigned short sel ) { return !(sel & 4); }
*
* Set the LDT locking/unlocking functions.
*/
-void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func)(void) )
+void wine_ldt_init_locking( void (*lock_func)(void), void (*unlock_func)(void) )
{
lock_ldt = lock_func;
unlock_ldt = unlock_func;
@@ -195,7 +140,7 @@ void wine_ldt_init_locking_obsolete( void (*lock_func)(void), void (*unlock_func
*
* Retrieve an LDT entry. Return a null entry if selector is not allocated.
*/
-void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
+void wine_ldt_get_entry( unsigned short sel, LDT_ENTRY *entry )
{
int index = sel >> 3;
@@ -205,11 +150,11 @@ void wine_ldt_get_entry_obsolete( unsigned short sel, LDT_ENTRY *entry )
return;
}
lock_ldt();
- if (wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
+ if (wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_ALLOCATED)
{
- wine_ldt_set_base( entry, wine_ldt_copy_obsolete.base[index] );
- wine_ldt_set_limit( entry, wine_ldt_copy_obsolete.limit[index] );
- wine_ldt_set_flags( entry, wine_ldt_copy_obsolete.flags[index] );
+ wine_ldt_set_base( entry, wine_ldt_copy.base[index] );
+ wine_ldt_set_limit( entry, wine_ldt_copy.limit[index] );
+ wine_ldt_set_flags( entry, wine_ldt_copy.flags[index] );
}
else *entry = null_entry;
unlock_ldt();
@@ -272,9 +217,9 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
if (ret >= 0)
{
- wine_ldt_copy_obsolete.base[index] = wine_ldt_get_base(entry);
- wine_ldt_copy_obsolete.limit[index] = wine_ldt_get_limit(entry);
- wine_ldt_copy_obsolete.flags[index] = (entry->HighWord.Bits.Type |
+ wine_ldt_copy.base[index] = wine_ldt_get_base(entry);
+ wine_ldt_copy.limit[index] = wine_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);
}
@@ -287,7 +232,7 @@ static int internal_set_entry( unsigned short sel, const LDT_ENTRY *entry )
*
* Set an LDT entry.
*/
-int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+int wine_ldt_set_entry( unsigned short sel, const LDT_ENTRY *entry )
{
int ret;
@@ -303,7 +248,7 @@ int wine_ldt_set_entry_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Check if the selector is a system selector (i.e. not managed by Wine).
*/
-int wine_ldt_is_system_obsolete( unsigned short sel )
+int wine_ldt_is_system( unsigned short sel )
{
return is_gdt_sel(sel) || ((sel >> 3) < LDT_FIRST_ENTRY);
}
@@ -315,7 +260,7 @@ int wine_ldt_is_system_obsolete( unsigned short sel )
* Convert a segment:offset pair to a linear pointer.
* Note: we don't lock the LDT since this has to be fast.
*/
-void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
+void *wine_ldt_get_ptr( unsigned short sel, unsigned long offset )
{
int index;
@@ -323,8 +268,8 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
return (void *)offset;
if ((index = (sel >> 3)) < LDT_FIRST_ENTRY) /* system selector */
return (void *)offset;
- if (!(wine_ldt_copy_obsolete.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
- return (char *)wine_ldt_copy_obsolete.base[index] + offset;
+ if (!(wine_ldt_copy.flags[index] & WINE_LDT_FLAGS_32BIT)) offset &= 0xffff;
+ return (char *)wine_ldt_copy.base[index] + offset;
}
@@ -334,7 +279,7 @@ void *wine_ldt_get_ptr_obsolete( unsigned short sel, unsigned long offset )
* Allocate a number of consecutive ldt entries, without setting the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_alloc_entries_obsolete( int count )
+unsigned short wine_ldt_alloc_entries( int count )
{
int i, index, size = 0;
@@ -342,13 +287,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
lock_ldt();
for (i = LDT_FIRST_ENTRY; i < LDT_SIZE; i++)
{
- if (wine_ldt_copy_obsolete.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
+ if (wine_ldt_copy.flags[i] & WINE_LDT_FLAGS_ALLOCATED) size = 0;
else if (++size >= count) /* found a large enough block */
{
index = i - size + 1;
/* mark selectors as allocated */
- for (i = 0; i < count; i++) wine_ldt_copy_obsolete.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
+ for (i = 0; i < count; i++) wine_ldt_copy.flags[index + i] |= WINE_LDT_FLAGS_ALLOCATED;
unlock_ldt();
return (index << 3) | 7;
}
@@ -358,15 +303,13 @@ unsigned short wine_ldt_alloc_entries_obsolete( int count )
}
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count );
-
/***********************************************************************
* wine_ldt_realloc_entries
*
* Reallocate a number of consecutive ldt entries, without changing the LDT contents.
* Return a selector for the first entry.
*/
-unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcount, int newcount )
+unsigned short wine_ldt_realloc_entries( unsigned short sel, int oldcount, int newcount )
{
int i;
@@ -379,23 +322,23 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
if (index + newcount > LDT_SIZE) i = oldcount;
else
for (i = oldcount; i < newcount; i++)
- if (wine_ldt_copy_obsolete.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
+ if (wine_ldt_copy.flags[index+i] & WINE_LDT_FLAGS_ALLOCATED) break;
if (i < newcount) /* they are not free */
{
- wine_ldt_free_entries_obsolete( sel, oldcount );
- sel = wine_ldt_alloc_entries_obsolete( newcount );
+ wine_ldt_free_entries( sel, oldcount );
+ sel = wine_ldt_alloc_entries( newcount );
}
else /* mark the selectors as allocated */
{
for (i = oldcount; i < newcount; i++)
- wine_ldt_copy_obsolete.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
+ wine_ldt_copy.flags[index+i] |= WINE_LDT_FLAGS_ALLOCATED;
}
unlock_ldt();
}
else if (oldcount > newcount) /* we need to remove selectors */
{
- wine_ldt_free_entries_obsolete( sel + (newcount << 3), newcount - oldcount );
+ wine_ldt_free_entries( sel + (newcount << 3), newcount - oldcount );
}
return sel;
}
@@ -406,7 +349,7 @@ unsigned short wine_ldt_realloc_entries_obsolete( unsigned short sel, int oldcou
*
* Free a number of consecutive ldt entries and clear their contents.
*/
-void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
+void wine_ldt_free_entries( unsigned short sel, int count )
{
int index;
@@ -414,7 +357,7 @@ void wine_ldt_free_entries_obsolete( unsigned short sel, int count )
for (index = sel >> 3; count > 0; count--, index++)
{
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[index] = 0;
+ wine_ldt_copy.flags[index] = 0;
}
unlock_ldt();
}
@@ -428,7 +371,7 @@ static int global_fs_sel = -1; /* global selector for %fs shared among all thre
* Allocate an LDT entry for a %fs selector, reusing a global
* GDT selector if possible. Return the selector value.
*/
-unsigned short wine_ldt_alloc_fs_obsolete(void)
+unsigned short wine_ldt_alloc_fs(void)
{
if (global_fs_sel == -1)
{
@@ -455,7 +398,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
#endif
}
if (global_fs_sel > 0) return global_fs_sel;
- return wine_ldt_alloc_entries_obsolete( 1 );
+ return wine_ldt_alloc_entries( 1 );
}
@@ -467,7 +410,7 @@ unsigned short wine_ldt_alloc_fs_obsolete(void)
*
* Note: this runs in the context of the new thread, so cannot acquire locks.
*/
-void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
+void wine_ldt_init_fs( unsigned short sel, const LDT_ENTRY *entry )
{
if ((sel & ~3) == (global_fs_sel & ~3))
{
@@ -495,7 +438,7 @@ void wine_ldt_init_fs_obsolete( unsigned short sel, const LDT_ENTRY *entry )
*
* Free a %fs selector returned by wine_ldt_alloc_fs.
*/
-void wine_ldt_free_fs_obsolete( unsigned short sel )
+void wine_ldt_free_fs( unsigned short sel )
{
WORD fs;
@@ -506,46 +449,22 @@ void wine_ldt_free_fs_obsolete( unsigned short sel )
/* FIXME: if freeing current %fs we cannot acquire locks */
__asm__( "mov %0,%%fs" :: "r" (0) );
internal_set_entry( sel, &null_entry );
- wine_ldt_copy_obsolete.flags[sel >> 3] = 0;
+ wine_ldt_copy.flags[sel >> 3] = 0;
}
- else wine_ldt_free_entries_obsolete( sel, 1 );
+ else wine_ldt_free_entries( sel, 1 );
}
/***********************************************************************
* selector access functions
*/
-__ASM_GLOBAL_FUNC( wine_get_cs_obsolete, "movw %cs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ds_obsolete, "movw %ds,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_es_obsolete, "movw %es,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_fs_obsolete, "movw %fs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_gs_obsolete, "movw %gs,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_get_ss_obsolete, "movw %ss,%ax\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_fs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
-__ASM_GLOBAL_FUNC( wine_set_gs_obsolete, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
-
-
-__ASM_OBSOLETE(wine_ldt_alloc_entries);
-__ASM_OBSOLETE(wine_ldt_alloc_fs);
-__ASM_OBSOLETE(wine_ldt_copy);
-__ASM_OBSOLETE(wine_ldt_free_entries);
-__ASM_OBSOLETE(wine_ldt_free_fs);
-__ASM_OBSOLETE(wine_ldt_get_entry);
-__ASM_OBSOLETE(wine_ldt_get_ptr);
-__ASM_OBSOLETE(wine_ldt_init_fs);
-__ASM_OBSOLETE(wine_ldt_init_locking);
-__ASM_OBSOLETE(wine_ldt_is_system);
-__ASM_OBSOLETE(wine_ldt_realloc_entries);
-__ASM_OBSOLETE(wine_ldt_set_entry);
-__ASM_OBSOLETE(wine_get_cs);
-__ASM_OBSOLETE(wine_get_ds);
-__ASM_OBSOLETE(wine_get_es);
-__ASM_OBSOLETE(wine_get_fs);
-__ASM_OBSOLETE(wine_get_gs);
-__ASM_OBSOLETE(wine_get_ss);
-__ASM_OBSOLETE(wine_set_fs);
-__ASM_OBSOLETE(wine_set_gs);
-
-#endif /* __ASM_OBSOLETE */
+__ASM_GLOBAL_FUNC( wine_get_cs, "movw %cs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ds, "movw %ds,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
#endif /* __i386__ */
--
2.28.0
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index abdc0efc51..411abb86d8 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256];
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+static int wine_cs;
+
static void* WINAPI __wine_fakedll_dispatcher( const char *module, ULONG ord )
{
UNICODE_STRING name;
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD
}
#endif
- if (!ldt_is_system(CS_sig(sigcontext)) || !ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
+ if ((CS_sig(sigcontext) != wine_cs && !ldt_is_system(CS_sig(sigcontext))) || !ldt_is_system(SS_sig(sigcontext)))
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
BYTE instr[16];
unsigned int i, len, prefix_count = 0;
- if (!ldt_is_system( context->SegCs )) return 0;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
for (i = 0; i < len; i++) switch (instr[i])
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
WORD system_gs = x86_thread_data()->gs;
if (context->SegGs == system_gs) return FALSE;
- if (!ldt_is_system( context->SegCs )) return FALSE;
+ if (context->SegCs != wine_cs && !ldt_is_system( context->SegCs )) return 0;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s
EIP_sig(sigcontext) = (DWORD)func;
/* clear single-step, direction, and align check flag */
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = get_cs();
+ CS_sig(sigcontext) = wine_cs;
DS_sig(sigcontext) = get_ds();
ES_sig(sigcontext) = get_es();
FS_sig(sigcontext) = get_fs();
@@ -2394,6 +2396,21 @@ static void ldt_unlock(void)
else RtlLeaveCriticalSection( &ldt_section );
}
+void signal_init_cs(void)
+{
+ LDT_ENTRY entry;
+
+ if (!wine_cs)
+ wine_cs = wine_ldt_alloc_entries( 1 );
+
+ wine_ldt_set_base( &entry, 0 );
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_set_entry( wine_cs, &entry );
+
+ wine_set_cs( wine_cs );
+}
+
/**********************************************************************
* signal_alloc_thread
@@ -2433,6 +2450,8 @@ NTSTATUS signal_alloc_thread( TEB *teb )
teb->WOW32Reserved = __wine_syscall_dispatcher;
teb->Spare2 = __wine_fakedll_dispatcher;
+
+ signal_init_cs();
return STATUS_SUCCESS;
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 7395a117c7..56e749033e 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs)
__DEFINE_SET_SEG(gs)
#undef __DEFINE_GET_SEG
#undef __DEFINE_SET_SEG
+extern void wine_set_cs(unsigned int);
#endif /* __i386__ */
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
index b9371814ba..21e9f0528b 100644
--- a/libs/wine/ldt.c
+++ b/libs/wine/ldt.c
@@ -461,6 +461,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "retf" )
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 72ffed80c0..c41f567fb6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -116,6 +116,7 @@ WINE_1.0
wine_ldt_set_entry;
wine_pthread_get_functions;
wine_pthread_set_functions;
+ wine_set_cs;
wine_set_fs;
wine_set_gs;
wine_utf8_mbstowcs;