mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 07:33:20 +00:00
[CRT/STARTUP]
* Sync startup code to recent mingw-w64. RosBE 2.0 here we come ! svn path=/trunk/; revision=52111
This commit is contained in:
parent
e54b5f0d2e
commit
864fd70bcc
10 changed files with 672 additions and 153 deletions
|
@ -8,6 +8,7 @@ endif()
|
||||||
list(APPEND MSVCRTEX_SOURCE
|
list(APPEND MSVCRTEX_SOURCE
|
||||||
startup/crtexe.c
|
startup/crtexe.c
|
||||||
startup/wcrtexe.c
|
startup/wcrtexe.c
|
||||||
|
startup/crt_handler.c
|
||||||
startup/crtdll.c
|
startup/crtdll.c
|
||||||
startup/_newmode.c
|
startup/_newmode.c
|
||||||
startup/wildcard.c
|
startup/wildcard.c
|
||||||
|
@ -18,6 +19,7 @@ list(APPEND MSVCRTEX_SOURCE
|
||||||
startup/merr.c
|
startup/merr.c
|
||||||
startup/atonexit.c
|
startup/atonexit.c
|
||||||
startup/txtmode.c
|
startup/txtmode.c
|
||||||
|
startup/pesect.c
|
||||||
startup/pseudo-reloc.c
|
startup/pseudo-reloc.c
|
||||||
startup/pseudo-reloc-list.c
|
startup/pseudo-reloc-list.c
|
||||||
startup/tlsmcrt.c
|
startup/tlsmcrt.c
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <internal.h>
|
|
||||||
#include <sect_attribs.h>
|
#include <sect_attribs.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma comment(linker, "/merge:.CRT=.rdata")
|
#pragma comment(linker, "/merge:.CRT=.rdata")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef void (__cdecl *_PVFV)(void);
|
||||||
|
|
||||||
_CRTALLOC(".CRT$XIA") _PVFV __xi_a[] = { NULL };
|
_CRTALLOC(".CRT$XIA") _PVFV __xi_a[] = { NULL };
|
||||||
_CRTALLOC(".CRT$XIZ") _PVFV __xi_z[] = { NULL };
|
_CRTALLOC(".CRT$XIZ") _PVFV __xi_z[] = { NULL };
|
||||||
_CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { NULL };
|
_CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { NULL };
|
||||||
|
|
290
reactos/lib/sdk/crt/startup/crt_handler.c
Normal file
290
reactos/lib/sdk/crt/startup/crt_handler.c
Normal file
|
@ -0,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;
|
||||||
|
}
|
|
@ -20,7 +20,6 @@
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <sect_attribs.h>
|
#include <sect_attribs.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <intrin.h>
|
|
||||||
|
|
||||||
#ifndef __winitenv
|
#ifndef __winitenv
|
||||||
extern wchar_t *** __MINGW_IMP_SYMBOL(__winitenv);
|
extern wchar_t *** __MINGW_IMP_SYMBOL(__winitenv);
|
||||||
|
@ -44,11 +43,11 @@ extern void _fpreset (void);
|
||||||
#define SPACECHAR _T(' ')
|
#define SPACECHAR _T(' ')
|
||||||
#define DQUOTECHAR _T('\"')
|
#define DQUOTECHAR _T('\"')
|
||||||
|
|
||||||
__declspec(dllimport) void __setusermatherr(int (__cdecl *)(struct _exception *));
|
|
||||||
|
|
||||||
extern int * __MINGW_IMP_SYMBOL(_fmode);
|
extern int * __MINGW_IMP_SYMBOL(_fmode);
|
||||||
extern int * __MINGW_IMP_SYMBOL(_commode);
|
extern int * __MINGW_IMP_SYMBOL(_commode);
|
||||||
|
|
||||||
|
#undef _fmode
|
||||||
|
extern int _fmode;
|
||||||
extern int * __MINGW_IMP_SYMBOL(_commode);
|
extern int * __MINGW_IMP_SYMBOL(_commode);
|
||||||
#define _commode (* __MINGW_IMP_SYMBOL(_commode))
|
#define _commode (* __MINGW_IMP_SYMBOL(_commode))
|
||||||
extern int _dowildcard;
|
extern int _dowildcard;
|
||||||
|
@ -56,7 +55,7 @@ extern int _dowildcard;
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
int _MINGW_INSTALL_DEBUG_MATHERR __attribute__((weak)) = 0;
|
int _MINGW_INSTALL_DEBUG_MATHERR __attribute__((weak)) = 0;
|
||||||
#else
|
#else
|
||||||
int __declspec(selectany) _MINGW_INSTALL_DEBUG_MATHERR = 0;
|
int _MINGW_INSTALL_DEBUG_MATHERR = 0;
|
||||||
#endif
|
#endif
|
||||||
extern int __defaultmatherr;
|
extern int __defaultmatherr;
|
||||||
extern _CRTIMP void __cdecl _initterm(_PVFV *, _PVFV *);
|
extern _CRTIMP void __cdecl _initterm(_PVFV *, _PVFV *);
|
||||||
|
@ -81,8 +80,8 @@ _TCHAR *__mingw_winmain_lpCmdLine;
|
||||||
DWORD __mingw_winmain_nShowCmd;
|
DWORD __mingw_winmain_nShowCmd;
|
||||||
|
|
||||||
static int argc;
|
static int argc;
|
||||||
#ifdef WPRFLAG
|
|
||||||
extern void __main(void);
|
extern void __main(void);
|
||||||
|
#ifdef WPRFLAG
|
||||||
static wchar_t **argv;
|
static wchar_t **argv;
|
||||||
static wchar_t **envp;
|
static wchar_t **envp;
|
||||||
#else
|
#else
|
||||||
|
@ -95,10 +94,10 @@ static int mainret=0;
|
||||||
static int managedapp;
|
static int managedapp;
|
||||||
static int has_cctor = 0;
|
static int has_cctor = 0;
|
||||||
static _startupinfo startinfo;
|
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);
|
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
|
#ifdef WPRFLAG
|
||||||
static void duplicate_ppstrings (int ac, wchar_t ***av);
|
static void duplicate_ppstrings (int ac, wchar_t ***av);
|
||||||
#else
|
#else
|
||||||
|
@ -108,8 +107,10 @@ static void duplicate_ppstrings (int ac, char ***av);
|
||||||
static int __cdecl pre_c_init (void);
|
static int __cdecl pre_c_init (void);
|
||||||
static void __cdecl pre_cpp_init (void);
|
static void __cdecl pre_cpp_init (void);
|
||||||
static void __cdecl __mingw_prepare_except_for_msvcr80_and_higher (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$XIAA") _PIFV mingw_pcinit = pre_c_init;
|
||||||
_CRTALLOC(".CRT$XCAA") _PVFV __declspec(selectany) mingw_pcppinit = pre_cpp_init;
|
_CRTALLOC(".CRT$XCAA") _PVFV mingw_pcppinit = pre_cpp_init;
|
||||||
|
|
||||||
|
extern int _MINGW_INSTALL_DEBUG_MATHERR;
|
||||||
|
|
||||||
static int __cdecl
|
static int __cdecl
|
||||||
pre_c_init (void)
|
pre_c_init (void)
|
||||||
|
@ -130,12 +131,8 @@ pre_c_init (void)
|
||||||
_setargv();
|
_setargv();
|
||||||
#endif
|
#endif
|
||||||
if (_MINGW_INSTALL_DEBUG_MATHERR)
|
if (_MINGW_INSTALL_DEBUG_MATHERR)
|
||||||
{
|
|
||||||
if (! __defaultmatherr)
|
|
||||||
{
|
{
|
||||||
__setusermatherr (_matherr);
|
__setusermatherr (_matherr);
|
||||||
__defaultmatherr = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__globallocalestatus == -1)
|
if (__globallocalestatus == -1)
|
||||||
|
@ -162,9 +159,24 @@ int WinMainCRTStartup (void);
|
||||||
|
|
||||||
int WinMainCRTStartup (void)
|
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;
|
mingw_app_type = 1;
|
||||||
__security_init_cookie ();
|
__security_init_cookie ();
|
||||||
return __tmainCRTStartup ();
|
ret = __tmainCRTStartup ();
|
||||||
|
#ifdef __SEH__
|
||||||
|
asm ("\tnop\n"
|
||||||
|
"\t.l_endw: nop\n");
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mainCRTStartup (void);
|
int mainCRTStartup (void);
|
||||||
|
@ -175,9 +187,24 @@ int __mingw_init_ehandler (void);
|
||||||
|
|
||||||
int mainCRTStartup (void)
|
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;
|
mingw_app_type = 0;
|
||||||
__security_init_cookie ();
|
__security_init_cookie ();
|
||||||
return __tmainCRTStartup ();
|
ret = __tmainCRTStartup ();
|
||||||
|
#ifdef __SEH__
|
||||||
|
asm ("\tnop\n"
|
||||||
|
"\t.l_end: nop\n");
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -189,6 +216,15 @@ __tmainCRTStartup (void)
|
||||||
WINBOOL inDoubleQuote = FALSE;
|
WINBOOL inDoubleQuote = FALSE;
|
||||||
memset (&StartupInfo, 0, sizeof (STARTUPINFO));
|
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)
|
if (mingw_app_type)
|
||||||
GetStartupInfo (&StartupInfo);
|
GetStartupInfo (&StartupInfo);
|
||||||
{
|
{
|
||||||
|
@ -267,11 +303,11 @@ __tmainCRTStartup (void)
|
||||||
StartupInfo.wShowWindow : SW_SHOWDEFAULT;
|
StartupInfo.wShowWindow : SW_SHOWDEFAULT;
|
||||||
}
|
}
|
||||||
duplicate_ppstrings (argc, &argv);
|
duplicate_ppstrings (argc, &argv);
|
||||||
|
__main ();
|
||||||
#ifdef WPRFLAG
|
#ifdef WPRFLAG
|
||||||
__winitenv = envp;
|
__winitenv = envp;
|
||||||
/* C++ initialization.
|
/* C++ initialization.
|
||||||
gcc inserts this call automatically for a function called main, but not for wmain. */
|
gcc inserts this call automatically for a function called main, but not for wmain. */
|
||||||
__main ();
|
|
||||||
mainret = wmain (argc, argv, envp);
|
mainret = wmain (argc, argv, envp);
|
||||||
#else
|
#else
|
||||||
__initenv = envp;
|
__initenv = envp;
|
||||||
|
@ -329,97 +365,6 @@ check_managed_app (void)
|
||||||
return 0;
|
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
|
#ifdef WPRFLAG
|
||||||
static size_t wbytelen(const wchar_t *p)
|
static size_t wbytelen(const wchar_t *p)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,13 +12,6 @@ typedef void (*func_ptr) (void);
|
||||||
extern func_ptr __CTOR_LIST__[];
|
extern func_ptr __CTOR_LIST__[];
|
||||||
extern func_ptr __DTOR_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_dtors (void);
|
||||||
void __do_global_ctors (void);
|
void __do_global_ctors (void);
|
||||||
void __main (void);
|
void __main (void);
|
||||||
|
@ -33,12 +26,6 @@ __do_global_dtors (void)
|
||||||
(*(p)) ();
|
(*(p)) ();
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
if (free_Msvcrt && hMsvcrt)
|
|
||||||
{
|
|
||||||
free_Msvcrt = 0;
|
|
||||||
FreeLibrary (hMsvcrt);
|
|
||||||
hMsvcrt = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -47,19 +34,6 @@ __do_global_ctors (void)
|
||||||
unsigned long nptrs = (unsigned long) (ptrdiff_t) __CTOR_LIST__[0];
|
unsigned long nptrs = (unsigned long) (ptrdiff_t) __CTOR_LIST__[0];
|
||||||
unsigned long i;
|
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)
|
if (nptrs == (unsigned long) -1)
|
||||||
{
|
{
|
||||||
for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++);
|
for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++);
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Externals. */
|
/* 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 */
|
typedef LONG NTSTATUS; /* same as in ntdef.h / winternl.h */
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,31 @@
|
||||||
|
|
||||||
int __defaultmatherr = 0;
|
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
|
int __CRTDECL
|
||||||
_matherr (struct _exception *pexcept)
|
_matherr (struct _exception *pexcept)
|
||||||
{
|
{
|
||||||
|
@ -50,3 +75,4 @@ _matherr (struct _exception *pexcept)
|
||||||
type, pexcept->name, pexcept->arg1, pexcept->arg2, pexcept->retval);
|
type, pexcept->name, pexcept->arg1, pexcept->arg2, pexcept->retval);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
186
reactos/lib/sdk/crt/startup/pesect.c
Normal file
186
reactos/lib/sdk/crt/startup/pesect.c
Normal file
|
@ -0,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;
|
||||||
|
}
|
|
@ -158,6 +158,87 @@ __report_error (const char *msg, ...)
|
||||||
#endif
|
#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
|
/* This function temporarily marks the page containing addr
|
||||||
* writable, before copying len bytes from *src to *addr, and
|
* writable, before copying len bytes from *src to *addr, and
|
||||||
* then restores the original protection settings to the page.
|
* then restores the original protection settings to the page.
|
||||||
|
@ -174,12 +255,15 @@ __report_error (const char *msg, ...)
|
||||||
static void
|
static void
|
||||||
__write_memory (void *addr, const void *src, size_t len)
|
__write_memory (void *addr, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
|
#ifndef __MINGW64_VERSION_MAJOR
|
||||||
MEMORY_BASIC_INFORMATION b;
|
MEMORY_BASIC_INFORMATION b;
|
||||||
DWORD oldprot;
|
DWORD oldprot;
|
||||||
|
#endif /* ! __MINGW64_VERSION_MAJOR */
|
||||||
|
|
||||||
if (!len)
|
if (!len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifndef __MINGW64_VERSION_MAJOR
|
||||||
if (!VirtualQuery (addr, &b, sizeof(b)))
|
if (!VirtualQuery (addr, &b, sizeof(b)))
|
||||||
{
|
{
|
||||||
__report_error (" VirtualQuery failed for %d bytes at address %p",
|
__report_error (" VirtualQuery failed for %d bytes at address %p",
|
||||||
|
@ -190,11 +274,17 @@ __write_memory (void *addr, const void *src, size_t len)
|
||||||
if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE)
|
if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE)
|
||||||
VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_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. */
|
/* write the data. */
|
||||||
memcpy (addr, src, len);
|
memcpy (addr, src, len);
|
||||||
/* Restore original protection. */
|
/* Restore original protection. */
|
||||||
|
#ifndef __MINGW64_VERSION_MAJOR
|
||||||
if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE)
|
if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE)
|
||||||
VirtualProtect (b.BaseAddress, b.RegionSize, oldprot, &oldprot);
|
VirtualProtect (b.BaseAddress, b.RegionSize, oldprot, &oldprot);
|
||||||
|
#endif /* !__MINGW64_VERSION_MAJOR */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RP_VERSION_V1 0
|
#define RP_VERSION_V1 0
|
||||||
|
@ -361,10 +451,23 @@ void
|
||||||
_pei386_runtime_relocator (void)
|
_pei386_runtime_relocator (void)
|
||||||
{
|
{
|
||||||
static NO_COPY int was_init = 0;
|
static NO_COPY int was_init = 0;
|
||||||
|
#ifdef __MINGW64_VERSION_MAJOR
|
||||||
|
int mSecs;
|
||||||
|
#endif /* __MINGW64_VERSION_MAJOR */
|
||||||
|
|
||||||
if (was_init)
|
if (was_init)
|
||||||
return;
|
return;
|
||||||
++was_init;
|
++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__,
|
do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
|
||||||
&__RUNTIME_PSEUDO_RELOC_LIST_END__,
|
&__RUNTIME_PSEUDO_RELOC_LIST_END__,
|
||||||
&__ImageBase);
|
&__MINGW_LSYMBOL(_image_base__));
|
||||||
|
#ifdef __MINGW64_VERSION_MAJOR
|
||||||
|
restore_modified_sections ();
|
||||||
|
#endif /* __MINGW64_VERSION_MAJOR */
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,18 +50,11 @@ _CRTALLOC(".tls$ZZZ") char _tls_end = 0;
|
||||||
_CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
|
_CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
|
||||||
_CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 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 = {
|
_CRTALLOC(".tls") const IMAGE_TLS_DIRECTORY _tls_used = {
|
||||||
(ULONG)(ULONG_PTR) &_tls_start+1, (ULONG)(ULONG_PTR) &_tls_end,
|
(ULONG_PTR) &_tls_start+1, (ULONG_PTR) &_tls_end,
|
||||||
(ULONG)(ULONG_PTR) &_tls_index, (ULONG)(ULONG_PTR) (&__xl_a+1),
|
(ULONG_PTR) &_tls_index, (ULONG_PTR) (&__xl_a+1),
|
||||||
(ULONG) 0, (ULONG) 0
|
(ULONG) 0, (ULONG) 0
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __CRT_THREAD
|
#ifndef __CRT_THREAD
|
||||||
#ifdef HAVE_ATTRIBUTE_THREAD
|
#ifdef HAVE_ATTRIBUTE_THREAD
|
||||||
|
@ -99,6 +92,7 @@ BOOL WINAPI
|
||||||
__dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
__dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
||||||
{
|
{
|
||||||
_PVFV *pfunc;
|
_PVFV *pfunc;
|
||||||
|
uintptr_t ps;
|
||||||
|
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
if (_winmajor < 4)
|
if (_winmajor < 4)
|
||||||
|
@ -135,8 +129,11 @@ __dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
|
||||||
return TRUE;
|
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)
|
if (*pfunc != NULL)
|
||||||
(*pfunc)();
|
(*pfunc)();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue