[CRT] Remove useless #undef abort from process.h
[reactos.git] / dll / win32 / dbghelp / type.c
1 /*
2 * File types.c - management of types (hierarchical tree)
3 *
4 * Copyright (C) 1997, Eric Youngdale.
5 * 2004, Eric Pouech.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 *
21 * Note: This really doesn't do much at the moment, but it forms the framework
22 * upon which full support for datatype handling will eventually be built.
23 */
24
25 #define NONAMELESSUNION
26
27 #include "config.h"
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <assert.h>
31
32 #ifndef DBGHELP_STATIC_LIB
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winnls.h"
36 #include "wine/debug.h"
37 #endif
38 #include "dbghelp_private.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
41 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
42
43 static const char* symt_get_tag_str(DWORD tag)
44 {
45 switch (tag)
46 {
47 case SymTagNull: return "SymTagNull";
48 case SymTagExe: return "SymTagExe";
49 case SymTagCompiland: return "SymTagCompiland";
50 case SymTagCompilandDetails: return "SymTagCompilandDetails";
51 case SymTagCompilandEnv: return "SymTagCompilandEnv";
52 case SymTagFunction: return "SymTagFunction";
53 case SymTagBlock: return "SymTagBlock";
54 case SymTagData: return "SymTagData";
55 case SymTagAnnotation: return "SymTagAnnotation";
56 case SymTagLabel: return "SymTagLabel";
57 case SymTagPublicSymbol: return "SymTagPublicSymbol";
58 case SymTagUDT: return "SymTagUDT";
59 case SymTagEnum: return "SymTagEnum";
60 case SymTagFunctionType: return "SymTagFunctionType";
61 case SymTagPointerType: return "SymTagPointerType";
62 case SymTagArrayType: return "SymTagArrayType";
63 case SymTagBaseType: return "SymTagBaseType";
64 case SymTagTypedef: return "SymTagTypedef,";
65 case SymTagBaseClass: return "SymTagBaseClass";
66 case SymTagFriend: return "SymTagFriend";
67 case SymTagFunctionArgType: return "SymTagFunctionArgType,";
68 case SymTagFuncDebugStart: return "SymTagFuncDebugStart,";
69 case SymTagFuncDebugEnd: return "SymTagFuncDebugEnd";
70 case SymTagUsingNamespace: return "SymTagUsingNamespace,";
71 case SymTagVTableShape: return "SymTagVTableShape";
72 case SymTagVTable: return "SymTagVTable";
73 case SymTagCustom: return "SymTagCustom";
74 case SymTagThunk: return "SymTagThunk";
75 case SymTagCustomType: return "SymTagCustomType";
76 case SymTagManagedType: return "SymTagManagedType";
77 case SymTagDimension: return "SymTagDimension";
78 default: return "---";
79 }
80 }
81
82 const char* symt_get_name(const struct symt* sym)
83 {
84 switch (sym->tag)
85 {
86 /* lexical tree */
87 case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name;
88 case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
89 case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name;
90 case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name;
91 case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name;
92 case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
93 /* hierarchy tree */
94 case SymTagEnum: return ((const struct symt_enum*)sym)->name;
95 case SymTagTypedef: return ((const struct symt_typedef*)sym)->hash_elt.name;
96 case SymTagUDT: return ((const struct symt_udt*)sym)->hash_elt.name;
97 default:
98 FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag));
99 /* fall through */
100 case SymTagArrayType:
101 case SymTagPointerType:
102 case SymTagFunctionType:
103 return NULL;
104 }
105 }
106
107 WCHAR* symt_get_nameW(const struct symt* sym)
108 {
109 const char* name = symt_get_name(sym);
110 WCHAR* nameW;
111 DWORD sz;
112
113 if (!name) return NULL;
114 sz = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
115 if ((nameW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
116 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, sz);
117 return nameW;
118 }
119
120 BOOL symt_get_address(const struct symt* type, ULONG64* addr)
121 {
122 switch (type->tag)
123 {
124 case SymTagData:
125 switch (((const struct symt_data*)type)->kind)
126 {
127 case DataIsGlobal:
128 case DataIsFileStatic:
129 *addr = ((const struct symt_data*)type)->u.var.offset;
130 break;
131 default: return FALSE;
132 }
133 break;
134 case SymTagFunction:
135 *addr = ((const struct symt_function*)type)->address;
136 break;
137 case SymTagPublicSymbol:
138 *addr = ((const struct symt_public*)type)->address;
139 break;
140 case SymTagFuncDebugStart:
141 case SymTagFuncDebugEnd:
142 case SymTagLabel:
143 if (!((const struct symt_hierarchy_point*)type)->parent ||
144 !symt_get_address(((const struct symt_hierarchy_point*)type)->parent, addr))
145 return FALSE;
146 *addr += ((const struct symt_hierarchy_point*)type)->loc.offset;
147 break;
148 case SymTagThunk:
149 *addr = ((const struct symt_thunk*)type)->address;
150 break;
151 case SymTagCompiland:
152 *addr = ((const struct symt_compiland*)type)->address;
153 break;
154 default:
155 FIXME("Unsupported sym-tag %s for get-address\n", symt_get_tag_str(type->tag));
156 return FALSE;
157 }
158 return TRUE;
159 }
160
161 static struct symt* symt_find_type_by_name(const struct module* module,
162 enum SymTagEnum sym_tag,
163 const char* typename)
164 {
165 void* ptr;
166 struct symt_ht* type;
167 struct hash_table_iter hti;
168
169 assert(typename);
170 assert(module);
171
172 hash_table_iter_init(&module->ht_types, &hti, typename);
173 while ((ptr = hash_table_iter_up(&hti)))
174 {
175 type = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
176
177 if ((sym_tag == SymTagNull || type->symt.tag == sym_tag) &&
178 type->hash_elt.name && !strcmp(type->hash_elt.name, typename))
179 return &type->symt;
180 }
181 SetLastError(ERROR_INVALID_NAME); /* FIXME ?? */
182 return NULL;
183 }
184
185 static void symt_add_type(struct module* module, struct symt* symt)
186 {
187 struct symt** p;
188 p = vector_add(&module->vtypes, &module->pool);
189 assert(p);
190 *p = symt;
191 }
192
193 struct symt_basic* symt_new_basic(struct module* module, enum BasicType bt,
194 const char* typename, unsigned size)
195 {
196 struct symt_basic* sym;
197
198 if (typename)
199 {
200 sym = (struct symt_basic*)symt_find_type_by_name(module, SymTagBaseType,
201 typename);
202 if (sym && sym->bt == bt && sym->size == size)
203 return sym;
204 }
205 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
206 {
207 sym->symt.tag = SymTagBaseType;
208 if (typename)
209 {
210 sym->hash_elt.name = pool_strdup(&module->pool, typename);
211 hash_table_add(&module->ht_types, &sym->hash_elt);
212 } else sym->hash_elt.name = NULL;
213 sym->bt = bt;
214 sym->size = size;
215 symt_add_type(module, &sym->symt);
216 }
217 return sym;
218 }
219
220 struct symt_udt* symt_new_udt(struct module* module, const char* typename,
221 unsigned size, enum UdtKind kind)
222 {
223 struct symt_udt* sym;
224
225 TRACE_(dbghelp_symt)("Adding udt %s:%s\n",
226 debugstr_w(module->module.ModuleName), typename);
227 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
228 {
229 sym->symt.tag = SymTagUDT;
230 sym->kind = kind;
231 sym->size = size;
232 if (typename)
233 {
234 sym->hash_elt.name = pool_strdup(&module->pool, typename);
235 hash_table_add(&module->ht_types, &sym->hash_elt);
236 } else sym->hash_elt.name = NULL;
237 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
238 symt_add_type(module, &sym->symt);
239 }
240 return sym;
241 }
242
243 BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned size)
244 {
245 assert(udt->symt.tag == SymTagUDT);
246 if (vector_length(&udt->vchildren) != 0)
247 {
248 if (udt->size != size)
249 FIXME_(dbghelp_symt)("Changing size for %s from %u to %u\n",
250 udt->hash_elt.name, udt->size, size);
251 return TRUE;
252 }
253 udt->size = size;
254 return TRUE;
255 }
256
257 /******************************************************************
258 * symt_add_udt_element
259 *
260 * add an element to a udt (struct, class, union)
261 * the size & offset parameters are expressed in bits (not bytes) so that
262 * we can mix in the single call bytes aligned elements (regular fields) and
263 * the others (bit fields)
264 */
265 BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
266 const char* name, struct symt* elt_type,
267 unsigned offset, unsigned size)
268 {
269 struct symt_data* m;
270 struct symt** p;
271
272 assert(udt_type->symt.tag == SymTagUDT);
273
274 TRACE_(dbghelp_symt)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name);
275 if (name)
276 {
277 unsigned int i;
278 for (i=0; i<vector_length(&udt_type->vchildren); i++)
279 {
280 m = *(struct symt_data**)vector_at(&udt_type->vchildren, i);
281 assert(m);
282 assert(m->symt.tag == SymTagData);
283 if (strcmp(m->hash_elt.name, name) == 0)
284 return TRUE;
285 }
286 }
287
288 if ((m = pool_alloc(&module->pool, sizeof(*m))) == NULL) return FALSE;
289 memset(m, 0, sizeof(*m));
290 m->symt.tag = SymTagData;
291 m->hash_elt.name = name ? pool_strdup(&module->pool, name) : "";
292 m->hash_elt.next = NULL;
293
294 m->kind = DataIsMember;
295 m->container = &udt_type->symt;
296 m->type = elt_type;
297 m->u.member.offset = offset;
298 m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0;
299 p = vector_add(&udt_type->vchildren, &module->pool);
300 *p = &m->symt;
301
302 return TRUE;
303 }
304
305 struct symt_enum* symt_new_enum(struct module* module, const char* typename,
306 struct symt* basetype)
307 {
308 struct symt_enum* sym;
309
310 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
311 {
312 sym->symt.tag = SymTagEnum;
313 sym->name = (typename) ? pool_strdup(&module->pool, typename) : NULL;
314 sym->base_type = basetype;
315 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
316 }
317 return sym;
318 }
319
320 BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type,
321 const char* name, int value)
322 {
323 struct symt_data* e;
324 struct symt** p;
325
326 assert(enum_type->symt.tag == SymTagEnum);
327 e = pool_alloc(&module->pool, sizeof(*e));
328 if (e == NULL) return FALSE;
329
330 e->symt.tag = SymTagData;
331 e->hash_elt.name = pool_strdup(&module->pool, name);
332 e->hash_elt.next = NULL;
333 e->kind = DataIsConstant;
334 e->container = &enum_type->symt;
335 e->type = enum_type->base_type;
336 e->u.value.n1.n2.vt = VT_I4;
337 e->u.value.n1.n2.n3.lVal = value;
338
339 p = vector_add(&enum_type->vchildren, &module->pool);
340 if (!p) return FALSE; /* FIXME we leak e */
341 *p = &e->symt;
342
343 return TRUE;
344 }
345
346 struct symt_array* symt_new_array(struct module* module, int min, int max,
347 struct symt* base, struct symt* index)
348 {
349 struct symt_array* sym;
350
351 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
352 {
353 sym->symt.tag = SymTagArrayType;
354 sym->start = min;
355 sym->end = max;
356 sym->base_type = base;
357 sym->index_type = index;
358 symt_add_type(module, &sym->symt);
359 }
360 return sym;
361 }
362
363 static inline DWORD symt_array_count(struct module* module, const struct symt_array* array)
364 {
365 if (array->end < 0)
366 {
367 DWORD64 elem_size;
368 /* One could want to also set the array->end field in array, but we won't do it
369 * as long as all the get_type() helpers use const objects
370 */
371 if (symt_get_info(module, array->base_type, TI_GET_LENGTH, &elem_size) && elem_size)
372 return -array->end / (DWORD)elem_size;
373 return 0;
374 }
375 return array->end - array->start + 1;
376 }
377
378 struct symt_function_signature* symt_new_function_signature(struct module* module,
379 struct symt* ret_type,
380 enum CV_call_e call_conv)
381 {
382 struct symt_function_signature* sym;
383
384 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
385 {
386 sym->symt.tag = SymTagFunctionType;
387 sym->rettype = ret_type;
388 vector_init(&sym->vchildren, sizeof(struct symt*), 4);
389 sym->call_conv = call_conv;
390 symt_add_type(module, &sym->symt);
391 }
392 return sym;
393 }
394
395 BOOL symt_add_function_signature_parameter(struct module* module,
396 struct symt_function_signature* sig_type,
397 struct symt* param)
398 {
399 struct symt** p;
400 struct symt_function_arg_type* arg;
401
402 assert(sig_type->symt.tag == SymTagFunctionType);
403 arg = pool_alloc(&module->pool, sizeof(*arg));
404 if (!arg) return FALSE;
405 arg->symt.tag = SymTagFunctionArgType;
406 arg->arg_type = param;
407 arg->container = &sig_type->symt;
408 p = vector_add(&sig_type->vchildren, &module->pool);
409 if (!p) return FALSE; /* FIXME we leak arg */
410 *p = &arg->symt;
411
412 return TRUE;
413 }
414
415 struct symt_pointer* symt_new_pointer(struct module* module, struct symt* ref_type, unsigned long size)
416 {
417 struct symt_pointer* sym;
418
419 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
420 {
421 sym->symt.tag = SymTagPointerType;
422 sym->pointsto = ref_type;
423 sym->size = size;
424 symt_add_type(module, &sym->symt);
425 }
426 return sym;
427 }
428
429 struct symt_typedef* symt_new_typedef(struct module* module, struct symt* ref,
430 const char* name)
431 {
432 struct symt_typedef* sym;
433
434 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
435 {
436 sym->symt.tag = SymTagTypedef;
437 sym->type = ref;
438 sym->hash_elt.name = pool_strdup(&module->pool, name);
439 hash_table_add(&module->ht_types, &sym->hash_elt);
440 symt_add_type(module, &sym->symt);
441 }
442 return sym;
443 }
444
445 /******************************************************************
446 * SymEnumTypes (DBGHELP.@)
447 *
448 */
449 BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
450 PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
451 PVOID UserContext)
452 {
453 struct module_pair pair;
454 char buffer[sizeof(SYMBOL_INFO) + 256];
455 SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
456 const char* tmp;
457 struct symt* type;
458 DWORD64 size;
459 unsigned int i;
460
461 TRACE("(%p %s %p %p)\n",
462 hProcess, wine_dbgstr_longlong(BaseOfDll), EnumSymbolsCallback,
463 UserContext);
464
465 if (!(pair.pcs = process_find_by_handle(hProcess))) return FALSE;
466 pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
467 if (!module_get_debug(&pair)) return FALSE;
468
469 sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
470 sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
471
472 for (i=0; i<vector_length(&pair.effective->vtypes); i++)
473 {
474 type = *(struct symt**)vector_at(&pair.effective->vtypes, i);
475 sym_info->TypeIndex = symt_ptr2index(pair.effective, type);
476 sym_info->Index = 0; /* FIXME */
477 symt_get_info(pair.effective, type, TI_GET_LENGTH, &size);
478 sym_info->Size = size;
479 sym_info->ModBase = pair.requested->module.BaseOfImage;
480 sym_info->Flags = 0; /* FIXME */
481 sym_info->Value = 0; /* FIXME */
482 sym_info->Address = 0; /* FIXME */
483 sym_info->Register = 0; /* FIXME */
484 sym_info->Scope = 0; /* FIXME */
485 sym_info->Tag = type->tag;
486 tmp = symt_get_name(type);
487 if (tmp)
488 {
489 sym_info->NameLen = min(strlen(tmp),sym_info->MaxNameLen-1);
490 memcpy(sym_info->Name, tmp, sym_info->NameLen);
491 sym_info->Name[sym_info->NameLen] = '\0';
492 }
493 else
494 sym_info->Name[sym_info->NameLen = 0] = '\0';
495 if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break;
496 }
497 return TRUE;
498 }
499
500 struct enum_types_AtoW
501 {
502 char buffer[sizeof(SYMBOL_INFOW) + 256 * sizeof(WCHAR)];
503 void* user;
504 PSYM_ENUMERATESYMBOLS_CALLBACKW callback;
505 };
506
507 static BOOL CALLBACK enum_types_AtoW(PSYMBOL_INFO si, ULONG addr, PVOID _et)
508 {
509 struct enum_types_AtoW* et = _et;
510 SYMBOL_INFOW* siW = (SYMBOL_INFOW*)et->buffer;
511
512 copy_symbolW(siW, si);
513 return et->callback(siW, addr, et->user);
514 }
515
516 /******************************************************************
517 * SymEnumTypesW (DBGHELP.@)
518 *
519 */
520 BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll,
521 PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
522 PVOID UserContext)
523 {
524 struct enum_types_AtoW et;
525
526 et.callback = EnumSymbolsCallback;
527 et.user = UserContext;
528
529 return SymEnumTypes(hProcess, BaseOfDll, enum_types_AtoW, &et);
530 }
531
532 /******************************************************************
533 * symt_get_info
534 *
535 * Retrieves information about a symt (either symbol or type)
536 */
537 BOOL symt_get_info(struct module* module, const struct symt* type,
538 IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo)
539 {
540 unsigned len;
541
542 if (!type) return FALSE;
543
544 /* helper to typecast pInfo to its expected type (_t) */
545 #define X(_t) (*((_t*)pInfo))
546
547 switch (req)
548 {
549 case TI_FINDCHILDREN:
550 {
551 const struct vector* v;
552 struct symt** pt;
553 unsigned i;
554 TI_FINDCHILDREN_PARAMS* tifp = pInfo;
555
556 switch (type->tag)
557 {
558 case SymTagUDT: v = &((const struct symt_udt*)type)->vchildren; break;
559 case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break;
560 case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break;
561 case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break;
562 default:
563 FIXME("Unsupported sym-tag %s for find-children\n",
564 symt_get_tag_str(type->tag));
565 return FALSE;
566 }
567 for (i = 0; i < tifp->Count; i++)
568 {
569 if (!(pt = vector_at(v, tifp->Start + i))) return FALSE;
570 tifp->ChildId[i] = symt_ptr2index(module, *pt);
571 }
572 }
573 break;
574
575 case TI_GET_ADDRESS:
576 return symt_get_address(type, (ULONG64*)pInfo);
577
578 case TI_GET_BASETYPE:
579 switch (type->tag)
580 {
581 case SymTagBaseType:
582 X(DWORD) = ((const struct symt_basic*)type)->bt;
583 break;
584 case SymTagEnum:
585 X(DWORD) = btInt;
586 break;
587 default:
588 return FALSE;
589 }
590 break;
591
592 case TI_GET_BITPOSITION:
593 if (type->tag == SymTagData &&
594 ((const struct symt_data*)type)->kind == DataIsMember &&
595 ((const struct symt_data*)type)->u.member.length != 0)
596 X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7;
597 else return FALSE;
598 break;
599
600 case TI_GET_CHILDRENCOUNT:
601 switch (type->tag)
602 {
603 case SymTagUDT:
604 X(DWORD) = vector_length(&((const struct symt_udt*)type)->vchildren);
605 break;
606 case SymTagEnum:
607 X(DWORD) = vector_length(&((const struct symt_enum*)type)->vchildren);
608 break;
609 case SymTagFunctionType:
610 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
611 break;
612 case SymTagFunction:
613 X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren);
614 break;
615 case SymTagPointerType: /* MS does it that way */
616 case SymTagArrayType: /* MS does it that way */
617 case SymTagThunk: /* MS does it that way */
618 X(DWORD) = 0;
619 break;
620 default:
621 FIXME("Unsupported sym-tag %s for get-children-count\n",
622 symt_get_tag_str(type->tag));
623 /* fall through */
624 case SymTagData:
625 case SymTagPublicSymbol:
626 case SymTagBaseType:
627 return FALSE;
628 }
629 break;
630
631 case TI_GET_COUNT:
632 switch (type->tag)
633 {
634 case SymTagArrayType:
635 X(DWORD) = symt_array_count(module, (const struct symt_array*)type);
636 break;
637 case SymTagFunctionType:
638 /* this seems to be wrong for (future) C++ methods, where 'this' parameter
639 * should be included in this value (and not in GET_CHILDREN_COUNT)
640 */
641 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
642 break;
643 default: return FALSE;
644 }
645 break;
646
647 case TI_GET_DATAKIND:
648 if (type->tag != SymTagData) return FALSE;
649 X(DWORD) = ((const struct symt_data*)type)->kind;
650 break;
651
652 case TI_GET_LENGTH:
653 switch (type->tag)
654 {
655 case SymTagBaseType:
656 X(DWORD64) = ((const struct symt_basic*)type)->size;
657 break;
658 case SymTagFunction:
659 X(DWORD64) = ((const struct symt_function*)type)->size;
660 break;
661 case SymTagPointerType:
662 X(DWORD64) = ((const struct symt_pointer*)type)->size;
663 break;
664 case SymTagUDT:
665 X(DWORD64) = ((const struct symt_udt*)type)->size;
666 break;
667 case SymTagEnum:
668 X(DWORD64) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */
669 break;
670 case SymTagData:
671 if (((const struct symt_data*)type)->kind != DataIsMember ||
672 !((const struct symt_data*)type)->u.member.length)
673 return FALSE;
674 X(DWORD64) = ((const struct symt_data*)type)->u.member.length;
675 break;
676 case SymTagArrayType:
677 if (!symt_get_info(module, ((const struct symt_array*)type)->base_type,
678 TI_GET_LENGTH, pInfo))
679 return FALSE;
680 X(DWORD64) *= symt_array_count(module, (const struct symt_array*)type);
681 break;
682 case SymTagPublicSymbol:
683 X(DWORD64) = ((const struct symt_public*)type)->size;
684 break;
685 case SymTagTypedef:
686 return symt_get_info(module, ((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
687 case SymTagThunk:
688 X(DWORD64) = ((const struct symt_thunk*)type)->size;
689 break;
690 case SymTagLabel:
691 X(DWORD64) = 0;
692 break;
693 default:
694 FIXME("Unsupported sym-tag %s for get-length\n",
695 symt_get_tag_str(type->tag));
696 /* fall through */
697 case SymTagFunctionType:
698 return FALSE;
699 }
700 break;
701
702 case TI_GET_LEXICALPARENT:
703 switch (type->tag)
704 {
705 case SymTagBlock:
706 X(DWORD) = symt_ptr2index(module, ((const struct symt_block*)type)->container);
707 break;
708 case SymTagData:
709 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->container);
710 break;
711 case SymTagFunction:
712 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->container);
713 break;
714 case SymTagThunk:
715 X(DWORD) = symt_ptr2index(module, ((const struct symt_thunk*)type)->container);
716 break;
717 case SymTagFunctionArgType:
718 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->container);
719 break;
720 default:
721 FIXME("Unsupported sym-tag %s for get-lexical-parent\n",
722 symt_get_tag_str(type->tag));
723 return FALSE;
724 }
725 break;
726
727 case TI_GET_NESTED:
728 switch (type->tag)
729 {
730 case SymTagUDT:
731 case SymTagEnum:
732 X(DWORD) = 0;
733 break;
734 default:
735 return FALSE;
736 }
737 break;
738
739 case TI_GET_OFFSET:
740 switch (type->tag)
741 {
742 case SymTagData:
743 switch (((const struct symt_data*)type)->kind)
744 {
745 case DataIsParam:
746 case DataIsLocal:
747 X(ULONG) = ((const struct symt_data*)type)->u.var.offset;
748 break;
749 case DataIsMember:
750 X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3;
751 break;
752 default:
753 FIXME("Unknown kind (%u) for get-offset\n",
754 ((const struct symt_data*)type)->kind);
755 return FALSE;
756 }
757 break;
758 default:
759 FIXME("Unsupported sym-tag %s for get-offset\n",
760 symt_get_tag_str(type->tag));
761 return FALSE;
762 }
763 break;
764
765 case TI_GET_SYMNAME:
766 {
767 const char* name = symt_get_name(type);
768 if (!name) return FALSE;
769 len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
770 X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
771 if (!X(WCHAR*)) return FALSE;
772 MultiByteToWideChar(CP_ACP, 0, name, -1, X(WCHAR*), len);
773 }
774 break;
775
776 case TI_GET_SYMTAG:
777 X(DWORD) = type->tag;
778 break;
779
780 case TI_GET_TYPE:
781 case TI_GET_TYPEID:
782 switch (type->tag)
783 {
784 /* hierarchical => hierarchical */
785 case SymTagArrayType:
786 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->base_type);
787 break;
788 case SymTagPointerType:
789 X(DWORD) = symt_ptr2index(module, ((const struct symt_pointer*)type)->pointsto);
790 break;
791 case SymTagFunctionType:
792 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_signature*)type)->rettype);
793 break;
794 case SymTagTypedef:
795 X(DWORD) = symt_ptr2index(module, ((const struct symt_typedef*)type)->type);
796 break;
797 /* lexical => hierarchical */
798 case SymTagData:
799 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->type);
800 break;
801 case SymTagFunction:
802 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->type);
803 break;
804 case SymTagEnum:
805 X(DWORD) = symt_ptr2index(module, ((const struct symt_enum*)type)->base_type);
806 break;
807 case SymTagFunctionArgType:
808 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->arg_type);
809 break;
810 default:
811 FIXME("Unsupported sym-tag %s for get-type\n",
812 symt_get_tag_str(type->tag));
813 /* fall through */
814 case SymTagPublicSymbol:
815 case SymTagThunk:
816 case SymTagLabel:
817 return FALSE;
818 }
819 break;
820
821 case TI_GET_UDTKIND:
822 if (type->tag != SymTagUDT) return FALSE;
823 X(DWORD) = ((const struct symt_udt*)type)->kind;
824 break;
825
826 case TI_GET_VALUE:
827 if (type->tag != SymTagData) return FALSE;
828 switch (((const struct symt_data*)type)->kind)
829 {
830 case DataIsConstant: X(VARIANT) = ((const struct symt_data*)type)->u.value; break;
831 case DataIsLocal:
832 case DataIsParam:
833 {
834 struct location loc = ((const struct symt_data*)type)->u.var;
835 unsigned i;
836 struct module_format* modfmt;
837
838 if (loc.kind < loc_user) return FALSE;
839 for (i = 0; i < DFI_LAST; i++)
840 {
841 modfmt = module->format_info[i];
842 if (modfmt && modfmt->loc_compute)
843 {
844 modfmt->loc_compute(module->process, modfmt,
845 (const struct symt_function*)((const struct symt_data*)type)->container, &loc);
846 break;
847 }
848 }
849 if (loc.kind != loc_absolute) return FALSE;
850 X(VARIANT).n1.n2.vt = VT_UI4; /* FIXME */
851 X(VARIANT).n1.n2.n3.uiVal = loc.offset;
852 }
853 break;
854 default: return FALSE;
855 }
856 break;
857
858 case TI_GET_CALLING_CONVENTION:
859 if (type->tag != SymTagFunctionType) return FALSE;
860 if (((const struct symt_function_signature*)type)->call_conv == -1)
861 {
862 FIXME("No support for calling convention for this signature\n");
863 X(DWORD) = CV_CALL_FAR_C; /* FIXME */
864 }
865 else X(DWORD) = ((const struct symt_function_signature*)type)->call_conv;
866 break;
867 case TI_GET_ARRAYINDEXTYPEID:
868 if (type->tag != SymTagArrayType) return FALSE;
869 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->index_type);
870 break;
871
872 case TI_GET_CLASSPARENTID:
873 /* FIXME: we don't support properly C++ for now, pretend this symbol doesn't
874 * belong to a parent class
875 */
876 return FALSE;
877
878 #undef X
879
880 case TI_GET_ADDRESSOFFSET:
881 case TI_GET_SYMINDEX:
882 case TI_GET_THISADJUST:
883 case TI_GET_VIRTUALBASECLASS:
884 case TI_GET_VIRTUALBASEPOINTEROFFSET:
885 case TI_GET_VIRTUALTABLESHAPEID:
886 case TI_IS_EQUIV_TO:
887 FIXME("Unsupported GetInfo request (%u)\n", req);
888 return FALSE;
889 default:
890 FIXME("Unknown GetInfo request (%u)\n", req);
891 return FALSE;
892 }
893
894 return TRUE;
895 }
896
897 /******************************************************************
898 * SymGetTypeInfo (DBGHELP.@)
899 *
900 */
901 BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase,
902 ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType,
903 PVOID pInfo)
904 {
905 struct module_pair pair;
906
907 pair.pcs = process_find_by_handle(hProcess);
908 if (!pair.pcs) return FALSE;
909
910 pair.requested = module_find_by_addr(pair.pcs, ModBase, DMT_UNKNOWN);
911 if (!module_get_debug(&pair))
912 {
913 FIXME("Someone didn't properly set ModBase (%s)\n", wine_dbgstr_longlong(ModBase));
914 return FALSE;
915 }
916
917 return symt_get_info(pair.effective, symt_index2ptr(pair.effective, TypeId), GetType, pInfo);
918 }
919
920 /******************************************************************
921 * SymGetTypeFromName (DBGHELP.@)
922 *
923 */
924 BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, ULONG64 BaseOfDll,
925 PCSTR Name, PSYMBOL_INFO Symbol)
926 {
927 struct process* pcs = process_find_by_handle(hProcess);
928 struct module_pair pair;
929 struct symt* type;
930
931 if (!pcs) return FALSE;
932 pair.requested = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
933 if (!module_get_debug(&pair)) return FALSE;
934 type = symt_find_type_by_name(pair.effective, SymTagNull, Name);
935 if (!type) return FALSE;
936 Symbol->TypeIndex = symt_ptr2index(pair.effective, type);
937
938 return TRUE;
939 }