1 /* 2 * msvcrt C++ exception handling 3 * 4 * Copyright 2002 Alexandre Julliard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #ifndef __MSVCRT_CPPEXCEPT_H 22 #define __MSVCRT_CPPEXCEPT_H 23 24 #include "wine/asm.h" 25 26 #define CXX_FRAME_MAGIC_VC6 0x19930520 27 #define CXX_FRAME_MAGIC_VC7 0x19930521 28 #define CXX_FRAME_MAGIC_VC8 0x19930522 29 #define CXX_EXCEPTION 0xe06d7363 30 31 #define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs and /EHsc) */ 32 33 typedef void (*vtable_ptr)(void); 34 35 /* type_info object, see cpp.c for implementation */ 36 typedef struct __type_info 37 { 38 const vtable_ptr *vtable; 39 char *name; /* Unmangled name, allocated lazily */ 40 char mangled[64]; /* Variable length, but we declare it large enough for static RTTI */ 41 } type_info; 42 43 /* exception object */ 44 typedef struct __exception 45 { 46 const vtable_ptr *vtable; 47 char *name; /* Name of this exception, always a new copy for each object */ 48 BOOL do_free; /* Whether to free 'name' in our dtor */ 49 } exception; 50 51 typedef void (*cxx_copy_ctor)(void); 52 53 /* offsets for computing the this pointer */ 54 typedef struct 55 { 56 int this_offset; /* offset of base class this pointer from start of object */ 57 int vbase_descr; /* offset of virtual base class descriptor */ 58 int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */ 59 } this_ptr_offsets; 60 61 /* complete information about a C++ type */ 62 #ifndef __x86_64__ 63 typedef struct __cxx_type_info 64 { 65 UINT flags; /* flags (see CLASS_* flags below) */ 66 const type_info *type_info; /* C++ type info */ 67 this_ptr_offsets offsets; /* offsets for computing the this pointer */ 68 unsigned int size; /* object size */ 69 cxx_copy_ctor copy_ctor; /* copy constructor */ 70 } cxx_type_info; 71 #else 72 typedef struct __cxx_type_info 73 { 74 UINT flags; 75 unsigned int type_info; 76 this_ptr_offsets offsets; 77 unsigned int size; 78 unsigned int copy_ctor; 79 } cxx_type_info; 80 #endif 81 82 #define CLASS_IS_SIMPLE_TYPE 1 83 #define CLASS_HAS_VIRTUAL_BASE_CLASS 4 84 85 /* table of C++ types that apply for a given object */ 86 #ifndef __x86_64__ 87 typedef struct __cxx_type_info_table 88 { 89 UINT count; /* number of types */ 90 const cxx_type_info *info[3]; /* variable length, we declare it large enough for static RTTI */ 91 } cxx_type_info_table; 92 #else 93 typedef struct __cxx_type_info_table 94 { 95 UINT count; 96 unsigned int info[3]; 97 } cxx_type_info_table; 98 #endif 99 100 struct __cxx_exception_frame; 101 struct __cxx_function_descr; 102 103 typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, struct __cxx_exception_frame*, 104 PCONTEXT, EXCEPTION_REGISTRATION_RECORD**, 105 const struct __cxx_function_descr*, int nested_trylevel, 106 EXCEPTION_REGISTRATION_RECORD *nested_frame, DWORD unknown3 ); 107 108 /* type information for an exception object */ 109 #ifndef __x86_64__ 110 typedef struct __cxx_exception_type 111 { 112 UINT flags; /* TYPE_FLAG flags */ 113 void (*destructor)(void);/* exception object destructor */ 114 cxx_exc_custom_handler custom_handler; /* custom handler for this exception */ 115 const cxx_type_info_table *type_info_table; /* list of types for this exception object */ 116 } cxx_exception_type; 117 #else 118 typedef struct 119 { 120 UINT flags; 121 unsigned int destructor; 122 unsigned int custom_handler; 123 unsigned int type_info_table; 124 } cxx_exception_type; 125 #endif 126 127 void WINAPI _CxxThrowException(exception*,const cxx_exception_type*); 128 int CDECL _XcptFilter(NTSTATUS, PEXCEPTION_POINTERS); 129 130 static inline const char *dbgstr_type_info( const type_info *info ) 131 { 132 if (!info) return "{}"; 133 return wine_dbg_sprintf( "{vtable=%p name=%s (%s)}", 134 info->vtable, info->mangled, info->name ? info->name : "" ); 135 } 136 137 /* compute the this pointer for a base class of a given type */ 138 static inline void *get_this_pointer( const this_ptr_offsets *off, void *object ) 139 { 140 if (!object) return NULL; 141 142 if (off->vbase_descr >= 0) 143 { 144 int *offset_ptr; 145 146 /* move this ptr to vbase descriptor */ 147 object = (char *)object + off->vbase_descr; 148 /* and fetch additional offset from vbase descriptor */ 149 offset_ptr = (int *)(*(char **)object + off->vbase_offset); 150 object = (char *)object + *offset_ptr; 151 } 152 153 object = (char *)object + off->this_offset; 154 return object; 155 } 156 157 #ifndef __x86_64__ 158 #define DEFINE_EXCEPTION_TYPE_INFO(type, base_no, cl1, cl2) \ 159 \ 160 static const cxx_type_info type ## _cxx_type_info = { \ 161 0, \ 162 & type ##_type_info, \ 163 { 0, -1, 0 }, \ 164 sizeof(type), \ 165 (cxx_copy_ctor)THISCALL(MSVCRT_ ## type ##_copy_ctor) \ 166 }; \ 167 \ 168 static const cxx_type_info_table type ## _type_info_table = { \ 169 base_no+1, \ 170 { \ 171 & type ## _cxx_type_info, \ 172 cl1, \ 173 cl2 \ 174 } \ 175 }; \ 176 \ 177 static const cxx_exception_type type ## _exception_type = { \ 178 0, \ 179 (cxx_copy_ctor)THISCALL(MSVCRT_ ## type ## _dtor), \ 180 NULL, \ 181 & type ## _type_info_table \ 182 }; 183 184 #else 185 186 #define DEFINE_EXCEPTION_TYPE_INFO(type, base_no, cl1, cl2) \ 187 \ 188 static cxx_type_info type ## _cxx_type_info = { \ 189 0, \ 190 0xdeadbeef, \ 191 { 0, -1, 0 }, \ 192 sizeof(type), \ 193 0xdeadbeef \ 194 }; \ 195 \ 196 static cxx_type_info_table type ## _type_info_table = { \ 197 base_no+1, \ 198 { \ 199 0xdeadbeef, \ 200 0xdeadbeef, \ 201 0xdeadbeef \ 202 } \ 203 }; \ 204 \ 205 static cxx_exception_type type ##_exception_type = { \ 206 0, \ 207 0xdeadbeef, \ 208 0, \ 209 0xdeadbeef \ 210 }; \ 211 \ 212 static void init_ ## type ## _cxx(char *base) \ 213 { \ 214 type ## _cxx_type_info.type_info = (char *)&type ## _type_info - base; \ 215 type ## _cxx_type_info.copy_ctor = (char *)MSVCRT_ ## type ## _copy_ctor - base; \ 216 type ## _type_info_table.info[0] = (char *)&type ## _cxx_type_info - base; \ 217 type ## _type_info_table.info[1] = (char *)cl1 - base; \ 218 type ## _type_info_table.info[2] = (char *)cl2 - base; \ 219 type ## _exception_type.destructor = (char *)MSVCRT_ ## type ## _dtor - base; \ 220 type ## _exception_type.type_info_table = (char *)&type ## _type_info_table - base; \ 221 } 222 #endif 223 224 #endif /* __MSVCRT_CPPEXCEPT_H */ 225