d3dx10: Check device in d3dx10_sprite_GetDevice().
[wine.git] / dlls / dbghelp / type.c
blob374b69aeb08e2520e1a9060a0b303b0354a01a75
1 /*
2 * File types.c - management of types (hierarchical tree)
4 * Copyright (C) 1997, Eric Youngdale.
5 * 2004, Eric Pouech.
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.
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.
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
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.
25 #define NONAMELESSUNION
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <assert.h>
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winnls.h"
34 #include "wine/debug.h"
35 #include "dbghelp_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
38 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
40 static const char* symt_get_tag_str(DWORD tag)
42 switch (tag)
44 case SymTagNull: return "SymTagNull";
45 case SymTagExe: return "SymTagExe";
46 case SymTagCompiland: return "SymTagCompiland";
47 case SymTagCompilandDetails: return "SymTagCompilandDetails";
48 case SymTagCompilandEnv: return "SymTagCompilandEnv";
49 case SymTagFunction: return "SymTagFunction";
50 case SymTagBlock: return "SymTagBlock";
51 case SymTagData: return "SymTagData";
52 case SymTagAnnotation: return "SymTagAnnotation";
53 case SymTagLabel: return "SymTagLabel";
54 case SymTagPublicSymbol: return "SymTagPublicSymbol";
55 case SymTagUDT: return "SymTagUDT";
56 case SymTagEnum: return "SymTagEnum";
57 case SymTagFunctionType: return "SymTagFunctionType";
58 case SymTagPointerType: return "SymTagPointerType";
59 case SymTagArrayType: return "SymTagArrayType";
60 case SymTagBaseType: return "SymTagBaseType";
61 case SymTagTypedef: return "SymTagTypedef,";
62 case SymTagBaseClass: return "SymTagBaseClass";
63 case SymTagFriend: return "SymTagFriend";
64 case SymTagFunctionArgType: return "SymTagFunctionArgType,";
65 case SymTagFuncDebugStart: return "SymTagFuncDebugStart,";
66 case SymTagFuncDebugEnd: return "SymTagFuncDebugEnd";
67 case SymTagUsingNamespace: return "SymTagUsingNamespace,";
68 case SymTagVTableShape: return "SymTagVTableShape";
69 case SymTagVTable: return "SymTagVTable";
70 case SymTagCustom: return "SymTagCustom";
71 case SymTagThunk: return "SymTagThunk";
72 case SymTagCustomType: return "SymTagCustomType";
73 case SymTagManagedType: return "SymTagManagedType";
74 case SymTagDimension: return "SymTagDimension";
75 default: return "---";
79 const char* symt_get_name(const struct symt* sym)
81 switch (sym->tag)
83 /* lexical tree */
84 case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name;
85 case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
86 case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name;
87 case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name;
88 case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name;
89 case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
90 /* hierarchy tree */
91 case SymTagEnum: return ((const struct symt_enum*)sym)->name;
92 case SymTagTypedef: return ((const struct symt_typedef*)sym)->hash_elt.name;
93 case SymTagUDT: return ((const struct symt_udt*)sym)->hash_elt.name;
94 default:
95 FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag));
96 /* fall through */
97 case SymTagArrayType:
98 case SymTagPointerType:
99 case SymTagFunctionType:
100 return NULL;
104 WCHAR* symt_get_nameW(const struct symt* sym)
106 const char* name = symt_get_name(sym);
107 WCHAR* nameW;
108 DWORD sz;
110 if (!name) return NULL;
111 sz = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
112 if ((nameW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
113 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, sz);
114 return nameW;
117 BOOL symt_get_address(const struct symt* type, ULONG64* addr)
119 switch (type->tag)
121 case SymTagData:
122 switch (((const struct symt_data*)type)->kind)
124 case DataIsGlobal:
125 case DataIsFileStatic:
126 *addr = ((const struct symt_data*)type)->u.var.offset;
127 break;
128 default: return FALSE;
130 break;
131 case SymTagFunction:
132 *addr = ((const struct symt_function*)type)->address;
133 break;
134 case SymTagPublicSymbol:
135 *addr = ((const struct symt_public*)type)->address;
136 break;
137 case SymTagFuncDebugStart:
138 case SymTagFuncDebugEnd:
139 case SymTagLabel:
140 if (!((const struct symt_hierarchy_point*)type)->parent ||
141 !symt_get_address(((const struct symt_hierarchy_point*)type)->parent, addr))
142 return FALSE;
143 *addr += ((const struct symt_hierarchy_point*)type)->loc.offset;
144 break;
145 case SymTagThunk:
146 *addr = ((const struct symt_thunk*)type)->address;
147 break;
148 case SymTagCompiland:
149 *addr = ((const struct symt_compiland*)type)->address;
150 break;
151 default:
152 FIXME("Unsupported sym-tag %s for get-address\n", symt_get_tag_str(type->tag));
153 return FALSE;
155 return TRUE;
158 static struct symt* symt_find_type_by_name(const struct module* module,
159 enum SymTagEnum sym_tag,
160 const char* typename)
162 void* ptr;
163 struct symt_ht* type;
164 struct hash_table_iter hti;
166 assert(typename);
167 assert(module);
169 hash_table_iter_init(&module->ht_types, &hti, typename);
170 while ((ptr = hash_table_iter_up(&hti)))
172 type = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
174 if ((sym_tag == SymTagNull || type->symt.tag == sym_tag) &&
175 type->hash_elt.name && !strcmp(type->hash_elt.name, typename))
176 return &type->symt;
178 SetLastError(ERROR_INVALID_NAME); /* FIXME ?? */
179 return NULL;
182 static void symt_add_type(struct module* module, struct symt* symt)
184 struct symt** p;
185 p = vector_add(&module->vtypes, &module->pool);
186 assert(p);
187 *p = symt;
190 struct symt_basic* symt_new_basic(struct module* module, enum BasicType bt,
191 const char* typename, unsigned size)
193 struct symt_basic* sym;
195 if (typename)
197 sym = (struct symt_basic*)symt_find_type_by_name(module, SymTagBaseType,
198 typename);
199 if (sym && sym->bt == bt && sym->size == size)
200 return sym;
202 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
204 sym->symt.tag = SymTagBaseType;
205 if (typename)
207 sym->hash_elt.name = pool_strdup(&module->pool, typename);
208 hash_table_add(&module->ht_types, &sym->hash_elt);
209 } else sym->hash_elt.name = NULL;
210 sym->bt = bt;
211 sym->size = size;
212 symt_add_type(module, &sym->symt);
214 return sym;
217 struct symt_udt* symt_new_udt(struct module* module, const char* typename,
218 unsigned size, enum UdtKind kind)
220 struct symt_udt* sym;
222 TRACE_(dbghelp_symt)("Adding udt %s:%s\n",
223 debugstr_w(module->module.ModuleName), typename);
224 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
226 sym->symt.tag = SymTagUDT;
227 sym->kind = kind;
228 sym->size = size;
229 if (typename)
231 sym->hash_elt.name = pool_strdup(&module->pool, typename);
232 hash_table_add(&module->ht_types, &sym->hash_elt);
233 } else sym->hash_elt.name = NULL;
234 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
235 symt_add_type(module, &sym->symt);
237 return sym;
240 BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned size)
242 assert(udt->symt.tag == SymTagUDT);
243 if (vector_length(&udt->vchildren) != 0)
245 if (udt->size != size)
246 FIXME_(dbghelp_symt)("Changing size for %s from %u to %u\n",
247 udt->hash_elt.name, udt->size, size);
248 return TRUE;
250 udt->size = size;
251 return TRUE;
254 /******************************************************************
255 * symt_add_udt_element
257 * add an element to a udt (struct, class, union)
258 * the size & offset parameters are expressed in bits (not bytes) so that
259 * we can mix in the single call bytes aligned elements (regular fields) and
260 * the others (bit fields)
262 BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
263 const char* name, struct symt* elt_type,
264 unsigned offset, unsigned size)
266 struct symt_data* m;
267 struct symt** p;
269 assert(udt_type->symt.tag == SymTagUDT);
271 TRACE_(dbghelp_symt)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name);
272 if (name)
274 unsigned int i;
275 for (i=0; i<vector_length(&udt_type->vchildren); i++)
277 m = *(struct symt_data**)vector_at(&udt_type->vchildren, i);
278 assert(m);
279 assert(m->symt.tag == SymTagData);
280 if (strcmp(m->hash_elt.name, name) == 0)
281 return TRUE;
285 if ((m = pool_alloc(&module->pool, sizeof(*m))) == NULL) return FALSE;
286 memset(m, 0, sizeof(*m));
287 m->symt.tag = SymTagData;
288 m->hash_elt.name = name ? pool_strdup(&module->pool, name) : "";
289 m->hash_elt.next = NULL;
291 m->kind = DataIsMember;
292 m->container = &udt_type->symt;
293 m->type = elt_type;
294 m->u.member.offset = offset;
295 m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0;
296 p = vector_add(&udt_type->vchildren, &module->pool);
297 *p = &m->symt;
299 return TRUE;
302 struct symt_enum* symt_new_enum(struct module* module, const char* typename,
303 struct symt* basetype)
305 struct symt_enum* sym;
307 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
309 sym->symt.tag = SymTagEnum;
310 sym->name = (typename) ? pool_strdup(&module->pool, typename) : NULL;
311 sym->base_type = basetype;
312 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
314 return sym;
317 BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type,
318 const char* name, int value)
320 struct symt_data* e;
321 struct symt** p;
323 assert(enum_type->symt.tag == SymTagEnum);
324 e = pool_alloc(&module->pool, sizeof(*e));
325 if (e == NULL) return FALSE;
327 e->symt.tag = SymTagData;
328 e->hash_elt.name = pool_strdup(&module->pool, name);
329 e->hash_elt.next = NULL;
330 e->kind = DataIsConstant;
331 e->container = &enum_type->symt;
332 e->type = enum_type->base_type;
333 e->u.value.n1.n2.vt = VT_I4;
334 e->u.value.n1.n2.n3.lVal = value;
336 p = vector_add(&enum_type->vchildren, &module->pool);
337 if (!p) return FALSE; /* FIXME we leak e */
338 *p = &e->symt;
340 return TRUE;
343 struct symt_array* symt_new_array(struct module* module, int min, int max,
344 struct symt* base, struct symt* index)
346 struct symt_array* sym;
348 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
350 sym->symt.tag = SymTagArrayType;
351 sym->start = min;
352 sym->end = max;
353 sym->base_type = base;
354 sym->index_type = index;
355 symt_add_type(module, &sym->symt);
357 return sym;
360 static inline DWORD symt_array_count(struct module* module, const struct symt_array* array)
362 if (array->end < 0)
364 DWORD64 elem_size;
365 /* One could want to also set the array->end field in array, but we won't do it
366 * as long as all the get_type() helpers use const objects
368 if (symt_get_info(module, array->base_type, TI_GET_LENGTH, &elem_size) && elem_size)
369 return -array->end / (DWORD)elem_size;
370 return 0;
372 return array->end - array->start + 1;
375 struct symt_function_signature* symt_new_function_signature(struct module* module,
376 struct symt* ret_type,
377 enum CV_call_e call_conv)
379 struct symt_function_signature* sym;
381 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
383 sym->symt.tag = SymTagFunctionType;
384 sym->rettype = ret_type;
385 vector_init(&sym->vchildren, sizeof(struct symt*), 4);
386 sym->call_conv = call_conv;
387 symt_add_type(module, &sym->symt);
389 return sym;
392 BOOL symt_add_function_signature_parameter(struct module* module,
393 struct symt_function_signature* sig_type,
394 struct symt* param)
396 struct symt** p;
397 struct symt_function_arg_type* arg;
399 assert(sig_type->symt.tag == SymTagFunctionType);
400 arg = pool_alloc(&module->pool, sizeof(*arg));
401 if (!arg) return FALSE;
402 arg->symt.tag = SymTagFunctionArgType;
403 arg->arg_type = param;
404 arg->container = &sig_type->symt;
405 p = vector_add(&sig_type->vchildren, &module->pool);
406 if (!p) return FALSE; /* FIXME we leak arg */
407 *p = &arg->symt;
409 return TRUE;
412 struct symt_pointer* symt_new_pointer(struct module* module, struct symt* ref_type, ULONG_PTR size)
414 struct symt_pointer* sym;
416 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
418 sym->symt.tag = SymTagPointerType;
419 sym->pointsto = ref_type;
420 sym->size = size;
421 symt_add_type(module, &sym->symt);
423 return sym;
426 struct symt_typedef* symt_new_typedef(struct module* module, struct symt* ref,
427 const char* name)
429 struct symt_typedef* sym;
431 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
433 sym->symt.tag = SymTagTypedef;
434 sym->type = ref;
435 sym->hash_elt.name = pool_strdup(&module->pool, name);
436 hash_table_add(&module->ht_types, &sym->hash_elt);
437 symt_add_type(module, &sym->symt);
439 return sym;
442 /******************************************************************
443 * SymEnumTypes (DBGHELP.@)
446 BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
447 PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
448 PVOID UserContext)
450 struct module_pair pair;
451 char buffer[sizeof(SYMBOL_INFO) + 256];
452 SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
453 const char* tmp;
454 struct symt* type;
455 DWORD64 size;
456 unsigned int i;
458 TRACE("(%p %s %p %p)\n",
459 hProcess, wine_dbgstr_longlong(BaseOfDll), EnumSymbolsCallback,
460 UserContext);
462 if (!(pair.pcs = process_find_by_handle(hProcess))) return FALSE;
463 pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
464 if (!module_get_debug(&pair)) return FALSE;
466 sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
467 sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
469 for (i=0; i<vector_length(&pair.effective->vtypes); i++)
471 type = *(struct symt**)vector_at(&pair.effective->vtypes, i);
472 sym_info->TypeIndex = symt_ptr2index(pair.effective, type);
473 sym_info->Index = 0; /* FIXME */
474 symt_get_info(pair.effective, type, TI_GET_LENGTH, &size);
475 sym_info->Size = size;
476 sym_info->ModBase = pair.requested->module.BaseOfImage;
477 sym_info->Flags = 0; /* FIXME */
478 sym_info->Value = 0; /* FIXME */
479 sym_info->Address = 0; /* FIXME */
480 sym_info->Register = 0; /* FIXME */
481 sym_info->Scope = 0; /* FIXME */
482 sym_info->Tag = type->tag;
483 tmp = symt_get_name(type);
484 if (tmp)
486 sym_info->NameLen = min(strlen(tmp),sym_info->MaxNameLen-1);
487 memcpy(sym_info->Name, tmp, sym_info->NameLen);
488 sym_info->Name[sym_info->NameLen] = '\0';
490 else
491 sym_info->Name[sym_info->NameLen = 0] = '\0';
492 if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break;
494 return TRUE;
497 struct enum_types_AtoW
499 char buffer[sizeof(SYMBOL_INFOW) + 256 * sizeof(WCHAR)];
500 void* user;
501 PSYM_ENUMERATESYMBOLS_CALLBACKW callback;
504 static BOOL CALLBACK enum_types_AtoW(PSYMBOL_INFO si, ULONG addr, PVOID _et)
506 struct enum_types_AtoW* et = _et;
507 SYMBOL_INFOW* siW = (SYMBOL_INFOW*)et->buffer;
509 copy_symbolW(siW, si);
510 return et->callback(siW, addr, et->user);
513 /******************************************************************
514 * SymEnumTypesW (DBGHELP.@)
517 BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll,
518 PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
519 PVOID UserContext)
521 struct enum_types_AtoW et;
523 et.callback = EnumSymbolsCallback;
524 et.user = UserContext;
526 return SymEnumTypes(hProcess, BaseOfDll, enum_types_AtoW, &et);
529 /******************************************************************
530 * symt_get_info
532 * Retrieves information about a symt (either symbol or type)
534 BOOL symt_get_info(struct module* module, const struct symt* type,
535 IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo)
537 unsigned len;
539 if (!type) return FALSE;
541 /* helper to typecast pInfo to its expected type (_t) */
542 #define X(_t) (*((_t*)pInfo))
544 switch (req)
546 case TI_FINDCHILDREN:
548 const struct vector* v;
549 struct symt** pt;
550 unsigned i;
551 TI_FINDCHILDREN_PARAMS* tifp = pInfo;
553 switch (type->tag)
555 case SymTagUDT: v = &((const struct symt_udt*)type)->vchildren; break;
556 case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break;
557 case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break;
558 case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break;
559 default:
560 FIXME("Unsupported sym-tag %s for find-children\n",
561 symt_get_tag_str(type->tag));
562 return FALSE;
564 for (i = 0; i < tifp->Count; i++)
566 if (!(pt = vector_at(v, tifp->Start + i))) return FALSE;
567 tifp->ChildId[i] = symt_ptr2index(module, *pt);
570 break;
572 case TI_GET_ADDRESS:
573 return symt_get_address(type, (ULONG64*)pInfo);
575 case TI_GET_BASETYPE:
576 switch (type->tag)
578 case SymTagBaseType:
579 X(DWORD) = ((const struct symt_basic*)type)->bt;
580 break;
581 case SymTagEnum:
582 X(DWORD) = btInt;
583 break;
584 default:
585 return FALSE;
587 break;
589 case TI_GET_BITPOSITION:
590 if (type->tag == SymTagData &&
591 ((const struct symt_data*)type)->kind == DataIsMember &&
592 ((const struct symt_data*)type)->u.member.length != 0)
593 X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7;
594 else return FALSE;
595 break;
597 case TI_GET_CHILDRENCOUNT:
598 switch (type->tag)
600 case SymTagUDT:
601 X(DWORD) = vector_length(&((const struct symt_udt*)type)->vchildren);
602 break;
603 case SymTagEnum:
604 X(DWORD) = vector_length(&((const struct symt_enum*)type)->vchildren);
605 break;
606 case SymTagFunctionType:
607 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
608 break;
609 case SymTagFunction:
610 X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren);
611 break;
612 case SymTagPointerType: /* MS does it that way */
613 case SymTagArrayType: /* MS does it that way */
614 case SymTagThunk: /* MS does it that way */
615 X(DWORD) = 0;
616 break;
617 default:
618 FIXME("Unsupported sym-tag %s for get-children-count\n",
619 symt_get_tag_str(type->tag));
620 /* fall through */
621 case SymTagData:
622 case SymTagPublicSymbol:
623 case SymTagBaseType:
624 return FALSE;
626 break;
628 case TI_GET_COUNT:
629 switch (type->tag)
631 case SymTagArrayType:
632 X(DWORD) = symt_array_count(module, (const struct symt_array*)type);
633 break;
634 case SymTagFunctionType:
635 /* this seems to be wrong for (future) C++ methods, where 'this' parameter
636 * should be included in this value (and not in GET_CHILDREN_COUNT)
638 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
639 break;
640 default: return FALSE;
642 break;
644 case TI_GET_DATAKIND:
645 if (type->tag != SymTagData) return FALSE;
646 X(DWORD) = ((const struct symt_data*)type)->kind;
647 break;
649 case TI_GET_LENGTH:
650 switch (type->tag)
652 case SymTagBaseType:
653 X(DWORD64) = ((const struct symt_basic*)type)->size;
654 break;
655 case SymTagFunction:
656 X(DWORD64) = ((const struct symt_function*)type)->size;
657 break;
658 case SymTagPointerType:
659 X(DWORD64) = ((const struct symt_pointer*)type)->size;
660 break;
661 case SymTagUDT:
662 X(DWORD64) = ((const struct symt_udt*)type)->size;
663 break;
664 case SymTagEnum:
665 X(DWORD64) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */
666 break;
667 case SymTagData:
668 if (((const struct symt_data*)type)->kind != DataIsMember ||
669 !((const struct symt_data*)type)->u.member.length)
670 return FALSE;
671 X(DWORD64) = ((const struct symt_data*)type)->u.member.length;
672 break;
673 case SymTagArrayType:
674 if (!symt_get_info(module, ((const struct symt_array*)type)->base_type,
675 TI_GET_LENGTH, pInfo))
676 return FALSE;
677 X(DWORD64) *= symt_array_count(module, (const struct symt_array*)type);
678 break;
679 case SymTagPublicSymbol:
680 X(DWORD64) = ((const struct symt_public*)type)->size;
681 break;
682 case SymTagTypedef:
683 return symt_get_info(module, ((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
684 case SymTagThunk:
685 X(DWORD64) = ((const struct symt_thunk*)type)->size;
686 break;
687 case SymTagLabel:
688 X(DWORD64) = 0;
689 break;
690 default:
691 FIXME("Unsupported sym-tag %s for get-length\n",
692 symt_get_tag_str(type->tag));
693 /* fall through */
694 case SymTagFunctionType:
695 return FALSE;
697 break;
699 case TI_GET_LEXICALPARENT:
700 switch (type->tag)
702 case SymTagBlock:
703 X(DWORD) = symt_ptr2index(module, ((const struct symt_block*)type)->container);
704 break;
705 case SymTagData:
706 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->container);
707 break;
708 case SymTagFunction:
709 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->container);
710 break;
711 case SymTagThunk:
712 X(DWORD) = symt_ptr2index(module, ((const struct symt_thunk*)type)->container);
713 break;
714 case SymTagFunctionArgType:
715 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->container);
716 break;
717 default:
718 FIXME("Unsupported sym-tag %s for get-lexical-parent\n",
719 symt_get_tag_str(type->tag));
720 return FALSE;
722 break;
724 case TI_GET_NESTED:
725 switch (type->tag)
727 case SymTagUDT:
728 case SymTagEnum:
729 X(DWORD) = 0;
730 break;
731 default:
732 return FALSE;
734 break;
736 case TI_GET_OFFSET:
737 switch (type->tag)
739 case SymTagData:
740 switch (((const struct symt_data*)type)->kind)
742 case DataIsParam:
743 case DataIsLocal:
744 X(ULONG) = ((const struct symt_data*)type)->u.var.offset;
745 break;
746 case DataIsMember:
747 X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3;
748 break;
749 default:
750 FIXME("Unknown kind (%u) for get-offset\n",
751 ((const struct symt_data*)type)->kind);
752 return FALSE;
754 break;
755 default:
756 FIXME("Unsupported sym-tag %s for get-offset\n",
757 symt_get_tag_str(type->tag));
758 return FALSE;
760 break;
762 case TI_GET_SYMNAME:
764 const char* name = symt_get_name(type);
765 if (!name) return FALSE;
766 len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
767 X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
768 if (!X(WCHAR*)) return FALSE;
769 MultiByteToWideChar(CP_ACP, 0, name, -1, X(WCHAR*), len);
771 break;
773 case TI_GET_SYMTAG:
774 X(DWORD) = type->tag;
775 break;
777 case TI_GET_TYPE:
778 case TI_GET_TYPEID:
779 switch (type->tag)
781 /* hierarchical => hierarchical */
782 case SymTagArrayType:
783 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->base_type);
784 break;
785 case SymTagPointerType:
786 X(DWORD) = symt_ptr2index(module, ((const struct symt_pointer*)type)->pointsto);
787 break;
788 case SymTagFunctionType:
789 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_signature*)type)->rettype);
790 break;
791 case SymTagTypedef:
792 X(DWORD) = symt_ptr2index(module, ((const struct symt_typedef*)type)->type);
793 break;
794 /* lexical => hierarchical */
795 case SymTagData:
796 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->type);
797 break;
798 case SymTagFunction:
799 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->type);
800 break;
801 case SymTagEnum:
802 X(DWORD) = symt_ptr2index(module, ((const struct symt_enum*)type)->base_type);
803 break;
804 case SymTagFunctionArgType:
805 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->arg_type);
806 break;
807 default:
808 FIXME("Unsupported sym-tag %s for get-type\n",
809 symt_get_tag_str(type->tag));
810 /* fall through */
811 case SymTagPublicSymbol:
812 case SymTagThunk:
813 case SymTagLabel:
814 return FALSE;
816 break;
818 case TI_GET_UDTKIND:
819 if (type->tag != SymTagUDT) return FALSE;
820 X(DWORD) = ((const struct symt_udt*)type)->kind;
821 break;
823 case TI_GET_VALUE:
824 if (type->tag != SymTagData) return FALSE;
825 switch (((const struct symt_data*)type)->kind)
827 case DataIsConstant: X(VARIANT) = ((const struct symt_data*)type)->u.value; break;
828 case DataIsLocal:
829 case DataIsParam:
831 struct location loc = ((const struct symt_data*)type)->u.var;
832 unsigned i;
833 struct module_format* modfmt;
835 if (loc.kind < loc_user) return FALSE;
836 for (i = 0; i < DFI_LAST; i++)
838 modfmt = module->format_info[i];
839 if (modfmt && modfmt->loc_compute)
841 modfmt->loc_compute(module->process, modfmt,
842 (const struct symt_function*)((const struct symt_data*)type)->container, &loc);
843 break;
846 if (loc.kind != loc_absolute) return FALSE;
847 X(VARIANT).n1.n2.vt = VT_UI4; /* FIXME */
848 X(VARIANT).n1.n2.n3.uiVal = loc.offset;
850 break;
851 default: return FALSE;
853 break;
855 case TI_GET_CALLING_CONVENTION:
856 if (type->tag != SymTagFunctionType) return FALSE;
857 if (((const struct symt_function_signature*)type)->call_conv == -1)
859 FIXME("No support for calling convention for this signature\n");
860 X(DWORD) = CV_CALL_FAR_C; /* FIXME */
862 else X(DWORD) = ((const struct symt_function_signature*)type)->call_conv;
863 break;
864 case TI_GET_ARRAYINDEXTYPEID:
865 if (type->tag != SymTagArrayType) return FALSE;
866 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->index_type);
867 break;
869 case TI_GET_CLASSPARENTID:
870 /* FIXME: we don't support properly C++ for now, pretend this symbol doesn't
871 * belong to a parent class
873 return FALSE;
875 #undef X
877 case TI_GET_ADDRESSOFFSET:
878 case TI_GET_SYMINDEX:
879 case TI_GET_THISADJUST:
880 case TI_GET_VIRTUALBASECLASS:
881 case TI_GET_VIRTUALBASEPOINTEROFFSET:
882 case TI_GET_VIRTUALTABLESHAPEID:
883 case TI_IS_EQUIV_TO:
884 FIXME("Unsupported GetInfo request (%u)\n", req);
885 return FALSE;
886 default:
887 FIXME("Unknown GetInfo request (%u)\n", req);
888 return FALSE;
891 return TRUE;
894 /******************************************************************
895 * SymGetTypeInfo (DBGHELP.@)
898 BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase,
899 ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType,
900 PVOID pInfo)
902 struct module_pair pair;
904 pair.pcs = process_find_by_handle(hProcess);
905 if (!pair.pcs) return FALSE;
907 pair.requested = module_find_by_addr(pair.pcs, ModBase, DMT_UNKNOWN);
908 if (!module_get_debug(&pair))
910 FIXME("Someone didn't properly set ModBase (%s)\n", wine_dbgstr_longlong(ModBase));
911 return FALSE;
914 return symt_get_info(pair.effective, symt_index2ptr(pair.effective, TypeId), GetType, pInfo);
917 /******************************************************************
918 * SymGetTypeFromName (DBGHELP.@)
921 BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, ULONG64 BaseOfDll,
922 PCSTR Name, PSYMBOL_INFO Symbol)
924 struct module_pair pair;
925 struct symt* type;
927 pair.pcs = process_find_by_handle(hProcess);
928 if (!pair.pcs) return FALSE;
929 pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
930 if (!module_get_debug(&pair)) return FALSE;
931 type = symt_find_type_by_name(pair.effective, SymTagNull, Name);
932 if (!type) return FALSE;
933 Symbol->TypeIndex = symt_ptr2index(pair.effective, type);
935 return TRUE;