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