ReactOS  0.4.15-dev-1033-gd7d716a
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 
40 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
41 
42 static 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 
81 const 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:
100  case SymTagPointerType:
101  case SymTagFunctionType:
102  return NULL;
103  }
104 }
105 
106 WCHAR* 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;
136  case SymTagPublicSymbol:
137  *addr = ((const struct symt_public*)type)->address;
138  break;
140  case SymTagFuncDebugEnd:
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 
160 static 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 
184 static 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 
219 struct 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 
242 BOOL 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  */
264 BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
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 
304 struct 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 
319 BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type,
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 
345 struct 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 
362 static 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;
399  struct symt_function_arg_type* arg;
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 
414 struct 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 
428 struct symt_typedef* symt_new_typedef(struct module* module, struct symt* ref,
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;
457  DWORD64 size;
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 */
476  symt_get_info(pair.effective, type, TI_GET_LENGTH, &size);
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  */
536 BOOL 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 
591  case TI_GET_BITPOSITION:
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;
608  case SymTagFunctionType:
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:
624  case SymTagPublicSymbol:
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;
636  case SymTagFunctionType:
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;
660  case SymTagPointerType:
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;
681  case SymTagPublicSymbol:
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 */
696  case SymTagFunctionType:
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;
771  MultiByteToWideChar(CP_ACP, 0, name, -1, X(WCHAR*), len);
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;
787  case SymTagPointerType:
788  X(DWORD) = symt_ptr2index(module, ((const struct symt_pointer*)type)->pointsto);
789  break;
790  case SymTagFunctionType:
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 */
813  case SymTagPublicSymbol:
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:
881  case TI_GET_THISADJUST:
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 {
926  struct process* pcs = process_find_by_handle(hProcess);
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 }
BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: type.c:923
BasicType
Definition: compat.h:1363
struct symt_enum * symt_new_enum(struct module *module, const char *typename, struct symt *basetype)
Definition: type.c:304
struct symt symt
#define max(a, b)
Definition: svc.c:63
WCHAR * symt_get_nameW(const struct symt *sym)
Definition: type.c:106
Definition: compat.h:2046
BOOL symt_set_udt_size(struct module *module, struct symt_udt *udt, unsigned size)
Definition: type.c:242
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt)
WCHAR ModuleName[32]
Definition: compat.h:824
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:900
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
void * vector_at(const struct vector *v, unsigned pos) DECLSPEC_HIDDEN
Definition: storage.c:162
BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll, PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, PVOID UserContext)
Definition: type.c:519
#define CP_ACP
Definition: compat.h:109
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
struct symt_pointer * symt_new_pointer(struct module *module, struct symt *ref_type, ULONG_PTR size)
Definition: type.c:414
GLintptr offset
Definition: glext.h:5920
#define CALLBACK
Definition: compat.h:35
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:42
struct symt symt
void copy_symbolW(SYMBOL_INFOW *siw, const SYMBOL_INFO *si) DECLSPEC_HIDDEN
Definition: symbol.c:1029
GLuint buffer
Definition: glext.h:5915
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
enum DataKind kind
void * arg
Definition: msvc.h:10
BOOL symt_add_enum_element(struct module *module, struct symt_enum *enum_type, const char *name, int value)
Definition: type.c:319
enum UdtKind kind
struct hash_table_elt hash_elt
#define DWORD
Definition: nt_native.h:44
Definition: send.c:48
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:362
ULONG_PTR size
uint32_t ULONG_PTR
Definition: typedefs.h:65
void * pool_alloc(struct pool *a, size_t len) DECLSPEC_HIDDEN
Definition: storage.c:89
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 FALSE
Definition: types.h:117
SymTagEnum
Definition: compat.h:1327
unsigned int BOOL
Definition: ntddk_ex.h:94
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:77
#define FIXME(fmt,...)
Definition: debug.h:111
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:405
smooth NULL
Definition: ftsmooth.c:416
static void symt_add_type(struct module *module, struct symt *symt)
Definition: type.c:184
void vector_init(struct vector *v, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:133
UdtKind
Definition: compat.h:1386
ULONG_PTR offset
ULONG_PTR size
static struct symt * symt_find_type_by_name(const struct module *module, enum SymTagEnum sym_tag, const char *typename)
Definition: type.c:160
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:502
static const WCHAR nameW[]
Definition: main.c:46
struct symt symt
#define TRACE_(x)
Definition: compat.h:76
BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: type.c:448
DWORD symt_ptr2index(struct module *module, const struct symt *sym) DECLSPEC_HIDDEN
Definition: symbol.c:68
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:484
struct symt_basic * symt_new_basic(struct module *module, enum BasicType bt, const char *typename, unsigned size)
Definition: type.c:192
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:377
BOOL module_get_debug(struct module_pair *) DECLSPEC_HIDDEN
Definition: module.c:374
r parent
Definition: btrfs.c:2944
PSYM_ENUMERATESYMBOLS_CALLBACKW callback
Definition: type.c:503
void(* loc_compute)(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
__wchar_t WCHAR
Definition: xmlstorage.h:180
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
static BOOL CALLBACK enum_types_AtoW(PSYMBOL_INFO si, ULONG addr, PVOID _et)
Definition: type.c:506
struct vector vtypes
GLfloat param
Definition: glext.h:5796
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
#define WINAPI
Definition: msvc.h:6
struct _SYMBOL_INFO SYMBOL_INFO
struct symt symt
char * name
Definition: compiler.c:66
unsigned long DWORD
Definition: ntddk_ex.h:95
struct symt * index_type
#define SetLastError(x)
Definition: compat.h:500
void hash_table_add(struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
Definition: storage.c:378
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:345
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type) DECLSPEC_HIDDEN
Definition: module.c:420
#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:1214
struct symt symt
char * value
Definition: compiler.c:67
void * hash_table_iter_up(struct hash_table_iter *hti) DECLSPEC_HIDDEN
Definition: storage.c:422
struct symt * pointsto
struct symt symt
struct pool pool
GLsizei const GLfloat * value
Definition: glext.h:6069
BOOL symt_add_function_signature_parameter(struct module *module, struct symt_function_signature *sig_type, struct symt *param)
Definition: type.c:394
char * pool_strdup(struct pool *a, const char *str) DECLSPEC_HIDDEN
Definition: storage.c:126
struct symt * symt_index2ptr(struct module *module, DWORD id) DECLSPEC_HIDDEN
Definition: symbol.c:110
unsigned kind
struct _SYMBOL_INFOW SYMBOL_INFOW
const char * symt_get_name(const struct symt *sym)
Definition: type.c:81
void * vector_add(struct vector *v, struct pool *pool) DECLSPEC_HIDDEN
Definition: storage.c:171
#define CV_CALL_FAR_C
Definition: symdump.c:30
uint64_t DWORD64
Definition: typedefs.h:67
const GLdouble * v
Definition: gl.h:2040
struct process * process
BOOL(CALLBACK * PSYM_ENUMERATESYMBOLS_CALLBACK)(PSYMBOL_INFO, ULONG, PVOID)
Definition: compat.h:867
struct define * next
Definition: compiler.c:65
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:110
Definition: compat.h:1369
char buffer[sizeof(SYMBOL_INFOW)+256 *sizeof(WCHAR)]
Definition: type.c:501
CV_call_e
Definition: compat.h:1971
Definition: name.c:38
unsigned int ULONG
Definition: retypes.h:1
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ERROR_INVALID_NAME
Definition: compat.h:103
enum _IMAGEHLP_SYMBOL_TYPE_INFO IMAGEHLP_SYMBOL_TYPE_INFO
struct symt * base_type
const char * PCSTR
Definition: typedefs.h:52
struct symt_udt * symt_new_udt(struct module *module, const char *typename, unsigned size, enum UdtKind kind)
Definition: type.c:219
BOOL symt_get_info(struct module *module, const struct symt *type, IMAGEHLP_SYMBOL_TYPE_INFO req, void *pInfo)
Definition: type.c:536
GLfloat GLfloat p
Definition: glext.h:8902
BOOL symt_get_address(const struct symt *type, ULONG64 *addr)
Definition: type.c:119
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:157
struct vector vchildren
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
struct symt_typedef * symt_new_typedef(struct module *module, struct symt *ref, const char *name)
Definition: type.c:428
const char * name
struct hash_table_elt hash_elt
GLuint const GLchar * name
Definition: glext.h:6031