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

209 lines
8.2 KiB
Diff

diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index c876d51f8e6..654c84de587 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1401,19 +1401,9 @@ void output_syscalls( DLLSPEC *spec )
switch (target.cpu)
{
case CPU_i386:
- if (UsePIC)
- {
- output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
- output( "1:\tmovl %s-1b(%%eax),%%edx\n", asm_name("__wine_syscall_dispatcher") );
- output( "\tmovl $%u,%%eax\n", id );
- needs_get_pc_thunk = 1;
- }
- else
- {
- output( "\tmovl $%u,%%eax\n", id );
- output( "\tmovl $%s,%%edx\n", asm_name("__wine_syscall") );
- }
- output( "\tcall *%%edx\n" );
+ output( "\t.byte 0xb8\n" ); /* mov eax, SYSCALL */
+ output( "\t.long %d\n", id );
+ output( "\t.byte 0x64,0xff,0x15,0xc0,0x00,0x00,0x00\n" ); /* call dword ptr fs:[0C0h] */
output( "\tret $%u\n", odp->type == TYPE_STDCALL ? get_args_size( odp ) : 0 );
break;
case CPU_x86_64:
--- a/dlls/ntdll/unix/signal_i386.c
+++ a/dlls/ntdll/unix/signal_i386.c
@@ -415,6 +415,8 @@ static inline int set_thread_area( struc
static ULONG first_ldt_entry = 32;
+static int wine_cs;
+
enum i386_trap_code
{
#if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
@@ -528,6 +530,11 @@ static inline WORD get_cs(void) { WORD r
static inline WORD get_ds(void) { WORD res; __asm__( "movw %%ds,%0" : "=r" (res) ); return res; }
static inline WORD get_fs(void) { WORD res; __asm__( "movw %%fs,%0" : "=r" (res) ); return res; }
static inline WORD get_gs(void) { WORD res; __asm__( "movw %%gs,%0" : "=r" (res) ); return res; }
+static CDECL void __attribute((naked)) set_cs( DWORD val ) {
+ asm ( "movl 4(%esp),%eax\n\t"
+ "xchg 0(%esp),%eax\n\t"
+ "push %eax\n\t"
+ "lret"); }
static inline void set_fs( WORD val ) { __asm__( "mov %0,%%fs" :: "r" (val)); }
static inline void set_gs( WORD val ) { __asm__( "mov %0,%%gs" :: "r" (val)); }
@@ -694,7 +701,8 @@ static inline void *init_handler( const
}
#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))) /* 16-bit mode */
{
/*
* Win16 or DOS protected mode. Note that during switch
@@ -1185,7 +1193,7 @@ static inline DWORD is_privileged_instr(
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])
@@ -1252,7 +1260,7 @@ static inline BOOL check_invalid_gs( uco
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 FALSE;
/* only handle faults in system libraries */
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
@@ -1489,7 +1497,7 @@ C_ASSERT( (offsetof(struct stack_layout,
EIP_sig(sigcontext) = (DWORD)pKiUserExceptionDispatcher;
/* 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_ds();
FS_sig(sigcontext) = get_fs();
@@ -2108,6 +2116,36 @@ static void ldt_set_entry( WORD sel, LDT
LDT_FLAGS_ALLOCATED);
}
+static WORD internal_ldt_alloc_entry(void)
+{
+ for (int idx = first_ldt_entry; idx < LDT_SIZE; idx++)
+ {
+ if (__wine_ldt_copy.flags[idx] & LDT_FLAGS_ALLOCATED) continue;
+
+ /* mark selector as allocated */
+ __wine_ldt_copy.flags[idx] |= LDT_FLAGS_ALLOCATED;
+ return (idx << 3) | 7;
+ }
+ return 0;
+}
+
+static inline void cs_init( int first_thread )
+{
+ LDT_ENTRY entry;
+ sigset_t sigset;
+
+ /* no locking for first thread */
+ if (!first_thread) server_enter_uninterrupted_section( &ldt_mutex, &sigset );
+ if (!wine_cs)
+ wine_cs = internal_ldt_alloc_entry();
+
+ entry = ldt_make_entry( 0, (UINT_PTR)-1, LDT_FLAGS_CODE|LDT_FLAGS_32BIT );
+ ldt_set_entry( wine_cs, entry );
+
+ if (!first_thread) server_leave_uninterrupted_section( &ldt_mutex, &sigset );
+ set_cs( wine_cs );
+}
+
static void ldt_set_fs( WORD sel, TEB *teb )
{
if (sel == gdt_fs_sel)
@@ -2223,38 +2261,35 @@ void signal_init_threading(void)
NTSTATUS signal_alloc_thread( TEB *teb )
{
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
+ static int first_thread = 1;
if (!gdt_fs_sel)
{
- static int first_thread = 1;
sigset_t sigset;
- int idx;
+ WORD sel;
LDT_ENTRY entry = ldt_make_entry( teb, page_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
if (first_thread) /* no locking for first thread */
{
/* leave some space if libc is using the LDT for %gs */
if (!is_gdt_sel( get_gs() )) first_ldt_entry = 512;
- idx = first_ldt_entry;
- ldt_set_entry( (idx << 3) | 7, entry );
- first_thread = 0;
+ sel = (first_ldt_entry << 3) | 7;
+ ldt_set_entry( sel, entry );
}
else
{
server_enter_uninterrupted_section( &ldt_mutex, &sigset );
- for (idx = first_ldt_entry; idx < LDT_SIZE; idx++)
- {
- if (__wine_ldt_copy.flags[idx]) continue;
- ldt_set_entry( (idx << 3) | 7, entry );
- break;
- }
+ sel = internal_ldt_alloc_entry();
+ if (sel) ldt_set_entry( sel, entry );
server_leave_uninterrupted_section( &ldt_mutex, &sigset );
- if (idx == LDT_SIZE) return STATUS_TOO_MANY_THREADS;
+ if (!sel) return STATUS_TOO_MANY_THREADS;
}
- thread_data->fs = (idx << 3) | 7;
+ thread_data->fs = sel;
}
else thread_data->fs = gdt_fs_sel;
+ cs_init( first_thread );
+ first_thread = 0;
teb->WOW32Reserved = __wine_syscall_dispatcher;
return STATUS_SUCCESS;
}
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 3d0c2deca35..b0c03d992d4 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2516,6 +2516,17 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr,
TRACE( "read %p, write %p, except %p, timeout %p\n", read_ptr, write_ptr, except_ptr, timeout );
+ static int is_RCS = -1;
+ if (is_RCS < 0) {
+ is_RCS = GetModuleHandleA(NULL) == GetModuleHandleA("RiotClientServices.exe");
+ }
+ const struct timeval zero_tv = { 0, 1000 };
+ if (is_RCS && read_ptr && write_ptr && except_ptr && timeout && timeout->tv_sec == 1 && timeout->tv_usec == 0) {
+ if (read_ptr->fd_count >= 4 && read_ptr->fd_count <= 8 && write_ptr->fd_count == 0 && except_ptr->fd_count == 1) {
+ timeout = &zero_tv;
+ }
+ }
+
if (!(sync_event = get_sync_event())) return -1;
if (read_ptr) poll_count += read_ptr->fd_count;
diff --git a/loader/preloader.c b/loader/preloader.c
index d88964e9c4b..1ac8b9bd16b 100644
--- a/loader/preloader.c
+++ b/loader/preloader.c
@@ -1460,7 +1460,7 @@ void* wld_start( void **stack )
i = 0;
/* delete sysinfo values if addresses conflict */
- if (is_in_preload_range( av, AT_SYSINFO ) || is_in_preload_range( av, AT_SYSINFO_EHDR ))
+ if (1)
{
delete_av[i++].a_type = AT_SYSINFO;
delete_av[i++].a_type = AT_SYSINFO_EHDR;