Author: akhaldi Date: Mon Jun 6 10:01:14 2011 New Revision: 52111
URL: http://svn.reactos.org/svn/reactos?rev=52111&view=rev Log: [CRT/STARTUP] * Sync startup code to recent mingw-w64. RosBE 2.0 here we come !
Added: trunk/reactos/lib/sdk/crt/startup/crt_handler.c (with props) trunk/reactos/lib/sdk/crt/startup/pesect.c (with props) Modified: trunk/reactos/lib/sdk/crt/msvcrtex.cmake trunk/reactos/lib/sdk/crt/startup/cinitexe.c trunk/reactos/lib/sdk/crt/startup/crtexe.c trunk/reactos/lib/sdk/crt/startup/gccmain.c trunk/reactos/lib/sdk/crt/startup/gs_support.c trunk/reactos/lib/sdk/crt/startup/merr.c trunk/reactos/lib/sdk/crt/startup/pseudo-reloc.c trunk/reactos/lib/sdk/crt/startup/tlssup.c
Modified: trunk/reactos/lib/sdk/crt/msvcrtex.cmake URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/msvcrtex.cmake?... ============================================================================== --- trunk/reactos/lib/sdk/crt/msvcrtex.cmake [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/msvcrtex.cmake [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -8,6 +8,7 @@ list(APPEND MSVCRTEX_SOURCE startup/crtexe.c startup/wcrtexe.c + startup/crt_handler.c startup/crtdll.c startup/_newmode.c startup/wildcard.c @@ -18,6 +19,7 @@ startup/merr.c startup/atonexit.c startup/txtmode.c + startup/pesect.c startup/pseudo-reloc.c startup/pseudo-reloc-list.c startup/tlsmcrt.c
Modified: trunk/reactos/lib/sdk/crt/startup/cinitexe.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/cinitex... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/cinitexe.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/startup/cinitexe.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -1,11 +1,12 @@ #include <stdio.h> -#include <internal.h> #include <sect_attribs.h>
#ifdef _MSC_VER #pragma comment(linker, "/merge:.CRT=.rdata") #endif
+typedef void (__cdecl *_PVFV)(void); + _CRTALLOC(".CRT$XIA") _PVFV __xi_a[] = { NULL }; _CRTALLOC(".CRT$XIZ") _PVFV __xi_z[] = { NULL }; _CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { NULL };
Added: trunk/reactos/lib/sdk/crt/startup/crt_handler.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/crt_han... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/crt_handler.c (added) +++ trunk/reactos/lib/sdk/crt/startup/crt_handler.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -1,0 +1,290 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <windows.h> +#include <excpt.h> +#include <string.h> +#include <stdlib.h> +#include <malloc.h> +#include <memory.h> +#include <signal.h> +#include <stdio.h> + +#if defined (_WIN64) && defined (__ia64__) +#error FIXME: Unsupported __ImageBase implementation. +#else +#ifndef _MSC_VER +#define __ImageBase __MINGW_LSYMBOL(_image_base__) +#endif +/* This symbol is defined by the linker. */ +extern IMAGE_DOS_HEADER __ImageBase; +#endif + +#pragma pack(push,1) +typedef struct _UNWIND_INFO { + BYTE VersionAndFlags; + BYTE PrologSize; + BYTE CountOfUnwindCodes; + BYTE FrameRegisterAndOffset; + ULONG AddressOfExceptionHandler; +} UNWIND_INFO,*PUNWIND_INFO; +#pragma pack(pop) + +PIMAGE_SECTION_HEADER _FindPESectionByName (const char *); +PIMAGE_SECTION_HEADER _FindPESectionExec (size_t); +PBYTE _GetPEImageBase (void); + +int __mingw_init_ehandler (void); +extern void _fpreset (void); + +#ifdef _WIN64 +EXCEPTION_DISPOSITION __mingw_SEH_error_handler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); + +#define MAX_PDATA_ENTRIES 32 +static RUNTIME_FUNCTION emu_pdata[MAX_PDATA_ENTRIES]; +static UNWIND_INFO emu_xdata[MAX_PDATA_ENTRIES]; + +int +__mingw_init_ehandler (void) +{ + static int was_here = 0; + size_t e = 0; + PIMAGE_SECTION_HEADER pSec; + PBYTE _ImageBase = _GetPEImageBase (); + + if (was_here || !_ImageBase) + return was_here; + was_here = 1; + if (_FindPESectionByName (".pdata") != NULL) + return 1; + + /* Allocate # of e tables and entries. */ + memset (emu_pdata, 0, sizeof (RUNTIME_FUNCTION) * MAX_PDATA_ENTRIES); + memset (emu_xdata, 0, sizeof (UNWIND_INFO) * MAX_PDATA_ENTRIES); + + e = 0; + /* Fill tables and entries. */ + while (e < MAX_PDATA_ENTRIES && (pSec = _FindPESectionExec (e)) != NULL) + { + emu_xdata[e].VersionAndFlags = 9; /* UNW_FLAG_EHANDLER | UNW_VERSION */ + emu_xdata[e].AddressOfExceptionHandler = + (DWORD)(size_t) ((LPBYTE)__mingw_SEH_error_handler - _ImageBase); + emu_pdata[e].BeginAddress = pSec->VirtualAddress; + emu_pdata[e].EndAddress = pSec->VirtualAddress + pSec->Misc.VirtualSize; + emu_pdata[e].UnwindData = + (DWORD)(size_t)((LPBYTE)&emu_xdata[e] - _ImageBase); + ++e; + } +#ifdef _DEBUG_CRT + if (!e || e > MAX_PDATA_ENTRIES) + abort (); +#endif + /* RtlAddFunctionTable. */ + if (e != 0) + RtlAddFunctionTable (emu_pdata, e, (DWORD64)_ImageBase); + return 1; +} + +extern void _fpreset (void); + +EXCEPTION_DISPOSITION +__mingw_SEH_error_handler (struct _EXCEPTION_RECORD* ExceptionRecord, + void *EstablisherFrame __attribute__ ((unused)), + struct _CONTEXT* ContextRecord __attribute__ ((unused)), + void *DispatcherContext __attribute__ ((unused))) +{ + EXCEPTION_DISPOSITION action = ExceptionContinueSearch; /* EXCEPTION_CONTINUE_SEARCH; */ + void (*old_handler) (int); + int reset_fpu = 0; + + switch (ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + /* test if the user has set SIGSEGV */ + old_handler = signal (SIGSEGV, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGSEGV, SIG_IGN); + action = 0; //EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGSEGV); + action = 0; // EXCEPTION_CONTINUE_EXECUTION; + } + else + action = 4; /* EXCEPTION_EXECUTE_HANDLER; */ + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + /* test if the user has set SIGILL */ + old_handler = signal (SIGILL, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGILL, SIG_IGN); + action = 0; // EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGILL); + action = 0; // EXCEPTION_CONTINUE_EXECUTION; + } + else + action = 4; /* EXCEPTION_EXECUTE_HANDLER;*/ + break; + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_FLT_INEXACT_RESULT: + reset_fpu = 1; + /* fall through. */ + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* test if the user has set SIGFPE */ + old_handler = signal (SIGFPE, SIG_DFL); + if (old_handler == SIG_IGN) + { + signal (SIGFPE, SIG_IGN); + if (reset_fpu) + _fpreset (); + action = 0; // EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGFPE); + action = 0; // EXCEPTION_CONTINUE_EXECUTION; + } + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_INT_OVERFLOW: + case EXCEPTION_INVALID_HANDLE: + /*case EXCEPTION_POSSIBLE_DEADLOCK: */ + action = 0; // EXCEPTION_CONTINUE_EXECUTION; + break; + default: + break; + } + return action; +} + +#endif + +LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler = NULL; + +long CALLBACK +_gnu_exception_handler (EXCEPTION_POINTERS *exception_data); + +#define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C' | (1U << 29)) + +long CALLBACK +_gnu_exception_handler (EXCEPTION_POINTERS *exception_data) +{ + void (*old_handler) (int); + long action = EXCEPTION_CONTINUE_SEARCH; + int reset_fpu = 0; + +#ifdef __SEH__ + if ((exception_data->ExceptionRecord->ExceptionCode & 0x20ffffff) == GCC_MAGIC) + { + if ((exception_data->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == 0) + return EXCEPTION_CONTINUE_EXECUTION; + } +#endif + + switch (exception_data->ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + /* test if the user has set SIGSEGV */ + old_handler = signal (SIGSEGV, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGSEGV, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGSEGV); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + /* test if the user has set SIGILL */ + old_handler = signal (SIGILL, SIG_DFL); + if (old_handler == SIG_IGN) + { + /* this is undefined if the signal was raised by anything other + than raise (). */ + signal (SIGILL, SIG_IGN); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGILL); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_FLT_INEXACT_RESULT: + reset_fpu = 1; + /* fall through. */ + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* test if the user has set SIGFPE */ + old_handler = signal (SIGFPE, SIG_DFL); + if (old_handler == SIG_IGN) + { + signal (SIGFPE, SIG_IGN); + if (reset_fpu) + _fpreset (); + action = EXCEPTION_CONTINUE_EXECUTION; + } + else if (old_handler != SIG_DFL) + { + /* This means 'old' is a user defined function. Call it */ + (*old_handler) (SIGFPE); + action = EXCEPTION_CONTINUE_EXECUTION; + } + break; +#ifdef _WIN64 + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_INT_OVERFLOW: + case EXCEPTION_INVALID_HANDLE: + /*case EXCEPTION_POSSIBLE_DEADLOCK: */ + action = EXCEPTION_CONTINUE_EXECUTION; + break; +#endif + default: + break; + } + + if (action == EXCEPTION_CONTINUE_SEARCH && __mingw_oldexcpt_handler) + action = (*__mingw_oldexcpt_handler)(exception_data); + return action; +}
Propchange: trunk/reactos/lib/sdk/crt/startup/crt_handler.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/lib/sdk/crt/startup/crtexe.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/crtexe.... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/crtexe.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/startup/crtexe.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -20,7 +20,6 @@ #include <tchar.h> #include <sect_attribs.h> #include <locale.h> -#include <intrin.h>
#ifndef __winitenv extern wchar_t *** __MINGW_IMP_SYMBOL(__winitenv); @@ -44,11 +43,11 @@ #define SPACECHAR _T(' ') #define DQUOTECHAR _T('"')
-__declspec(dllimport) void __setusermatherr(int (__cdecl *)(struct _exception *)); - extern int * __MINGW_IMP_SYMBOL(_fmode); extern int * __MINGW_IMP_SYMBOL(_commode);
+#undef _fmode +extern int _fmode; extern int * __MINGW_IMP_SYMBOL(_commode); #define _commode (* __MINGW_IMP_SYMBOL(_commode)) extern int _dowildcard; @@ -56,7 +55,7 @@ #if defined(__GNUC__) int _MINGW_INSTALL_DEBUG_MATHERR __attribute__((weak)) = 0; #else -int __declspec(selectany) _MINGW_INSTALL_DEBUG_MATHERR = 0; +int _MINGW_INSTALL_DEBUG_MATHERR = 0; #endif extern int __defaultmatherr; extern _CRTIMP void __cdecl _initterm(_PVFV *, _PVFV *); @@ -81,8 +80,8 @@ DWORD __mingw_winmain_nShowCmd;
static int argc; -#ifdef WPRFLAG extern void __main(void); +#ifdef WPRFLAG static wchar_t **argv; static wchar_t **envp; #else @@ -95,10 +94,10 @@ static int managedapp; static int has_cctor = 0; static _startupinfo startinfo; -static LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler = NULL; +extern LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler;
extern void _pei386_runtime_relocator (void); -static long CALLBACK _gnu_exception_handler (EXCEPTION_POINTERS * exception_data); +long CALLBACK _gnu_exception_handler (EXCEPTION_POINTERS * exception_data); #ifdef WPRFLAG static void duplicate_ppstrings (int ac, wchar_t ***av); #else @@ -108,8 +107,10 @@ static int __cdecl pre_c_init (void); static void __cdecl pre_cpp_init (void); static void __cdecl __mingw_prepare_except_for_msvcr80_and_higher (void); -_CRTALLOC(".CRT$XIAA") _PIFV __declspec(selectany) mingw_pcinit = pre_c_init; -_CRTALLOC(".CRT$XCAA") _PVFV __declspec(selectany) mingw_pcppinit = pre_cpp_init; +_CRTALLOC(".CRT$XIAA") _PIFV mingw_pcinit = pre_c_init; +_CRTALLOC(".CRT$XCAA") _PVFV mingw_pcppinit = pre_cpp_init; + +extern int _MINGW_INSTALL_DEBUG_MATHERR;
static int __cdecl pre_c_init (void) @@ -131,11 +132,7 @@ #endif if (_MINGW_INSTALL_DEBUG_MATHERR) { - if (! __defaultmatherr) - { - __setusermatherr (_matherr); - __defaultmatherr = 1; - } + __setusermatherr (_matherr); }
if (__globallocalestatus == -1) @@ -162,9 +159,24 @@
int WinMainCRTStartup (void) { + int ret = 255; +#ifdef __SEH__ + asm ("\t.l_startw:\n" + "\t.seh_handler __C_specific_handler, @except\n" + "\t.seh_handlerdata\n" + "\t.long 1\n" + "\t.rva .l_startw, .l_endw, _gnu_exception_handler ,.l_endw\n" + "\t.text" + ); +#endif mingw_app_type = 1; __security_init_cookie (); - return __tmainCRTStartup (); + ret = __tmainCRTStartup (); +#ifdef __SEH__ + asm ("\tnop\n" + "\t.l_endw: nop\n"); +#endif + return ret; }
int mainCRTStartup (void); @@ -175,9 +187,24 @@
int mainCRTStartup (void) { + int ret = 255; +#ifdef __SEH__ + asm ("\t.l_start:\n" + "\t.seh_handler __C_specific_handler, @except\n" + "\t.seh_handlerdata\n" + "\t.long 1\n" + "\t.rva .l_start, .l_end, _gnu_exception_handler ,.l_end\n" + "\t.text" + ); +#endif mingw_app_type = 0; __security_init_cookie (); - return __tmainCRTStartup (); + ret = __tmainCRTStartup (); +#ifdef __SEH__ + asm ("\tnop\n" + "\t.l_end: nop\n"); +#endif + return ret; }
static @@ -188,7 +215,16 @@ STARTUPINFO StartupInfo; WINBOOL inDoubleQuote = FALSE; memset (&StartupInfo, 0, sizeof (STARTUPINFO)); - + +#ifndef _WIN64 + /* We need to make sure that this function is build with frame-pointer + and that we align the stack to 16 bytes for the sake of SSE ops in main + or in functions inlined into main. */ + lpszCommandLine = (_TCHAR *) alloca (32); + memset (lpszCommandLine, 0xcc, 32); + asm __volatile__ ("andl $-16, %%esp" : : : "%esp"); +#endif + if (mingw_app_type) GetStartupInfo (&StartupInfo); { @@ -267,11 +303,11 @@ StartupInfo.wShowWindow : SW_SHOWDEFAULT; } duplicate_ppstrings (argc, &argv); + __main (); #ifdef WPRFLAG __winitenv = envp; /* C++ initialization. gcc inserts this call automatically for a function called main, but not for wmain. */ - __main (); mainret = wmain (argc, argv, envp); #else __initenv = envp; @@ -329,97 +365,6 @@ return 0; }
-static long CALLBACK -_gnu_exception_handler (EXCEPTION_POINTERS *exception_data) -{ - void (*old_handler) (int); - long action = EXCEPTION_CONTINUE_SEARCH; - int reset_fpu = 0; - - switch (exception_data->ExceptionRecord->ExceptionCode) - { - case EXCEPTION_ACCESS_VIOLATION: - /* test if the user has set SIGSEGV */ - old_handler = signal (SIGSEGV, SIG_DFL); - if (old_handler == SIG_IGN) - { - /* this is undefined if the signal was raised by anything other - than raise (). */ - signal (SIGSEGV, SIG_IGN); - action = EXCEPTION_CONTINUE_EXECUTION; - } - else if (old_handler != SIG_DFL) - { - /* This means 'old' is a user defined function. Call it */ - (*old_handler) (SIGSEGV); - action = EXCEPTION_CONTINUE_EXECUTION; - } - break; - - case EXCEPTION_ILLEGAL_INSTRUCTION: - case EXCEPTION_PRIV_INSTRUCTION: - /* test if the user has set SIGILL */ - old_handler = signal (SIGILL, SIG_DFL); - if (old_handler == SIG_IGN) - { - /* this is undefined if the signal was raised by anything other - than raise (). */ - signal (SIGILL, SIG_IGN); - action = EXCEPTION_CONTINUE_EXECUTION; - } - else if (old_handler != SIG_DFL) - { - /* This means 'old' is a user defined function. Call it */ - (*old_handler) (SIGILL); - action = EXCEPTION_CONTINUE_EXECUTION; - } - break; - - case EXCEPTION_FLT_INVALID_OPERATION: - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - case EXCEPTION_FLT_DENORMAL_OPERAND: - case EXCEPTION_FLT_OVERFLOW: - case EXCEPTION_FLT_UNDERFLOW: - case EXCEPTION_FLT_INEXACT_RESULT: - reset_fpu = 1; - /* fall through. */ - - case EXCEPTION_INT_DIVIDE_BY_ZERO: - /* test if the user has set SIGFPE */ - old_handler = signal (SIGFPE, SIG_DFL); - if (old_handler == SIG_IGN) - { - signal (SIGFPE, SIG_IGN); - if (reset_fpu) - _fpreset (); - action = EXCEPTION_CONTINUE_EXECUTION; - } - else if (old_handler != SIG_DFL) - { - /* This means 'old' is a user defined function. Call it */ - (*old_handler) (SIGFPE); - action = EXCEPTION_CONTINUE_EXECUTION; - } - break; -#ifdef _WIN64 - case EXCEPTION_DATATYPE_MISALIGNMENT: - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - case EXCEPTION_FLT_STACK_CHECK: - case EXCEPTION_INT_OVERFLOW: - case EXCEPTION_INVALID_HANDLE: - /*case EXCEPTION_POSSIBLE_DEADLOCK: */ - action = EXCEPTION_CONTINUE_EXECUTION; - break; -#endif - default: - break; - } - - if (action == EXCEPTION_CONTINUE_SEARCH && __mingw_oldexcpt_handler) - action = (*__mingw_oldexcpt_handler)(exception_data); - return action; -} - #ifdef WPRFLAG static size_t wbytelen(const wchar_t *p) {
Modified: trunk/reactos/lib/sdk/crt/startup/gccmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/gccmain... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/gccmain.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/startup/gccmain.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -11,13 +11,6 @@ typedef void (*func_ptr) (void); extern func_ptr __CTOR_LIST__[]; extern func_ptr __DTOR_LIST__[]; - -static HMODULE hMsvcrt = NULL; -static int free_Msvcrt = 0; - -typedef void __cdecl flongjmp(jmp_buf _Buf,int _Value); - -flongjmp *fctMsvcrtLongJmp = NULL;
void __do_global_dtors (void); void __do_global_ctors (void); @@ -33,12 +26,6 @@ (*(p)) (); p++; } - if (free_Msvcrt && hMsvcrt) - { - free_Msvcrt = 0; - FreeLibrary (hMsvcrt); - hMsvcrt = NULL; - } }
void @@ -46,19 +33,6 @@ { unsigned long nptrs = (unsigned long) (ptrdiff_t) __CTOR_LIST__[0]; unsigned long i; - - if (!hMsvcrt) { - hMsvcrt = GetModuleHandleA ("msvcr80.dll"); - if (!hMsvcrt) - hMsvcrt = GetModuleHandleA ("msvcr70.dll"); - if (!hMsvcrt) - hMsvcrt = GetModuleHandleA ("msvcrt.dll"); - if (!hMsvcrt) { - hMsvcrt = LoadLibraryA ("msvcrt.dll"); - free_Msvcrt = 1; - } - fctMsvcrtLongJmp = (flongjmp *) GetProcAddress( hMsvcrt, "longjmp"); - }
if (nptrs == (unsigned long) -1) {
Modified: trunk/reactos/lib/sdk/crt/startup/gs_support.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/gs_supp... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/gs_support.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/startup/gs_support.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -23,11 +23,6 @@ #endif
/* Externals. */ -#ifdef _WIN64 -PRUNTIME_FUNCTION RtlLookupFunctionEntry (ULONG64, PULONG64, PVOID); -PVOID RtlVirtualUnwind (ULONG HandlerType, ULONG64, ULONG64, PRUNTIME_FUNCTION, - PCONTEXT, PVOID *, PULONG64, PVOID); -#endif
typedef LONG NTSTATUS; /* same as in ntdef.h / winternl.h */
Modified: trunk/reactos/lib/sdk/crt/startup/merr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/merr.c?... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/merr.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/startup/merr.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -9,6 +9,31 @@ #include <stdio.h>
int __defaultmatherr = 0; + +typedef int (__cdecl *fUserMathErr)(struct _exception *); +static fUserMathErr stUserMathErr; + +void __mingw_raise_matherr (int typ, const char *name, double a1, double a2, + double rslt) +{ + struct _exception ex; + if (!stUserMathErr) + return; + ex.type = typ; + ex.name = name; + ex.arg1 = a1; + ex.arg2 = a2; + ex.retval = rslt; + (*stUserMathErr)(&ex); +} + +#undef __setusermatherr + +void __mingw_setusermatherr (int (__cdecl *f)(struct _exception *)) +{ + stUserMathErr = f; + __setusermatherr (f); +}
int __CRTDECL _matherr (struct _exception *pexcept) @@ -50,3 +75,4 @@ type, pexcept->name, pexcept->arg1, pexcept->arg2, pexcept->retval); return 0; } +
Added: trunk/reactos/lib/sdk/crt/startup/pesect.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/pesect.... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/pesect.c (added) +++ trunk/reactos/lib/sdk/crt/startup/pesect.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -1,0 +1,186 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <windows.h> +#include <string.h> + +#if defined (_WIN64) && defined (__ia64__) +#error FIXME: Unsupported __ImageBase implementation. +#else +/* Hack, for bug in ld. Will be removed soon. */ +#ifndef _MSC_VER +#define __ImageBase __MINGW_LSYMBOL(_image_base__) +#endif +/* This symbol is defined by the linker. */ +extern IMAGE_DOS_HEADER __ImageBase; +#endif + +WINBOOL _ValidateImageBase (PBYTE); + +WINBOOL +_ValidateImageBase (PBYTE pImageBase) +{ + PIMAGE_DOS_HEADER pDOSHeader; + PIMAGE_NT_HEADERS pNTHeader; + PIMAGE_OPTIONAL_HEADER pOptHeader; + + pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase; + if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) + return FALSE; + pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew); + if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) + return FALSE; + pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader; + if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) + return FALSE; + return TRUE; +} + +PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR); + +PIMAGE_SECTION_HEADER +_FindPESection (PBYTE pImageBase, DWORD_PTR rva) +{ + PIMAGE_NT_HEADERS pNTHeader; + PIMAGE_SECTION_HEADER pSection; + unsigned int iSection; + + pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); + + for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); + iSection < pNTHeader->FileHeader.NumberOfSections; + ++iSection,++pSection) + { + if (rva >= pSection->VirtualAddress + && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize) + return pSection; + } + return NULL; +} + +PIMAGE_SECTION_HEADER _FindPESectionByName (const char *); + +PIMAGE_SECTION_HEADER +_FindPESectionByName (const char *pName) +{ + PBYTE pImageBase; + PIMAGE_NT_HEADERS pNTHeader; + PIMAGE_SECTION_HEADER pSection; + unsigned int iSection; + + /* Long names aren't supported. */ + if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME) + return NULL; + + pImageBase = (PBYTE) &__ImageBase; + if (! _ValidateImageBase (pImageBase)) + return NULL; + + pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); + + for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); + iSection < pNTHeader->FileHeader.NumberOfSections; + ++iSection,++pSection) + { + if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME)) + return pSection; + } + return NULL; +} + +int __mingw_GetSectionCount (void); +PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p); + +PIMAGE_SECTION_HEADER +__mingw_GetSectionForAddress (LPVOID p) +{ + PBYTE pImageBase; + DWORD_PTR rva; + + pImageBase = (PBYTE) &__ImageBase; + if (! _ValidateImageBase (pImageBase)) + return NULL; + + rva = (DWORD_PTR) (((PBYTE) p) - pImageBase); + return _FindPESection (pImageBase, rva); +} + +int +__mingw_GetSectionCount (void) +{ + PBYTE pImageBase; + PIMAGE_NT_HEADERS pNTHeader; + + pImageBase = (PBYTE) &__ImageBase; + if (! _ValidateImageBase (pImageBase)) + return 0; + + pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); + + return (int) pNTHeader->FileHeader.NumberOfSections; +} + + +PIMAGE_SECTION_HEADER _FindPESectionExec (size_t); + +PIMAGE_SECTION_HEADER +_FindPESectionExec (size_t eNo) +{ + PBYTE pImageBase; + PIMAGE_NT_HEADERS pNTHeader; + PIMAGE_SECTION_HEADER pSection; + unsigned int iSection; + + pImageBase = (PBYTE) &__ImageBase; + if (! _ValidateImageBase (pImageBase)) + return NULL; + + pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); + + for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); + iSection < pNTHeader->FileHeader.NumberOfSections; + ++iSection,++pSection) + { + if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0) + { + if (!eNo) + return pSection; + --eNo; + } + } + return NULL; +} + +PBYTE _GetPEImageBase (void); + +PBYTE +_GetPEImageBase (void) +{ + PBYTE pImageBase; + pImageBase = (PBYTE) &__ImageBase; + if (! _ValidateImageBase (pImageBase)) + return NULL; + return pImageBase; +} + +WINBOOL _IsNonwritableInCurrentImage (PBYTE); + +WINBOOL +_IsNonwritableInCurrentImage (PBYTE pTarget) +{ + PBYTE pImageBase; + DWORD_PTR rvaTarget; + PIMAGE_SECTION_HEADER pSection; + + pImageBase = (PBYTE) &__ImageBase; + if (! _ValidateImageBase (pImageBase)) + return FALSE; + rvaTarget = pTarget - pImageBase; + pSection = _FindPESection (pImageBase, rvaTarget); + if (pSection == NULL) + return FALSE; + return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0; +}
Propchange: trunk/reactos/lib/sdk/crt/startup/pesect.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/lib/sdk/crt/startup/pseudo-reloc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/pseudo-... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/pseudo-reloc.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/startup/pseudo-reloc.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -158,6 +158,87 @@ #endif }
+/* For mingw-w64 we have additional helpers to get image information + on runtime. This allows us to cache for pseudo-relocation pass + the temporary access of code/read-only sections. + This step speeds up pseudo-relocation pass. */ +#ifdef __MINGW64_VERSION_MAJOR +extern int __mingw_GetSectionCount (void); +extern PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p); +extern PBYTE _GetPEImageBase (void); + +typedef struct sSecInfo { + /* Keeps altered section flags, or zero if nothing was changed. */ + DWORD old_protect; + PBYTE sec_start; + PIMAGE_SECTION_HEADER hash; +} sSecInfo; + +static sSecInfo *the_secs = NULL; +static int maxSections = 0; + +static void +mark_section_writable (LPVOID addr) +{ + MEMORY_BASIC_INFORMATION b; + PIMAGE_SECTION_HEADER h; + int i; + + for (i = 0; i < maxSections; i++) + { + if (the_secs[i].sec_start <= ((LPBYTE) addr) + && ((LPBYTE) addr) < (the_secs[i].sec_start + the_secs[i].hash->Misc.VirtualSize)) + return; + } + h = __mingw_GetSectionForAddress (addr); + if (!h) + { + __report_error ("Address %p has no image-section", addr); + return; + } + the_secs[i].hash = h; + the_secs[i].old_protect = 0; + the_secs[i].sec_start = _GetPEImageBase () + h->VirtualAddress; + + if (!VirtualQuery (the_secs[i].sec_start, &b, sizeof(b))) + { + __report_error (" VirtualQuery failed for %d bytes at address %p", + (int) h->Misc.VirtualSize, the_secs[i].sec_start); + return; + } + + if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE) + VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE, + &the_secs[i].old_protect); + ++maxSections; + return; +} + +static void +restore_modified_sections (void) +{ + int i; + MEMORY_BASIC_INFORMATION b; + DWORD oldprot; + + for (i = 0; i < maxSections; i++) + { + if (the_secs[i].old_protect == 0) + continue; + if (!VirtualQuery (the_secs[i].sec_start, &b, sizeof(b))) + { + __report_error (" VirtualQuery failed for %d bytes at address %p", + (int) the_secs[i].hash->Misc.VirtualSize, + the_secs[i].sec_start); + return; + } + VirtualProtect (b.BaseAddress, b.RegionSize, the_secs[i].old_protect, + &oldprot); + } +} + +#endif /* __MINGW64_VERSION_MAJOR */ + /* This function temporarily marks the page containing addr * writable, before copying len bytes from *src to *addr, and * then restores the original protection settings to the page. @@ -174,12 +255,15 @@ static void __write_memory (void *addr, const void *src, size_t len) { +#ifndef __MINGW64_VERSION_MAJOR MEMORY_BASIC_INFORMATION b; DWORD oldprot; +#endif /* ! __MINGW64_VERSION_MAJOR */
if (!len) return;
+#ifndef __MINGW64_VERSION_MAJOR if (!VirtualQuery (addr, &b, sizeof(b))) { __report_error (" VirtualQuery failed for %d bytes at address %p", @@ -189,12 +273,18 @@ /* Temporarily allow write access to read-only protected memory. */ if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE) VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE, - &oldprot); + &oldprot); +#else /* ! __MINGW64_VERSION_MAJOR */ + mark_section_writable ((LPVOID) addr); +#endif /* __MINGW64_VERSION_MAJOR */ + /* write the data. */ memcpy (addr, src, len); /* Restore original protection. */ +#ifndef __MINGW64_VERSION_MAJOR if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE) VirtualProtect (b.BaseAddress, b.RegionSize, oldprot, &oldprot); +#endif /* !__MINGW64_VERSION_MAJOR */ }
#define RP_VERSION_V1 0 @@ -361,10 +451,23 @@ _pei386_runtime_relocator (void) { static NO_COPY int was_init = 0; +#ifdef __MINGW64_VERSION_MAJOR + int mSecs; +#endif /* __MINGW64_VERSION_MAJOR */ + if (was_init) return; ++was_init; +#ifdef __MINGW64_VERSION_MAJOR + mSecs = __mingw_GetSectionCount (); + the_secs = (sSecInfo *) alloca (sizeof (sSecInfo) * (size_t) mSecs); + maxSections = 0; +#endif /* __MINGW64_VERSION_MAJOR */ + do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__, &__RUNTIME_PSEUDO_RELOC_LIST_END__, - &__ImageBase); -} + &__MINGW_LSYMBOL(_image_base__)); +#ifdef __MINGW64_VERSION_MAJOR + restore_modified_sections (); +#endif /* __MINGW64_VERSION_MAJOR */ +}
Modified: trunk/reactos/lib/sdk/crt/startup/tlssup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/startup/tlssup.... ============================================================================== --- trunk/reactos/lib/sdk/crt/startup/tlssup.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/startup/tlssup.c [iso-8859-1] Mon Jun 6 10:01:14 2011 @@ -50,18 +50,11 @@ _CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0; _CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
-#ifdef _WIN64 -_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY64 _tls_used = { - (ULONGLONG) &_tls_start+1, (ULONGLONG) &_tls_end, (ULONGLONG) &_tls_index, - (ULONGLONG) (&__xl_a+1), (ULONG) 0, (ULONG) 0 -}; -#else _CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY _tls_used = { - (ULONG)(ULONG_PTR) &_tls_start+1, (ULONG)(ULONG_PTR) &_tls_end, - (ULONG)(ULONG_PTR) &_tls_index, (ULONG)(ULONG_PTR) (&__xl_a+1), + (ULONG_PTR) &_tls_start+1, (ULONG_PTR) &_tls_end, + (ULONG_PTR) &_tls_index, (ULONG_PTR) (&__xl_a+1), (ULONG) 0, (ULONG) 0 }; -#endif
#ifndef __CRT_THREAD #ifdef HAVE_ATTRIBUTE_THREAD @@ -99,6 +92,7 @@ __dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { _PVFV *pfunc; + uintptr_t ps;
#ifndef _WIN64 if (_winmajor < 4) @@ -135,8 +129,11 @@ return TRUE; }
- for (pfunc = &__xd_a + 1; pfunc != &__xd_z; ++pfunc) - { + ps = (uintptr_t) &__xd_a; + ps += sizeof (uintptr_t); + for ( ; ps != (uintptr_t) &__xd_z; ps += sizeof (uintptr_t)) + { + pfunc = (_PVFV *) ps; if (*pfunc != NULL) (*pfunc)(); }