ReactOS 0.4.16-dev-2104-gb84fa49
cxx.h
Go to the documentation of this file.
1/*
2 * Copyright 2012 Piotr Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include "windef.h"
20#include "winternl.h"
21#include "rtlsupportapi.h"
22#include "wine/asm.h"
23
24#ifdef __i386__
25#undef RTTI_USE_RVA
26#else
27#define RTTI_USE_RVA 1
28#endif
29
30#ifdef _MSC_VER
31#define __ASM_VTABLE(name,funcs)
32#else
33#ifdef _WIN64
34
35#define VTABLE_ADD_FUNC(name) "\t.quad " THISCALL_NAME(name) "\n"
36
37#define __ASM_VTABLE(name,funcs) \
38 __asm__(".data\n" \
39 "\t.balign 8\n" \
40 "\t.quad " __ASM_NAME(#name "_rtti") "\n" \
41 "\t.globl " __ASM_NAME(#name "_vtable") "\n" \
42 __ASM_NAME(#name "_vtable") ":\n" \
43 funcs "\n\t.text")
44
45#else
46
47#define VTABLE_ADD_FUNC(name) "\t.long " THISCALL_NAME(name) "\n"
48
49#define __ASM_VTABLE(name,funcs) \
50 __asm__(".data\n" \
51 "\t.balign 4\n" \
52 "\t.long " __ASM_NAME(#name "_rtti") "\n" \
53 "\t.globl " __ASM_NAME(#name "_vtable") "\n" \
54 __ASM_NAME(#name "_vtable") ":\n" \
55 funcs "\n\t.text")
56
57#endif /* _WIN64 */
58#endif // _MSC_VER
59
60#ifndef RTTI_USE_RVA
61
62#define DEFINE_RTTI_BASE(name, base_classes_no, mangled_name) \
63 static type_info name ## _type_info = { \
64 &type_info_vtable, \
65 NULL, \
66 mangled_name \
67 }; \
68\
69static const rtti_base_descriptor name ## _rtti_base_descriptor = { \
70 &name ##_type_info, \
71 base_classes_no, \
72 { 0, -1, 0}, \
73 64 \
74};
75
76#define DEFINE_RTTI_DATA(name, off, base_classes_no, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \
77 DEFINE_RTTI_BASE(name, base_classes_no, mangled_name) \
78\
79static const rtti_base_array name ## _rtti_base_array = { \
80 { \
81 &name ## _rtti_base_descriptor, \
82 cl1, \
83 cl2, \
84 cl3, \
85 cl4, \
86 cl5, \
87 cl6, \
88 cl7, \
89 cl8, \
90 cl9, \
91 } \
92}; \
93\
94static const rtti_object_hierarchy name ## _hierarchy = { \
95 0, \
96 0, \
97 base_classes_no+1, \
98 &name ## _rtti_base_array \
99}; \
100\
101const rtti_object_locator name ## _rtti = { \
102 0, \
103 off, \
104 0, \
105 &name ## _type_info, \
106 &name ## _hierarchy \
107};
108
109#define DEFINE_CXX_TYPE_INFO(type) \
110static const cxx_type_info type ## _cxx_type_info = { \
111 0, \
112 & type ##_type_info, \
113 { 0, -1, 0 }, \
114 sizeof(type), \
115 THISCALL(type ##_copy_ctor) \
116};
117
118#define DEFINE_CXX_DATA(type, base_no, cl1, cl2, cl3, cl4, dtor) \
119DEFINE_CXX_TYPE_INFO(type) \
120\
121static const cxx_type_info_table type ## _cxx_type_table = { \
122 base_no+1, \
123 { \
124 & type ## _cxx_type_info, \
125 cl1, \
126 cl2, \
127 cl3, \
128 cl4 \
129 } \
130}; \
131\
132static const cxx_exception_type type ## _exception_type = { \
133 0, \
134 THISCALL(dtor), \
135 NULL, \
136 & type ## _cxx_type_table \
137};
138
139#else
140
141#define __DEFINE_RTTI_BASE(name, base_classes_no, mangled_name) \
142 static type_info name ## _type_info = { \
143 &type_info_vtable, \
144 NULL, \
145 mangled_name \
146 }; \
147\
148static rtti_base_descriptor name ## _rtti_base_descriptor = { \
149 0xdeadbeef, \
150 base_classes_no, \
151 { 0, -1, 0}, \
152 64 \
153};
154
155#define DEFINE_RTTI_BASE(name, base_classes_no, mangled_name) \
156 __DEFINE_RTTI_BASE(name, base_classes_no, mangled_name) \
157 \
158 static void init_ ## name ## _rtti(char *base) \
159 { \
160 name ## _rtti_base_descriptor.type_descriptor = (char*)&name ## _type_info - base; \
161 }
162
163#define DEFINE_RTTI_DATA(name, off, base_classes_no, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \
164 __DEFINE_RTTI_BASE(name, base_classes_no, mangled_name) \
165\
166static rtti_base_array name ## _rtti_base_array = { \
167 { \
168 0xdeadbeef, \
169 0xdeadbeef, \
170 0xdeadbeef, \
171 0xdeadbeef, \
172 0xdeadbeef, \
173 0xdeadbeef, \
174 0xdeadbeef, \
175 0xdeadbeef, \
176 0xdeadbeef, \
177 0xdeadbeef, \
178 } \
179}; \
180\
181static rtti_object_hierarchy name ## _hierarchy = { \
182 0, \
183 0, \
184 base_classes_no+1, \
185 0xdeadbeef \
186}; \
187\
188rtti_object_locator name ## _rtti = { \
189 1, \
190 off, \
191 0, \
192 0xdeadbeef, \
193 0xdeadbeef, \
194 0xdeadbeef \
195};\
196\
197static void init_ ## name ## _rtti(char *base) \
198{ \
199 name ## _rtti_base_descriptor.type_descriptor = (char*)&name ## _type_info - base; \
200 name ## _rtti_base_array.bases[0] = (char*)&name ## _rtti_base_descriptor - base; \
201 name ## _rtti_base_array.bases[1] = (char*)cl1 - base; \
202 name ## _rtti_base_array.bases[2] = (char*)cl2 - base; \
203 name ## _rtti_base_array.bases[3] = (char*)cl3 - base; \
204 name ## _rtti_base_array.bases[4] = (char*)cl4 - base; \
205 name ## _rtti_base_array.bases[5] = (char*)cl5 - base; \
206 name ## _rtti_base_array.bases[6] = (char*)cl6 - base; \
207 name ## _rtti_base_array.bases[7] = (char*)cl7 - base; \
208 name ## _rtti_base_array.bases[8] = (char*)cl8 - base; \
209 name ## _rtti_base_array.bases[9] = (char*)cl9 - base; \
210 name ## _hierarchy.base_classes = (char*)&name ## _rtti_base_array - base; \
211 name ## _rtti.type_descriptor = (char*)&name ## _type_info - base; \
212 name ## _rtti.type_hierarchy = (char*)&name ## _hierarchy - base; \
213 name ## _rtti.object_locator = (char*)&name ## _rtti - base; \
214}
215
216#define DEFINE_CXX_TYPE_INFO(type) \
217static cxx_type_info type ## _cxx_type_info = { \
218 0, \
219 0xdeadbeef, \
220 { 0, -1, 0 }, \
221 sizeof(type), \
222 0xdeadbeef \
223}; \
224\
225static void init_ ## type ## _cxx_type_info(char *base) \
226{ \
227 type ## _cxx_type_info.type_info = (char *)&type ## _type_info - base; \
228 type ## _cxx_type_info.copy_ctor = (char *)type ## _copy_ctor - base; \
229}
230
231#define DEFINE_CXX_DATA(type, base_no, cl1, cl2, cl3, cl4, dtor) \
232\
233DEFINE_CXX_TYPE_INFO(type) \
234\
235static cxx_type_info_table type ## _cxx_type_table = { \
236 base_no+1, \
237 { \
238 0xdeadbeef, \
239 0xdeadbeef, \
240 0xdeadbeef, \
241 0xdeadbeef, \
242 0xdeadbeef \
243 } \
244}; \
245\
246static cxx_exception_type type ##_exception_type = { \
247 0, \
248 0xdeadbeef, \
249 0, \
250 0xdeadbeef \
251}; \
252\
253static void init_ ## type ## _cxx(char *base) \
254{ \
255 init_ ## type ## _cxx_type_info(base); \
256 type ## _cxx_type_table.info[0] = (char *)&type ## _cxx_type_info - base; \
257 type ## _cxx_type_table.info[1] = (char *)cl1 - base; \
258 type ## _cxx_type_table.info[2] = (char *)cl2 - base; \
259 type ## _cxx_type_table.info[3] = (char *)cl3 - base; \
260 type ## _cxx_type_table.info[4] = (char *)cl4 - base; \
261 type ## _exception_type.destructor = (char *)dtor - base; \
262 type ## _exception_type.type_info_table = (char *)&type ## _cxx_type_table - base; \
263}
264
265#endif
266
267#define DEFINE_RTTI_DATA0(name, off, mangled_name) \
268 DEFINE_RTTI_DATA(name, off, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
269#define DEFINE_RTTI_DATA1(name, off, cl1, mangled_name) \
270 DEFINE_RTTI_DATA(name, off, 1, cl1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
271#define DEFINE_RTTI_DATA2(name, off, cl1, cl2, mangled_name) \
272 DEFINE_RTTI_DATA(name, off, 2, cl1, cl2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
273#define DEFINE_RTTI_DATA3(name, off, cl1, cl2, cl3, mangled_name) \
274 DEFINE_RTTI_DATA(name, off, 3, cl1, cl2, cl3, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
275#define DEFINE_RTTI_DATA4(name, off, cl1, cl2, cl3, cl4, mangled_name) \
276 DEFINE_RTTI_DATA(name, off, 4, cl1, cl2, cl3, cl4, NULL, NULL, NULL, NULL, NULL, mangled_name)
277#define DEFINE_RTTI_DATA5(name, off, cl1, cl2, cl3, cl4, cl5, mangled_name) \
278 DEFINE_RTTI_DATA(name, off, 5, cl1, cl2, cl3, cl4, cl5, NULL, NULL, NULL, NULL, mangled_name)
279#define DEFINE_RTTI_DATA8(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, mangled_name) \
280 DEFINE_RTTI_DATA(name, off, 8, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, NULL, mangled_name)
281#define DEFINE_RTTI_DATA9(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \
282 DEFINE_RTTI_DATA(name, off, 9, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name)
283
284#define DEFINE_CXX_DATA0(name, dtor) \
285 DEFINE_CXX_DATA(name, 0, NULL, NULL, NULL, NULL, dtor)
286#define DEFINE_CXX_DATA1(name, cl1, dtor) \
287 DEFINE_CXX_DATA(name, 1, cl1, NULL, NULL, NULL, dtor)
288#define DEFINE_CXX_DATA2(name, cl1, cl2, dtor) \
289 DEFINE_CXX_DATA(name, 2, cl1, cl2, NULL, NULL, dtor)
290#define DEFINE_CXX_DATA3(name, cl1, cl2, cl3, dtor) \
291 DEFINE_CXX_DATA(name, 3, cl1, cl2, cl3, NULL, dtor)
292#define DEFINE_CXX_DATA4(name, cl1, cl2, cl3, cl4, dtor) \
293 DEFINE_CXX_DATA(name, 4, cl1, cl2, cl3, cl4, dtor)
294
295#ifdef __ASM_USE_THISCALL_WRAPPER
296
297#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args
298
299extern void *vtbl_wrapper_0;
300extern void *vtbl_wrapper_4;
301extern void *vtbl_wrapper_8;
302extern void *vtbl_wrapper_12;
303extern void *vtbl_wrapper_16;
304extern void *vtbl_wrapper_20;
305extern void *vtbl_wrapper_24;
306extern void *vtbl_wrapper_28;
307extern void *vtbl_wrapper_32;
308extern void *vtbl_wrapper_36;
309extern void *vtbl_wrapper_40;
310extern void *vtbl_wrapper_44;
311extern void *vtbl_wrapper_48;
312extern void *vtbl_wrapper_52;
313extern void *vtbl_wrapper_56;
314
315#else
316
317#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (__thiscall***)type)this)[0][off/4]args
318
319#endif
320
321/* exception object */
322typedef void (*vtable_ptr)(void);
323typedef struct __exception
324{
326 char *name; /* Name of this exception, always a new copy for each object */
327 int do_free; /* Whether to free 'name' in our dtor */
329
330/* rtti */
331typedef struct __type_info
332{
334 char *name; /* Unmangled name, allocated lazily */
335 char mangled[128]; /* Variable length, but we declare it large enough for static RTTI */
337
338/* offsets for computing the this pointer */
339typedef struct
340{
341 int this_offset; /* offset of base class this pointer from start of object */
342 int vbase_descr; /* offset of virtual base class descriptor */
343 int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */
345
346#ifndef RTTI_USE_RVA
347
348typedef struct _rtti_base_descriptor
349{
352 this_ptr_offsets offsets; /* offsets for computing the this pointer */
353 unsigned int attributes;
355
356typedef struct _rtti_base_array
357{
358 const rtti_base_descriptor *bases[10]; /* First element is the class itself */
360
361typedef struct _rtti_object_hierarchy
362{
363 unsigned int signature;
364 unsigned int attributes;
365 int array_len; /* Size of the array pointed to by 'base_classes' */
368
369typedef struct _rtti_object_locator
370{
371 unsigned int signature;
373 unsigned int flags;
377
378typedef struct
379{
380 UINT flags;
381 const type_info *type_info;
383 unsigned int size;
384 void *copy_ctor;
386
387typedef struct
388{
389 UINT count;
390 const cxx_type_info *info[5];
392
393typedef struct
394{
395 UINT flags;
396 void *destructor;
397 void *custom_handler;
398 const cxx_type_info_table *type_info_table;
400
401#else
402
403typedef struct
404{
405 unsigned int type_descriptor;
407 this_ptr_offsets offsets; /* offsets for computing the this pointer */
408 unsigned int attributes;
410
411typedef struct
412{
413 unsigned int bases[10]; /* First element is the class itself */
415
416typedef struct
417{
418 unsigned int signature;
419 unsigned int attributes;
420 int array_len; /* Size of the array pointed to by 'base_classes' */
421 unsigned int base_classes;
423
424typedef struct
425{
426 unsigned int signature;
428 unsigned int flags;
429 unsigned int type_descriptor;
430 unsigned int type_hierarchy;
431 unsigned int object_locator;
433
434typedef struct
435{
437 unsigned int type_info;
439 unsigned int size;
440 unsigned int copy_ctor;
442
443typedef struct
444{
446 unsigned int info[5];
448
449typedef struct
450{
452 unsigned int destructor;
453 unsigned int custom_handler;
454 unsigned int type_info_table;
456
457#endif
458
459extern const vtable_ptr type_info_vtable;
460
461#ifdef RTTI_USE_RVA
462
463static inline uintptr_t rtti_rva_base( const void *ptr )
464{
465 void *base;
466 return (uintptr_t)RtlPcToFileHeader( (void *)ptr, &base );
467}
468
469static inline void *rtti_rva( unsigned int rva, uintptr_t base )
470{
471 return (void *)(base + rva);
472}
473
474#else
475
476static inline uintptr_t rtti_rva_base( const void *ptr )
477{
478 return 0;
479}
480
481static inline void *rtti_rva( const void *ptr, uintptr_t base )
482{
483 return (void *)ptr;
484}
485
486#endif
487
488#ifdef __REACTOS__
489void * __thiscall type_info_vector_dtor(type_info * _this, unsigned int flags);
490#endif
491
492#define CREATE_TYPE_INFO_VTABLE \
493DEFINE_THISCALL_WRAPPER(type_info_vector_dtor,8) \
494void * __thiscall type_info_vector_dtor(type_info * _this, unsigned int flags) \
495{ \
496 if (flags & 2) \
497 { \
498 /* we have an array, with the number of elements stored before the first object */ \
499 INT_PTR i, *ptr = (INT_PTR *)_this - 1; \
500\
501 for (i = *ptr - 1; i >= 0; i--) free(_this[i].name); \
502 free(ptr); \
503 } \
504 else \
505 { \
506 free(_this->name); \
507 if (flags & 1) free(_this); \
508 } \
509 return _this; \
510} \
511\
512DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" ) \
513\
514__ASM_BLOCK_BEGIN(type_info_vtables) \
515 __ASM_VTABLE(type_info, \
516 VTABLE_ADD_FUNC(type_info_vector_dtor)); \
517__ASM_BLOCK_END
PVOID NTAPI RtlPcToFileHeader(IN PVOID PcValue, PVOID *BaseOfImage)
Definition: libsupp.c:658
struct __type_info type_info
struct __exception exception
static void * rtti_rva(unsigned int rva, uintptr_t base)
Definition: cxx.h:469
const vtable_ptr type_info_vtable
void(* vtable_ptr)(void)
Definition: cxx.h:322
static uintptr_t rtti_rva_base(const void *ptr)
Definition: cxx.h:463
unsigned int uintptr_t
Definition: corecrt.h:185
static const FxOffsetAndName offsets[]
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
static PVOID ptr
Definition: dispmode.c:27
#define __thiscall
Definition: cpp.c:43
unsigned int UINT
Definition: ndis.h:50
void(* vtable_ptr)(void)
Definition: cppexcept.h:34
char * name
Definition: cxx.h:326
const vtable_ptr * vtable
Definition: cxx.h:325
int do_free
Definition: cxx.h:327
const vtable_ptr * vtable
Definition: cxx.h:333
char mangled[128]
Definition: cxx.h:335
char * name
Definition: cxx.h:334
const rtti_base_descriptor * bases[10]
Definition: cxx.h:206
this_ptr_offsets offsets
Definition: cxx.h:200
int num_base_classes
Definition: cxx.h:199
const type_info * type_descriptor
Definition: cxx.h:198
unsigned int attributes
Definition: cxx.h:201
unsigned int signature
Definition: cxx.h:211
unsigned int attributes
Definition: cxx.h:212
const rtti_base_array * base_classes
Definition: cxx.h:214
const type_info * type_descriptor
Definition: cxx.h:222
unsigned int flags
Definition: cxx.h:221
unsigned int signature
Definition: cxx.h:219
int base_class_offset
Definition: cxx.h:220
const rtti_object_hierarchy * type_hierarchy
Definition: cxx.h:223
unsigned int custom_handler
Definition: cxx.h:453
unsigned int type_info_table
Definition: cxx.h:454
unsigned int destructor
Definition: cxx.h:452
unsigned int size
Definition: cxx.h:439
unsigned int type_info
Definition: cxx.h:437
this_ptr_offsets offsets
Definition: cxx.h:438
UINT flags
Definition: cxx.h:436
unsigned int copy_ctor
Definition: cxx.h:440
unsigned int attributes
Definition: cxx.h:408
int num_base_classes
Definition: cxx.h:406
unsigned int type_descriptor
Definition: cxx.h:405
this_ptr_offsets offsets
Definition: cxx.h:407
unsigned int signature
Definition: cxx.h:418
unsigned int base_classes
Definition: cxx.h:421
unsigned int attributes
Definition: cxx.h:419
unsigned int object_locator
Definition: cxx.h:431
unsigned int type_hierarchy
Definition: cxx.h:430
unsigned int signature
Definition: cxx.h:426
int base_class_offset
Definition: cxx.h:427
unsigned int flags
Definition: cxx.h:428
unsigned int type_descriptor
Definition: cxx.h:429
int this_offset
Definition: cxx.h:341
int vbase_offset
Definition: cxx.h:343
int vbase_descr
Definition: cxx.h:342
void *__thiscall type_info_vector_dtor(type_info *_this, unsigned int flags)