ReactOS  0.4.14-dev-77-gd9e7c48
symbol.c
Go to the documentation of this file.
1 /*
2  * File symbol.c - management of symbols (lexical tree)
3  *
4  * Copyright (C) 1993, 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 
22 #define NONAMELESSUNION
23 
24 #include "config.h"
25 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <limits.h>
30 #include <sys/types.h>
31 #include <assert.h>
32 #ifndef DBGHELP_STATIC_LIB
33 #include "wine/debug.h"
34 #endif
35 #include "dbghelp_private.h"
36 #ifndef DBGHELP_STATIC_LIB
37 #include "winnls.h"
38 #endif
39 
41 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
42 
43 static const WCHAR starW[] = {'*','\0'};
44 
45 static inline int cmp_addr(ULONG64 a1, ULONG64 a2)
46 {
47  if (a1 > a2) return 1;
48  if (a1 < a2) return -1;
49  return 0;
50 }
51 
52 static inline int cmp_sorttab_addr(struct module* module, int idx, ULONG64 addr)
53 {
54  ULONG64 ref;
56  return cmp_addr(ref, addr);
57 }
58 
59 int symt_cmp_addr(const void* p1, const void* p2)
60 {
61  const struct symt* sym1 = *(const struct symt* const *)p1;
62  const struct symt* sym2 = *(const struct symt* const *)p2;
63  ULONG64 a1, a2;
64 
65  symt_get_address(sym1, &a1);
66  symt_get_address(sym2, &a2);
67  return cmp_addr(a1, a2);
68 }
69 
70 DWORD symt_ptr2index(struct module* module, const struct symt* sym)
71 {
72 #ifdef __x86_64__
73  const struct symt** c;
74  int len = vector_length(&module->vsymt);
75  struct hash_table_iter hti;
76  void *ptr;
77  struct symt_idx_to_ptr *idx_to_ptr;
78  /* place enough storage on the stack to represent a pointer in %p form */
79  char ptrbuf[3 + (sizeof(void *) * 2)];
80 
81  /* make a string representation of the pointer to use as a hash key */
82  sprintf(ptrbuf, "%p", sym);
83  hash_table_iter_init(&module->ht_symaddr, &hti, ptrbuf);
84 
85  /* try to find the pointer in our ht */
86  while ((ptr = hash_table_iter_up(&hti))) {
87  idx_to_ptr = CONTAINING_RECORD(ptr, struct symt_idx_to_ptr, hash_elt);
88  if (idx_to_ptr->sym == sym)
89  return idx_to_ptr->idx;
90  }
91 
92  /* not found */
93  /* add the symbol to our symbol vector */
95 
96  /* add an idx to ptr mapping so we can find it again by address */
97  if ((idx_to_ptr = pool_alloc(&module->pool, sizeof(*idx_to_ptr))))
98  {
99  idx_to_ptr->hash_elt.name = pool_strdup(&module->pool, ptrbuf);
100  idx_to_ptr->sym = sym;
101  idx_to_ptr->idx = len + 1;
102  hash_table_add(&module->ht_symaddr, &idx_to_ptr->hash_elt);
103  }
104 
105  if (c) *c = sym;
106  return len + 1;
107 #else
108  return (DWORD)sym;
109 #endif
110 }
111 
112 struct symt* symt_index2ptr(struct module* module, DWORD id)
113 {
114 #ifdef __x86_64__
115  if (!id-- || id >= vector_length(&module->vsymt)) return NULL;
116  return *(struct symt**)vector_at(&module->vsymt, id);
117 #else
118  return (struct symt*)id;
119 #endif
120 }
121 
122 static BOOL symt_grow_sorttab(struct module* module, unsigned sz)
123 {
124  struct symt_ht** new;
125  unsigned int size;
126 
127  if (sz <= module->sorttab_size) return TRUE;
128  if (module->addr_sorttab)
129  {
130  size = module->sorttab_size * 2;
132  size * sizeof(struct symt_ht*));
133  }
134  else
135  {
136  size = 64;
137  new = HeapAlloc(GetProcessHeap(), 0, size * sizeof(struct symt_ht*));
138  }
139  if (!new) return FALSE;
141  module->addr_sorttab = new;
142  return TRUE;
143 }
144 
145 static void symt_add_module_ht(struct module* module, struct symt_ht* ht)
146 {
147  ULONG64 addr;
148 
149  hash_table_add(&module->ht_symbols, &ht->hash_elt);
150  /* Don't store in sorttab a symbol without address, they are of
151  * no use here (e.g. constant values)
152  */
153  if (symt_get_address(&ht->symt, &addr) &&
155  {
158  }
159 }
160 
161 static WCHAR* file_regex(const char* srcfile)
162 {
163  WCHAR* mask;
164  WCHAR* p;
165 
166  if (!srcfile || !*srcfile)
167  {
168  if (!(p = mask = HeapAlloc(GetProcessHeap(), 0, 3 * sizeof(WCHAR)))) return NULL;
169  *p++ = '?';
170  *p++ = '#';
171  }
172  else
173  {
174  DWORD sz = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
175  WCHAR* srcfileW;
176 
177  /* FIXME: we use here the largest conversion for every char... could be optimized */
178  p = mask = HeapAlloc(GetProcessHeap(), 0, (5 * strlen(srcfile) + 1 + sz) * sizeof(WCHAR));
179  if (!mask) return NULL;
180  srcfileW = mask + 5 * strlen(srcfile) + 1;
181  MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, sz);
182 
183  while (*srcfileW)
184  {
185  switch (*srcfileW)
186  {
187  case '\\':
188  case '/':
189  *p++ = '[';
190  *p++ = '\\';
191  *p++ = '\\';
192  *p++ = '/';
193  *p++ = ']';
194  break;
195  case '.':
196  *p++ = '?';
197  break;
198  default:
199  *p++ = *srcfileW;
200  break;
201  }
202  srcfileW++;
203  }
204  }
205  *p = 0;
206  return mask;
207 }
208 
210  unsigned long address, unsigned src_idx)
211 {
212  struct symt_compiland* sym;
213 
214  TRACE_(dbghelp_symt)("Adding compiland symbol %s:%s\n",
216  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
217  {
218  sym->symt.tag = SymTagCompiland;
219  sym->address = address;
220  sym->source = src_idx;
221  vector_init(&sym->vchildren, sizeof(struct symt*), 32);
222  }
223  return sym;
224 }
225 
227  struct symt_compiland* compiland,
228  const char* name,
230  unsigned long address, unsigned size)
231 {
232  struct symt_public* sym;
233  struct symt** p;
234 
235  TRACE_(dbghelp_symt)("Adding public symbol %s:%s @%lx\n",
239  return NULL;
240  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
241  {
242  sym->symt.tag = SymTagPublicSymbol;
243  sym->hash_elt.name = pool_strdup(&module->pool, name);
244  sym->container = compiland ? &compiland->symt : NULL;
245  sym->is_function = is_function;
246  sym->address = address;
247  sym->size = size;
248  symt_add_module_ht(module, (struct symt_ht*)sym);
249  if (compiland)
250  {
251  p = vector_add(&compiland->vchildren, &module->pool);
252  *p = &sym->symt;
253  }
254  }
255  return sym;
256 }
257 
259  struct symt_compiland* compiland,
260  const char* name, unsigned is_static,
261  struct location loc, unsigned long size,
262  struct symt* type)
263 {
264  struct symt_data* sym;
265  struct symt** p;
266  DWORD64 tsz;
267 
268  TRACE_(dbghelp_symt)("Adding global symbol %s:%s %d@%lx %p\n",
270  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
271  {
272  sym->symt.tag = SymTagData;
273  sym->hash_elt.name = pool_strdup(&module->pool, name);
274  sym->kind = is_static ? DataIsFileStatic : DataIsGlobal;
275  sym->container = compiland ? &compiland->symt : NULL;
276  sym->type = type;
277  sym->u.var = loc;
278  if (type && size && symt_get_info(module, type, TI_GET_LENGTH, &tsz))
279  {
280  if (tsz != size)
281  FIXME("Size mismatch for %s.%s between type (%s) and src (%lu)\n",
283  wine_dbgstr_longlong(tsz), size);
284  }
285  symt_add_module_ht(module, (struct symt_ht*)sym);
286  if (compiland)
287  {
288  p = vector_add(&compiland->vchildren, &module->pool);
289  *p = &sym->symt;
290  }
291  }
292  return sym;
293 }
294 
296  struct symt_compiland* compiland,
297  const char* name,
298  unsigned long addr, unsigned long size,
299  struct symt* sig_type)
300 {
301  struct symt_function* sym;
302  struct symt** p;
303 
304  TRACE_(dbghelp_symt)("Adding global function %s:%s @%lx-%lx\n",
306 
307  assert(!sig_type || sig_type->tag == SymTagFunctionType);
308  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
309  {
310  sym->symt.tag = SymTagFunction;
311  sym->hash_elt.name = pool_strdup(&module->pool, name);
312  sym->container = &compiland->symt;
313  sym->address = addr;
314  sym->type = sig_type;
315  sym->size = size;
316  vector_init(&sym->vlines, sizeof(struct line_info), 64);
317  vector_init(&sym->vchildren, sizeof(struct symt*), 8);
318  symt_add_module_ht(module, (struct symt_ht*)sym);
319  if (compiland)
320  {
321  p = vector_add(&compiland->vchildren, &module->pool);
322  *p = &sym->symt;
323  }
324  }
325  return sym;
326 }
327 
329  unsigned source_idx, int line_num, unsigned long offset)
330 {
331  struct line_info* dli;
332  BOOL last_matches = FALSE;
333  int i;
334 
335  if (func == NULL || !(dbghelp_options & SYMOPT_LOAD_LINES)) return;
336 
337  TRACE_(dbghelp_symt)("(%p)%s:%lx %s:%u\n",
338  func, func->hash_elt.name, offset,
339  source_get(module, source_idx), line_num);
340 
341  assert(func->symt.tag == SymTagFunction);
342 
343  for (i=vector_length(&func->vlines)-1; i>=0; i--)
344  {
345  dli = vector_at(&func->vlines, i);
346  if (dli->is_source_file)
347  {
348  last_matches = (source_idx == dli->u.source_file);
349  break;
350  }
351  }
352 
353  if (!last_matches)
354  {
355  /* we shouldn't have line changes on first line of function */
356  dli = vector_add(&func->vlines, &module->pool);
357  dli->is_source_file = 1;
358  dli->is_first = dli->is_last = 0;
359  dli->line_number = 0;
360  dli->u.source_file = source_idx;
361  }
362  dli = vector_add(&func->vlines, &module->pool);
363  dli->is_source_file = 0;
364  dli->is_first = dli->is_last = 0;
365  dli->line_number = line_num;
366  dli->u.pc_offset = func->address + offset;
367 }
368 
369 /******************************************************************
370  * symt_add_func_local
371  *
372  * Adds a new local/parameter to a given function:
373  * In any cases, dt tells whether it's a local variable or a parameter
374  * If regno it's not 0:
375  * - then variable is stored in a register
376  * - otherwise, value is referenced by register + offset
377  * Otherwise, the variable is stored on the stack:
378  * - offset is then the offset from the frame register
379  */
381  struct symt_function* func,
382  enum DataKind dt,
383  const struct location* loc,
384  struct symt_block* block,
385  struct symt* type, const char* name)
386 {
387  struct symt_data* locsym;
388  struct symt** p;
389 
390  TRACE_(dbghelp_symt)("Adding local symbol (%s:%s): %s %p\n",
392  name, type);
393 
394  assert(func);
395  assert(func->symt.tag == SymTagFunction);
396  assert(dt == DataIsParam || dt == DataIsLocal);
397 
398  locsym = pool_alloc(&module->pool, sizeof(*locsym));
399  locsym->symt.tag = SymTagData;
400  locsym->hash_elt.name = pool_strdup(&module->pool, name);
401  locsym->hash_elt.next = NULL;
402  locsym->kind = dt;
403  locsym->container = block ? &block->symt : &func->symt;
404  locsym->type = type;
405  locsym->u.var = *loc;
406  if (block)
407  p = vector_add(&block->vchildren, &module->pool);
408  else
409  p = vector_add(&func->vchildren, &module->pool);
410  *p = &locsym->symt;
411  return locsym;
412 }
413 
414 
416  struct symt_function* func,
417  struct symt_block* parent_block,
418  unsigned pc, unsigned len)
419 {
420  struct symt_block* block;
421  struct symt** p;
422 
423  assert(func);
424  assert(func->symt.tag == SymTagFunction);
425 
426  assert(!parent_block || parent_block->symt.tag == SymTagBlock);
427  block = pool_alloc(&module->pool, sizeof(*block));
428  block->symt.tag = SymTagBlock;
429  block->address = func->address + pc;
430  block->size = len;
431  block->container = parent_block ? &parent_block->symt : &func->symt;
432  vector_init(&block->vchildren, sizeof(struct symt*), 4);
433  if (parent_block)
434  p = vector_add(&parent_block->vchildren, &module->pool);
435  else
436  p = vector_add(&func->vchildren, &module->pool);
437  *p = &block->symt;
438 
439  return block;
440 }
441 
443  const struct symt_function* func,
444  struct symt_block* block, unsigned pc)
445 {
446  assert(func);
447  assert(func->symt.tag == SymTagFunction);
448 
449  if (pc) block->size = func->address + pc - block->address;
450  return (block->container->tag == SymTagBlock) ?
451  CONTAINING_RECORD(block->container, struct symt_block, symt) : NULL;
452 }
453 
455  struct symt_function* func,
456  enum SymTagEnum point,
457  const struct location* loc,
458  const char* name)
459 {
460  struct symt_hierarchy_point*sym;
461  struct symt** p;
462 
463  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
464  {
465  sym->symt.tag = point;
466  sym->parent = &func->symt;
467  sym->loc = *loc;
468  sym->hash_elt.name = name ? pool_strdup(&module->pool, name) : NULL;
469  p = vector_add(&func->vchildren, &module->pool);
470  *p = &sym->symt;
471  }
472  return sym;
473 }
474 
476 {
477  unsigned len;
478  struct line_info* dli;
479 
480  assert(func);
481  /* We aren't adding any more locals or line numbers to this function.
482  * Free any spare memory that we might have allocated.
483  */
484  assert(func->symt.tag == SymTagFunction);
485 
486 /* EPP vector_pool_normalize(&func->vlines, &module->pool); */
487 /* EPP vector_pool_normalize(&func->vchildren, &module->pool); */
488 
489  len = vector_length(&func->vlines);
490  if (len--)
491  {
492  dli = vector_at(&func->vlines, 0); dli->is_first = 1;
493  dli = vector_at(&func->vlines, len); dli->is_last = 1;
494  }
495  return TRUE;
496 }
497 
499  struct symt_compiland* compiland,
500  const char* name, THUNK_ORDINAL ord,
501  unsigned long addr, unsigned long size)
502 {
503  struct symt_thunk* sym;
504 
505  TRACE_(dbghelp_symt)("Adding global thunk %s:%s @%lx-%lx\n",
507 
508  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
509  {
510  sym->symt.tag = SymTagThunk;
511  sym->hash_elt.name = pool_strdup(&module->pool, name);
512  sym->container = &compiland->symt;
513  sym->address = addr;
514  sym->size = size;
515  sym->ordinal = ord;
516  symt_add_module_ht(module, (struct symt_ht*)sym);
517  if (compiland)
518  {
519  struct symt** p;
520  p = vector_add(&compiland->vchildren, &module->pool);
521  *p = &sym->symt;
522  }
523  }
524  return sym;
525 }
526 
528  struct symt_compiland* compiland,
529  const char* name, struct symt* type,
530  const VARIANT* v)
531 {
532  struct symt_data* sym;
533 
534  TRACE_(dbghelp_symt)("Adding constant value %s:%s\n",
536 
537  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
538  {
539  sym->symt.tag = SymTagData;
540  sym->hash_elt.name = pool_strdup(&module->pool, name);
541  sym->kind = DataIsConstant;
542  sym->container = compiland ? &compiland->symt : NULL;
543  sym->type = type;
544  sym->u.value = *v;
545  symt_add_module_ht(module, (struct symt_ht*)sym);
546  if (compiland)
547  {
548  struct symt** p;
549  p = vector_add(&compiland->vchildren, &module->pool);
550  *p = &sym->symt;
551  }
552  }
553  return sym;
554 }
555 
557  struct symt_compiland* compiland,
558  const char* name, unsigned long address)
559 {
560  struct symt_hierarchy_point* sym;
561 
562  TRACE_(dbghelp_symt)("Adding global label value %s:%s\n",
564 
565  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
566  {
567  sym->symt.tag = SymTagLabel;
568  sym->hash_elt.name = pool_strdup(&module->pool, name);
569  sym->loc.kind = loc_absolute;
570  sym->loc.offset = address;
571  sym->parent = compiland ? &compiland->symt : NULL;
572  symt_add_module_ht(module, (struct symt_ht*)sym);
573  if (compiland)
574  {
575  struct symt** p;
576  p = vector_add(&compiland->vchildren, &module->pool);
577  *p = &sym->symt;
578  }
579  }
580  return sym;
581 }
582 
583 /* expect sym_info->MaxNameLen to be set before being called */
584 static void symt_fill_sym_info(struct module_pair* pair,
585  const struct symt_function* func,
586  const struct symt* sym, SYMBOL_INFO* sym_info)
587 {
588  const char* name;
589  DWORD64 size;
590 
591  if (!symt_get_info(pair->effective, sym, TI_GET_TYPE, &sym_info->TypeIndex))
592  sym_info->TypeIndex = 0;
593  sym_info->Index = symt_ptr2index(pair->effective, sym);
594  sym_info->Reserved[0] = sym_info->Reserved[1] = 0;
595  if (!symt_get_info(pair->effective, sym, TI_GET_LENGTH, &size) &&
596  (!sym_info->TypeIndex ||
597  !symt_get_info(pair->effective, symt_index2ptr(pair->effective, sym_info->TypeIndex),
598  TI_GET_LENGTH, &size)))
599  size = 0;
600  sym_info->Size = (DWORD)size;
601  sym_info->ModBase = pair->requested->module.BaseOfImage;
602  sym_info->Flags = 0;
603  sym_info->Value = 0;
604 
605  switch (sym->tag)
606  {
607  case SymTagData:
608  {
609  const struct symt_data* data = (const struct symt_data*)sym;
610  switch (data->kind)
611  {
612  case DataIsParam:
613  sym_info->Flags |= SYMFLAG_PARAMETER;
614  /* fall through */
615  case DataIsLocal:
616  sym_info->Flags |= SYMFLAG_LOCAL;
617  {
618  struct location loc = data->u.var;
619 
620  if (loc.kind >= loc_user)
621  {
622  unsigned i;
623  struct module_format* modfmt;
624 
625  for (i = 0; i < DFI_LAST; i++)
626  {
627  modfmt = pair->effective->format_info[i];
628  if (modfmt && modfmt->loc_compute)
629  {
630  modfmt->loc_compute(pair->pcs, modfmt, func, &loc);
631  break;
632  }
633  }
634  }
635  switch (loc.kind)
636  {
637  case loc_error:
638  /* for now we report error cases as a negative register number */
639  /* fall through */
640  case loc_register:
641  sym_info->Flags |= SYMFLAG_REGISTER;
642  sym_info->Register = loc.reg;
643  sym_info->Address = 0;
644  break;
645  case loc_regrel:
646  sym_info->Flags |= SYMFLAG_REGREL;
647  sym_info->Register = loc.reg;
648  if (loc.reg == CV_REG_NONE || (int)loc.reg < 0 /* error */)
649  FIXME("suspicious register value %x\n", loc.reg);
650  sym_info->Address = loc.offset;
651  break;
652  case loc_absolute:
653  sym_info->Flags |= SYMFLAG_VALUEPRESENT;
654  sym_info->Value = loc.offset;
655  break;
656  default:
657  FIXME("Shouldn't happen (kind=%d), debug reader backend is broken\n", loc.kind);
658  assert(0);
659  }
660  }
661  break;
662  case DataIsGlobal:
663  case DataIsFileStatic:
664  switch (data->u.var.kind)
665  {
666  case loc_tlsrel:
667  sym_info->Flags |= SYMFLAG_TLSREL;
668  /* fall through */
669  case loc_absolute:
670  symt_get_address(sym, &sym_info->Address);
671  sym_info->Register = 0;
672  break;
673  default:
674  FIXME("Shouldn't happen (kind=%d), debug reader backend is broken\n", data->u.var.kind);
675  assert(0);
676  }
677  break;
678  case DataIsConstant:
679  sym_info->Flags |= SYMFLAG_VALUEPRESENT;
680  switch (data->u.value.n1.n2.vt)
681  {
682  case VT_I4: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.lVal; break;
683  case VT_I2: sym_info->Value = (ULONG)(long)data->u.value.n1.n2.n3.iVal; break;
684  case VT_I1: sym_info->Value = (ULONG)(long)data->u.value.n1.n2.n3.cVal; break;
685  case VT_UI4: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.ulVal; break;
686  case VT_UI2: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.uiVal; break;
687  case VT_UI1: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.bVal; break;
688  case VT_I1 | VT_BYREF: sym_info->Value = (ULONG64)(DWORD_PTR)data->u.value.n1.n2.n3.byref; break;
689  case VT_EMPTY: sym_info->Value = 0; break;
690  default:
691  FIXME("Unsupported variant type (%u)\n", data->u.value.n1.n2.vt);
692  sym_info->Value = 0;
693  break;
694  }
695  break;
696  default:
697  FIXME("Unhandled kind (%u) in sym data\n", data->kind);
698  }
699  }
700  break;
701  case SymTagPublicSymbol:
702  {
703  const struct symt_public* pub = (const struct symt_public*)sym;
704  if (pub->is_function)
705  sym_info->Flags |= SYMFLAG_PUBLIC_CODE;
706  else
707  sym_info->Flags |= SYMFLAG_EXPORT;
708  symt_get_address(sym, &sym_info->Address);
709  }
710  break;
711  case SymTagFunction:
712  symt_get_address(sym, &sym_info->Address);
713  break;
714  case SymTagThunk:
715  sym_info->Flags |= SYMFLAG_THUNK;
716  symt_get_address(sym, &sym_info->Address);
717  break;
718  default:
719  symt_get_address(sym, &sym_info->Address);
720  sym_info->Register = 0;
721  break;
722  }
723  sym_info->Scope = 0; /* FIXME */
724  sym_info->Tag = sym->tag;
725  name = symt_get_name(sym);
726  if (sym_info->MaxNameLen)
727  {
729  ((sym_info->NameLen = UnDecorateSymbolName(name, sym_info->Name,
730  sym_info->MaxNameLen, UNDNAME_NAME_ONLY)) == 0))
731  {
732  sym_info->NameLen = min(strlen(name), sym_info->MaxNameLen - 1);
733  memcpy(sym_info->Name, name, sym_info->NameLen);
734  sym_info->Name[sym_info->NameLen] = '\0';
735  }
736  }
737  TRACE_(dbghelp_symt)("%p => %s %u %s\n",
738  sym, sym_info->Name, sym_info->Size,
739  wine_dbgstr_longlong(sym_info->Address));
740 }
741 
742 struct sym_enum
743 {
750  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
751 };
752 
753 static BOOL send_symbol(const struct sym_enum* se, struct module_pair* pair,
754  const struct symt_function* func, const struct symt* sym)
755 {
756  symt_fill_sym_info(pair, func, sym, se->sym_info);
757  if (se->index && se->sym_info->Index != se->index) return FALSE;
758  if (se->tag && se->sym_info->Tag != se->tag) return FALSE;
759  if (se->addr && !(se->addr >= se->sym_info->Address && se->addr < se->sym_info->Address + se->sym_info->Size)) return FALSE;
760  return !se->cb(se->sym_info, se->sym_info->Size, se->user);
761 }
762 
764  const struct sym_enum* se)
765 {
766  void* ptr;
767  struct symt_ht* sym = NULL;
768  struct hash_table_iter hti;
769  WCHAR* nameW;
770  BOOL ret;
771 
772  hash_table_iter_init(&pair->effective->ht_symbols, &hti, NULL);
773  while ((ptr = hash_table_iter_up(&hti)))
774  {
775  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
776  nameW = symt_get_nameW(&sym->symt);
779  if (ret)
780  {
781  se->sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
782  se->sym_info->MaxNameLen = sizeof(se->buffer) - sizeof(SYMBOL_INFO);
783  if (send_symbol(se, pair, NULL, &sym->symt)) return TRUE;
784  }
785  }
786  return FALSE;
787 }
788 
789 static inline unsigned where_to_insert(struct module* module, unsigned high, const struct symt_ht* elt)
790 {
791  unsigned low = 0, mid = high / 2;
792  ULONG64 addr;
793 
794  if (!high) return 0;
795  symt_get_address(&elt->symt, &addr);
796  do
797  {
798  switch (cmp_sorttab_addr(module, mid, addr))
799  {
800  case 0: return mid;
801  case -1: low = mid + 1; break;
802  case 1: high = mid; break;
803  }
804  mid = low + (high - low) / 2;
805  } while (low < high);
806  return mid;
807 }
808 
809 /***********************************************************************
810  * resort_symbols
811  *
812  * Rebuild sorted list of symbols for a module.
813  */
815 {
816  int delta;
817 
819  return FALSE;
820 
821  /* we know that set from 0 up to num_sorttab is already sorted
822  * so sort the remaining (new) symbols, and merge the two sets
823  * (unless the first set is empty)
824  */
825  delta = module->num_symbols - module->num_sorttab;
826  qsort(&module->addr_sorttab[module->num_sorttab], delta, sizeof(struct symt_ht*), symt_cmp_addr);
827  if (module->num_sorttab)
828  {
829  int i, ins_idx = module->num_sorttab, prev_ins_idx;
830  static struct symt_ht** tmp;
831  static unsigned num_tmp;
832 
833  if (num_tmp < delta)
834  {
835  static struct symt_ht** new;
836  if (tmp)
837  new = HeapReAlloc(GetProcessHeap(), 0, tmp, delta * sizeof(struct symt_ht*));
838  else
839  new = HeapAlloc(GetProcessHeap(), 0, delta * sizeof(struct symt_ht*));
840  if (!new)
841  {
842  module->num_sorttab = 0;
843  return resort_symbols(module);
844  }
845  tmp = new;
846  num_tmp = delta;
847  }
848  memcpy(tmp, &module->addr_sorttab[module->num_sorttab], delta * sizeof(struct symt_ht*));
849  qsort(tmp, delta, sizeof(struct symt_ht*), symt_cmp_addr);
850 
851  for (i = delta - 1; i >= 0; i--)
852  {
853  prev_ins_idx = ins_idx;
854  ins_idx = where_to_insert(module, ins_idx, tmp[i]);
855  memmove(&module->addr_sorttab[ins_idx + i + 1],
856  &module->addr_sorttab[ins_idx],
857  (prev_ins_idx - ins_idx) * sizeof(struct symt_ht*));
858  module->addr_sorttab[ins_idx + i] = tmp[i];
859  }
860  }
862  return module->sortlist_valid = TRUE;
863 }
864 
865 static void symt_get_length(struct module* module, const struct symt* symt, ULONG64* size)
866 {
867  DWORD type_index;
868 
870  return;
871 
872  if (symt_get_info(module, symt, TI_GET_TYPE, &type_index) &&
873  symt_get_info(module, symt_index2ptr(module, type_index), TI_GET_LENGTH, size)) return;
874  *size = 0x1000; /* arbitrary value */
875 }
876 
877 /* neede by symt_find_nearest */
878 int symt_get_best_at(struct module* module, int idx_sorttab)
879 {
880  ULONG64 ref_addr;
881  int idx_sorttab_orig = idx_sorttab;
882  if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
883  {
884  symt_get_address(&module->addr_sorttab[idx_sorttab]->symt, &ref_addr);
885  while (idx_sorttab > 0 &&
886  module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol &&
887  !cmp_sorttab_addr(module, idx_sorttab - 1, ref_addr))
888  idx_sorttab--;
889  if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
890  {
891  idx_sorttab = idx_sorttab_orig;
892  while (idx_sorttab < module->num_sorttab - 1 &&
893  module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol &&
894  !cmp_sorttab_addr(module, idx_sorttab + 1, ref_addr))
895  idx_sorttab++;
896  }
897  /* if no better symbol fond restore original */
898  if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
899  idx_sorttab = idx_sorttab_orig;
900  }
901  return idx_sorttab;
902 }
903 
904 /* assume addr is in module */
906 {
907  int mid, high, low;
908  ULONG64 ref_addr, ref_size;
909 
911  {
912  if (!resort_symbols(module)) return NULL;
913  }
914 
915  /*
916  * Binary search to find closest symbol.
917  */
918  low = 0;
919  high = module->num_sorttab;
920 
921  symt_get_address(&module->addr_sorttab[0]->symt, &ref_addr);
922  if (addr <= ref_addr)
923  {
924  low = symt_get_best_at(module, 0);
925  return module->addr_sorttab[low];
926  }
927 
928  if (high)
929  {
930  symt_get_address(&module->addr_sorttab[high - 1]->symt, &ref_addr);
931  symt_get_length(module, &module->addr_sorttab[high - 1]->symt, &ref_size);
932  if (addr >= ref_addr + ref_size) return NULL;
933  }
934 
935  while (high > low + 1)
936  {
937  mid = (high + low) / 2;
938  if (cmp_sorttab_addr(module, mid, addr) < 0)
939  low = mid;
940  else
941  high = mid;
942  }
943  if (low != high && high != module->num_sorttab &&
944  cmp_sorttab_addr(module, high, addr) <= 0)
945  low = high;
946 
947  /* If found symbol is a public symbol, check if there are any other entries that
948  * might also have the same address, but would get better information
949  */
950  low = symt_get_best_at(module, low);
951 
952  /* finally check that we fit into the found symbol */
953  //symt_get_address(&module->addr_sorttab[low]->symt, &ref_addr);
954  //if (addr < ref_addr) return NULL;
955  //symt_get_length(module, &module->addr_sorttab[low]->symt, &ref_size);
956  //if (addr >= ref_addr + ref_size) return NULL;
957 
958  return module->addr_sorttab[low];
959 }
960 
962  const WCHAR* match, const struct sym_enum* se,
963  struct symt_function* func, const struct vector* v)
964 {
965  struct symt* lsym = NULL;
966  DWORD pc = pair->pcs->ctx_frame.InstructionOffset;
967  unsigned int i;
968  WCHAR* nameW;
969  BOOL ret;
970 
971  for (i=0; i<vector_length(v); i++)
972  {
973  lsym = *(struct symt**)vector_at(v, i);
974  switch (lsym->tag)
975  {
976  case SymTagBlock:
977  {
978  struct symt_block* block = (struct symt_block*)lsym;
979  if (pc < block->address || block->address + block->size <= pc)
980  continue;
981  if (!symt_enum_locals_helper(pair, match, se, func, &block->vchildren))
982  return FALSE;
983  }
984  break;
985  case SymTagData:
986  nameW = symt_get_nameW(lsym);
990  if (ret)
991  {
992  if (send_symbol(se, pair, func, lsym)) return FALSE;
993  }
994  break;
995  case SymTagLabel:
997  case SymTagFuncDebugEnd:
998  case SymTagCustom:
999  break;
1000  default:
1001  FIXME("Unknown type: %u (%x)\n", lsym->tag, lsym->tag);
1002  assert(0);
1003  }
1004  }
1005  return TRUE;
1006 }
1007 
1008 static BOOL symt_enum_locals(struct process* pcs, const WCHAR* mask,
1009  const struct sym_enum* se)
1010 {
1011  struct module_pair pair;
1012  struct symt_ht* sym;
1014 
1015  se->sym_info->SizeOfStruct = sizeof(*se->sym_info);
1016  se->sym_info->MaxNameLen = sizeof(se->buffer) - sizeof(SYMBOL_INFO);
1017 
1018  pair.pcs = pcs;
1019  pair.requested = module_find_by_addr(pair.pcs, pc, DMT_UNKNOWN);
1020  if (!module_get_debug(&pair)) return FALSE;
1021  if ((sym = symt_find_nearest(pair.effective, pc)) == NULL) return FALSE;
1022 
1023  if (sym->symt.tag == SymTagFunction)
1024  {
1025  return symt_enum_locals_helper(&pair, mask ? mask : starW, se, (struct symt_function*)sym,
1026  &((struct symt_function*)sym)->vchildren);
1027  }
1028  return FALSE;
1029 }
1030 
1031 /******************************************************************
1032  * copy_symbolW
1033  *
1034  * Helper for transforming an ANSI symbol info into a UNICODE one.
1035  * Assume that MaxNameLen is the same for both version (A & W).
1036  */
1038 {
1039  siw->SizeOfStruct = si->SizeOfStruct;
1040  siw->TypeIndex = si->TypeIndex;
1041  siw->Reserved[0] = si->Reserved[0];
1042  siw->Reserved[1] = si->Reserved[1];
1043  siw->Index = si->Index;
1044  siw->Size = si->Size;
1045  siw->ModBase = si->ModBase;
1046  siw->Flags = si->Flags;
1047  siw->Value = si->Value;
1048  siw->Address = si->Address;
1049  siw->Register = si->Register;
1050  siw->Scope = si->Scope;
1051  siw->Tag = si->Tag;
1052  siw->NameLen = si->NameLen;
1053  siw->MaxNameLen = si->MaxNameLen;
1054  MultiByteToWideChar(CP_ACP, 0, si->Name, -1, siw->Name, siw->MaxNameLen);
1055 }
1056 
1057 /******************************************************************
1058  * sym_enum
1059  *
1060  * Core routine for most of the enumeration of symbols
1061  */
1062 static BOOL sym_enum(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask,
1063  const struct sym_enum* se)
1064 {
1065  struct module_pair pair;
1066  const WCHAR* bang;
1067  WCHAR* mod;
1068 
1070  if (!pair.pcs) return FALSE;
1071  if (BaseOfDll == 0)
1072  {
1073  /* do local variables ? */
1074  if (!Mask || !(bang = strchrW(Mask, '!')))
1075  return symt_enum_locals(pair.pcs, Mask, se);
1076 
1077  if (bang == Mask) return FALSE;
1078 
1079  mod = HeapAlloc(GetProcessHeap(), 0, (bang - Mask + 1) * sizeof(WCHAR));
1080  if (!mod) return FALSE;
1081  memcpy(mod, Mask, (bang - Mask) * sizeof(WCHAR));
1082  mod[bang - Mask] = 0;
1083 
1084  for (pair.requested = pair.pcs->lmodules; pair.requested; pair.requested = pair.requested->next)
1085  {
1086  if (pair.requested->type == DMT_PE && module_get_debug(&pair))
1087  {
1088  if (SymMatchStringW(pair.requested->module.ModuleName, mod, FALSE) &&
1089  symt_enum_module(&pair, bang + 1, se))
1090  break;
1091  }
1092  }
1093  /* not found in PE modules, retry on the ELF ones
1094  */
1096  {
1097  for (pair.requested = pair.pcs->lmodules; pair.requested; pair.requested = pair.requested->next)
1098  {
1099  if ((pair.requested->type == DMT_ELF || pair.requested->type == DMT_MACHO) &&
1100  !module_get_containee(pair.pcs, pair.requested) &&
1102  {
1103  if (SymMatchStringW(pair.requested->module.ModuleName, mod, FALSE) &&
1104  symt_enum_module(&pair, bang + 1, se))
1105  break;
1106  }
1107  }
1108  }
1109  HeapFree(GetProcessHeap(), 0, mod);
1110  return TRUE;
1111  }
1112  pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
1113  if (!module_get_debug(&pair))
1114  return FALSE;
1115 
1116  /* we always ignore module name from Mask when BaseOfDll is defined */
1117  if (Mask && (bang = strchrW(Mask, '!')))
1118  {
1119  if (bang == Mask) return FALSE;
1120  Mask = bang + 1;
1121  }
1122 
1123  symt_enum_module(&pair, Mask ? Mask : starW, se);
1124 
1125  return TRUE;
1126 }
1127 
1128 static inline BOOL doSymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask,
1129  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
1130  PVOID UserContext)
1131 {
1132  struct sym_enum se;
1133 
1134  se.cb = EnumSymbolsCallback;
1135  se.user = UserContext;
1136  se.index = 0;
1137  se.tag = 0;
1138  se.addr = 0;
1139  se.sym_info = (PSYMBOL_INFO)se.buffer;
1140 
1141  return sym_enum(hProcess, BaseOfDll, Mask, &se);
1142 }
1143 
1144 /******************************************************************
1145  * SymEnumSymbols (DBGHELP.@)
1146  *
1147  * cases BaseOfDll = 0
1148  * !foo fails always (despite what MSDN states)
1149  * RE1!RE2 looks up all modules matching RE1, and in all these modules, lookup RE2
1150  * no ! in Mask, lookup in local Context
1151  * cases BaseOfDll != 0
1152  * !foo fails always (despite what MSDN states)
1153  * RE1!RE2 gets RE2 from BaseOfDll (whatever RE1 is)
1154  */
1156  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
1157  PVOID UserContext)
1158 {
1159  BOOL ret;
1160  PWSTR maskW = NULL;
1161 
1162  TRACE("(%p %s %s %p %p)\n",
1163  hProcess, wine_dbgstr_longlong(BaseOfDll), debugstr_a(Mask),
1164  EnumSymbolsCallback, UserContext);
1165 
1166  if (Mask)
1167  {
1168  DWORD sz = MultiByteToWideChar(CP_ACP, 0, Mask, -1, NULL, 0);
1169  if (!(maskW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
1170  return FALSE;
1171  MultiByteToWideChar(CP_ACP, 0, Mask, -1, maskW, sz);
1172  }
1173  ret = doSymEnumSymbols(hProcess, BaseOfDll, maskW, EnumSymbolsCallback, UserContext);
1174  HeapFree(GetProcessHeap(), 0, maskW);
1175  return ret;
1176 }
1177 
1179 {
1181  void* ctx;
1184 
1185 };
1186 
1188 {
1189  struct sym_enumW* sew = ctx;
1190 
1191  copy_symbolW(sew->sym_info, si);
1192 
1193  return (sew->cb)(sew->sym_info, size, sew->ctx);
1194 }
1195 
1196 /******************************************************************
1197  * SymEnumSymbolsW (DBGHELP.@)
1198  *
1199  */
1201  PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
1202  PVOID UserContext)
1203 {
1204  struct sym_enumW sew;
1205 
1206  sew.ctx = UserContext;
1207  sew.cb = EnumSymbolsCallback;
1208  sew.sym_info = (PSYMBOL_INFOW)sew.buffer;
1209 
1210  return doSymEnumSymbols(hProcess, BaseOfDll, Mask, sym_enumW, &sew);
1211 }
1212 
1214 {
1215  void* ctx;
1217 };
1218 
1220 {
1221  struct sym_enumerate* se = ctx;
1222  return (se->cb)(syminfo->Name, syminfo->Address, syminfo->Size, se->ctx);
1223 }
1224 
1225 /***********************************************************************
1226  * SymEnumerateSymbols (DBGHELP.@)
1227  */
1229  PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
1230  PVOID UserContext)
1231 {
1232  struct sym_enumerate se;
1233 
1234  se.ctx = UserContext;
1235  se.cb = EnumSymbolsCallback;
1236 
1237  return SymEnumSymbols(hProcess, BaseOfDll, NULL, sym_enumerate_cb, &se);
1238 }
1239 
1241 {
1242  void* ctx;
1244 };
1245 
1247 {
1248  struct sym_enumerate64* se = ctx;
1249  return (se->cb)(syminfo->Name, syminfo->Address, syminfo->Size, se->ctx);
1250 }
1251 
1252 /***********************************************************************
1253  * SymEnumerateSymbols64 (DBGHELP.@)
1254  */
1256  PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
1257  PVOID UserContext)
1258 {
1259  struct sym_enumerate64 se;
1260 
1261  se.ctx = UserContext;
1262  se.cb = EnumSymbolsCallback;
1263 
1264  return SymEnumSymbols(hProcess, BaseOfDll, NULL, sym_enumerate_cb64, &se);
1265 }
1266 
1267 /******************************************************************
1268  * SymFromAddr (DBGHELP.@)
1269  *
1270  */
1272  DWORD64* Displacement, PSYMBOL_INFO Symbol)
1273 {
1274  struct module_pair pair;
1275  struct symt_ht* sym;
1276 
1278  if (!pair.pcs) return FALSE;
1279  pair.requested = module_find_by_addr(pair.pcs, Address, DMT_UNKNOWN);
1280  if (!module_get_debug(&pair)) return FALSE;
1281  if ((sym = symt_find_nearest(pair.effective, Address)) == NULL) return FALSE;
1282 
1283  symt_fill_sym_info(&pair, NULL, &sym->symt, Symbol);
1284  if (Displacement)
1285  *Displacement = (Address >= Symbol->Address) ? (Address - Symbol->Address) : (DWORD64)-1;
1286  return TRUE;
1287 }
1288 
1289 /******************************************************************
1290  * SymFromAddrW (DBGHELP.@)
1291  *
1292  */
1294  DWORD64* Displacement, PSYMBOL_INFOW Symbol)
1295 {
1296  PSYMBOL_INFO si;
1297  unsigned len;
1298  BOOL ret;
1299 
1300  len = sizeof(*si) + Symbol->MaxNameLen * sizeof(WCHAR);
1301  si = HeapAlloc(GetProcessHeap(), 0, len);
1302  if (!si) return FALSE;
1303 
1304  si->SizeOfStruct = sizeof(*si);
1305  si->MaxNameLen = Symbol->MaxNameLen;
1306  if ((ret = SymFromAddr(hProcess, Address, Displacement, si)))
1307  {
1308  copy_symbolW(Symbol, si);
1309  }
1310  HeapFree(GetProcessHeap(), 0, si);
1311  return ret;
1312 }
1313 
1314 /******************************************************************
1315  * SymGetSymFromAddr (DBGHELP.@)
1316  *
1317  */
1319  PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
1320 {
1321  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1323  size_t len;
1324  DWORD64 Displacement64;
1325 
1326  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1327  si->SizeOfStruct = sizeof(*si);
1328  si->MaxNameLen = MAX_SYM_NAME;
1329  if (!SymFromAddr(hProcess, Address, &Displacement64, si))
1330  return FALSE;
1331 
1332  if (Displacement)
1333  *Displacement = Displacement64;
1334  Symbol->Address = si->Address;
1335  Symbol->Size = si->Size;
1336  Symbol->Flags = si->Flags;
1337  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1338  lstrcpynA(Symbol->Name, si->Name, len);
1339  return TRUE;
1340 }
1341 
1342 /******************************************************************
1343  * SymGetSymFromAddr64 (DBGHELP.@)
1344  *
1345  */
1347  PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol)
1348 {
1349  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1351  size_t len;
1352  DWORD64 Displacement64;
1353 
1354  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1355  si->SizeOfStruct = sizeof(*si);
1356  si->MaxNameLen = MAX_SYM_NAME;
1357  if (!SymFromAddr(hProcess, Address, &Displacement64, si))
1358  return FALSE;
1359 
1360  if (Displacement)
1361  *Displacement = Displacement64;
1362  Symbol->Address = si->Address;
1363  Symbol->Size = si->Size;
1364  Symbol->Flags = si->Flags;
1365  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1366  lstrcpynA(Symbol->Name, si->Name, len);
1367  return TRUE;
1368 }
1369 
1370 static BOOL find_name(struct process* pcs, struct module* module, const char* name,
1371  SYMBOL_INFO* symbol)
1372 {
1373  struct hash_table_iter hti;
1374  void* ptr;
1375  struct symt_ht* sym = NULL;
1376  struct module_pair pair;
1377 
1378  pair.pcs = pcs;
1379  if (!(pair.requested = module)) return FALSE;
1380  if (!module_get_debug(&pair)) return FALSE;
1381 
1382  hash_table_iter_init(&pair.effective->ht_symbols, &hti, name);
1383  while ((ptr = hash_table_iter_up(&hti)))
1384  {
1385  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
1386 
1387  if (!strcmp(sym->hash_elt.name, name))
1388  {
1389  symt_fill_sym_info(&pair, NULL, &sym->symt, symbol);
1390  return TRUE;
1391  }
1392  }
1393  return FALSE;
1394 
1395 }
1396 /******************************************************************
1397  * SymFromName (DBGHELP.@)
1398  *
1399  */
1401 {
1402  struct process* pcs = process_find_by_handle(hProcess);
1403  struct module* module;
1404  const char* name;
1405 
1406  TRACE("(%p, %s, %p)\n", hProcess, Name, Symbol);
1407  if (!pcs) return FALSE;
1408  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1409  name = strchr(Name, '!');
1410  if (name)
1411  {
1412  char tmp[128];
1413  assert(name - Name < sizeof(tmp));
1414  memcpy(tmp, Name, name - Name);
1415  tmp[name - Name] = '\0';
1416  module = module_find_by_nameA(pcs, tmp);
1417  return find_name(pcs, module, name + 1, Symbol);
1418  }
1419  for (module = pcs->lmodules; module; module = module->next)
1420  {
1421  if (module->type == DMT_PE && find_name(pcs, module, Name, Symbol))
1422  return TRUE;
1423  }
1424  /* not found in PE modules, retry on the ELF ones
1425  */
1427  {
1428  for (module = pcs->lmodules; module; module = module->next)
1429  {
1430  if ((module->type == DMT_ELF || module->type == DMT_MACHO) &&
1431  !module_get_containee(pcs, module) &&
1432  find_name(pcs, module, Name, Symbol))
1433  return TRUE;
1434  }
1435  }
1436  return FALSE;
1437 }
1438 
1439 /***********************************************************************
1440  * SymGetSymFromName64 (DBGHELP.@)
1441  */
1443 {
1444  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1446  size_t len;
1447 
1448  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1449  si->SizeOfStruct = sizeof(*si);
1450  si->MaxNameLen = MAX_SYM_NAME;
1451  if (!SymFromName(hProcess, Name, si)) return FALSE;
1452 
1453  Symbol->Address = si->Address;
1454  Symbol->Size = si->Size;
1455  Symbol->Flags = si->Flags;
1456  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1457  lstrcpynA(Symbol->Name, si->Name, len);
1458  return TRUE;
1459 }
1460 
1461 /***********************************************************************
1462  * SymGetSymFromName (DBGHELP.@)
1463  */
1465 {
1466  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1468  size_t len;
1469 
1470  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1471  si->SizeOfStruct = sizeof(*si);
1472  si->MaxNameLen = MAX_SYM_NAME;
1473  if (!SymFromName(hProcess, Name, si)) return FALSE;
1474 
1475  Symbol->Address = si->Address;
1476  Symbol->Size = si->Size;
1477  Symbol->Flags = si->Flags;
1478  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1479  lstrcpynA(Symbol->Name, si->Name, len);
1480  return TRUE;
1481 }
1482 
1483 /******************************************************************
1484  * sym_fill_func_line_info
1485  *
1486  * fills information about a file
1487  */
1490 {
1491  struct line_info* dli = NULL;
1492  BOOL found = FALSE;
1493  int i;
1494 
1495  assert(func->symt.tag == SymTagFunction);
1496 
1497  for (i=vector_length(&func->vlines)-1; i>=0; i--)
1498  {
1499  dli = vector_at(&func->vlines, i);
1500  if (!dli->is_source_file)
1501  {
1502  if (found || dli->u.pc_offset > addr) continue;
1503  line->LineNumber = dli->line_number;
1504  line->Address = dli->u.pc_offset;
1505  line->Key = dli;
1506  found = TRUE;
1507  continue;
1508  }
1509  if (found)
1510  {
1511  line->FileName = (char*)source_get(module, dli->u.source_file);
1512  return TRUE;
1513  }
1514  }
1515  return FALSE;
1516 }
1517 
1518 /***********************************************************************
1519  * SymGetSymNext64 (DBGHELP.@)
1520  */
1522 {
1523  /* algo:
1524  * get module from Symbol.Address
1525  * get index in module.addr_sorttab of Symbol.Address
1526  * increment index
1527  * if out of module bounds, move to next module in process address space
1528  */
1529  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1531  return FALSE;
1532 }
1533 
1534 /***********************************************************************
1535  * SymGetSymNext (DBGHELP.@)
1536  */
1538 {
1539  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1541  return FALSE;
1542 }
1543 
1544 /***********************************************************************
1545  * SymGetSymPrev64 (DBGHELP.@)
1546  */
1548 {
1549  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1551  return FALSE;
1552 }
1553 
1554 /***********************************************************************
1555  * SymGetSymPrev (DBGHELP.@)
1556  */
1558 {
1559  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1561  return FALSE;
1562 }
1563 
1564 /******************************************************************
1565  * copy_line_64_from_32 (internal)
1566  *
1567  */
1569 
1570 {
1571  l64->Key = l32->Key;
1572  l64->LineNumber = l32->LineNumber;
1573  l64->FileName = l32->FileName;
1574  l64->Address = l32->Address;
1575 }
1576 
1577 /******************************************************************
1578  * copy_line_W64_from_32 (internal)
1579  *
1580  */
1581 static void copy_line_W64_from_64(struct process* pcs, IMAGEHLP_LINEW64* l64w, const IMAGEHLP_LINE64* l64)
1582 {
1583  unsigned len;
1584 
1585  l64w->Key = l64->Key;
1586  l64w->LineNumber = l64->LineNumber;
1587  len = MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, NULL, 0);
1588  if ((l64w->FileName = fetch_buffer(pcs, len * sizeof(WCHAR))))
1589  MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, l64w->FileName, len);
1590  l64w->Address = l64->Address;
1591 }
1592 
1593 /******************************************************************
1594  * copy_line_32_from_64 (internal)
1595  *
1596  */
1598 
1599 {
1600  l32->Key = l64->Key;
1601  l32->LineNumber = l64->LineNumber;
1602  l32->FileName = l64->FileName;
1603  l32->Address = l64->Address;
1604 }
1605 
1606 /******************************************************************
1607  * SymGetLineFromAddr (DBGHELP.@)
1608  *
1609  */
1611  PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
1612 {
1613  IMAGEHLP_LINE64 il64;
1614 
1615  il64.SizeOfStruct = sizeof(il64);
1616  if (!SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, &il64))
1617  return FALSE;
1618  copy_line_32_from_64(Line, &il64);
1619  return TRUE;
1620 }
1621 
1622 /******************************************************************
1623  * SymGetLineFromAddr64 (DBGHELP.@)
1624  *
1625  */
1627  PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line)
1628 {
1629  struct module_pair pair;
1630  struct symt_ht* symt;
1631 
1632  TRACE("%p %s %p %p\n", hProcess, wine_dbgstr_longlong(dwAddr), pdwDisplacement, Line);
1633 
1634  if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
1635 
1637  if (!pair.pcs) return FALSE;
1638  pair.requested = module_find_by_addr(pair.pcs, dwAddr, DMT_UNKNOWN);
1639  if (!module_get_debug(&pair)) return FALSE;
1640  if ((symt = symt_find_nearest(pair.effective, dwAddr)) == NULL) return FALSE;
1641 
1642  if (symt->symt.tag != SymTagFunction) return FALSE;
1643  if (!symt_fill_func_line_info(pair.effective, (struct symt_function*)symt,
1644  dwAddr, Line)) return FALSE;
1645  *pdwDisplacement = dwAddr - Line->Address;
1646  return TRUE;
1647 }
1648 
1649 /******************************************************************
1650  * SymGetLineFromAddrW64 (DBGHELP.@)
1651  *
1652  */
1654  PDWORD pdwDisplacement, PIMAGEHLP_LINEW64 Line)
1655 {
1656  IMAGEHLP_LINE64 il64;
1657 
1658  il64.SizeOfStruct = sizeof(il64);
1659  if (!SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, &il64))
1660  return FALSE;
1662  return TRUE;
1663 }
1664 
1665 /******************************************************************
1666  * SymGetLinePrev64 (DBGHELP.@)
1667  *
1668  */
1670 {
1671  struct module_pair pair;
1672  struct line_info* li;
1673  BOOL in_search = FALSE;
1674 
1675  TRACE("(%p %p)\n", hProcess, Line);
1676 
1677  if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
1678 
1680  if (!pair.pcs) return FALSE;
1681  pair.requested = module_find_by_addr(pair.pcs, Line->Address, DMT_UNKNOWN);
1682  if (!module_get_debug(&pair)) return FALSE;
1683 
1684  if (Line->Key == 0) return FALSE;
1685  li = Line->Key;
1686  /* things are a bit complicated because when we encounter a DLIT_SOURCEFILE
1687  * element we have to go back until we find the prev one to get the real
1688  * source file name for the DLIT_OFFSET element just before
1689  * the first DLIT_SOURCEFILE
1690  */
1691  while (!li->is_first)
1692  {
1693  li--;
1694  if (!li->is_source_file)
1695  {
1696  Line->LineNumber = li->line_number;
1697  Line->Address = li->u.pc_offset;
1698  Line->Key = li;
1699  if (!in_search) return TRUE;
1700  }
1701  else
1702  {
1703  if (in_search)
1704  {
1705  Line->FileName = (char*)source_get(pair.effective, li->u.source_file);
1706  return TRUE;
1707  }
1708  in_search = TRUE;
1709  }
1710  }
1711  SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
1712  return FALSE;
1713 }
1714 
1715 /******************************************************************
1716  * SymGetLinePrev (DBGHELP.@)
1717  *
1718  */
1720 {
1721  IMAGEHLP_LINE64 line64;
1722 
1723  line64.SizeOfStruct = sizeof(line64);
1724  copy_line_64_from_32(&line64, Line);
1725  if (!SymGetLinePrev64(hProcess, &line64)) return FALSE;
1726  copy_line_32_from_64(Line, &line64);
1727  return TRUE;
1728 }
1729 
1731 {
1732  struct line_info* li;
1733 
1734  if (line->Key == 0) return FALSE;
1735  li = line->Key;
1736  while (!li->is_last)
1737  {
1738  li++;
1739  if (!li->is_source_file)
1740  {
1741  line->LineNumber = li->line_number;
1742  line->Address = li->u.pc_offset;
1743  line->Key = li;
1744  return TRUE;
1745  }
1746  line->FileName = (char*)source_get(module, li->u.source_file);
1747  }
1748  return FALSE;
1749 }
1750 
1751 /******************************************************************
1752  * SymGetLineNext64 (DBGHELP.@)
1753  *
1754  */
1756 {
1757  struct module_pair pair;
1758 
1759  TRACE("(%p %p)\n", hProcess, Line);
1760 
1761  if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
1763  if (!pair.pcs) return FALSE;
1764  pair.requested = module_find_by_addr(pair.pcs, Line->Address, DMT_UNKNOWN);
1765  if (!module_get_debug(&pair)) return FALSE;
1766 
1767  if (symt_get_func_line_next(pair.effective, Line)) return TRUE;
1768  SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
1769  return FALSE;
1770 }
1771 
1772 /******************************************************************
1773  * SymGetLineNext (DBGHELP.@)
1774  *
1775  */
1777 {
1778  IMAGEHLP_LINE64 line64;
1779 
1780  line64.SizeOfStruct = sizeof(line64);
1781  copy_line_64_from_32(&line64, Line);
1782  if (!SymGetLineNext64(hProcess, &line64)) return FALSE;
1783  copy_line_32_from_64(Line, &line64);
1784  return TRUE;
1785 }
1786 
1787 /***********************************************************************
1788  * SymUnDName (DBGHELP.@)
1789  */
1790 BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL sym, PSTR UnDecName, DWORD UnDecNameLength)
1791 {
1792  return UnDecorateSymbolName(sym->Name, UnDecName, UnDecNameLength,
1793  UNDNAME_COMPLETE) != 0;
1794 }
1795 
1796 /***********************************************************************
1797  * SymUnDName64 (DBGHELP.@)
1798  */
1799 BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecNameLength)
1800 {
1801  return UnDecorateSymbolName(sym->Name, UnDecName, UnDecNameLength,
1802  UNDNAME_COMPLETE) != 0;
1803 }
1804 
1805 static void * CDECL und_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); }
1806 static void CDECL und_free (void* ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
1807 
1808 static char *und_name(char *buffer, const char *mangled, int buflen, unsigned short flags)
1809 {
1810  /* undocumented from msvcrt */
1811  static HANDLE hMsvcrt;
1812  static char* (CDECL *p_undname)(char*, const char*, int, void* (CDECL*)(size_t), void (CDECL*)(void*), unsigned short);
1813  static const WCHAR szMsvcrt[] = {'m','s','v','c','r','t','.','d','l','l',0};
1814 
1815  if (!p_undname)
1816  {
1817  if (!hMsvcrt) hMsvcrt = LoadLibraryW(szMsvcrt);
1818  if (hMsvcrt) p_undname = (void*)GetProcAddress(hMsvcrt, "__unDName");
1819  if (!p_undname) return NULL;
1820  }
1821 
1822  return p_undname(buffer, mangled, buflen, und_alloc, und_free, flags);
1823 }
1824 
1825 /***********************************************************************
1826  * UnDecorateSymbolName (DBGHELP.@)
1827  */
1828 DWORD WINAPI UnDecorateSymbolName(const char *decorated_name, char *undecorated_name,
1829  DWORD undecorated_length, DWORD flags)
1830 {
1831  TRACE("(%s, %p, %d, 0x%08x)\n",
1832  debugstr_a(decorated_name), undecorated_name, undecorated_length, flags);
1833 
1834  if (!undecorated_name || !undecorated_length)
1835  return 0;
1836  if (!und_name(undecorated_name, decorated_name, undecorated_length, flags))
1837  return 0;
1838  return strlen(undecorated_name);
1839 }
1840 
1841 /***********************************************************************
1842  * UnDecorateSymbolNameW (DBGHELP.@)
1843  */
1844 DWORD WINAPI UnDecorateSymbolNameW(const WCHAR *decorated_name, WCHAR *undecorated_name,
1845  DWORD undecorated_length, DWORD flags)
1846 {
1847  char *buf, *ptr;
1848  int len, ret = 0;
1849 
1850  TRACE("(%s, %p, %d, 0x%08x)\n",
1851  debugstr_w(decorated_name), undecorated_name, undecorated_length, flags);
1852 
1853  if (!undecorated_name || !undecorated_length)
1854  return 0;
1855 
1856  len = WideCharToMultiByte(CP_ACP, 0, decorated_name, -1, NULL, 0, NULL, NULL);
1857  if ((buf = HeapAlloc(GetProcessHeap(), 0, len)))
1858  {
1859  WideCharToMultiByte(CP_ACP, 0, decorated_name, -1, buf, len, NULL, NULL);
1860  if ((ptr = und_name(NULL, buf, 0, flags)))
1861  {
1862  MultiByteToWideChar(CP_ACP, 0, ptr, -1, undecorated_name, undecorated_length);
1863  undecorated_name[undecorated_length - 1] = 0;
1864  ret = strlenW(undecorated_name);
1865  und_free(ptr);
1866  }
1867  HeapFree(GetProcessHeap(), 0, buf);
1868  }
1869 
1870  return ret;
1871 }
1872 
1873 #define WILDCHAR(x) (-(x))
1874 
1875 static int re_fetch_char(const WCHAR** re)
1876 {
1877  switch (**re)
1878  {
1879  case '\\': (*re)++; return *(*re)++;
1880  case '*': case '[': case '?': case '+': case '#': case ']': return WILDCHAR(*(*re)++);
1881  default: return *(*re)++;
1882  }
1883 }
1884 
1885 static inline int re_match_char(WCHAR ch1, WCHAR ch2, BOOL _case)
1886 {
1887  return _case ? ch1 - ch2 : toupperW(ch1) - toupperW(ch2);
1888 }
1889 
1890 static const WCHAR* re_match_one(const WCHAR* string, const WCHAR* elt, BOOL _case)
1891 {
1892  int ch1, prev = 0;
1893  unsigned state = 0;
1894 
1895  switch (ch1 = re_fetch_char(&elt))
1896  {
1897  default:
1898  return (ch1 >= 0 && re_match_char(*string, ch1, _case) == 0) ? ++string : NULL;
1899  case WILDCHAR('?'): return *string ? ++string : NULL;
1900  case WILDCHAR('*'): assert(0);
1901  case WILDCHAR('['): break;
1902  }
1903 
1904  for (;;)
1905  {
1906  ch1 = re_fetch_char(&elt);
1907  if (ch1 == WILDCHAR(']')) return NULL;
1908  if (state == 1 && ch1 == '-') state = 2;
1909  else
1910  {
1911  if (re_match_char(*string, ch1, _case) == 0) return ++string;
1912  switch (state)
1913  {
1914  case 0:
1915  state = 1;
1916  prev = ch1;
1917  break;
1918  case 1:
1919  state = 0;
1920  break;
1921  case 2:
1922  if (prev >= 0 && ch1 >= 0 && re_match_char(prev, *string, _case) <= 0 &&
1923  re_match_char(*string, ch1, _case) <= 0)
1924  return ++string;
1925  state = 0;
1926  break;
1927  }
1928  }
1929  }
1930 }
1931 
1932 /******************************************************************
1933  * re_match_multi
1934  *
1935  * match a substring of *pstring according to *pre regular expression
1936  * pstring and pre are only updated in case of successful match
1937  */
1938 static BOOL re_match_multi(const WCHAR** pstring, const WCHAR** pre, BOOL _case)
1939 {
1940  const WCHAR* re_end = *pre;
1941  const WCHAR* string_end = *pstring;
1942  const WCHAR* re_beg;
1943  const WCHAR* string_beg;
1944  const WCHAR* next;
1945  int ch;
1946 
1947  while (*re_end && *string_end)
1948  {
1949  string_beg = string_end;
1950  re_beg = re_end;
1951  switch (ch = re_fetch_char(&re_end))
1952  {
1953  case WILDCHAR(']'): case WILDCHAR('+'): case WILDCHAR('#'): return FALSE;
1954  case WILDCHAR('*'):
1955  /* transform '*' into '?#' */
1956  {static const WCHAR qmW[] = {'?',0}; re_beg = qmW;}
1957  goto closure;
1958  case WILDCHAR('['):
1959  do
1960  {
1961  if (!(ch = re_fetch_char(&re_end))) return FALSE;
1962  } while (ch != WILDCHAR(']'));
1963  /* fall through */
1964  case WILDCHAR('?'):
1965  default:
1966  break;
1967  }
1968 
1969  switch (*re_end)
1970  {
1971  case '+':
1972  if (!(next = re_match_one(string_end, re_beg, _case))) return FALSE;
1973  string_beg++;
1974  /* fall through */
1975  case '#':
1976  re_end++;
1977  closure:
1978  while ((next = re_match_one(string_end, re_beg, _case))) string_end = next;
1979  for ( ; string_end >= string_beg; string_end--)
1980  {
1981  if (re_match_multi(&string_end, &re_end, _case)) goto found;
1982  }
1983  return FALSE;
1984  default:
1985  if (!(next = re_match_one(string_end, re_beg, _case))) return FALSE;
1986  string_end = next;
1987  }
1988  re_beg = re_end;
1989  }
1990 
1991  if (*re_end || *string_end) return FALSE;
1992 
1993 found:
1994  *pre = re_end;
1995  *pstring = string_end;
1996  return TRUE;
1997 }
1998 
1999 /******************************************************************
2000  * SymMatchStringA (DBGHELP.@)
2001  *
2002  */
2004 {
2005  WCHAR* strW;
2006  WCHAR* reW;
2007  BOOL ret = FALSE;
2008  DWORD sz;
2009 
2010  if (!string || !re)
2011  {
2013  return FALSE;
2014  }
2015  TRACE("%s %s %c\n", string, re, _case ? 'Y' : 'N');
2016 
2017  sz = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0);
2018  if ((strW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2019  MultiByteToWideChar(CP_ACP, 0, string, -1, strW, sz);
2020  sz = MultiByteToWideChar(CP_ACP, 0, re, -1, NULL, 0);
2021  if ((reW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2022  MultiByteToWideChar(CP_ACP, 0, re, -1, reW, sz);
2023 
2024  if (strW && reW)
2025  ret = SymMatchStringW(strW, reW, _case);
2026  HeapFree(GetProcessHeap(), 0, strW);
2027  HeapFree(GetProcessHeap(), 0, reW);
2028  return ret;
2029 }
2030 
2031 /******************************************************************
2032  * SymMatchStringW (DBGHELP.@)
2033  *
2034  */
2036 {
2037  TRACE("%s %s %c\n", debugstr_w(string), debugstr_w(re), _case ? 'Y' : 'N');
2038 
2039  if (!string || !re)
2040  {
2042  return FALSE;
2043  }
2044  return re_match_multi(&string, &re, _case);
2045 }
2046 
2047 static inline BOOL doSymSearch(HANDLE hProcess, ULONG64 BaseOfDll, DWORD Index,
2048  DWORD SymTag, PCWSTR Mask, DWORD64 Address,
2049  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
2050  PVOID UserContext, DWORD Options)
2051 {
2052  struct sym_enum se;
2053 
2055  {
2056  FIXME("Unsupported searching with options (%x)\n", Options);
2058  return FALSE;
2059  }
2060 
2061  se.cb = EnumSymbolsCallback;
2062  se.user = UserContext;
2063  se.index = Index;
2064  se.tag = SymTag;
2065  se.addr = Address;
2066  se.sym_info = (PSYMBOL_INFO)se.buffer;
2067 
2068  return sym_enum(hProcess, BaseOfDll, Mask, &se);
2069 }
2070 
2071 /******************************************************************
2072  * SymSearch (DBGHELP.@)
2073  */
2075  DWORD SymTag, PCSTR Mask, DWORD64 Address,
2076  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
2077  PVOID UserContext, DWORD Options)
2078 {
2079  LPWSTR maskW = NULL;
2080  BOOLEAN ret;
2081 
2082  TRACE("(%p %s %u %u %s %s %p %p %x)\n",
2083  hProcess, wine_dbgstr_longlong(BaseOfDll), Index, SymTag, Mask,
2084  wine_dbgstr_longlong(Address), EnumSymbolsCallback,
2085  UserContext, Options);
2086 
2087  if (Mask)
2088  {
2089  DWORD sz = MultiByteToWideChar(CP_ACP, 0, Mask, -1, NULL, 0);
2090 
2091  if (!(maskW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2092  return FALSE;
2093  MultiByteToWideChar(CP_ACP, 0, Mask, -1, maskW, sz);
2094  }
2095  ret = doSymSearch(hProcess, BaseOfDll, Index, SymTag, maskW, Address,
2096  EnumSymbolsCallback, UserContext, Options);
2097  HeapFree(GetProcessHeap(), 0, maskW);
2098  return ret;
2099 }
2100 
2101 /******************************************************************
2102  * SymSearchW (DBGHELP.@)
2103  */
2105  DWORD SymTag, PCWSTR Mask, DWORD64 Address,
2106  PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
2107  PVOID UserContext, DWORD Options)
2108 {
2109  struct sym_enumW sew;
2110 
2111  TRACE("(%p %s %u %u %s %s %p %p %x)\n",
2112  hProcess, wine_dbgstr_longlong(BaseOfDll), Index, SymTag, debugstr_w(Mask),
2113  wine_dbgstr_longlong(Address), EnumSymbolsCallback,
2114  UserContext, Options);
2115 
2116  sew.ctx = UserContext;
2117  sew.cb = EnumSymbolsCallback;
2118  sew.sym_info = (PSYMBOL_INFOW)sew.buffer;
2119 
2120  return doSymSearch(hProcess, BaseOfDll, Index, SymTag, Mask, Address,
2121  sym_enumW, &sew, Options);
2122 }
2123 
2124 /******************************************************************
2125  * SymAddSymbol (DBGHELP.@)
2126  *
2127  */
2130 {
2132 
2133  MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, sizeof(nameW) / sizeof(WCHAR));
2134  return SymAddSymbolW(hProcess, BaseOfDll, nameW, addr, size, flags);
2135 }
2136 
2137 /******************************************************************
2138  * SymAddSymbolW (DBGHELP.@)
2139  *
2140  */
2143 {
2144  struct module_pair pair;
2145 
2146  TRACE("(%p %s %s %u)\n", hProcess, wine_dbgstr_w(name), wine_dbgstr_longlong(addr), size);
2147 
2149  if (!pair.pcs) return FALSE;
2150  pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
2151  if (!module_get_debug(&pair)) return FALSE;
2152 
2154  return FALSE;
2155 }
2156 
2157 /******************************************************************
2158  * SymSetScopeFromAddr (DBGHELP.@)
2159  */
2161 {
2162  struct process* pcs;
2163 
2164  FIXME("(%p %s): stub\n", hProcess, wine_dbgstr_longlong(addr));
2165 
2166  if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
2167  return TRUE;
2168 }
2169 
2170 /******************************************************************
2171  * SymEnumLines (DBGHELP.@)
2172  *
2173  */
2176 {
2177  struct module_pair pair;
2178  struct hash_table_iter hti;
2179  struct symt_ht* sym;
2180  WCHAR* srcmask;
2181  struct line_info* dli;
2182  void* ptr;
2183  SRCCODEINFO sci;
2184  const char* file;
2185 
2186  if (!cb) return FALSE;
2187  if (!(dbghelp_options & SYMOPT_LOAD_LINES)) return TRUE;
2188 
2190  if (!pair.pcs) return FALSE;
2191  if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland);
2192  pair.requested = module_find_by_addr(pair.pcs, base, DMT_UNKNOWN);
2193  if (!module_get_debug(&pair)) return FALSE;
2194  if (!(srcmask = file_regex(srcfile))) return FALSE;
2195 
2196  sci.SizeOfStruct = sizeof(sci);
2197  sci.ModBase = base;
2198 
2199  hash_table_iter_init(&pair.effective->ht_symbols, &hti, NULL);
2200  while ((ptr = hash_table_iter_up(&hti)))
2201  {
2202  unsigned int i;
2203 
2204  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
2205  if (sym->symt.tag != SymTagFunction) continue;
2206 
2207  sci.FileName[0] = '\0';
2208  for (i=0; i<vector_length(&((struct symt_function*)sym)->vlines); i++)
2209  {
2210  dli = vector_at(&((struct symt_function*)sym)->vlines, i);
2211  if (dli->is_source_file)
2212  {
2213  file = source_get(pair.effective, dli->u.source_file);
2214  if (!file) sci.FileName[0] = '\0';
2215  else
2216  {
2217  DWORD sz = MultiByteToWideChar(CP_ACP, 0, file, -1, NULL, 0);
2218  WCHAR* fileW;
2219 
2220  if ((fileW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2221  MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, sz);
2222  if (SymMatchStringW(fileW, srcmask, FALSE))
2223  strcpy(sci.FileName, file);
2224  else
2225  sci.FileName[0] = '\0';
2226  HeapFree(GetProcessHeap(), 0, fileW);
2227  }
2228  }
2229  else if (sci.FileName[0])
2230  {
2231  sci.Key = dli;
2232  sci.Obj[0] = '\0'; /* FIXME */
2233  sci.LineNumber = dli->line_number;
2234  sci.Address = dli->u.pc_offset;
2235  if (!cb(&sci, user)) break;
2236  }
2237  }
2238  }
2239  HeapFree(GetProcessHeap(), 0, srcmask);
2240  return TRUE;
2241 }
2242 
2244  DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINE Line)
2245 {
2246  FIXME("(%p) (%s, %s, %d %p %p): stub\n", hProcess, ModuleName, FileName,
2247  dwLineNumber, plDisplacement, Line);
2248  return FALSE;
2249 }
2250 
2252  DWORD dwLineNumber, PLONG lpDisplacement, PIMAGEHLP_LINE64 Line)
2253 {
2254  FIXME("(%p) (%s, %s, %d %p %p): stub\n", hProcess, ModuleName, FileName,
2255  dwLineNumber, lpDisplacement, Line);
2256  return FALSE;
2257 }
2258 
2260  DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINEW64 Line)
2261 {
2262  FIXME("(%p) (%s, %s, %d %p %p): stub\n", hProcess, debugstr_w(ModuleName), debugstr_w(FileName),
2263  dwLineNumber, plDisplacement, Line);
2264  return FALSE;
2265 }
2266 
2267 /******************************************************************
2268  * SymFromIndex (DBGHELP.@)
2269  *
2270  */
2272 {
2273  FIXME("hProcess = %p, BaseOfDll = %s, index = %d, symbol = %p\n",
2274  hProcess, wine_dbgstr_longlong(BaseOfDll), index, symbol);
2275 
2276  return FALSE;
2277 }
2278 
2279 /******************************************************************
2280  * SymFromIndexW (DBGHELP.@)
2281  *
2282  */
2284 {
2285  FIXME("hProcess = %p, BaseOfDll = %s, index = %d, symbol = %p\n",
2286  hProcess, wine_dbgstr_longlong(BaseOfDll), index, symbol);
2287 
2288  return FALSE;
2289 }
2290 
2291 /******************************************************************
2292  * SymSetHomeDirectory (DBGHELP.@)
2293  *
2294  */
2296 {
2297  FIXME("(%p, %s): stub\n", hProcess, dir);
2298 
2299  return NULL;
2300 }
2301 
2302 /******************************************************************
2303  * SymSetHomeDirectoryW (DBGHELP.@)
2304  *
2305  */
2307 {
2308  FIXME("(%p, %s): stub\n", hProcess, debugstr_w(dir));
2309 
2310  return NULL;
2311 }
struct symt_compiland * symt_new_compiland(struct module *module, unsigned long address, unsigned src_idx)
Definition: symbol.c:209
static unsigned int block
Definition: xmlmemory.c:118
unsigned long line_number
BOOL WINAPI SymGetSymPrev(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1557
static char * und_name(char *buffer, const char *mangled, int buflen, unsigned short flags)
Definition: symbol.c:1808
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL symt_get_address(const struct symt *type, ULONG64 *addr) DECLSPEC_HIDDEN
Definition: type.c:120
unsigned long pc_offset
GLenum func
Definition: glext.h:6028
struct module * module_get_containee(const struct process *pcs, const struct module *inner) DECLSPEC_HIDDEN
Definition: module.c:314
SYMBOL_INFO * sym_info
Definition: symbol.c:746
char * name
Definition: wpp.c:36
DWORD64 addr
Definition: symbol.c:749
BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1626
ULONG Tag
Definition: compat.h:698
void * ctx
Definition: symbol.c:1242
const uint16_t * PCWSTR
Definition: typedefs.h:55
struct hash_table_elt hash_elt
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
CHAR Name[1]
Definition: compat.h:701
static BOOL resort_symbols(struct module *module)
Definition: symbol.c:814
PWSTR WINAPI SymSetHomeDirectoryW(HANDLE hProcess, PCWSTR dir)
Definition: symbol.c:2306
#define TRUE
Definition: types.h:120
#define SYMOPT_WINE_WITH_NATIVE_MODULES
HMODULE module
Definition: main.cpp:47
ULONG NameLen
Definition: compat.h:699
struct symt * container
static int cmp_addr(ULONG64 a1, ULONG64 a2)
Definition: symbol.c:45
Definition: compat.h:1939
static BOOL symt_enum_locals(struct process *pcs, const WCHAR *mask, const struct sym_enum *se)
Definition: symbol.c:1008
ULONG64 Address
Definition: compat.h:1007
BOOL WINAPI SymGetSymPrev64(HANDLE hProcess, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1547
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
WCHAR * symt_get_nameW(const struct symt *sym) DECLSPEC_HIDDEN
Definition: type.c:107
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:80
ULONG MaxNameLen
Definition: compat.h:700
union line_info::@359 u
BOOL WINAPI SymSetScopeFromAddr(HANDLE hProcess, ULONG64 addr)
Definition: symbol.c:2160
BOOL WINAPI SymAddSymbolW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR name, DWORD64 addr, DWORD size, DWORD flags)
Definition: symbol.c:2141
static BOOL doSymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1128
#define WideCharToMultiByte
Definition: compat.h:101
BOOL WINAPI SymEnumSymbolsW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1200
struct symt_hierarchy_point * symt_add_function_point(struct module *module, struct symt_function *func, enum SymTagEnum point, const struct location *loc, const char *name)
Definition: symbol.c:454
WCHAR ModuleName[32]
Definition: compat.h:725
struct vector vchildren
void copy_symbolW(SYMBOL_INFOW *siw, const SYMBOL_INFO *si)
Definition: symbol.c:1037
#define SYMFLAG_REGREL
Definition: compat.h:646
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
ULONG MaxNameLen
Definition: compat.h:1012
Definition: compat.h:1951
ULONG64 ModBase
Definition: compat.h:1004
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
PVOID Key
Definition: compat.h:753
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOL WINAPI SymEnumerateSymbols(HANDLE hProcess, DWORD BaseOfDll, PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1228
struct symt symt
Definition: match.c:28
void * vector_at(const struct vector *v, unsigned pos) DECLSPEC_HIDDEN
Definition: storage.c:163
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
Definition: symbol.c:2174
DWORD LineNumber
Definition: compat.h:1180
uint16_t * PWSTR
Definition: typedefs.h:54
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
#define CP_ACP
Definition: compat.h:99
#define SYMFLAG_TLSREL
Definition: compat.h:656
struct hash_table ht_symbols
ULONG Scope
Definition: compat.h:697
struct vector vsymt
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
BOOL WINAPI SymGetSymFromAddr64(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1346
struct symt * container
BOOL symt_fill_func_line_info(const struct module *module, const struct symt_function *func, DWORD64 addr, IMAGEHLP_LINE64 *line)
Definition: symbol.c:1488
BOOL WINAPI SymGetLineFromName64(HANDLE hProcess, PCSTR ModuleName, PCSTR FileName, DWORD dwLineNumber, PLONG lpDisplacement, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:2251
static const WCHAR * re_match_one(const WCHAR *string, const WCHAR *elt, BOOL _case)
Definition: symbol.c:1890
GLintptr offset
Definition: glext.h:5920
#define CALLBACK
Definition: compat.h:27
static HMODULE hMsvcrt
Definition: cpp.c:47
struct module * module_find_by_nameA(const struct process *pcs, const char *name) DECLSPEC_HIDDEN
Definition: module.c:256
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
ULONG Flags
Definition: compat.h:693
PSYM_ENUMSYMBOLS_CALLBACK cb
Definition: symbol.c:1216
BOOL(CALLBACK * PSYM_ENUMSYMBOLS_CALLBACK64)(PCSTR, DWORD64, ULONG, PVOID)
Definition: compat.h:829
BOOL WINAPI SymEnumerateSymbols64(HANDLE hProcess, DWORD64 BaseOfDll, PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1255
static BOOL doSymSearch(HANDLE hProcess, ULONG64 BaseOfDll, DWORD Index, DWORD SymTag, PCWSTR Mask, DWORD64 Address, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext, DWORD Options)
Definition: symbol.c:2047
static int re_match_char(WCHAR ch1, WCHAR ch2, BOOL _case)
Definition: symbol.c:1885
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define SYMOPT_AUTO_PUBLICS
Definition: compat.h:643
ULONG TypeIndex
Definition: compat.h:688
#define assert(x)
Definition: debug.h:53
GLuint buffer
Definition: glext.h:5915
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
enum DataKind kind
DWORD WINAPI UnDecorateSymbolNameW(const WCHAR *decorated_name, WCHAR *undecorated_name, DWORD undecorated_length, DWORD flags)
Definition: symbol.c:1844
struct symt_block * symt_close_func_block(struct module *module, const struct symt_function *func, struct symt_block *block, unsigned pc)
Definition: symbol.c:442
ULONG64 Address
Definition: compat.h:695
struct vector vlines
BOOL WINAPI SymFromIndex(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFO symbol)
Definition: symbol.c:2271
const char * source_get(const struct module *module, unsigned idx) DECLSPEC_HIDDEN
Definition: source.c:131
DWORD LineNumber
Definition: compat.h:1162
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1264
struct symt * container
BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
Definition: symbol.c:1610
const char * symt_get_name(const struct symt *sym) DECLSPEC_HIDDEN
Definition: type.c:82
BOOL WINAPI SymFromAddrW(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFOW Symbol)
Definition: symbol.c:1293
CHAR FileName[MAX_PATH+1]
Definition: compat.h:756
#define SYMFLAG_PUBLIC_CODE
Definition: compat.h:664
unsigned num_symbols
DataKind
Definition: compat.h:1287
PSYM_ENUMSYMBOLS_CALLBACK64 cb
Definition: symbol.c:1243
enum OPTION_FLAGS Options
Definition: stats.c:44
static BOOL CALLBACK sym_enumerate_cb(PSYMBOL_INFO syminfo, ULONG size, void *ctx)
Definition: symbol.c:1219
#define UNDNAME_NAME_ONLY
Definition: compat.h:666
#define DWORD
Definition: nt_native.h:44
Definition: send.c:47
PCHAR FileName
Definition: compat.h:747
POINTL point
Definition: edittest.c:50
IMAGEHLP_STACK_FRAME ctx_frame
CHAR Obj[MAX_PATH+1]
Definition: compat.h:755
BOOL symt_get_func_line_next(const struct module *module, PIMAGEHLP_LINE64 line)
Definition: symbol.c:1730
enum module_type type
PCHAR WINAPI SymSetHomeDirectory(HANDLE hProcess, PCSTR dir)
Definition: symbol.c:2295
unsigned source_file
#define sprintf(buf, format,...)
Definition: sprintf.c:55
union symt_data::@356 u
void * pool_alloc(struct pool *a, size_t len) DECLSPEC_HIDDEN
Definition: storage.c:90
struct hash_table_elt hash_elt
DWORD symt_ptr2index(struct module *module, const struct symt *sym)
Definition: symbol.c:70
ULONG NameLen
Definition: compat.h:1011
BOOL(CALLBACK * PSYM_ENUMSYMBOLS_CALLBACK)(PCSTR, ULONG, ULONG, PVOID)
Definition: compat.h:874
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 SYMSEARCH_GLOBALSONLY
Definition: compat.h:673
ULONG64 Reserved[2]
Definition: compat.h:689
THUNK_ORDINAL ordinal
GLenum GLint GLuint mask
Definition: glext.h:6028
struct symt * symt_index2ptr(struct module *module, DWORD id)
Definition: symbol.c:112
BOOL WINAPI SymMatchStringW(PCWSTR string, PCWSTR re, BOOL _case)
Definition: symbol.c:2035
#define SYMOPT_CASE_INSENSITIVE
Definition: compat.h:636
struct _SYMBOL_INFO * PSYMBOL_INFO
ULONG64 Reserved[2]
Definition: compat.h:1001
struct symt_block * symt_open_func_block(struct module *module, struct symt_function *func, struct symt_block *parent_block, unsigned pc, unsigned len)
Definition: symbol.c:415
SymTagEnum
Definition: compat.h:1220
struct module * lmodules
unsigned int BOOL
Definition: ntddk_ex.h:94
WCHAR strW[12]
Definition: clipboard.c:2029
GLuint base
Definition: 3dtext.c:35
enum SymTagEnum tag
BOOL WINAPI SymSearch(HANDLE hProcess, ULONG64 BaseOfDll, DWORD Index, DWORD SymTag, PCSTR Mask, DWORD64 Address, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext, DWORD Options)
Definition: symbol.c:2074
int sortlist_valid
CHAR Name[1]
Definition: compat.h:1121
static void copy_line_64_from_32(IMAGEHLP_LINE64 *l64, const IMAGEHLP_LINE *l32)
Definition: symbol.c:1568
DWORD tag
Definition: symbol.c:748
#define debugstr_w
Definition: kernel32.h:32
ULONG SizeOfStruct
Definition: compat.h:999
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
GLenum GLint ref
Definition: glext.h:6028
DWORD SizeOfStruct
Definition: compat.h:744
#define FIXME(fmt,...)
Definition: debug.h:110
static WCHAR * file_regex(const char *srcfile)
Definition: symbol.c:161
static PVOID ptr
Definition: dispmode.c:27
ULONG Scope
Definition: compat.h:1009
struct NameRec_ * Name
Definition: cdprocs.h:464
unsigned int idx
Definition: utils.c:41
DWORD64 ModBase
Definition: compat.h:754
void hash_table_iter_init(const struct hash_table *ht, struct hash_table_iter *hti, const char *name) DECLSPEC_HIDDEN
Definition: storage.c:406
ULONG64 ModBase
Definition: compat.h:692
ULONG Index
Definition: compat.h:690
unsigned char BOOLEAN
#define SYMFLAG_LOCAL
Definition: compat.h:649
#define LoadLibraryW(x)
Definition: compat.h:404
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
struct symt symt
void vector_init(struct vector *v, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:134
int symt_cmp_addr(const void *p1, const void *p2)
Definition: symbol.c:59
static BOOL find_name(struct process *pcs, struct module *module, const char *name, SYMBOL_INFO *symbol)
Definition: symbol.c:1370
Definition: parser.c:48
struct symt_hierarchy_point * symt_new_label(struct module *module, struct symt_compiland *compiland, const char *name, unsigned long address)
Definition: symbol.c:556
static int re_fetch_char(const WCHAR **re)
Definition: symbol.c:1875
unsigned long address
struct symt_data * symt_new_constant(struct module *module, struct symt_compiland *compiland, const char *name, struct symt *type, const VARIANT *v)
Definition: symbol.c:527
static BOOL symt_enum_module(struct module_pair *pair, const WCHAR *match, const struct sym_enum *se)
Definition: symbol.c:763
char buffer[sizeof(SYMBOL_INFO)+MAX_SYM_NAME]
Definition: symbol.c:750
#define SYMFLAG_VALUEPRESENT
Definition: compat.h:644
DWORD Address
Definition: compat.h:1164
GLuint index
Definition: glext.h:6031
unsigned int dir
Definition: maze.c:112
unsigned num_sorttab
DWORD WINAPI UnDecorateSymbolName(const char *decorated_name, char *undecorated_name, DWORD undecorated_length, DWORD flags)
Definition: symbol.c:1828
struct symt * type
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
struct symt_data * symt_add_func_local(struct module *module, struct symt_function *func, enum DataKind dt, const struct location *loc, struct symt_block *block, struct symt *type, const char *name)
Definition: symbol.c:380
char buffer[sizeof(SYMBOL_INFOW)+MAX_SYM_NAME]
Definition: symbol.c:1183
static const WCHAR nameW[]
Definition: main.c:46
WINE_UNICODE_INLINE WCHAR toupperW(WCHAR ch)
Definition: unicode.h:141
void symt_add_func_line(struct module *module, struct symt_function *func, unsigned source_idx, int line_num, unsigned long offset)
Definition: symbol.c:328
__kernel_size_t size_t
Definition: linux.h:237
#define TRACE_(x)
Definition: compat.h:66
struct symt_public * symt_new_public(struct module *module, struct symt_compiland *compiland, const char *name, BOOL is_function, unsigned long address, unsigned size)
Definition: symbol.c:226
struct vector vchildren
unsigned long is_first
unsigned long address
static int cmp_sorttab_addr(struct module *module, int idx, ULONG64 addr)
Definition: symbol.c:52
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFO Symbol)
Definition: symbol.c:1271
BOOL module_get_debug(struct module_pair *) DECLSPEC_HIDDEN
Definition: module.c:340
static BOOL symt_grow_sorttab(struct module *module, unsigned sz)
Definition: symbol.c:122
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
static void symt_get_length(struct module *module, const struct symt *symt, ULONG64 *size)
Definition: symbol.c:865
#define debugstr_a
Definition: kernel32.h:31
BOOL WINAPI SymGetLineNext64(HANDLE hProcess, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1755
static const struct update_accum a2
Definition: msg.c:586
BOOL WINAPI SymGetLinePrev64(HANDLE hProcess, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1669
DWORD LineNumber
Definition: compat.h:757
#define UNDNAME_COMPLETE
Definition: compat.h:665
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
struct symt * type
const GLubyte * c
Definition: glext.h:8905
struct symt_thunk * symt_new_thunk(struct module *module, struct symt_compiland *compiland, const char *name, THUNK_ORDINAL ord, unsigned long addr, unsigned long size)
Definition: symbol.c:498
struct _SYMBOL_INFO SYMBOL_INFO
static const UCHAR Index[8]
Definition: usbohci.c:18
#define MAX_SYM_NAME
Definition: compat.h:624
unsigned dbghelp_options
Definition: dbghelp.c:72
struct location loc
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint address
Definition: glext.h:9393
static void symt_fill_sym_info(struct module_pair *pair, const struct symt_function *func, const struct symt *sym, SYMBOL_INFO *sym_info)
Definition: symbol.c:584
VARIANT value
#define SYMOPT_LOAD_LINES
Definition: compat.h:639
#define SetLastError(x)
Definition: compat.h:409
struct hash_table_elt hash_elt
void hash_table_add(struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
Definition: storage.c:379
PVOID user
Definition: symbol.c:745
struct symt symt
static DWORD cb
Definition: integrity.c:41
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct symt * container
static BOOL re_match_multi(const WCHAR **pstring, const WCHAR **pre, BOOL _case)
Definition: symbol.c:1938
GLbitfield flags
Definition: glext.h:7161
ULONG64 Value
Definition: compat.h:1006
DWORD SizeOfStruct
Definition: compat.h:752
struct process * pcs
#define SYMOPT_UNDNAME
Definition: compat.h:637
Definition: ncftp.h:79
BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1318
unsigned __int64 ULONG64
Definition: imports.h:198
BOOL WINAPI SymGetLineFromAddrW64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINEW64 Line)
Definition: symbol.c:1653
unsigned reg
BOOL WINAPI SymGetSymFromName(HANDLE hProcess, PCSTR Name, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1464
static BOOL CALLBACK sym_enumerate_cb64(PSYMBOL_INFO syminfo, ULONG size, void *ctx)
Definition: symbol.c:1246
ULONG Index
Definition: compat.h:1002
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt)
ULONG64 InstructionOffset
Definition: compat.h:1017
int ret
GLenum const GLvoid * addr
Definition: glext.h:9621
DWORD64 Address
Definition: compat.h:758
static void copy_line_32_from_64(IMAGEHLP_LINE *l32, const IMAGEHLP_LINE64 *l64)
Definition: symbol.c:1597
struct location var
ULONG Flags
Definition: compat.h:1005
static BOOL CALLBACK sym_enumW(PSYMBOL_INFO si, ULONG size, PVOID ctx)
Definition: symbol.c:1187
static int state
Definition: maze.c:121
BOOL(CALLBACK * PSYM_ENUMLINES_CALLBACK)(PSRCCODEINFO, PVOID)
Definition: compat.h:760
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type) DECLSPEC_HIDDEN
Definition: module.c:399
BOOL WINAPI SymGetLineNext(HANDLE hProcess, PIMAGEHLP_LINE Line)
Definition: symbol.c:1776
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG SizeOfStruct
Definition: compat.h:687
GLenum GLsizei len
Definition: glext.h:6722
BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL sym, PSTR UnDecName, DWORD UnDecNameLength)
Definition: symbol.c:1790
BOOL(CALLBACK * PSYM_ENUMERATESYMBOLS_CALLBACKW)(PSYMBOL_INFOW, ULONG, PVOID)
Definition: compat.h:1107
void * hash_table_iter_up(struct hash_table_iter *hti) DECLSPEC_HIDDEN
Definition: storage.c:423
BOOL symt_normalize_function(struct module *module, const struct symt_function *func)
Definition: symbol.c:475
uint32_t DWORD_PTR
Definition: typedefs.h:63
struct pool pool
void * fetch_buffer(struct process *pcs, unsigned size)
Definition: dbghelp.c:109
#define SYMFLAG_REGISTER
Definition: compat.h:645
char * pool_strdup(struct pool *a, const char *str) DECLSPEC_HIDDEN
Definition: storage.c:127
char string[160]
Definition: util.h:11
ULONG Register
Definition: compat.h:696
BOOL WINAPI SymSearchW(HANDLE hProcess, ULONG64 BaseOfDll, DWORD Index, DWORD SymTag, PCWSTR Mask, DWORD64 Address, PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, PVOID UserContext, DWORD Options)
Definition: symbol.c:2104
BOOL WINAPI SymGetLineFromName(HANDLE hProcess, PCSTR ModuleName, PCSTR FileName, DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINE Line)
Definition: symbol.c:2243
DWORD index
Definition: symbol.c:747
unsigned kind
PSYMBOL_INFOW sym_info
Definition: symbol.c:1182
static void copy_line_W64_from_64(struct process *pcs, IMAGEHLP_LINEW64 *l64w, const IMAGEHLP_LINE64 *l64)
Definition: symbol.c:1581
struct _SYMBOL_INFOW SYMBOL_INFOW
void * vector_add(struct vector *v, struct pool *pool) DECLSPEC_HIDDEN
Definition: storage.c:172
static BOOL symt_enum_locals_helper(struct module_pair *pair, const WCHAR *match, const struct sym_enum *se, struct symt_function *func, const struct vector *v)
Definition: symbol.c:961
static unsigned __int64 next
Definition: rand_nt.c:6
BOOL symt_get_info(struct module *module, const struct symt *type, IMAGEHLP_SYMBOL_TYPE_INFO req, void *pInfo) DECLSPEC_HIDDEN
Definition: type.c:537
uint64_t DWORD64
Definition: typedefs.h:65
const GLdouble * v
Definition: gl.h:2040
ULONG TypeIndex
Definition: compat.h:1000
#define CDECL
Definition: compat.h:21
BOOL(CALLBACK * PSYM_ENUMERATESYMBOLS_CALLBACK)(PSYMBOL_INFO, ULONG, PVOID)
Definition: compat.h:761
DWORD LineNumber
Definition: compat.h:746
BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1155
BOOL WINAPI SymFromIndexW(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFOW symbol)
Definition: symbol.c:2283
#define long
Definition: qsort.c:33
#define HeapReAlloc
Definition: compat.h:393
struct symt symt
Definition: Symbol.h:8
signed char * PSTR
Definition: retypes.h:7
struct symt symt
static const struct newhuff ht[]
Definition: huffman.h:296
#define SYMFLAG_EXPORT
Definition: compat.h:651
PSYM_ENUMERATESYMBOLS_CALLBACKW cb
Definition: symbol.c:1180
static void symt_add_module_ht(struct module *module, struct symt_ht *ht)
Definition: symbol.c:145
#define min(a, b)
Definition: monoChain.cc:55
Definition: _pair.h:47
unsigned long size
unsigned sorttab_size
int symt_get_best_at(struct module *module, int idx_sorttab)
Definition: symbol.c:878
struct hash_table_elt hash_elt
#define lstrcpynA
Definition: compat.h:408
static const WCHAR starW[]
Definition: symbol.c:43
DWORD * PDWORD
Definition: pedump.c:68
struct _SYMBOL_INFOW * PSYMBOL_INFOW
static void *CDECL und_alloc(size_t len)
Definition: symbol.c:1805
#define MultiByteToWideChar
Definition: compat.h:100
WCHAR Name[1]
Definition: compat.h:1013
static BOOL send_symbol(const struct sym_enum *se, struct module_pair *pair, const struct symt_function *func, const struct symt *sym)
Definition: symbol.c:753
char * strchr(const char *String, int ch)
Definition: utclib.c:501
unsigned long address
unsigned long is_last
static void CDECL und_free(void *ptr)
Definition: symbol.c:1806
#define SYMFLAG_THUNK
Definition: compat.h:655
ULONG Register
Definition: compat.h:1008
BOOL WINAPI SymGetSymNext(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1537
struct symt_data * symt_new_global_variable(struct module *module, struct symt_compiland *compiland, const char *name, unsigned is_static, struct location loc, unsigned long size, struct symt *type)
Definition: symbol.c:258
ULONG64 Value
Definition: compat.h:694
BOOL WINAPI SymAddSymbol(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR name, DWORD64 addr, DWORD size, DWORD flags)
Definition: symbol.c:2128
BOOL WINAPI SymGetSymFromName64(HANDLE hProcess, PCSTR Name, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1442
Definition: name.c:36
unsigned long offset
unsigned long size
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned long is_source_file
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
uint64_t * PDWORD64
Definition: typedefs.h:65
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_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
BOOL WINAPI SymMatchStringA(PCSTR string, PCSTR re, BOOL _case)
Definition: symbol.c:2003
BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
Definition: symbol.c:1719
BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: symbol.c:1400
#define GetProcAddress(x, y)
Definition: compat.h:410
struct symt_ht ** addr_sorttab
PSYM_ENUMERATESYMBOLS_CALLBACK cb
Definition: symbol.c:744
const char * PCSTR
Definition: typedefs.h:51
static const struct update_accum a1
Definition: msg.c:578
static BOOL sym_enum(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, const struct sym_enum *se)
Definition: symbol.c:1062
PCHAR FileName
Definition: compat.h:1163
GLfloat GLfloat p
Definition: glext.h:8902
#define WILDCHAR(x)
Definition: symbol.c:1873
WCHAR * LPWSTR
Definition: xmlstorage.h:184
void * ctx
Definition: symbol.c:1215
DWORD64 Address
Definition: compat.h:748
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *compiland, const char *name, unsigned long addr, unsigned long size, struct symt *sig_type)
Definition: symbol.c:295
unsigned long size
ULONG Tag
Definition: compat.h:1010
struct symt symt
BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecNameLength)
Definition: symbol.c:1799
static const WCHAR fileW[]
Definition: url.c:111
signed int * PLONG
Definition: retypes.h:5
IMAGEHLP_MODULEW64 module
DWORD64 Address
Definition: compat.h:1182
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define SYMFLAG_PARAMETER
Definition: compat.h:648
struct module * next
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL WINAPI SymGetSymNext64(HANDLE hProcess, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1521
static unsigned where_to_insert(struct module *module, unsigned high, const struct symt_ht *elt)
Definition: symbol.c:789
struct hash_table_elt hash_elt
BOOL WINAPI SymGetLineFromNameW64(HANDLE hProcess, PCWSTR ModuleName, PCWSTR FileName, DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINEW64 Line)
Definition: symbol.c:2259
unsigned vector_length(const struct vector *v) DECLSPEC_HIDDEN
Definition: storage.c:158
struct hash_table_elt hash_elt
ULONG Size
Definition: compat.h:691
Definition: compat.h:1938
struct symt_ht * symt_find_nearest(struct module *module, DWORD_PTR addr)
Definition: symbol.c:905
unsigned long address
THUNK_ORDINAL
Definition: compat.h:1855
struct vector vchildren
struct symt symt
static int mod
Definition: i386-dis.c:1273
void * ctx
Definition: symbol.c:1181
Definition: fci.c:126
ULONG Size
Definition: compat.h:1003
GLuint const GLchar * name
Definition: glext.h:6031