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