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 "wine/asm.h" 20 21 #ifdef _WIN64 22 23 #define VTABLE_ADD_FUNC(name) "\t.quad " THISCALL_NAME(name) "\n" 24 25 #define __ASM_VTABLE(name,funcs) \ 26 __asm__(".data\n" \ 27 "\t.balign 8\n" \ 28 "\t.quad " __ASM_NAME(#name "_rtti") "\n" \ 29 "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \ 30 __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \ 31 funcs "\n\t.text") 32 33 #else 34 35 #define VTABLE_ADD_FUNC(name) "\t.long " THISCALL_NAME(name) "\n" 36 37 #define __ASM_VTABLE(name,funcs) \ 38 __asm__(".data\n" \ 39 "\t.balign 4\n" \ 40 "\t.long " __ASM_NAME(#name "_rtti") "\n" \ 41 "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \ 42 __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \ 43 funcs "\n\t.text") 44 45 #endif /* _WIN64 */ 46 47 #ifndef __x86_64__ 48 49 #define DEFINE_RTTI_DATA(name, off, base_classes_no, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \ 50 static type_info name ## _type_info = { \ 51 &MSVCRT_type_info_vtable, \ 52 NULL, \ 53 mangled_name \ 54 }; \ 55 \ 56 static const rtti_base_descriptor name ## _rtti_base_descriptor = { \ 57 &name ##_type_info, \ 58 base_classes_no, \ 59 { 0, -1, 0}, \ 60 64 \ 61 }; \ 62 \ 63 static const rtti_base_array name ## _rtti_base_array = { \ 64 { \ 65 &name ## _rtti_base_descriptor, \ 66 cl1, \ 67 cl2, \ 68 cl3, \ 69 cl4, \ 70 cl5, \ 71 cl6, \ 72 cl7, \ 73 cl8, \ 74 cl9, \ 75 } \ 76 }; \ 77 \ 78 static const rtti_object_hierarchy name ## _hierarchy = { \ 79 0, \ 80 0, \ 81 base_classes_no+1, \ 82 &name ## _rtti_base_array \ 83 }; \ 84 \ 85 const rtti_object_locator name ## _rtti = { \ 86 0, \ 87 off, \ 88 0, \ 89 &name ## _type_info, \ 90 &name ## _hierarchy \ 91 }; 92 93 #else 94 95 #define DEFINE_RTTI_DATA(name, off, base_classes_no, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \ 96 static type_info name ## _type_info = { \ 97 &MSVCRT_type_info_vtable, \ 98 NULL, \ 99 mangled_name \ 100 }; \ 101 \ 102 static rtti_base_descriptor name ## _rtti_base_descriptor = { \ 103 0xdeadbeef, \ 104 base_classes_no, \ 105 { 0, -1, 0}, \ 106 64 \ 107 }; \ 108 \ 109 static rtti_base_array name ## _rtti_base_array = { \ 110 { \ 111 0xdeadbeef, \ 112 0xdeadbeef, \ 113 0xdeadbeef, \ 114 0xdeadbeef, \ 115 0xdeadbeef, \ 116 0xdeadbeef, \ 117 0xdeadbeef, \ 118 0xdeadbeef, \ 119 0xdeadbeef, \ 120 0xdeadbeef, \ 121 } \ 122 }; \ 123 \ 124 static rtti_object_hierarchy name ## _hierarchy = { \ 125 0, \ 126 0, \ 127 base_classes_no+1, \ 128 0xdeadbeef \ 129 }; \ 130 \ 131 rtti_object_locator name ## _rtti = { \ 132 1, \ 133 off, \ 134 0, \ 135 0xdeadbeef, \ 136 0xdeadbeef, \ 137 0xdeadbeef \ 138 };\ 139 \ 140 static void init_ ## name ## _rtti(char *base) \ 141 { \ 142 name ## _rtti_base_descriptor.type_descriptor = (char*)&name ## _type_info - base; \ 143 name ## _rtti_base_array.bases[0] = (char*)&name ## _rtti_base_descriptor - base; \ 144 name ## _rtti_base_array.bases[1] = (char*)cl1 - base; \ 145 name ## _rtti_base_array.bases[2] = (char*)cl2 - base; \ 146 name ## _rtti_base_array.bases[3] = (char*)cl3 - base; \ 147 name ## _rtti_base_array.bases[4] = (char*)cl4 - base; \ 148 name ## _rtti_base_array.bases[5] = (char*)cl5 - base; \ 149 name ## _rtti_base_array.bases[6] = (char*)cl6 - base; \ 150 name ## _rtti_base_array.bases[7] = (char*)cl7 - base; \ 151 name ## _rtti_base_array.bases[8] = (char*)cl8 - base; \ 152 name ## _rtti_base_array.bases[9] = (char*)cl9 - base; \ 153 name ## _hierarchy.base_classes = (char*)&name ## _rtti_base_array - base; \ 154 name ## _rtti.type_descriptor = (char*)&name ## _type_info - base; \ 155 name ## _rtti.type_hierarchy = (char*)&name ## _hierarchy - base; \ 156 name ## _rtti.object_locator = (char*)&name ## _rtti - base; \ 157 } 158 159 #endif 160 161 #define DEFINE_RTTI_DATA0(name, off, mangled_name) \ 162 DEFINE_RTTI_DATA(name, off, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) 163 #define DEFINE_RTTI_DATA1(name, off, cl1, mangled_name) \ 164 DEFINE_RTTI_DATA(name, off, 1, cl1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) 165 #define DEFINE_RTTI_DATA2(name, off, cl1, cl2, mangled_name) \ 166 DEFINE_RTTI_DATA(name, off, 2, cl1, cl2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) 167 #define DEFINE_RTTI_DATA3(name, off, cl1, cl2, cl3, mangled_name) \ 168 DEFINE_RTTI_DATA(name, off, 3, cl1, cl2, cl3, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) 169 #define DEFINE_RTTI_DATA4(name, off, cl1, cl2, cl3, cl4, mangled_name) \ 170 DEFINE_RTTI_DATA(name, off, 4, cl1, cl2, cl3, cl4, NULL, NULL, NULL, NULL, NULL, mangled_name) 171 #define DEFINE_RTTI_DATA8(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, mangled_name) \ 172 DEFINE_RTTI_DATA(name, off, 8, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, NULL, mangled_name) 173 #define DEFINE_RTTI_DATA9(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \ 174 DEFINE_RTTI_DATA(name, off, 9, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) 175 176 #ifndef __x86_64__ 177 178 typedef struct _rtti_base_descriptor 179 { 180 const type_info *type_descriptor; 181 int num_base_classes; 182 this_ptr_offsets offsets; /* offsets for computing the this pointer */ 183 unsigned int attributes; 184 } rtti_base_descriptor; 185 186 typedef struct _rtti_base_array 187 { 188 const rtti_base_descriptor *bases[10]; /* First element is the class itself */ 189 } rtti_base_array; 190 191 typedef struct _rtti_object_hierarchy 192 { 193 unsigned int signature; 194 unsigned int attributes; 195 int array_len; /* Size of the array pointed to by 'base_classes' */ 196 const rtti_base_array *base_classes; 197 } rtti_object_hierarchy; 198 199 typedef struct _rtti_object_locator 200 { 201 unsigned int signature; 202 int base_class_offset; 203 unsigned int flags; 204 const type_info *type_descriptor; 205 const rtti_object_hierarchy *type_hierarchy; 206 } rtti_object_locator; 207 208 #else 209 210 typedef struct 211 { 212 unsigned int type_descriptor; 213 int num_base_classes; 214 this_ptr_offsets offsets; /* offsets for computing the this pointer */ 215 unsigned int attributes; 216 } rtti_base_descriptor; 217 218 typedef struct 219 { 220 unsigned int bases[10]; /* First element is the class itself */ 221 } rtti_base_array; 222 223 typedef struct 224 { 225 unsigned int signature; 226 unsigned int attributes; 227 int array_len; /* Size of the array pointed to by 'base_classes' */ 228 unsigned int base_classes; 229 } rtti_object_hierarchy; 230 231 typedef struct 232 { 233 unsigned int signature; 234 int base_class_offset; 235 unsigned int flags; 236 unsigned int type_descriptor; 237 unsigned int type_hierarchy; 238 unsigned int object_locator; 239 } rtti_object_locator; 240 241 #endif 242 243 #if defined(__i386__) && !defined(__MINGW32__) 244 245 #define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args 246 247 extern void *vtbl_wrapper_0; 248 extern void *vtbl_wrapper_4; 249 extern void *vtbl_wrapper_8; 250 extern void *vtbl_wrapper_12; 251 extern void *vtbl_wrapper_16; 252 extern void *vtbl_wrapper_20; 253 extern void *vtbl_wrapper_24; 254 extern void *vtbl_wrapper_28; 255 extern void *vtbl_wrapper_32; 256 extern void *vtbl_wrapper_36; 257 extern void *vtbl_wrapper_40; 258 extern void *vtbl_wrapper_44; 259 extern void *vtbl_wrapper_48; 260 261 #else 262 263 #define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (__thiscall***)type)this)[0][off/4]args 264 265 #endif 266 267 //exception* __thiscall MSVCRT_exception_ctor(exception*, const char**); 268