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