~mingw-w64/mingw-w64/experimental

« back to all changes in this revision

Viewing changes to ros-privexp/mingw-w64-crt/crt/crt_handler.c

  • Committer: NightStrike
  • Date: 2010-08-11 22:20:57 UTC
  • Revision ID: svn-v4:4407c894-4637-0410-b4f5-ada5f102cad1:experimental:3266
Branch for adding option for supporting ros

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * This file has no copyright assigned and is placed in the Public Domain.
 
3
 * This file is part of the w64 mingw-runtime package.
 
4
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 
5
 */
 
6
 
 
7
#include <windows.h>
 
8
#include <excpt.h>
 
9
#include <string.h>
 
10
#include <stdlib.h>
 
11
#include <malloc.h>
 
12
#include <memory.h>
 
13
#include <signal.h>
 
14
#include <stdio.h>
 
15
 
 
16
#if defined (_WIN64) && defined (__ia64__)
 
17
#error FIXME: Unsupported __ImageBase implementation.
 
18
#else
 
19
#define __ImageBase __MINGW_LSYMBOL(_image_base__)
 
20
/* This symbol is defined by the linker.  */
 
21
extern IMAGE_DOS_HEADER __ImageBase;
 
22
#endif
 
23
 
 
24
#pragma pack(push,1)
 
25
typedef struct _UNWIND_INFO {
 
26
  BYTE VersionAndFlags;
 
27
  BYTE PrologSize;
 
28
  BYTE CountOfUnwindCodes;
 
29
  BYTE FrameRegisterAndOffset;
 
30
  ULONG AddressOfExceptionHandler;
 
31
} UNWIND_INFO,*PUNWIND_INFO;
 
32
#pragma pack(pop)
 
33
 
 
34
PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
 
35
PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
 
36
PBYTE _GetPEImageBase (void);
 
37
 
 
38
int __mingw_init_ehandler (void);
 
39
 
 
40
#ifdef _WIN64
 
41
EXCEPTION_DISPOSITION __mingw_SEH_error_handler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
 
42
 
 
43
#define MAX_PDATA_ENTRIES 32
 
44
static RUNTIME_FUNCTION emu_pdata[MAX_PDATA_ENTRIES];
 
45
static UNWIND_INFO emu_xdata[MAX_PDATA_ENTRIES];
 
46
 
 
47
int
 
48
__mingw_init_ehandler (void)
 
49
{
 
50
  static int was_here = 0;
 
51
  size_t e = 0;
 
52
  PIMAGE_SECTION_HEADER pSec;
 
53
  PBYTE _ImageBase = _GetPEImageBase ();
 
54
  
 
55
  if (was_here || !_ImageBase)
 
56
    return was_here;
 
57
  was_here = 1;
 
58
  if (_FindPESectionByName (".pdata") != NULL)
 
59
    return 1;
 
60
 
 
61
  /* Allocate # of e tables and entries.  */
 
62
  memset (emu_pdata, 0, sizeof (RUNTIME_FUNCTION) * MAX_PDATA_ENTRIES);
 
63
  memset (emu_xdata, 0, sizeof (UNWIND_INFO) * MAX_PDATA_ENTRIES);
 
64
    
 
65
  e = 0;
 
66
  /* Fill tables and entries.  */
 
67
  while (e < MAX_PDATA_ENTRIES && (pSec = _FindPESectionExec (e)) != NULL)
 
68
    {
 
69
      emu_xdata[e].VersionAndFlags = 9; /* UNW_FLAG_EHANDLER | UNW_VERSION */
 
70
      emu_xdata[e].AddressOfExceptionHandler =
 
71
        (DWORD)(size_t) ((LPBYTE)__mingw_SEH_error_handler - _ImageBase);
 
72
      emu_pdata[e].BeginAddress = pSec->VirtualAddress;
 
73
      emu_pdata[e].EndAddress = pSec->VirtualAddress + pSec->Misc.VirtualSize;
 
74
      emu_pdata[e].UnwindData =
 
75
        (DWORD)(size_t)((LPBYTE)&emu_xdata[e] - _ImageBase);
 
76
      ++e;
 
77
    }
 
78
#ifdef _DEBUG_CRT
 
79
  if (!e || e > MAX_PDATA_ENTRIES)
 
80
    abort ();
 
81
#endif
 
82
  /* RtlAddFunctionTable.  */
 
83
  if (e != 0)
 
84
    RtlAddFunctionTable (emu_pdata, e, (DWORD64)_ImageBase);
 
85
  return 1;
 
86
}
 
