4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-17 20:09:21 +08:00
Qian Hong ff3c4a7d2f Check for correct funtion entry address in munge_threadfunc
* init.cc (munge_threadfunc): Check that we're actually replacing
	the correct original function address on the stack.
	* ntdll.h (enum _THREADINFOCLASS): Add ThreadQuerySetWin32StartAddress.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2015-10-29 09:17:57 +01:00

111 lines
2.5 KiB
C++

/* init.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015 Red Hat, Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
#include "cygtls.h"
#include "ntdll.h"
#include "shared_info.h"
static DWORD _my_oldfunc;
static char *search_for = (char *) cygthread::stub;
unsigned threadfunc_ix[8];
static bool dll_finished_loading;
#define OLDFUNC_OFFSET -1
static void WINAPI
threadfunc_fe (VOID *arg)
{
#ifndef __x86_64__
(void)__builtin_return_address(1);
asm volatile ("andl $-16,%%esp" ::: "%esp");
#endif
_cygtls::call ((DWORD (*) (void *, void *)) TlsGetValue (_my_oldfunc), arg);
}
/* If possible, redirect the thread entry point to a cygwin routine which
adds tls stuff to the stack. */
static void
munge_threadfunc ()
{
int i;
char **ebp = (char **) __builtin_frame_address (0);
if (!threadfunc_ix[0])
{
char **peb;
char **top = (char **) _tlsbase;
for (peb = ebp, i = 0; peb < top && i < 7; peb++)
if (*peb == search_for)
threadfunc_ix[i++] = peb - ebp;
if (0 && !threadfunc_ix[0])
{
try_to_debug ();
return;
}
}
if (threadfunc_ix[0])
{
char *threadfunc = NULL;
NtQueryInformationThread (NtCurrentThread (),
ThreadQuerySetWin32StartAddress,
&threadfunc, sizeof threadfunc, NULL);
if (!search_for || threadfunc == search_for)
{
search_for = NULL;
for (i = 0; threadfunc_ix[i]; i++)
if (!threadfunc || ebp[threadfunc_ix[i]] == threadfunc)
ebp[threadfunc_ix[i]] = (char *) threadfunc_fe;
TlsSetValue (_my_oldfunc, threadfunc);
}
}
}
void dll_crt0_0 ();
extern "C" BOOL WINAPI
dll_entry (HANDLE h, DWORD reason, void *static_load)
{
BOOL test_stack_marker;
switch (reason)
{
case DLL_PROCESS_ATTACH:
init_console_handler (false);
cygwin_hmodule = (HMODULE) h;
dynamically_loaded = (static_load == NULL);
dll_crt0_0 ();
_my_oldfunc = TlsAlloc ();
dll_finished_loading = true;
break;
case DLL_PROCESS_DETACH:
if (dynamically_loaded)
shared_destroy ();
break;
case DLL_THREAD_ATTACH:
if (dll_finished_loading)
munge_threadfunc ();
break;
case DLL_THREAD_DETACH:
if (dll_finished_loading
&& (PVOID) &_my_tls > (PVOID) &test_stack_marker
&& _my_tls.isinitialized ())
_my_tls.remove (0);
break;
}
return TRUE;
}