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