ReactOS 0.4.15-dev-7788-g1ad9096
type.c
Go to the documentation of this file.
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 <stdlib.h>
28#include <stdarg.h>
29#include <assert.h>
30
31#ifndef DBGHELP_STATIC_LIB
32#include "windef.h"
33#include "winbase.h"
34#include "winnls.h"
35#include "wine/debug.h"
36#endif
37#include "dbghelp_private.h"
38
41
42static const char* symt_get_tag_str(DWORD tag)
43{
44 switch (tag)
45 {
46 case SymTagNull: return "SymTagNull";
47 case SymTagExe: return "SymTagExe";
48 case SymTagCompiland: return "SymTagCompiland";
49 case SymTagCompilandDetails: return "SymTagCompilandDetails";
50 case SymTagCompilandEnv: return "SymTagCompilandEnv";
51 case SymTagFunction: return "SymTagFunction";
52 case SymTagBlock: return "SymTagBlock";
53 case SymTagData: return "SymTagData";
54 case SymTagAnnotation: return "SymTagAnnotation";
55 case SymTagLabel: return "SymTagLabel";
56 case SymTagPublicSymbol: return "SymTagPublicSymbol";
57 case SymTagUDT: return "SymTagUDT";
58 case SymTagEnum: return "SymTagEnum";
59 case SymTagFunctionType: return "SymTagFunctionType";
60 case SymTagPointerType: return "SymTagPointerType";
61 case SymTagArrayType: return "SymTagArrayType";
62 case SymTagBaseType: return "SymTagBaseType";
63 case SymTagTypedef: return "SymTagTypedef,";
64 case SymTagBaseClass: return "SymTagBaseClass";
65 case SymTagFriend: return "SymTagFriend";
66 case SymTagFunctionArgType: return "SymTagFunctionArgType,";
67 case SymTagFuncDebugStart: return "SymTagFuncDebugStart,";
68 case SymTagFuncDebugEnd: return "SymTagFuncDebugEnd";
69 case SymTagUsingNamespace: return "SymTagUsingNamespace,";
70 case SymTagVTableShape: return "SymTagVTableShape";
71 case SymTagVTable: return "SymTagVTable";
72 case SymTagCustom: return "SymTagCustom";
73 case SymTagThunk: return "SymTagThunk";
74 case SymTagCustomType: return "SymTagCustomType";
75 case SymTagManagedType: return "SymTagManagedType";
76 case SymTagDimension: return "SymTagDimension";
77 default: return "---";
78 }
79}
80
81const char* symt_get_name(const struct symt* sym)
82{
83 switch (sym->tag)
84 {
85 /* lexical tree */
86 case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name;
87 case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
88 case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name;
89 case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name;
90 case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name;
91 case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
92 /* hierarchy tree */
93 case SymTagEnum: return ((const struct symt_enum*)sym)->name;
94 case SymTagTypedef: return ((const struct symt_typedef*)sym)->hash_elt.name;
95 case SymTagUDT: return ((const struct symt_udt*)sym)->hash_elt.name;
96 default:
97 FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag));
98 /* fall through */
99 case SymTagArrayType:
102 return NULL;
103 }
104}
105
106WCHAR* symt_get_nameW(const struct symt* sym)
107{
108 const char* name = symt_get_name(sym);
109 WCHAR* nameW;
110 DWORD sz;
111
112 if (!name) return NULL;
113 sz = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
114 if ((nameW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
115 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, sz);
116 return nameW;
117}
118
120{
121 switch (type->tag)
122 {
123 case SymTagData:
124 switch (((const struct symt_data*)type)->kind)
125 {
126 case DataIsGlobal:
127 case DataIsFileStatic:
128 *addr = ((const struct symt_data*)type)->u.var.offset;
129 break;
130 default: return FALSE;
131 }
132 break;
133 case SymTagFunction:
134 *addr = ((const struct symt_function*)type)->address;
135 break;
137 *addr = ((const struct symt_public*)type)->address;
138 break;
141 case SymTagLabel:
142 if (!((const struct symt_hierarchy_point*)type)->parent ||
144 return FALSE;
145 *addr += ((const struct symt_hierarchy_point*)type)->loc.offset;
146 break;
147 case SymTagThunk:
148 *addr = ((const struct symt_thunk*)type)->address;
149 break;
150 case SymTagCompiland:
151 *addr = ((const struct symt_compiland*)type)->address;
152 break;
153 default:
154 FIXME("Unsupported sym-tag %s for get-address\n", symt_get_tag_str(type->tag));
155 return FALSE;
156 }
157 return TRUE;
158}
159
160static struct symt* symt_find_type_by_name(const struct module* module,
161 enum SymTagEnum sym_tag,
162 const char* typename)
163{
164 void* ptr;
165 struct symt_ht* type;
166 struct hash_table_iter hti;
167
168 assert(typename);
169 assert(module);
170
171 hash_table_iter_init(&module->ht_types, &hti, typename);
172 while ((ptr = hash_table_iter_up(&hti)))
173 {
174 type = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
175
176 if ((sym_tag == SymTagNull || type->symt.tag == sym_tag) &&
177 type->hash_elt.name && !strcmp(type->hash_elt.name, typename))
178 return &type->symt;
179 }
180 SetLastError(ERROR_INVALID_NAME); /* FIXME ?? */
181 return NULL;
182}
183
184static void symt_add_type(struct module* module, struct symt* symt)
185{
186 struct symt** p;
188 assert(p);
189 *p = symt;
190}
191
193 const char* typename, unsigned size)
194{
195 struct symt_basic* sym;
196
197 if (typename)
198 {
200 typename);
201 if (sym && sym->bt == bt && sym->size == size)
202 return sym;
203 }
204 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
205 {
206 sym->symt.tag = SymTagBaseType;
207 if (typename)
208 {
209 sym->hash_elt.name = pool_strdup(&module->pool, typename);
211 } else sym->hash_elt.name = NULL;
212 sym->bt = bt;
213 sym->size = size;
214 symt_add_type(module, &sym->symt);
215 }
216 return sym;
217}
218
219struct symt_udt* symt_new_udt(struct module* module, const char* typename,
220 unsigned size, enum UdtKind kind)
221{
222 struct symt_udt* sym;
223
224 TRACE_(dbghelp_symt)("Adding udt %s:%s\n",
225 debugstr_w(module->module.ModuleName), typename);
226 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
227 {
228 sym->symt.tag = SymTagUDT;
229 sym->kind = kind;
230 sym->size = size;
231 if (typename)
232 {
233 sym->hash_elt.name = pool_strdup(&module->pool, typename);
235 } else sym->hash_elt.name = NULL;
236 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
237 symt_add_type(module, &sym->symt);
238 }
239 return sym;
240}
241
242BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned size)
243{
244 assert(udt->symt.tag == SymTagUDT);
245 if (vector_length(&udt->vchildren) != 0)
246 {
247 if (udt->size != size)
248 FIXME_(dbghelp_symt)("Changing size for %s from %u to %u\n",
249 udt->hash_elt.name, udt->size, size);
250 return TRUE;
251 }
252 udt->size = size;
253 return TRUE;
254}
255
256/******************************************************************
257 * symt_add_udt_element
258 *
259 * add an element to a udt (struct, class, union)
260 * the size & offset parameters are expressed in bits (not bytes) so that
261 * we can mix in the single call bytes aligned elements (regular fields) and
262 * the others (bit fields)
263 */
265 const char* name, struct symt* elt_type,
266 unsigned offset, unsigned size)
267{
268 struct symt_data* m;
269 struct symt** p;
270
271 assert(udt_type->symt.tag == SymTagUDT);
272
273 TRACE_(dbghelp_symt)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name);
274 if (name)
275 {
276 unsigned int i;
277 for (i=0; i<vector_length(&udt_type->vchildren); i++)
278 {
279 m = *(struct symt_data**)vector_at(&udt_type->vchildren, i);
280 assert(m);
281 assert(m->symt.tag == SymTagData);
282 if (strcmp(m->hash_elt.name, name) == 0)
283 return TRUE;
284 }
285 }
286
287 if ((m = pool_alloc(&module->pool, sizeof(*m))) == NULL) return FALSE;
288 memset(m, 0, sizeof(*m));
289 m->symt.tag = SymTagData;
290 m->hash_elt.name = name ? pool_strdup(&module->pool, name) : "";
291 m->hash_elt.next = NULL;
292
293 m->kind = DataIsMember;
294 m->container = &udt_type->symt;
295 m->type = elt_type;
296 m->u.member.offset = offset;
297 m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0;
298 p = vector_add(&udt_type->vchildren, &module->pool);
299 *p = &m->symt;
300
301 return TRUE;
302}
303
304struct symt_enum* symt_new_enum(struct module* module, const char* typename,
305 struct symt* basetype)
306{
307 struct symt_enum* sym;
308
309 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
310 {
311 sym->symt.tag = SymTagEnum;
312 sym->name = (typename) ? pool_strdup(&module->pool, typename) : NULL;
313 sym->base_type = basetype;
314 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
315 }
316 return sym;
317}
318
320 const char* name, int value)
321{
322 struct symt_data* e;
323 struct symt** p;
324
325 assert(enum_type->symt.tag == SymTagEnum);
326 e = pool_alloc(&module->pool, sizeof(*e));
327 if (e == NULL) return FALSE;
328
329 e->symt.tag = SymTagData;
330 e->hash_elt.name = pool_strdup(&module->pool, name);
331 e->hash_elt.next = NULL;
332 e->kind = DataIsConstant;
333 e->container = &enum_type->symt;
334 e->type = enum_type->base_type;
335 e->u.value.n1.n2.vt = VT_I4;
336 e->u.value.n1.n2.n3.lVal = value;
337
338 p = vector_add(&enum_type->vchildren, &module->pool);
339 if (!p) return FALSE; /* FIXME we leak e */
340 *p = &e->symt;
341
342 return TRUE;
343}
344
345struct symt_array* symt_new_array(struct module* module, int min, int max,
346 struct symt* base, struct symt* index)
347{
348 struct symt_array* sym;
349
350 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
351 {
352 sym->symt.tag = SymTagArrayType;
353 sym->start = min;
354 sym->end = max;
355 sym->base_type = base;
356 sym->index_type = index;
357 symt_add_type(module, &sym->symt);
358 }
359 return sym;
360}
361
362static inline DWORD symt_array_count(struct module* module, const struct symt_array* array)
363{
364 if (array->end < 0)
365 {
366 DWORD64 elem_size;
367 /* One could want to also set the array->end field in array, but we won't do it
368 * as long as all the get_type() helpers use const objects
369 */
370 if (symt_get_info(module, array->base_type, TI_GET_LENGTH, &elem_size) && elem_size)
371 return -array->end / (DWORD)elem_size;
372 return 0;
373 }
374 return array->end - array->start + 1;
375}
376
378 struct symt* ret_type,
379 enum CV_call_e call_conv)
380{
381 struct symt_function_signature* sym;
382
383 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
384 {
385 sym->symt.tag = SymTagFunctionType;
386 sym->rettype = ret_type;
387 vector_init(&sym->vchildren, sizeof(struct symt*), 4);
388 sym->call_conv = call_conv;
389 symt_add_type(module, &sym->symt);
390 }
391 return sym;
392}
393
395 struct symt_function_signature* sig_type,
396 struct symt* param)
397{
398 struct symt** p;
400
401 assert(sig_type->symt.tag == SymTagFunctionType);
402 arg = pool_alloc(&module->pool, sizeof(*arg));
403 if (!arg) return FALSE;
404 arg->symt.tag = SymTagFunctionArgType;
405 arg->arg_type = param;
406 arg->container = &sig_type->symt;
407 p = vector_add(&sig_type->vchildren, &module->pool);
408 if (!p) return FALSE; /* FIXME we leak arg */
409 *p = &arg->symt;
410
411 return TRUE;
412}
413
414struct symt_pointer* symt_new_pointer(struct module* module, struct symt* ref_type, ULONG_PTR size)
415{
416 struct symt_pointer* sym;
417
418 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
419 {
420 sym->symt.tag = SymTagPointerType;
421 sym->pointsto = ref_type;
422 sym->size = size;
423 symt_add_type(module, &sym->symt);
424 }
425 return sym;
426}
427
429 const char* name)
430{
431 struct symt_typedef* sym;
432
433 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
434 {
435 sym->symt.tag = SymTagTypedef;
436 sym->type = ref;
437 sym->hash_elt.name = pool_strdup(&module->pool, name);
439 symt_add_type(module, &sym->symt);
440 }
441 return sym;
442}
443
444/******************************************************************
445 * SymEnumTypes (DBGHELP.@)
446 *
447 */
449 PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
450 PVOID UserContext)
451{
452 struct module_pair pair;
453 char buffer[sizeof(SYMBOL_INFO) + 256];
454 SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
455 const char* tmp;
456 struct symt* type;
458 unsigned int i;
459
460 TRACE("(%p %s %p %p)\n",
461 hProcess, wine_dbgstr_longlong(BaseOfDll), EnumSymbolsCallback,
462 UserContext);
463
464 if (!(pair.pcs = process_find_by_handle(hProcess))) return FALSE;
465 pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
466 if (!module_get_debug(&pair)) return FALSE;
467
468 sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
469 sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
470
471 for (i=0; i<vector_length(&pair.effective->vtypes); i++)
472 {
473 type = *(struct symt**)vector_at(&pair.effective->vtypes, i);
474 sym_info->TypeIndex = symt_ptr2index(pair.effective, type);
475 sym_info->Index = 0; /* FIXME */
477 sym_info->Size = size;
478 sym_info->ModBase = pair.requested->module.BaseOfImage;
479 sym_info->Flags = 0; /* FIXME */
480 sym_info->Value = 0; /* FIXME */
481 sym_info->Address = 0; /* FIXME */
482 sym_info->Register = 0; /* FIXME */
483 sym_info->Scope = 0; /* FIXME */
484 sym_info->Tag = type->tag;
485 tmp = symt_get_name(type);
486 if (tmp)
487 {
488 sym_info->NameLen = min(strlen(tmp),sym_info->MaxNameLen-1);
489 memcpy(sym_info->Name, tmp, sym_info->NameLen);
490 sym_info->Name[sym_info->NameLen] = '\0';
491 }
492 else
493 sym_info->Name[sym_info->NameLen = 0] = '\0';
494 if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break;
495 }
496 return TRUE;
497}
498
500{
501 char buffer[sizeof(SYMBOL_INFOW) + 256 * sizeof(WCHAR)];
502 void* user;
504};
505
507{
508 struct enum_types_AtoW* et = _et;
509 SYMBOL_INFOW* siW = (SYMBOL_INFOW*)et->buffer;
510
511 copy_symbolW(siW, si);
512 return et->callback(siW, addr, et->user);
513}
514
515/******************************************************************
516 * SymEnumTypesW (DBGHELP.@)
517 *
518 */
520 PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
521 PVOID UserContext)
522{
523 struct enum_types_AtoW et;
524
525 et.callback = EnumSymbolsCallback;
526 et.user = UserContext;
527
528 return SymEnumTypes(hProcess, BaseOfDll, enum_types_AtoW, &et);
529}
530
531/******************************************************************
532 * symt_get_info
533 *
534 * Retrieves information about a symt (either symbol or type)
535 */
536BOOL symt_get_info(struct module* module, const struct symt* type,
537 IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo)
538{
539 unsigned len;
540
541 if (!type) return FALSE;
542
543/* helper to typecast pInfo to its expected type (_t) */
544#define X(_t) (*((_t*)pInfo))
545
546 switch (req)
547 {
548 case TI_FINDCHILDREN:
549 {
550 const struct vector* v;
551 struct symt** pt;
552 unsigned i;
553 TI_FINDCHILDREN_PARAMS* tifp = pInfo;
554
555 switch (type->tag)
556 {
557 case SymTagUDT: v = &((const struct symt_udt*)type)->vchildren; break;
558 case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break;
559 case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break;
560 case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break;
561 default:
562 FIXME("Unsupported sym-tag %s for find-children\n",
563 symt_get_tag_str(type->tag));
564 return FALSE;
565 }
566 for (i = 0; i < tifp->Count; i++)
567 {
568 if (!(pt = vector_at(v, tifp->Start + i))) return FALSE;
569 tifp->ChildId[i] = symt_ptr2index(module, *pt);
570 }
571 }
572 break;
573
574 case TI_GET_ADDRESS:
575 return symt_get_address(type, (ULONG64*)pInfo);
576
577 case TI_GET_BASETYPE:
578 switch (type->tag)
579 {
580 case SymTagBaseType:
581 X(DWORD) = ((const struct symt_basic*)type)->bt;
582 break;
583 case SymTagEnum:
584 X(DWORD) = btInt;
585 break;
586 default:
587 return FALSE;
588 }
589 break;
590
592 if (type->tag == SymTagData &&
593 ((const struct symt_data*)type)->kind == DataIsMember &&
594 ((const struct symt_data*)type)->u.member.length != 0)
595 X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7;
596 else return FALSE;
597 break;
598
600 switch (type->tag)
601 {
602 case SymTagUDT:
603 X(DWORD) = vector_length(&((const struct symt_udt*)type)->vchildren);
604 break;
605 case SymTagEnum:
606 X(DWORD) = vector_length(&((const struct symt_enum*)type)->vchildren);
607 break;
609 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
610 break;
611 case SymTagFunction:
612 X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren);
613 break;
614 case SymTagPointerType: /* MS does it that way */
615 case SymTagArrayType: /* MS does it that way */
616 case SymTagThunk: /* MS does it that way */
617 X(DWORD) = 0;
618 break;
619 default:
620 FIXME("Unsupported sym-tag %s for get-children-count\n",
621 symt_get_tag_str(type->tag));
622 /* fall through */
623 case SymTagData:
625 case SymTagBaseType:
626 return FALSE;
627 }
628 break;
629
630 case TI_GET_COUNT:
631 switch (type->tag)
632 {
633 case SymTagArrayType:
634 X(DWORD) = symt_array_count(module, (const struct symt_array*)type);
635 break;
637 /* this seems to be wrong for (future) C++ methods, where 'this' parameter
638 * should be included in this value (and not in GET_CHILDREN_COUNT)
639 */
640 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
641 break;
642 default: return FALSE;
643 }
644 break;
645
646 case TI_GET_DATAKIND:
647 if (type->tag != SymTagData) return FALSE;
648 X(DWORD) = ((const struct symt_data*)type)->kind;
649 break;
650
651 case TI_GET_LENGTH:
652 switch (type->tag)
653 {
654 case SymTagBaseType:
655 X(DWORD64) = ((const struct symt_basic*)type)->size;
656 break;
657 case SymTagFunction:
658 X(DWORD64) = ((const struct symt_function*)type)->size;
659 break;
661 X(DWORD64) = ((const struct symt_pointer*)type)->size;
662 break;
663 case SymTagUDT:
664 X(DWORD64) = ((const struct symt_udt*)type)->size;
665 break;
666 case SymTagEnum:
667 X(DWORD64) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */
668 break;
669 case SymTagData:
670 if (((const struct symt_data*)type)->kind != DataIsMember ||
671 !((const struct symt_data*)type)->u.member.length)
672 return FALSE;
673 X(DWORD64) = ((const struct symt_data*)type)->u.member.length;
674 break;
675 case SymTagArrayType:
676 if (!symt_get_info(module, ((const struct symt_array*)type)->base_type,
677 TI_GET_LENGTH, pInfo))
678 return FALSE;
679 X(DWORD64) *= symt_array_count(module, (const struct symt_array*)type);
680 break;
682 X(DWORD64) = ((const struct symt_public*)type)->size;
683 break;
684 case SymTagTypedef:
685 return symt_get_info(module, ((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
686 case SymTagThunk:
687 X(DWORD64) = ((const struct symt_thunk*)type)->size;
688 break;
689 case SymTagLabel:
690 X(DWORD64) = 0;
691 break;
692 default:
693 FIXME("Unsupported sym-tag %s for get-length\n",
694 symt_get_tag_str(type->tag));
695 /* fall through */
697 return FALSE;
698 }
699 break;
700
702 switch (type->tag)
703 {
704 case SymTagBlock:
705 X(DWORD) = symt_ptr2index(module, ((const struct symt_block*)type)->container);
706 break;
707 case SymTagData:
708 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->container);
709 break;
710 case SymTagFunction:
711 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->container);
712 break;
713 case SymTagThunk:
714 X(DWORD) = symt_ptr2index(module, ((const struct symt_thunk*)type)->container);
715 break;
718 break;
719 default:
720 FIXME("Unsupported sym-tag %s for get-lexical-parent\n",
721 symt_get_tag_str(type->tag));
722 return FALSE;
723 }
724 break;
725
726 case TI_GET_NESTED:
727 switch (type->tag)
728 {
729 case SymTagUDT:
730 case SymTagEnum:
731 X(DWORD) = 0;
732 break;
733 default:
734 return FALSE;
735 }
736 break;
737
738 case TI_GET_OFFSET:
739 switch (type->tag)
740 {
741 case SymTagData:
742 switch (((const struct symt_data*)type)->kind)
743 {
744 case DataIsParam:
745 case DataIsLocal:
746 X(ULONG) = ((const struct symt_data*)type)->u.var.offset;
747 break;
748 case DataIsMember:
749 X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3;
750 break;
751 default:
752 FIXME("Unknown kind (%u) for get-offset\n",
753 ((const struct symt_data*)type)->kind);
754 return FALSE;
755 }
756 break;
757 default:
758 FIXME("Unsupported sym-tag %s for get-offset\n",
759 symt_get_tag_str(type->tag));
760 return FALSE;
761 }
762 break;
763
764 case TI_GET_SYMNAME:
765 {
766 const char* name = symt_get_name(type);
767 if (!name) return FALSE;
768 len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
769 X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
770 if (!X(WCHAR*)) return FALSE;
772 }
773 break;
774
775 case TI_GET_SYMTAG:
776 X(DWORD) = type->tag;
777 break;
778
779 case TI_GET_TYPE:
780 case TI_GET_TYPEID:
781 switch (type->tag)
782 {
783 /* hierarchical => hierarchical */
784 case SymTagArrayType:
785 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->base_type);
786 break;
788 X(DWORD) = symt_ptr2index(module, ((const struct symt_pointer*)type)->pointsto);
789 break;
791 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_signature*)type)->rettype);
792 break;
793 case SymTagTypedef:
794 X(DWORD) = symt_ptr2index(module, ((const struct symt_typedef*)type)->type);
795 break;
796 /* lexical => hierarchical */
797 case SymTagData:
798 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->type);
799 break;
800 case SymTagFunction:
801 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->type);
802 break;
803 case SymTagEnum:
804 X(DWORD) = symt_ptr2index(module, ((const struct symt_enum*)type)->base_type);
805 break;
807 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->arg_type);
808 break;
809 default:
810 FIXME("Unsupported sym-tag %s for get-type\n",
811 symt_get_tag_str(type->tag));
812 /* fall through */
814 case SymTagThunk:
815 case SymTagLabel:
816 return FALSE;
817 }
818 break;
819
820 case TI_GET_UDTKIND:
821 if (type->tag != SymTagUDT) return FALSE;
822 X(DWORD) = ((const struct symt_udt*)type)->kind;
823 break;
824
825 case TI_GET_VALUE:
826 if (type->tag != SymTagData) return FALSE;
827 switch (((const struct symt_data*)type)->kind)
828 {
829 case DataIsConstant: X(VARIANT) = ((const struct symt_data*)type)->u.value; break;
830 case DataIsLocal:
831 case DataIsParam:
832 {
833 struct location loc = ((const struct symt_data*)type)->u.var;
834 unsigned i;
835 struct module_format* modfmt;
836
837 if (loc.kind < loc_user) return FALSE;
838 for (i = 0; i < DFI_LAST; i++)
839 {
840 modfmt = module->format_info[i];
841 if (modfmt && modfmt->loc_compute)
842 {
843 modfmt->loc_compute(module->process, modfmt,
844 (const struct symt_function*)((const struct symt_data*)type)->container, &loc);
845 break;
846 }
847 }
848 if (loc.kind != loc_absolute) return FALSE;
849 X(VARIANT).n1.n2.vt = VT_UI4; /* FIXME */
850 X(VARIANT).n1.n2.n3.uiVal = loc.offset;
851 }
852 break;
853 default: return FALSE;
854 }
855 break;
856
858 if (type->tag != SymTagFunctionType) return FALSE;
859 if (((const struct symt_function_signature*)type)->call_conv == -1)
860 {
861 FIXME("No support for calling convention for this signature\n");
862 X(DWORD) = CV_CALL_FAR_C; /* FIXME */
863 }
864 else X(DWORD) = ((const struct symt_function_signature*)type)->call_conv;
865 break;
867 if (type->tag != SymTagArrayType) return FALSE;
868 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->index_type);
869 break;
870
872 /* FIXME: we don't support properly C++ for now, pretend this symbol doesn't
873 * belong to a parent class
874 */
875 return FALSE;
876
877#undef X
878
880 case TI_GET_SYMINDEX:
885 case TI_IS_EQUIV_TO:
886 FIXME("Unsupported GetInfo request (%u)\n", req);
887 return FALSE;
888 default:
889 FIXME("Unknown GetInfo request (%u)\n", req);
890 return FALSE;
891 }
892
893 return TRUE;
894}
895
896/******************************************************************
897 * SymGetTypeInfo (DBGHELP.@)
898 *
899 */
902 PVOID pInfo)
903{
904 struct module_pair pair;
905
907 if (!pair.pcs) return FALSE;
908
909 pair.requested = module_find_by_addr(pair.pcs, ModBase, DMT_UNKNOWN);
910 if (!module_get_debug(&pair))
911 {
912 FIXME("Someone didn't properly set ModBase (%s)\n", wine_dbgstr_longlong(ModBase));
913 return FALSE;
914 }
915
916 return symt_get_info(pair.effective, symt_index2ptr(pair.effective, TypeId), GetType, pInfo);
917}
918
919/******************************************************************
920 * SymGetTypeFromName (DBGHELP.@)
921 *
922 */
925{
927 struct module_pair pair;
928 struct symt* type;
929
930 if (!pcs) return FALSE;
931 pair.requested = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
932 if (!module_get_debug(&pair)) return FALSE;
934 if (!type) return FALSE;
935 Symbol->TypeIndex = symt_ptr2index(pair.effective, type);
936
937 return TRUE;
938}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static const WCHAR nameW[]
Definition: main.c:46
#define index(s, c)
Definition: various.h:29
#define FIXME(fmt,...)
Definition: debug.h:111
Definition: Symbol.h:9
DWORD symt_ptr2index(struct module *module, const struct symt *sym) DECLSPEC_HIDDEN
Definition: symbol.c:68
void vector_init(struct vector *v, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:133
void * vector_add(struct vector *v, struct pool *pool) DECLSPEC_HIDDEN
Definition: storage.c:171
void * pool_alloc(struct pool *a, size_t len) DECLSPEC_HIDDEN
Definition: storage.c:89
unsigned vector_length(const struct vector *v) DECLSPEC_HIDDEN
Definition: storage.c:157
@ DFI_LAST
void hash_table_iter_init(const struct hash_table *ht, struct hash_table_iter *hti, const char *name) DECLSPEC_HIDDEN
Definition: storage.c:405
void * hash_table_iter_up(struct hash_table_iter *hti) DECLSPEC_HIDDEN
Definition: storage.c:422
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type) DECLSPEC_HIDDEN
Definition: module.c:420
void * vector_at(const struct vector *v, unsigned pos) DECLSPEC_HIDDEN
Definition: storage.c:162
@ loc_user
@ loc_absolute
void copy_symbolW(SYMBOL_INFOW *siw, const SYMBOL_INFO *si) DECLSPEC_HIDDEN
Definition: symbol.c:1029
BOOL module_get_debug(struct module_pair *) DECLSPEC_HIDDEN
Definition: module.c:374
char * pool_strdup(struct pool *a, const char *str) DECLSPEC_HIDDEN
Definition: storage.c:126
void hash_table_add(struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
Definition: storage.c:378
struct symt * symt_index2ptr(struct module *module, DWORD id) DECLSPEC_HIDDEN
Definition: symbol.c:110
@ DMT_UNKNOWN
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL(CALLBACK * PSYM_ENUMERATESYMBOLS_CALLBACK)(PSYMBOL_INFO, ULONG, PVOID)
Definition: compat.h:1119
#define GetProcessHeap()
Definition: compat.h:736
BOOL(CALLBACK * PSYM_ENUMERATESYMBOLS_CALLBACKW)(PSYMBOL_INFOW, ULONG, PVOID)
Definition: compat.h:1466
#define FIXME_(x)
Definition: compat.h:77
#define CP_ACP
Definition: compat.h:109
#define TRACE_(x)
Definition: compat.h:76
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
CV_call_e
Definition: compat.h:2224
struct _SYMBOL_INFOW SYMBOL_INFOW
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
struct _SYMBOL_INFO SYMBOL_INFO
@ TI_GET_NESTED
Definition: compat.h:1434
@ TI_GET_LENGTH
Definition: compat.h:1417
@ TI_GET_VIRTUALBASEPOINTEROFFSET
Definition: compat.h:1432
@ TI_GET_SYMNAME
Definition: compat.h:1416
@ TI_GET_BITPOSITION
Definition: compat.h:1429
@ TI_GET_CHILDRENCOUNT
Definition: compat.h:1428
@ TI_GET_TYPE
Definition: compat.h:1418
@ TI_GET_THISADJUST
Definition: compat.h:1438
@ TI_GET_SYMTAG
Definition: compat.h:1415
@ TI_GET_CALLING_CONVENTION
Definition: compat.h:1441
@ TI_GET_VIRTUALBASECLASS
Definition: compat.h:1430
@ TI_GET_ADDRESSOFFSET
Definition: compat.h:1424
@ TI_GET_UDTKIND
Definition: compat.h:1439
@ TI_GET_LEXICALPARENT
Definition: compat.h:1436
@ TI_GET_TYPEID
Definition: compat.h:1419
@ TI_GET_DATAKIND
Definition: compat.h:1423
@ TI_GET_VIRTUALTABLESHAPEID
Definition: compat.h:1431
@ TI_GET_CLASSPARENTID
Definition: compat.h:1433
@ TI_GET_ADDRESS
Definition: compat.h:1437
@ TI_FINDCHILDREN
Definition: compat.h:1422
@ TI_GET_SYMINDEX
Definition: compat.h:1435
@ TI_GET_OFFSET
Definition: compat.h:1425
@ TI_IS_EQUIV_TO
Definition: compat.h:1440
@ TI_GET_ARRAYINDEXTYPEID
Definition: compat.h:1421
@ TI_GET_COUNT
Definition: compat.h:1427
@ TI_GET_BASETYPE
Definition: compat.h:1420
@ TI_GET_VALUE
Definition: compat.h:1426
SymTagEnum
Definition: compat.h:1580
@ SymTagArrayType
Definition: compat.h:1596
@ SymTagVTable
Definition: compat.h:1606
@ SymTagFunction
Definition: compat.h:1586
@ SymTagThunk
Definition: compat.h:1608
@ SymTagVTableShape
Definition: compat.h:1605
@ SymTagFunctionArgType
Definition: compat.h:1601
@ SymTagNull
Definition: compat.h:1581
@ SymTagCustom
Definition: compat.h:1607
@ SymTagExe
Definition: compat.h:1582
@ SymTagPointerType
Definition: compat.h:1595
@ SymTagFuncDebugEnd
Definition: compat.h:1603
@ SymTagAnnotation
Definition: compat.h:1589
@ SymTagCompilandEnv
Definition: compat.h:1585
@ SymTagCustomType
Definition: compat.h:1609
@ SymTagPublicSymbol
Definition: compat.h:1591
@ SymTagCompilandDetails
Definition: compat.h:1584
@ SymTagFuncDebugStart
Definition: compat.h:1602
@ SymTagTypedef
Definition: compat.h:1598
@ SymTagBaseType
Definition: compat.h:1597
@ SymTagData
Definition: compat.h:1588
@ SymTagBlock
Definition: compat.h:1587
@ SymTagManagedType
Definition: compat.h:1610
@ SymTagUDT
Definition: compat.h:1592
@ SymTagDimension
Definition: compat.h:1611
@ SymTagLabel
Definition: compat.h:1590
@ SymTagFunctionType
Definition: compat.h:1594
@ SymTagCompiland
Definition: compat.h:1583
@ SymTagBaseClass
Definition: compat.h:1599
@ SymTagUsingNamespace
Definition: compat.h:1604
@ SymTagFriend
Definition: compat.h:1600
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
@ DataIsLocal
Definition: compat.h:1649
@ DataIsGlobal
Definition: compat.h:1654
@ DataIsMember
Definition: compat.h:1655
@ DataIsConstant
Definition: compat.h:1657
@ DataIsFileStatic
Definition: compat.h:1653
@ DataIsParam
Definition: compat.h:1651
#define CALLBACK
Definition: compat.h:35
enum _IMAGEHLP_SYMBOL_TYPE_INFO IMAGEHLP_SYMBOL_TYPE_INFO
#define MultiByteToWideChar
Definition: compat.h:110
BasicType
Definition: compat.h:1616
@ btInt
Definition: compat.h:1621
#define ERROR_INVALID_NAME
Definition: compat.h:103
@ VT_I4
Definition: compat.h:2298
@ VT_UI4
Definition: compat.h:2313
UdtKind
Definition: compat.h:1639
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
BOOL symt_set_udt_size(struct module *module, struct symt_udt *udt, unsigned size)
Definition: type.c:242
static DWORD symt_array_count(struct module *module, const struct symt_array *array)
Definition: type.c:362
struct symt_udt * symt_new_udt(struct module *module, const char *typename, unsigned size, enum UdtKind kind)
Definition: type.c:219
static const char * symt_get_tag_str(DWORD tag)
Definition: type.c:42
struct symt_function_signature * symt_new_function_signature(struct module *module, struct symt *ret_type, enum CV_call_e call_conv)
Definition: type.c:377
BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: type.c:923
#define X(_t)
static void symt_add_type(struct module *module, struct symt *symt)
Definition: type.c:184
WCHAR * symt_get_nameW(const struct symt *sym)
Definition: type.c:106
static struct symt * symt_find_type_by_name(const struct module *module, enum SymTagEnum sym_tag, const char *typename)
Definition: type.c:160
struct symt_pointer * symt_new_pointer(struct module *module, struct symt *ref_type, ULONG_PTR size)
Definition: type.c:414
BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase, ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType, PVOID pInfo)
Definition: type.c:900
BOOL symt_get_address(const struct symt *type, ULONG64 *addr)
Definition: type.c:119
BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll, PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, PVOID UserContext)
Definition: type.c:519
BOOL symt_add_udt_element(struct module *module, struct symt_udt *udt_type, const char *name, struct symt *elt_type, unsigned offset, unsigned size)
Definition: type.c:264
BOOL symt_add_function_signature_parameter(struct module *module, struct symt_function_signature *sig_type, struct symt *param)
Definition: type.c:394
struct symt_enum * symt_new_enum(struct module *module, const char *typename, struct symt *basetype)
Definition: type.c:304
BOOL symt_add_enum_element(struct module *module, struct symt_enum *enum_type, const char *name, int value)
Definition: type.c:319
const char * symt_get_name(const struct symt *sym)
Definition: type.c:81
struct symt_basic * symt_new_basic(struct module *module, enum BasicType bt, const char *typename, unsigned size)
Definition: type.c:192
BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: type.c:448
struct symt_array * symt_new_array(struct module *module, int min, int max, struct symt *base, struct symt *index)
Definition: type.c:345
BOOL symt_get_info(struct module *module, const struct symt *type, IMAGEHLP_SYMBOL_TYPE_INFO req, void *pInfo)
Definition: type.c:536
struct symt_typedef * symt_new_typedef(struct module *module, struct symt *ref, const char *name)
Definition: type.c:428
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define e
Definition: ke_i.h:82
#define debugstr_w
Definition: kernel32.h:32
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned __int64 ULONG64
Definition: imports.h:198
static PVOID ptr
Definition: dispmode.c:27
#define min(a, b)
Definition: monoChain.cc:55
#define DWORD
Definition: nt_native.h:44
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR ModuleName[32]
Definition: compat.h:1076
unsigned start
Definition: undname.c:59
struct define * next
Definition: compiler.c:65
char * value
Definition: compiler.c:67
char * name
Definition: compiler.c:66
void * user
Definition: type.c:502
PSYM_ENUMERATESYMBOLS_CALLBACKW callback
Definition: type.c:503
char buffer[sizeof(SYMBOL_INFOW)+256 *sizeof(WCHAR)]
Definition: type.c:501
ULONG_PTR offset
unsigned kind
void(* loc_compute)(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
IMAGEHLP_MODULEW64 module
struct process * process
struct hash_table ht_types
struct module_format * format_info[DFI_LAST]
struct pool pool
struct vector vtypes
Definition: name.c:39
Definition: _pair.h:47
Definition: send.c:48
struct symt * base_type
struct symt symt
struct symt * index_type
enum BasicType bt
struct symt symt
struct hash_table_elt hash_elt
ULONG_PTR size
enum DataKind kind
struct symt symt
const char * name
struct symt * base_type
struct vector vchildren
ULONG_PTR size
struct symt * pointsto
struct symt symt
struct hash_table_elt hash_elt
struct symt symt
struct symt * type
struct vector vchildren
struct symt symt
enum UdtKind kind
struct hash_table_elt hash_elt
enum SymTagEnum tag
Definition: ecma_167.h:138
#define max(a, b)
Definition: svc.c:63
#define CV_CALL_FAR_C
Definition: symdump.c:30
uint64_t DWORD64
Definition: typedefs.h:67
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
#define GetType(This)
Definition: conio.h:54
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
__wchar_t WCHAR
Definition: xmlstorage.h:180