87
 
 
88
extern void _fpreset (void);
 
89
 
 
90
EXCEPTION_DISPOSITION
 
91
__mingw_SEH_error_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
 
92
                           void *EstablisherFrame  __attribute__ ((unused)),
 
93
                           struct _CONTEXT* ContextRecord __attribute__ ((unused)),
 
94
                           void *DispatcherContext __attribute__ ((unused)))
 
95
{
 
96
  EXCEPTION_DISPOSITION action = EXCEPTION_CONTINUE_SEARCH;
 
97
  void (*old_handler) (int);
 
98
  int reset_fpu = 0;
 
99
 
 
100
  switch (ExceptionRecord->ExceptionCode)
 
101
    {
 
102
    case EXCEPTION_ACCESS_VIOLATION:
 
103
      /* test if the user has set SIGSEGV */
 
104
      old_handler = signal (SIGSEGV, SIG_DFL);
 
105
      if (old_handler == SIG_IGN)
 
106
        {
 
107
          /* this is undefined if the signal was raised by anything other
 
108
             than raise ().  */
 
109
          signal (SIGSEGV, SIG_IGN);
 
110
          action = EXCEPTION_CONTINUE_EXECUTION;
 
111
        }
 
112
      else if (old_handler != SIG_DFL)
 
113
        {
 
114
          /* This means 'old' is a user defined function. Call it */
 
115
          (*old_handler) (SIGSEGV);
 
116
          action = EXCEPTION_CONTINUE_EXECUTION;
 
117
        }
 
118
      else
 
119
        action = EXCEPTION_EXECUTE_HANDLER;
 
120
      break;
 
121
    case EXCEPTION_ILLEGAL_INSTRUCTION:
 
122
    case EXCEPTION_PRIV_INSTRUCTION:
 
123
      /* test if the user has set SIGILL */
 
124
      old_handler = signal (SIGILL, SIG_DFL);
 
125
      if (old_handler == SIG_IGN)
 
126
        {
 
127
          /* this is undefined if the signal was raised by anything other
 
128
             than raise ().  */
 
129
          signal (SIGILL, SIG_IGN);
 
130
          action = EXCEPTION_CONTINUE_EXECUTION;
 
131
        }
 
132
      else if (old_handler != SIG_DFL)
 
133
        {
 
134
          /* This means 'old' is a user defined function. Call it */
 
135
          (*old_handler) (SIGILL);
 
136
          action = EXCEPTION_CONTINUE_EXECUTION;
 
137
        }
 
138
      else
 
139
        action = EXCEPTION_EXECUTE_HANDLER;
 
140
      break;
 
141
    case EXCEPTION_FLT_INVALID_OPERATION:
 
142
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
 
143
    case EXCEPTION_FLT_DENORMAL_OPERAND:
 
144
    case EXCEPTION_FLT_OVERFLOW:
 
145
    case EXCEPTION_FLT_UNDERFLOW:
 
146
    case EXCEPTION_FLT_INEXACT_RESULT:
 
147
      reset_fpu = 1;
 
148
      /* fall through. */
 
149
 
 
150
    case EXCEPTION_INT_DIVIDE_BY_ZERO:
 
151
      /* test if the user has set SIGFPE */
 
152
      old_handler = signal (SIGFPE, SIG_DFL);
 
153
      if (old_handler == SIG_IGN)
 
154
        {
 
155
          signal (SIGFPE, SIG_IGN);
 
156
          if (reset_fpu)
 
157
            _fpreset ();
 
158
          action = EXCEPTION_CONTINUE_EXECUTION;
 
159
        }
 
160
      else if (old_handler != SIG_DFL)
 
161
        {
 
162
          /* This means 'old' is a user defined function. Call it */
 
163
          (*old_handler) (SIGFPE);
 
164
          action = EXCEPTION_CONTINUE_EXECUTION;
 
165
        }
 
166
      break;
 
167
    case EXCEPTION_DATATYPE_MISALIGNMENT:
 
168
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
 
169
    case EXCEPTION_FLT_STACK_CHECK:
 
170
    case EXCEPTION_INT_OVERFLOW:
 
171
    case EXCEPTION_INVALID_HANDLE:
 
172
    /*case EXCEPTION_POSSIBLE_DEADLOCK: */
 
173
      action = EXCEPTION_CONTINUE_EXECUTION;
 
174
      break;
 
175
    default:
 
176
      break;
 
177
    }
 
178
  return action;
 
179
}
 
180
 
 
181
#endif