ReactOS  0.4.15-dev-1201-gb2cf5a4
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 <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <limits.h>
28 #include <sys/types.h>
29 #include <assert.h>
30 #ifndef DBGHELP_STATIC_LIB
31 #include "wine/debug.h"
32 #endif
33 #include "dbghelp_private.h"
34 #ifndef DBGHELP_STATIC_LIB
35 #include "winnls.h"
36 #endif
37 
39 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
40 
41 static const WCHAR starW[] = {'*','\0'};
42 
43 static inline int cmp_addr(ULONG64 a1, ULONG64 a2)
44 {
45  if (a1 > a2) return 1;
46  if (a1 < a2) return -1;
47  return 0;
48 }
49 
50 static inline int cmp_sorttab_addr(struct module* module, int idx, ULONG64 addr)
51 {
52  ULONG64 ref;
54  return cmp_addr(ref, addr);
55 }
56 
57 int __cdecl symt_cmp_addr(const void* p1, const void* p2)
58 {
59  const struct symt* sym1 = *(const struct symt* const *)p1;
60  const struct symt* sym2 = *(const struct symt* const *)p2;
61  ULONG64 a1, a2;
62 
63  symt_get_address(sym1, &a1);
64  symt_get_address(sym2, &a2);
65  return cmp_addr(a1, a2);
66 }
67 
68 DWORD symt_ptr2index(struct module* module, const struct symt* sym)
69 {
70 #ifdef __x86_64__
71  const struct symt** c;
72  int len = vector_length(&module->vsymt);
73  struct hash_table_iter hti;
74  void *ptr;
75  struct symt_idx_to_ptr *idx_to_ptr;
76  /* place enough storage on the stack to represent a pointer in %p form */
77  char ptrbuf[3 + (sizeof(void *) * 2)];
78 
79  /* make a string representation of the pointer to use as a hash key */
80  sprintf(ptrbuf, "%p", sym);
81  hash_table_iter_init(&module->ht_symaddr, &hti, ptrbuf);
82 
83  /* try to find the pointer in our ht */
84  while ((ptr = hash_table_iter_up(&hti))) {
85  idx_to_ptr = CONTAINING_RECORD(ptr, struct symt_idx_to_ptr, hash_elt);
86  if (idx_to_ptr->sym == sym)
87  return idx_to_ptr->idx;
88  }
89 
90  /* not found */
91  /* add the symbol to our symbol vector */
93 
94  /* add an idx to ptr mapping so we can find it again by address */
95  if ((idx_to_ptr = pool_alloc(&module->pool, sizeof(*idx_to_ptr))))
96  {
97  idx_to_ptr->hash_elt.name = pool_strdup(&module->pool, ptrbuf);
98  idx_to_ptr->sym = sym;
99  idx_to_ptr->idx = len + 1;
100  hash_table_add(&module->ht_symaddr, &idx_to_ptr->hash_elt);
101  }
102 
103  if (c) *c = sym;
104  return len + 1;
105 #else
106  return (DWORD)sym;
107 #endif
108 }
109 
110 struct symt* symt_index2ptr(struct module* module, DWORD id)
111 {
112 #ifdef __x86_64__
113  if (!id-- || id >= vector_length(&module->vsymt)) return NULL;
114  return *(struct symt**)vector_at(&module->vsymt, id);
115 #else
116  return (struct symt*)id;
117 #endif
118 }
119 
120 static BOOL symt_grow_sorttab(struct module* module, unsigned sz)
121 {
122  struct symt_ht** new;
123  unsigned int size;
124 
125  if (sz <= module->sorttab_size) return TRUE;
126  if (module->addr_sorttab)
127  {
128  size = module->sorttab_size * 2;
130  size * sizeof(struct symt_ht*));
131  }
132  else
133  {
134  size = 64;
135  new = HeapAlloc(GetProcessHeap(), 0, size * sizeof(struct symt_ht*));
136  }
137  if (!new) return FALSE;
139  module->addr_sorttab = new;
140  return TRUE;
141 }
142 
143 static void symt_add_module_ht(struct module* module, struct symt_ht* ht)
144 {
145  ULONG64 addr;
146 
147  hash_table_add(&module->ht_symbols, &ht->hash_elt);
148  /* Don't store in sorttab a symbol without address, they are of
149  * no use here (e.g. constant values)
150  */
151  if (symt_get_address(&ht->symt, &addr) &&
153  {
156  }
157 }
158 
159 static WCHAR* file_regex(const char* srcfile)
160 {
161  WCHAR* mask;
162  WCHAR* p;
163 
164  if (!srcfile || !*srcfile)
165  {
166  if (!(p = mask = HeapAlloc(GetProcessHeap(), 0, 3 * sizeof(WCHAR)))) return NULL;
167  *p++ = '?';
168  *p++ = '#';
169  }
170  else
171  {
172  DWORD sz = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
173  WCHAR* srcfileW;
174 
175  /* FIXME: we use here the largest conversion for every char... could be optimized */
176  p = mask = HeapAlloc(GetProcessHeap(), 0, (5 * strlen(srcfile) + 1 + sz) * sizeof(WCHAR));
177  if (!mask) return NULL;
178  srcfileW = mask + 5 * strlen(srcfile) + 1;
179  MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, sz);
180 
181  while (*srcfileW)
182  {
183  switch (*srcfileW)
184  {
185  case '\\':
186  case '/':
187  *p++ = '[';
188  *p++ = '\\';
189  *p++ = '\\';
190  *p++ = '/';
191  *p++ = ']';
192  break;
193  case '.':
194  *p++ = '?';
195  break;
196  default:
197  *p++ = *srcfileW;
198  break;
199  }
200  srcfileW++;
201  }
202  }
203  *p = 0;
204  return mask;
205 }
206 
208  ULONG_PTR address, unsigned src_idx)
209 {
210  struct symt_compiland* sym;
211 
212  TRACE_(dbghelp_symt)("Adding compiland symbol %s:%s\n",
214  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
215  {
216  sym->symt.tag = SymTagCompiland;
217  sym->address = address;
218  sym->source = src_idx;
219  vector_init(&sym->vchildren, sizeof(struct symt*), 32);
220  }
221  return sym;
222 }
223 
225  struct symt_compiland* compiland,
226  const char* name,
228  ULONG_PTR address, unsigned size)
229 {
230  struct symt_public* sym;
231  struct symt** p;
232 
233  TRACE_(dbghelp_symt)("Adding public symbol %s:%s @%lx\n",
237  return NULL;
238  if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
239  {
240  sym->symt.tag = SymTagPublicSymbol;
241  sym->hash_elt.name = pool_strdup(&module->pool, name);
242  sym->container = compiland ? &compiland->symt : NULL;
243  sym->is_function = is_function;
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, ULONG_PTR 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,
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, ULONG_PTR 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,
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, ULONG_PTR 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_PTR)data->u.value.n1.n2.n3.iVal; break;
682  case VT_I1: sym_info->Value = (ULONG)(LONG_PTR)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  {
701  const struct symt_public* pub = (const struct symt_public*)sym;
702  if (pub->is_function)
703  sym_info->Flags |= SYMFLAG_PUBLIC_CODE;
704  else
705  sym_info->Flags |= SYMFLAG_EXPORT;
706  symt_get_address(sym, &sym_info->Address);
707  }
708  break;
709  case SymTagFunction:
710  symt_get_address(sym, &sym_info->Address);
711  break;
712  case SymTagThunk:
713  sym_info->Flags |= SYMFLAG_THUNK;
714  symt_get_address(sym, &sym_info->Address);
715  break;
716  default:
717  symt_get_address(sym, &sym_info->Address);
718  sym_info->Register = 0;
719  break;
720  }
721  sym_info->Scope = 0; /* FIXME */
722  sym_info->Tag = sym->tag;
723  name = symt_get_name(sym);
724  if (sym_info->MaxNameLen)
725  {
727  ((sym_info->NameLen = UnDecorateSymbolName(name, sym_info->Name,
728  sym_info->MaxNameLen, UNDNAME_NAME_ONLY)) == 0))
729  {
730  sym_info->NameLen = min(strlen(name), sym_info->MaxNameLen - 1);
731  memcpy(sym_info->Name, name, sym_info->NameLen);
732  sym_info->Name[sym_info->NameLen] = '\0';
733  }
734  }
735  TRACE_(dbghelp_symt)("%p => %s %u %s\n",
736  sym, sym_info->Name, sym_info->Size,
737  wine_dbgstr_longlong(sym_info->Address));
738 }
739 
740 struct sym_enum
741 {
748  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
749 };
750 
751 static BOOL send_symbol(const struct sym_enum* se, struct module_pair* pair,
752  const struct symt_function* func, const struct symt* sym)
753 {
754  symt_fill_sym_info(pair, func, sym, se->sym_info);
755  if (se->index && se->sym_info->Index != se->index) return FALSE;
756  if (se->tag && se->sym_info->Tag != se->tag) return FALSE;
757  if (se->addr && !(se->addr >= se->sym_info->Address && se->addr < se->sym_info->Address + se->sym_info->Size)) return FALSE;
758  return !se->cb(se->sym_info, se->sym_info->Size, se->user);
759 }
760 
762  const struct sym_enum* se)
763 {
764  void* ptr;
765  struct symt_ht* sym = NULL;
766  struct hash_table_iter hti;
767  WCHAR* nameW;
768  BOOL ret;
769 
770  hash_table_iter_init(&pair->effective->ht_symbols, &hti, NULL);
771  while ((ptr = hash_table_iter_up(&hti)))
772  {
773  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
774  nameW = symt_get_nameW(&sym->symt);
777  if (ret)
778  {
779  se->sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
780  se->sym_info->MaxNameLen = sizeof(se->buffer) - sizeof(SYMBOL_INFO);
781  if (send_symbol(se, pair, NULL, &sym->symt)) return TRUE;
782  }
783  }
784  return FALSE;
785 }
786 
787 static inline unsigned where_to_insert(struct module* module, unsigned high, const struct symt_ht* elt)
788 {
789  unsigned low = 0, mid = high / 2;
790  ULONG64 addr;
791 
792  if (!high) return 0;
793  symt_get_address(&elt->symt, &addr);
794  do
795  {
796  switch (cmp_sorttab_addr(module, mid, addr))
797  {
798  case 0: return mid;
799  case -1: low = mid + 1; break;
800  case 1: high = mid; break;
801  }
802  mid = low + (high - low) / 2;
803  } while (low < high);
804  return mid;
805 }
806 
807 /***********************************************************************
808  * resort_symbols
809  *
810  * Rebuild sorted list of symbols for a module.
811  */
813 {
814  int delta;
815 
817  return FALSE;
818 
819  /* we know that set from 0 up to num_sorttab is already sorted
820  * so sort the remaining (new) symbols, and merge the two sets
821  * (unless the first set is empty)
822  */
823  delta = module->num_symbols - module->num_sorttab;
824  qsort(&module->addr_sorttab[module->num_sorttab], delta, sizeof(struct symt_ht*), symt_cmp_addr);
825  if (module->num_sorttab)
826  {
827  int i, ins_idx = module->num_sorttab, prev_ins_idx;
828  static struct symt_ht** tmp;
829  static unsigned num_tmp;
830 
831  if (num_tmp < delta)
832  {
833  static struct symt_ht** new;
834  if (tmp)
835  new = HeapReAlloc(GetProcessHeap(), 0, tmp, delta * sizeof(struct symt_ht*));
836  else
837  new = HeapAlloc(GetProcessHeap(), 0, delta * sizeof(struct symt_ht*));
838  if (!new)
839  {
840  module->num_sorttab = 0;
841  return resort_symbols(module);
842  }
843  tmp = new;
844  num_tmp = delta;
845  }
846  memcpy(tmp, &module->addr_sorttab[module->num_sorttab], delta * sizeof(struct symt_ht*));
847  qsort(tmp, delta, sizeof(struct symt_ht*), symt_cmp_addr);
848 
849  for (i = delta - 1; i >= 0; i--)
850  {
851  prev_ins_idx = ins_idx;
852  ins_idx = where_to_insert(module, ins_idx, tmp[i]);
853  memmove(&module->addr_sorttab[ins_idx + i + 1],
854  &module->addr_sorttab[ins_idx],
855  (prev_ins_idx - ins_idx) * sizeof(struct symt_ht*));
856  module->addr_sorttab[ins_idx + i] = tmp[i];
857  }
858  }
860  return module->sortlist_valid = TRUE;
861 }
862 
863 static void symt_get_length(struct module* module, const struct symt* symt, ULONG64* size)
864 {
865  DWORD type_index;
866 
868  return;
869 
870  if (symt_get_info(module, symt, TI_GET_TYPE, &type_index) &&
871  symt_get_info(module, symt_index2ptr(module, type_index), TI_GET_LENGTH, size)) return;
872  *size = 0x1000; /* arbitrary value */
873 }
874 
875 /* needed by symt_find_nearest */
876 static int symt_get_best_at(struct module* module, int idx_sorttab)
877 {
878  ULONG64 ref_addr;
879  int idx_sorttab_orig = idx_sorttab;
880  if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
881  {
882  symt_get_address(&module->addr_sorttab[idx_sorttab]->symt, &ref_addr);
883  while (idx_sorttab > 0 &&
884  module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol &&
885  !cmp_sorttab_addr(module, idx_sorttab - 1, ref_addr))
886  idx_sorttab--;
887  if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
888  {
889  idx_sorttab = idx_sorttab_orig;
890  while (idx_sorttab < module->num_sorttab - 1 &&
891  module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol &&
892  !cmp_sorttab_addr(module, idx_sorttab + 1, ref_addr))
893  idx_sorttab++;
894  }
895  /* if no better symbol was found restore the original */
896  if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
897  idx_sorttab = idx_sorttab_orig;
898  }
899  return idx_sorttab;
900 }
901 
902 /* assume addr is in module */
904 {
905  int mid, high, low;
906  ULONG64 ref_addr, ref_size;
907 
909  {
910  if (!resort_symbols(module)) return NULL;
911  }
912 
913  /*
914  * Binary search to find closest symbol.
915  */
916  low = 0;
917  high = module->num_sorttab;
918 
919  symt_get_address(&module->addr_sorttab[0]->symt, &ref_addr);
920  if (addr <= ref_addr)
921  {
922  low = symt_get_best_at(module, 0);
923  return module->addr_sorttab[low];
924  }
925 
926  if (high)
927  {
928  symt_get_address(&module->addr_sorttab[high - 1]->symt, &ref_addr);
929  symt_get_length(module, &module->addr_sorttab[high - 1]->symt, &ref_size);
930  if (addr >= ref_addr + ref_size) return NULL;
931  }
932 
933  while (high > low + 1)
934  {
935  mid = (high + low) / 2;
936  if (cmp_sorttab_addr(module, mid, addr) < 0)
937  low = mid;
938  else
939  high = mid;
940  }
941  if (low != high && high != module->num_sorttab &&
942  cmp_sorttab_addr(module, high, addr) <= 0)
943  low = high;
944 
945  /* If found symbol is a public symbol, check if there are any other entries that
946  * might also have the same address, but would get better information
947  */
948  low = symt_get_best_at(module, low);
949 
950  return module->addr_sorttab[low];
951 }
952 
954  const WCHAR* match, const struct sym_enum* se,
955  struct symt_function* func, const struct vector* v)
956 {
957  struct symt* lsym = NULL;
958  DWORD pc = pair->pcs->ctx_frame.InstructionOffset;
959  unsigned int i;
960  WCHAR* nameW;
961  BOOL ret;
962 
963  for (i=0; i<vector_length(v); i++)
964  {
965  lsym = *(struct symt**)vector_at(v, i);
966  switch (lsym->tag)
967  {
968  case SymTagBlock:
969  {
970  struct symt_block* block = (struct symt_block*)lsym;
971  if (pc < block->address || block->address + block->size <= pc)
972  continue;
973  if (!symt_enum_locals_helper(pair, match, se, func, &block->vchildren))
974  return FALSE;
975  }
976  break;
977  case SymTagData:
978  nameW = symt_get_nameW(lsym);
982  if (ret)
983  {
984  if (send_symbol(se, pair, func, lsym)) return FALSE;
985  }
986  break;
987  case SymTagLabel:
989  case SymTagFuncDebugEnd:
990  case SymTagCustom:
991  break;
992  default:
993  FIXME("Unknown type: %u (%x)\n", lsym->tag, lsym->tag);
994  assert(0);
995  }
996  }
997  return TRUE;
998 }
999 
1000 static BOOL symt_enum_locals(struct process* pcs, const WCHAR* mask,
1001  const struct sym_enum* se)
1002 {
1003  struct module_pair pair;
1004  struct symt_ht* sym;
1006 
1007  se->sym_info->SizeOfStruct = sizeof(*se->sym_info);
1008  se->sym_info->MaxNameLen = sizeof(se->buffer) - sizeof(SYMBOL_INFO);
1009 
1010  pair.pcs = pcs;
1011  pair.requested = module_find_by_addr(pair.pcs, pc, DMT_UNKNOWN);
1012  if (!module_get_debug(&pair)) return FALSE;
1013  if ((sym = symt_find_nearest(pair.effective, pc)) == NULL) return FALSE;
1014 
1015  if (sym->symt.tag == SymTagFunction)
1016  {
1017  return symt_enum_locals_helper(&pair, mask ? mask : starW, se, (struct symt_function*)sym,
1018  &((struct symt_function*)sym)->vchildren);
1019  }
1020  return FALSE;
1021 }
1022 
1023 /******************************************************************
1024  * copy_symbolW
1025  *
1026  * Helper for transforming an ANSI symbol info into a UNICODE one.
1027  * Assume that MaxNameLen is the same for both version (A & W).
1028  */
1030 {
1031  siw->SizeOfStruct = si->SizeOfStruct;
1032  siw->TypeIndex = si->TypeIndex;
1033  siw->Reserved[0] = si->Reserved[0];
1034  siw->Reserved[1] = si->Reserved[1];
1035  siw->Index = si->Index;
1036  siw->Size = si->Size;
1037  siw->ModBase = si->ModBase;
1038  siw->Flags = si->Flags;
1039  siw->Value = si->Value;
1040  siw->Address = si->Address;
1041  siw->Register = si->Register;
1042  siw->Scope = si->Scope;
1043  siw->Tag = si->Tag;
1044  siw->NameLen = si->NameLen;
1045  siw->MaxNameLen = si->MaxNameLen;
1046  MultiByteToWideChar(CP_ACP, 0, si->Name, -1, siw->Name, siw->MaxNameLen);
1047 }
1048 
1049 /******************************************************************
1050  * sym_enum
1051  *
1052  * Core routine for most of the enumeration of symbols
1053  */
1054 static BOOL sym_enum(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask,
1055  const struct sym_enum* se)
1056 {
1057  struct module_pair pair;
1058  const WCHAR* bang;
1059  WCHAR* mod;
1060 
1062  if (!pair.pcs) return FALSE;
1063  if (BaseOfDll == 0)
1064  {
1065  /* do local variables ? */
1066  if (!Mask || !(bang = wcschr(Mask, '!')))
1067  return symt_enum_locals(pair.pcs, Mask, se);
1068 
1069  if (bang == Mask) return FALSE;
1070 
1071  mod = HeapAlloc(GetProcessHeap(), 0, (bang - Mask + 1) * sizeof(WCHAR));
1072  if (!mod) return FALSE;
1073  memcpy(mod, Mask, (bang - Mask) * sizeof(WCHAR));
1074  mod[bang - Mask] = 0;
1075 
1076  for (pair.requested = pair.pcs->lmodules; pair.requested; pair.requested = pair.requested->next)
1077  {
1078  if (pair.requested->type == DMT_PE && module_get_debug(&pair))
1079  {
1080  if (SymMatchStringW(pair.requested->module.ModuleName, mod, FALSE) &&
1081  symt_enum_module(&pair, bang + 1, se))
1082  break;
1083  }
1084  }
1085  /* not found in PE modules, retry on the ELF ones
1086  */
1087  if (!pair.requested && dbghelp_opt_native)
1088  {
1089  for (pair.requested = pair.pcs->lmodules; pair.requested; pair.requested = pair.requested->next)
1090  {
1091  if ((pair.requested->type == DMT_ELF || pair.requested->type == DMT_MACHO) &&
1092  !module_get_containee(pair.pcs, pair.requested) &&
1094  {
1095  if (SymMatchStringW(pair.requested->module.ModuleName, mod, FALSE) &&
1096  symt_enum_module(&pair, bang + 1, se))
1097  break;
1098  }
1099  }
1100  }
1101  HeapFree(GetProcessHeap(), 0, mod);
1102  return TRUE;
1103  }
1104  pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
1105  if (!module_get_debug(&pair))
1106  return FALSE;
1107 
1108  /* we always ignore module name from Mask when BaseOfDll is defined */
1109  if (Mask && (bang = wcschr(Mask, '!')))
1110  {
1111  if (bang == Mask) return FALSE;
1112  Mask = bang + 1;
1113  }
1114 
1115  symt_enum_module(&pair, Mask ? Mask : starW, se);
1116 
1117  return TRUE;
1118 }
1119 
1120 static inline BOOL doSymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask,
1121  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
1122  PVOID UserContext)
1123 {
1124  struct sym_enum se;
1125 
1126  se.cb = EnumSymbolsCallback;
1127  se.user = UserContext;
1128  se.index = 0;
1129  se.tag = 0;
1130  se.addr = 0;
1131  se.sym_info = (PSYMBOL_INFO)se.buffer;
1132 
1133  return sym_enum(hProcess, BaseOfDll, Mask, &se);
1134 }
1135 
1136 /******************************************************************
1137  * SymEnumSymbols (DBGHELP.@)
1138  *
1139  * cases BaseOfDll = 0
1140  * !foo fails always (despite what MSDN states)
1141  * RE1!RE2 looks up all modules matching RE1, and in all these modules, lookup RE2
1142  * no ! in Mask, lookup in local Context
1143  * cases BaseOfDll != 0
1144  * !foo fails always (despite what MSDN states)
1145  * RE1!RE2 gets RE2 from BaseOfDll (whatever RE1 is)
1146  */
1148  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
1149  PVOID UserContext)
1150 {
1151  BOOL ret;
1152  PWSTR maskW = NULL;
1153 
1154  TRACE("(%p %s %s %p %p)\n",
1155  hProcess, wine_dbgstr_longlong(BaseOfDll), debugstr_a(Mask),
1156  EnumSymbolsCallback, UserContext);
1157 
1158  if (Mask)
1159  {
1160  DWORD sz = MultiByteToWideChar(CP_ACP, 0, Mask, -1, NULL, 0);
1161  if (!(maskW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
1162  return FALSE;
1163  MultiByteToWideChar(CP_ACP, 0, Mask, -1, maskW, sz);
1164  }
1165  ret = doSymEnumSymbols(hProcess, BaseOfDll, maskW, EnumSymbolsCallback, UserContext);
1166  HeapFree(GetProcessHeap(), 0, maskW);
1167  return ret;
1168 }
1169 
1171 {
1173  void* ctx;
1176 
1177 };
1178 
1180 {
1181  struct sym_enumW* sew = ctx;
1182 
1183  copy_symbolW(sew->sym_info, si);
1184 
1185  return (sew->cb)(sew->sym_info, size, sew->ctx);
1186 }
1187 
1188 /******************************************************************
1189  * SymEnumSymbolsW (DBGHELP.@)
1190  *
1191  */
1193  PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
1194  PVOID UserContext)
1195 {
1196  struct sym_enumW sew;
1197 
1198  sew.ctx = UserContext;
1199  sew.cb = EnumSymbolsCallback;
1200  sew.sym_info = (PSYMBOL_INFOW)sew.buffer;
1201 
1202  return doSymEnumSymbols(hProcess, BaseOfDll, Mask, sym_enumW, &sew);
1203 }
1204 
1206 {
1207  void* ctx;
1209 };
1210 
1212 {
1213  struct sym_enumerate* se = ctx;
1214  return (se->cb)(syminfo->Name, syminfo->Address, syminfo->Size, se->ctx);
1215 }
1216 
1217 /***********************************************************************
1218  * SymEnumerateSymbols (DBGHELP.@)
1219  */
1221  PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
1222  PVOID UserContext)
1223 {
1224  struct sym_enumerate se;
1225 
1226  se.ctx = UserContext;
1227  se.cb = EnumSymbolsCallback;
1228 
1229  return SymEnumSymbols(hProcess, BaseOfDll, NULL, sym_enumerate_cb, &se);
1230 }
1231 
1233 {
1234  void* ctx;
1236 };
1237 
1239 {
1240  struct sym_enumerate64* se = ctx;
1241  return (se->cb)(syminfo->Name, syminfo->Address, syminfo->Size, se->ctx);
1242 }
1243 
1244 /***********************************************************************
1245  * SymEnumerateSymbols64 (DBGHELP.@)
1246  */
1248  PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
1249  PVOID UserContext)
1250 {
1251  struct sym_enumerate64 se;
1252 
1253  se.ctx = UserContext;
1254  se.cb = EnumSymbolsCallback;
1255 
1256  return SymEnumSymbols(hProcess, BaseOfDll, NULL, sym_enumerate_cb64, &se);
1257 }
1258 
1259 /******************************************************************
1260  * SymFromAddr (DBGHELP.@)
1261  *
1262  */
1264  DWORD64* Displacement, PSYMBOL_INFO Symbol)
1265 {
1266  struct module_pair pair;
1267  struct symt_ht* sym;
1268 
1270  if (!pair.pcs) return FALSE;
1271  pair.requested = module_find_by_addr(pair.pcs, Address, DMT_UNKNOWN);
1272  if (!module_get_debug(&pair)) return FALSE;
1273  if ((sym = symt_find_nearest(pair.effective, Address)) == NULL) return FALSE;
1274 
1275  symt_fill_sym_info(&pair, NULL, &sym->symt, Symbol);
1276  if (Displacement)
1277  *Displacement = (Address >= Symbol->Address) ? (Address - Symbol->Address) : (DWORD64)-1;
1278  return TRUE;
1279 }
1280 
1281 /******************************************************************
1282  * SymFromAddrW (DBGHELP.@)
1283  *
1284  */
1286  DWORD64* Displacement, PSYMBOL_INFOW Symbol)
1287 {
1288  PSYMBOL_INFO si;
1289  unsigned len;
1290  BOOL ret;
1291 
1292  len = sizeof(*si) + Symbol->MaxNameLen * sizeof(WCHAR);
1293  si = HeapAlloc(GetProcessHeap(), 0, len);
1294  if (!si) return FALSE;
1295 
1296  si->SizeOfStruct = sizeof(*si);
1297  si->MaxNameLen = Symbol->MaxNameLen;
1298  if ((ret = SymFromAddr(hProcess, Address, Displacement, si)))
1299  {
1300  copy_symbolW(Symbol, si);
1301  }
1302  HeapFree(GetProcessHeap(), 0, si);
1303  return ret;
1304 }
1305 
1306 /******************************************************************
1307  * SymGetSymFromAddr (DBGHELP.@)
1308  *
1309  */
1311  PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
1312 {
1313  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1315  size_t len;
1316  DWORD64 Displacement64;
1317 
1318  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1319  si->SizeOfStruct = sizeof(*si);
1320  si->MaxNameLen = MAX_SYM_NAME;
1321  if (!SymFromAddr(hProcess, Address, &Displacement64, si))
1322  return FALSE;
1323 
1324  if (Displacement)
1325  *Displacement = Displacement64;
1326  Symbol->Address = si->Address;
1327  Symbol->Size = si->Size;
1328  Symbol->Flags = si->Flags;
1329  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1330  lstrcpynA(Symbol->Name, si->Name, len);
1331  return TRUE;
1332 }
1333 
1334 /******************************************************************
1335  * SymGetSymFromAddr64 (DBGHELP.@)
1336  *
1337  */
1339  PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol)
1340 {
1341  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1343  size_t len;
1344  DWORD64 Displacement64;
1345 
1346  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1347  si->SizeOfStruct = sizeof(*si);
1348  si->MaxNameLen = MAX_SYM_NAME;
1349  if (!SymFromAddr(hProcess, Address, &Displacement64, si))
1350  return FALSE;
1351 
1352  if (Displacement)
1353  *Displacement = Displacement64;
1354  Symbol->Address = si->Address;
1355  Symbol->Size = si->Size;
1356  Symbol->Flags = si->Flags;
1357  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1358  lstrcpynA(Symbol->Name, si->Name, len);
1359  return TRUE;
1360 }
1361 
1362 static BOOL find_name(struct process* pcs, struct module* module, const char* name,
1363  SYMBOL_INFO* symbol)
1364 {
1365  struct hash_table_iter hti;
1366  void* ptr;
1367  struct symt_ht* sym = NULL;
1368  struct module_pair pair;
1369 
1370  pair.pcs = pcs;
1371  if (!(pair.requested = module)) return FALSE;
1372  if (!module_get_debug(&pair)) return FALSE;
1373 
1374  hash_table_iter_init(&pair.effective->ht_symbols, &hti, name);
1375  while ((ptr = hash_table_iter_up(&hti)))
1376  {
1377  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
1378 
1379  if (!strcmp(sym->hash_elt.name, name))
1380  {
1381  symt_fill_sym_info(&pair, NULL, &sym->symt, symbol);
1382  return TRUE;
1383  }
1384  }
1385  return FALSE;
1386 
1387 }
1388 /******************************************************************
1389  * SymFromName (DBGHELP.@)
1390  *
1391  */
1393 {
1394  struct process* pcs = process_find_by_handle(hProcess);
1395  struct module* module;
1396  const char* name;
1397 
1398  TRACE("(%p, %s, %p)\n", hProcess, Name, Symbol);
1399  if (!pcs) return FALSE;
1400  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1401  name = strchr(Name, '!');
1402  if (name)
1403  {
1404  char tmp[128];
1405  assert(name - Name < sizeof(tmp));
1406  memcpy(tmp, Name, name - Name);
1407  tmp[name - Name] = '\0';
1408  module = module_find_by_nameA(pcs, tmp);
1409  return find_name(pcs, module, name + 1, Symbol);
1410  }
1411  for (module = pcs->lmodules; module; module = module->next)
1412  {
1413  if (module->type == DMT_PE && find_name(pcs, module, Name, Symbol))
1414  return TRUE;
1415  }
1416  /* not found in PE modules, retry on the ELF ones
1417  */
1418  if (dbghelp_opt_native)
1419  {
1420  for (module = pcs->lmodules; module; module = module->next)
1421  {
1422  if ((module->type == DMT_ELF || module->type == DMT_MACHO) &&
1423  !module_get_containee(pcs, module) &&
1424  find_name(pcs, module, Name, Symbol))
1425  return TRUE;
1426  }
1427  }
1428  return FALSE;
1429 }
1430 
1431 /***********************************************************************
1432  * SymGetSymFromName64 (DBGHELP.@)
1433  */
1435 {
1436  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1438  size_t len;
1439 
1440  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1441  si->SizeOfStruct = sizeof(*si);
1442  si->MaxNameLen = MAX_SYM_NAME;
1443  if (!SymFromName(hProcess, Name, si)) return FALSE;
1444 
1445  Symbol->Address = si->Address;
1446  Symbol->Size = si->Size;
1447  Symbol->Flags = si->Flags;
1448  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1449  lstrcpynA(Symbol->Name, si->Name, len);
1450  return TRUE;
1451 }
1452 
1453 /***********************************************************************
1454  * SymGetSymFromName (DBGHELP.@)
1455  */
1457 {
1458  char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
1460  size_t len;
1461 
1462  if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
1463  si->SizeOfStruct = sizeof(*si);
1464  si->MaxNameLen = MAX_SYM_NAME;
1465  if (!SymFromName(hProcess, Name, si)) return FALSE;
1466 
1467  Symbol->Address = si->Address;
1468  Symbol->Size = si->Size;
1469  Symbol->Flags = si->Flags;
1470  len = min(Symbol->MaxNameLength, si->MaxNameLen);
1471  lstrcpynA(Symbol->Name, si->Name, len);
1472  return TRUE;
1473 }
1474 
1475 /******************************************************************
1476  * sym_fill_func_line_info
1477  *
1478  * fills information about a file
1479  */
1482 {
1483  struct line_info* dli = NULL;
1484  BOOL found = FALSE;
1485  int i;
1486 
1487  assert(func->symt.tag == SymTagFunction);
1488 
1489  for (i=vector_length(&func->vlines)-1; i>=0; i--)
1490  {
1491  dli = vector_at(&func->vlines, i);
1492  if (!dli->is_source_file)
1493  {
1494  if (found || dli->u.pc_offset > addr) continue;
1495  line->LineNumber = dli->line_number;
1496  line->Address = dli->u.pc_offset;
1497  line->Key = dli;
1498  found = TRUE;
1499  continue;
1500  }
1501  if (found)
1502  {
1503  if (dbghelp_opt_native)
1504  {
1505  /* Return native file paths when using winedbg */
1506  line->FileName = (char*)source_get(module, dli->u.source_file);
1507  }
1508  else
1509  {
1511  DWORD len = WideCharToMultiByte(CP_ACP, 0, dospath, -1, NULL, 0, NULL, NULL);
1512  line->FileName = fetch_buffer(module->process, len);
1513  WideCharToMultiByte(CP_ACP, 0, dospath, -1, line->FileName, len, NULL, NULL);
1514  HeapFree( GetProcessHeap(), 0, dospath );
1515  }
1516  return TRUE;
1517  }
1518  }
1519  return FALSE;
1520 }
1521 
1522 /***********************************************************************
1523  * SymGetSymNext64 (DBGHELP.@)
1524  */
1526 {
1527  /* algo:
1528  * get module from Symbol.Address
1529  * get index in module.addr_sorttab of Symbol.Address
1530  * increment index
1531  * if out of module bounds, move to next module in process address space
1532  */
1533  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1535  return FALSE;
1536 }
1537 
1538 /***********************************************************************
1539  * SymGetSymNext (DBGHELP.@)
1540  */
1542 {
1543  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1545  return FALSE;
1546 }
1547 
1548 /***********************************************************************
1549  * SymGetSymPrev64 (DBGHELP.@)
1550  */
1552 {
1553  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1555  return FALSE;
1556 }
1557 
1558 /***********************************************************************
1559  * SymGetSymPrev (DBGHELP.@)
1560  */
1562 {
1563  FIXME("(%p, %p): stub\n", hProcess, Symbol);
1565  return FALSE;
1566 }
1567 
1568 /******************************************************************
1569  * copy_line_64_from_32 (internal)
1570  *
1571  */
1573 
1574 {
1575  l64->Key = l32->Key;
1576  l64->LineNumber = l32->LineNumber;
1577  l64->FileName = l32->FileName;
1578  l64->Address = l32->Address;
1579 }
1580 
1581 /******************************************************************
1582  * copy_line_W64_from_32 (internal)
1583  *
1584  */
1585 static void copy_line_W64_from_64(struct process* pcs, IMAGEHLP_LINEW64* l64w, const IMAGEHLP_LINE64* l64)
1586 {
1587  unsigned len;
1588 
1589  l64w->Key = l64->Key;
1590  l64w->LineNumber = l64->LineNumber;
1591  len = MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, NULL, 0);
1592  if ((l64w->FileName = fetch_buffer(pcs, len * sizeof(WCHAR))))
1593  MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, l64w->FileName, len);
1594  l64w->Address = l64->Address;
1595 }
1596 
1597 /******************************************************************
1598  * copy_line_32_from_64 (internal)
1599  *
1600  */
1602 
1603 {
1604  l32->Key = l64->Key;
1605  l32->LineNumber = l64->LineNumber;
1606  l32->FileName = l64->FileName;
1607  l32->Address = l64->Address;
1608 }
1609 
1610 /******************************************************************
1611  * SymGetLineFromAddr (DBGHELP.@)
1612  *
1613  */
1615  PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
1616 {
1617  IMAGEHLP_LINE64 il64;
1618 
1619  il64.SizeOfStruct = sizeof(il64);
1620  if (!SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, &il64))
1621  return FALSE;
1622  copy_line_32_from_64(Line, &il64);
1623  return TRUE;
1624 }
1625 
1626 /******************************************************************
1627  * SymGetLineFromAddr64 (DBGHELP.@)
1628  *
1629  */
1631  PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line)
1632 {
1633  struct module_pair pair;
1634  struct symt_ht* symt;
1635 
1636  TRACE("%p %s %p %p\n", hProcess, wine_dbgstr_longlong(dwAddr), pdwDisplacement, Line);
1637 
1638  if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
1639 
1641  if (!pair.pcs) return FALSE;
1642  pair.requested = module_find_by_addr(pair.pcs, dwAddr, DMT_UNKNOWN);
1643  if (!module_get_debug(&pair)) return FALSE;
1644  if ((symt = symt_find_nearest(pair.effective, dwAddr)) == NULL) return FALSE;
1645 
1646  if (symt->symt.tag != SymTagFunction) return FALSE;
1647  if (!symt_fill_func_line_info(pair.effective, (struct symt_function*)symt,
1648  dwAddr, Line)) return FALSE;
1649  *pdwDisplacement = dwAddr - Line->Address;
1650  return TRUE;
1651 }
1652 
1653 /******************************************************************
1654  * SymGetLineFromAddrW64 (DBGHELP.@)
1655  *
1656  */
1658  PDWORD pdwDisplacement, PIMAGEHLP_LINEW64 Line)
1659 {
1660  IMAGEHLP_LINE64 il64;
1661 
1662  il64.SizeOfStruct = sizeof(il64);
1663  if (!SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, &il64))
1664  return FALSE;
1666  return TRUE;
1667 }
1668 
1669 /******************************************************************
1670  * SymGetLinePrev64 (DBGHELP.@)
1671  *
1672  */
1674 {
1675  struct module_pair pair;
1676  struct line_info* li;
1677  BOOL in_search = FALSE;
1678 
1679  TRACE("(%p %p)\n", hProcess, Line);
1680 
1681  if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
1682 
1684  if (!pair.pcs) return FALSE;
1685  pair.requested = module_find_by_addr(pair.pcs, Line->Address, DMT_UNKNOWN);
1686  if (!module_get_debug(&pair)) return FALSE;
1687 
1688  if (Line->Key == 0) return FALSE;
1689  li = Line->Key;
1690  /* things are a bit complicated because when we encounter a DLIT_SOURCEFILE
1691  * element we have to go back until we find the prev one to get the real
1692  * source file name for the DLIT_OFFSET element just before
1693  * the first DLIT_SOURCEFILE
1694  */
1695  while (!li->is_first)
1696  {
1697  li--;
1698  if (!li->is_source_file)
1699  {
1700  Line->LineNumber = li->line_number;
1701  Line->Address = li->u.pc_offset;
1702  Line->Key = li;
1703  if (!in_search) return TRUE;
1704  }
1705  else
1706  {
1707  if (in_search)
1708  {
1709  Line->FileName = (char*)source_get(pair.effective, li->u.source_file);
1710  return TRUE;
1711  }
1712  in_search = TRUE;
1713  }
1714  }
1715  SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
1716  return FALSE;
1717 }
1718 
1719 /******************************************************************
1720  * SymGetLinePrev (DBGHELP.@)
1721  *
1722  */
1724 {
1725  IMAGEHLP_LINE64 line64;
1726 
1727  line64.SizeOfStruct = sizeof(line64);
1728  copy_line_64_from_32(&line64, Line);
1729  if (!SymGetLinePrev64(hProcess, &line64)) return FALSE;
1730  copy_line_32_from_64(Line, &line64);
1731  return TRUE;
1732 }
1733 
1735 {
1736  struct line_info* li;
1737 
1738  if (line->Key == 0) return FALSE;
1739  li = line->Key;
1740  while (!li->is_last)
1741  {
1742  li++;
1743  if (!li->is_source_file)
1744  {
1745  line->LineNumber = li->line_number;
1746  line->Address = li->u.pc_offset;
1747  line->Key = li;
1748  return TRUE;
1749  }
1750  line->FileName = (char*)source_get(module, li->u.source_file);
1751  }
1752  return FALSE;
1753 }
1754 
1755 /******************************************************************
1756  * SymGetLineNext64 (DBGHELP.@)
1757  *
1758  */
1760 {
1761  struct module_pair pair;
1762 
1763  TRACE("(%p %p)\n", hProcess, Line);
1764 
1765  if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
1767  if (!pair.pcs) return FALSE;
1768  pair.requested = module_find_by_addr(pair.pcs, Line->Address, DMT_UNKNOWN);
1769  if (!module_get_debug(&pair)) return FALSE;
1770 
1771  if (symt_get_func_line_next(pair.effective, Line)) return TRUE;
1772  SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
1773  return FALSE;
1774 }
1775 
1776 /******************************************************************
1777  * SymGetLineNext (DBGHELP.@)
1778  *
1779  */
1781 {
1782  IMAGEHLP_LINE64 line64;
1783 
1784  line64.SizeOfStruct = sizeof(line64);
1785  copy_line_64_from_32(&line64, Line);
1786  if (!SymGetLineNext64(hProcess, &line64)) return FALSE;
1787  copy_line_32_from_64(Line, &line64);
1788  return TRUE;
1789 }
1790 
1791 /***********************************************************************
1792  * SymUnDName (DBGHELP.@)
1793  */
1794 BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL sym, PSTR UnDecName, DWORD UnDecNameLength)
1795 {
1796  return UnDecorateSymbolName(sym->Name, UnDecName, UnDecNameLength,
1797  UNDNAME_COMPLETE) != 0;
1798 }
1799 
1800 /***********************************************************************
1801  * SymUnDName64 (DBGHELP.@)
1802  */
1803 BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecNameLength)
1804 {
1805  return UnDecorateSymbolName(sym->Name, UnDecName, UnDecNameLength,
1806  UNDNAME_COMPLETE) != 0;
1807 }
1808 
1809 static void * CDECL und_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); }
1810 static void CDECL und_free (void* ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
1811 
1812 static char *und_name(char *buffer, const char *mangled, int buflen, unsigned short flags)
1813 {
1814  /* undocumented from msvcrt */
1815  static HANDLE hMsvcrt;
1816  static char* (CDECL *p_undname)(char*, const char*, int, void* (CDECL*)(size_t), void (CDECL*)(void*), unsigned short);
1817  static const WCHAR szMsvcrt[] = {'m','s','v','c','r','t','.','d','l','l',0};
1818 
1819  if (!p_undname)
1820  {
1821  if (!hMsvcrt) hMsvcrt = LoadLibraryW(szMsvcrt);
1822  if (hMsvcrt) p_undname = (void*)GetProcAddress(hMsvcrt, "__unDName");
1823  if (!p_undname) return NULL;
1824  }
1825 
1826  return p_undname(buffer, mangled, buflen, und_alloc, und_free, flags);
1827 }
1828 
1829 /***********************************************************************
1830  * UnDecorateSymbolName (DBGHELP.@)
1831  */
1832 DWORD WINAPI UnDecorateSymbolName(const char *decorated_name, char *undecorated_name,
1833  DWORD undecorated_length, DWORD flags)
1834 {
1835  TRACE("(%s, %p, %d, 0x%08x)\n",
1836  debugstr_a(decorated_name), undecorated_name, undecorated_length, flags);
1837 
1838  if (!undecorated_name || !undecorated_length)
1839  return 0;
1840  if (!und_name(undecorated_name, decorated_name, undecorated_length, flags))
1841  return 0;
1842  return strlen(undecorated_name);
1843 }
1844 
1845 /***********************************************************************
1846  * UnDecorateSymbolNameW (DBGHELP.@)
1847  */
1848 DWORD WINAPI UnDecorateSymbolNameW(const WCHAR *decorated_name, WCHAR *undecorated_name,
1849  DWORD undecorated_length, DWORD flags)
1850 {
1851  char *buf, *ptr;
1852  int len, ret = 0;
1853 
1854  TRACE("(%s, %p, %d, 0x%08x)\n",
1855  debugstr_w(decorated_name), undecorated_name, undecorated_length, flags);
1856 
1857  if (!undecorated_name || !undecorated_length)
1858  return 0;
1859 
1860  len = WideCharToMultiByte(CP_ACP, 0, decorated_name, -1, NULL, 0, NULL, NULL);
1861  if ((buf = HeapAlloc(GetProcessHeap(), 0, len)))
1862  {
1863  WideCharToMultiByte(CP_ACP, 0, decorated_name, -1, buf, len, NULL, NULL);
1864  if ((ptr = und_name(NULL, buf, 0, flags)))
1865  {
1866  MultiByteToWideChar(CP_ACP, 0, ptr, -1, undecorated_name, undecorated_length);
1867  undecorated_name[undecorated_length - 1] = 0;
1868  ret = lstrlenW(undecorated_name);
1869  und_free(ptr);
1870  }
1871  HeapFree(GetProcessHeap(), 0, buf);
1872  }
1873 
1874  return ret;
1875 }
1876 
1877 #define WILDCHAR(x) (-(x))
1878 
1879 static int re_fetch_char(const WCHAR** re)
1880 {
1881  switch (**re)
1882  {
1883  case '\\': (*re)++; return *(*re)++;
1884  case '*': case '[': case '?': case '+': case '#': case ']': return WILDCHAR(*(*re)++);
1885  default: return *(*re)++;
1886  }
1887 }
1888 
1889 static inline int re_match_char(WCHAR ch1, WCHAR ch2, BOOL _case)
1890 {
1891  return _case ? ch1 - ch2 : towupper(ch1) - towupper(ch2);
1892 }
1893 
1894 static const WCHAR* re_match_one(const WCHAR* string, const WCHAR* elt, BOOL _case)
1895 {
1896  int ch1, prev = 0;
1897  unsigned state = 0;
1898 
1899  switch (ch1 = re_fetch_char(&elt))
1900  {
1901  default:
1902  return (ch1 >= 0 && re_match_char(*string, ch1, _case) == 0) ? ++string : NULL;
1903  case WILDCHAR('?'): return *string ? ++string : NULL;
1904  case WILDCHAR('*'): assert(0);
1905  case WILDCHAR('['): break;
1906  }
1907 
1908  for (;;)
1909  {
1910  ch1 = re_fetch_char(&elt);
1911  if (ch1 == WILDCHAR(']')) return NULL;
1912  if (state == 1 && ch1 == '-') state = 2;
1913  else
1914  {
1915  if (re_match_char(*string, ch1, _case) == 0) return ++string;
1916  switch (state)
1917  {
1918  case 0:
1919  state = 1;
1920  prev = ch1;
1921  break;
1922  case 1:
1923  state = 0;
1924  break;
1925  case 2:
1926  if (prev >= 0 && ch1 >= 0 && re_match_char(prev, *string, _case) <= 0 &&
1927  re_match_char(*string, ch1, _case) <= 0)
1928  return ++string;
1929  state = 0;
1930  break;
1931  }
1932  }
1933  }
1934 }
1935 
1936 /******************************************************************
1937  * re_match_multi
1938  *
1939  * match a substring of *pstring according to *pre regular expression
1940  * pstring and pre are only updated in case of successful match
1941  */
1942 static BOOL re_match_multi(const WCHAR** pstring, const WCHAR** pre, BOOL _case)
1943 {
1944  const WCHAR* re_end = *pre;
1945  const WCHAR* string_end = *pstring;
1946  const WCHAR* re_beg;
1947  const WCHAR* string_beg;
1948  const WCHAR* next;
1949  int ch;
1950 
1951  while (*re_end && *string_end)
1952  {
1953  string_beg = string_end;
1954  re_beg = re_end;
1955  switch (ch = re_fetch_char(&re_end))
1956  {
1957  case WILDCHAR(']'): case WILDCHAR('+'): case WILDCHAR('#'): return FALSE;
1958  case WILDCHAR('*'):
1959  /* transform '*' into '?#' */
1960  {static const WCHAR qmW[] = {'?',0}; re_beg = qmW;}
1961  goto closure;
1962  case WILDCHAR('['):
1963  do
1964  {
1965  if (!(ch = re_fetch_char(&re_end))) return FALSE;
1966  } while (ch != WILDCHAR(']'));
1967  /* fall through */
1968  case WILDCHAR('?'):
1969  default:
1970  break;
1971  }
1972 
1973  switch (*re_end)
1974  {
1975  case '+':
1976  if (!(next = re_match_one(string_end, re_beg, _case))) return FALSE;
1977  string_beg++;
1978  /* fall through */
1979  case '#':
1980  re_end++;
1981  closure:
1982  while ((next = re_match_one(string_end, re_beg, _case))) string_end = next;
1983  for ( ; string_end >= string_beg; string_end--)
1984  {
1985  if (re_match_multi(&string_end, &re_end, _case)) goto found;
1986  }
1987  return FALSE;
1988  default:
1989  if (!(next = re_match_one(string_end, re_beg, _case))) return FALSE;
1990  string_end = next;
1991  }
1992  }
1993 
1994  if (*re_end || *string_end) return FALSE;
1995 
1996 found:
1997  *pre = re_end;
1998  *pstring = string_end;
1999  return TRUE;
2000 }
2001 
2002 /******************************************************************
2003  * SymMatchStringA (DBGHELP.@)
2004  *
2005  */
2007 {
2008  WCHAR* strW;
2009  WCHAR* reW;
2010  BOOL ret = FALSE;
2011  DWORD sz;
2012 
2013  if (!string || !re)
2014  {
2016  return FALSE;
2017  }
2018  TRACE("%s %s %c\n", string, re, _case ? 'Y' : 'N');
2019 
2020  sz = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0);
2021  if ((strW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2022  MultiByteToWideChar(CP_ACP, 0, string, -1, strW, sz);
2023  sz = MultiByteToWideChar(CP_ACP, 0, re, -1, NULL, 0);
2024  if ((reW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2025  MultiByteToWideChar(CP_ACP, 0, re, -1, reW, sz);
2026 
2027  if (strW && reW)
2028  ret = SymMatchStringW(strW, reW, _case);
2029  HeapFree(GetProcessHeap(), 0, strW);
2030  HeapFree(GetProcessHeap(), 0, reW);
2031  return ret;
2032 }
2033 
2034 /******************************************************************
2035  * SymMatchStringW (DBGHELP.@)
2036  *
2037  */
2039 {
2040  TRACE("%s %s %c\n", debugstr_w(string), debugstr_w(re), _case ? 'Y' : 'N');
2041 
2042  if (!string || !re)
2043  {
2045  return FALSE;
2046  }
2047  return re_match_multi(&string, &re, _case);
2048 }
2049 
2050 static inline BOOL doSymSearch(HANDLE hProcess, ULONG64 BaseOfDll, DWORD Index,
2051  DWORD SymTag, PCWSTR Mask, DWORD64 Address,
2052  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
2053  PVOID UserContext, DWORD Options)
2054 {
2055  struct sym_enum se;
2056 
2058  {
2059  FIXME("Unsupported searching with options (%x)\n", Options);
2061  return FALSE;
2062  }
2063 
2064  se.cb = EnumSymbolsCallback;
2065  se.user = UserContext;
2066  se.index = Index;
2067  se.tag = SymTag;
2068  se.addr = Address;
2069  se.sym_info = (PSYMBOL_INFO)se.buffer;
2070 
2071  return sym_enum(hProcess, BaseOfDll, Mask, &se);
2072 }
2073 
2074 /******************************************************************
2075  * SymSearch (DBGHELP.@)
2076  */
2078  DWORD SymTag, PCSTR Mask, DWORD64 Address,
2079  PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
2080  PVOID UserContext, DWORD Options)
2081 {
2082  LPWSTR maskW = NULL;
2083  BOOLEAN ret;
2084 
2085  TRACE("(%p %s %u %u %s %s %p %p %x)\n",
2086  hProcess, wine_dbgstr_longlong(BaseOfDll), Index, SymTag, Mask,
2087  wine_dbgstr_longlong(Address), EnumSymbolsCallback,
2088  UserContext, Options);
2089 
2090  if (Mask)
2091  {
2092  DWORD sz = MultiByteToWideChar(CP_ACP, 0, Mask, -1, NULL, 0);
2093 
2094  if (!(maskW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2095  return FALSE;
2096  MultiByteToWideChar(CP_ACP, 0, Mask, -1, maskW, sz);
2097  }
2098  ret = doSymSearch(hProcess, BaseOfDll, Index, SymTag, maskW, Address,
2099  EnumSymbolsCallback, UserContext, Options);
2100  HeapFree(GetProcessHeap(), 0, maskW);
2101  return ret;
2102 }
2103 
2104 /******************************************************************
2105  * SymSearchW (DBGHELP.@)
2106  */
2108  DWORD SymTag, PCWSTR Mask, DWORD64 Address,
2109  PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
2110  PVOID UserContext, DWORD Options)
2111 {
2112  struct sym_enumW sew;
2113 
2114  TRACE("(%p %s %u %u %s %s %p %p %x)\n",
2115  hProcess, wine_dbgstr_longlong(BaseOfDll), Index, SymTag, debugstr_w(Mask),
2116  wine_dbgstr_longlong(Address), EnumSymbolsCallback,
2117  UserContext, Options);
2118 
2119  sew.ctx = UserContext;
2120  sew.cb = EnumSymbolsCallback;
2121  sew.sym_info = (PSYMBOL_INFOW)sew.buffer;
2122 
2123  return doSymSearch(hProcess, BaseOfDll, Index, SymTag, Mask, Address,
2124  sym_enumW, &sew, Options);
2125 }
2126 
2127 /******************************************************************
2128  * SymAddSymbol (DBGHELP.@)
2129  *
2130  */
2133 {
2135 
2137  return SymAddSymbolW(hProcess, BaseOfDll, nameW, addr, size, flags);
2138 }
2139 
2140 /******************************************************************
2141  * SymAddSymbolW (DBGHELP.@)
2142  *
2143  */
2146 {
2147  struct module_pair pair;
2148 
2149  TRACE("(%p %s %s %u)\n", hProcess, wine_dbgstr_w(name), wine_dbgstr_longlong(addr), size);
2150 
2152  if (!pair.pcs) return FALSE;
2153  pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
2154  if (!module_get_debug(&pair)) return FALSE;
2155 
2157  return FALSE;
2158 }
2159 
2160 /******************************************************************
2161  * SymSetScopeFromAddr (DBGHELP.@)
2162  */
2164 {
2165  struct process* pcs;
2166 
2167  FIXME("(%p %s): stub\n", hProcess, wine_dbgstr_longlong(addr));
2168 
2169  if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
2170  return TRUE;
2171 }
2172 
2173 /******************************************************************
2174  * SymEnumLines (DBGHELP.@)
2175  *
2176  */
2179 {
2180  struct module_pair pair;
2181  struct hash_table_iter hti;
2182  struct symt_ht* sym;
2183  WCHAR* srcmask;
2184  struct line_info* dli;
2185  void* ptr;
2186  SRCCODEINFO sci;
2187  const char* file;
2188 
2189  if (!cb) return FALSE;
2190  if (!(dbghelp_options & SYMOPT_LOAD_LINES)) return TRUE;
2191 
2193  if (!pair.pcs) return FALSE;
2194  if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland);
2195  pair.requested = module_find_by_addr(pair.pcs, base, DMT_UNKNOWN);
2196  if (!module_get_debug(&pair)) return FALSE;
2197  if (!(srcmask = file_regex(srcfile))) return FALSE;
2198 
2199  sci.SizeOfStruct = sizeof(sci);
2200  sci.ModBase = base;
2201 
2202  hash_table_iter_init(&pair.effective->ht_symbols, &hti, NULL);
2203  while ((ptr = hash_table_iter_up(&hti)))
2204  {
2205  unsigned int i;
2206 
2207  sym = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
2208  if (sym->symt.tag != SymTagFunction) continue;
2209 
2210  sci.FileName[0] = '\0';
2211  for (i=0; i<vector_length(&((struct symt_function*)sym)->vlines); i++)
2212  {
2213  dli = vector_at(&((struct symt_function*)sym)->vlines, i);
2214  if (dli->is_source_file)
2215  {
2216  file = source_get(pair.effective, dli->u.source_file);
2217  if (!file) sci.FileName[0] = '\0';
2218  else
2219  {
2220  DWORD sz = MultiByteToWideChar(CP_ACP, 0, file, -1, NULL, 0);
2221  WCHAR* fileW;
2222 
2223  if ((fileW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR))))
2224  MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, sz);
2225  if (SymMatchStringW(fileW, srcmask, FALSE))
2226  strcpy(sci.FileName, file);
2227  else
2228  sci.FileName[0] = '\0';
2229  HeapFree(GetProcessHeap(), 0, fileW);
2230  }
2231  }
2232  else if (sci.FileName[0])
2233  {
2234  sci.Key = dli;
2235  sci.Obj[0] = '\0'; /* FIXME */
2236  sci.LineNumber = dli->line_number;
2237  sci.Address = dli->u.pc_offset;
2238  if (!cb(&sci, user)) break;
2239  }
2240  }
2241  }
2242  HeapFree(GetProcessHeap(), 0, srcmask);
2243  return TRUE;
2244 }
2245 
2247  DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINE Line)
2248 {
2249  FIXME("(%p) (%s, %s, %d %p %p): stub\n", hProcess, ModuleName, FileName,
2250  dwLineNumber, plDisplacement, Line);
2251  return FALSE;
2252 }
2253 
2255  DWORD dwLineNumber, PLONG lpDisplacement, PIMAGEHLP_LINE64 Line)
2256 {
2257  FIXME("(%p) (%s, %s, %d %p %p): stub\n", hProcess, ModuleName, FileName,
2258  dwLineNumber, lpDisplacement, Line);
2259  return FALSE;
2260 }
2261 
2263  DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINEW64 Line)
2264 {
2265  FIXME("(%p) (%s, %s, %d %p %p): stub\n", hProcess, debugstr_w(ModuleName), debugstr_w(FileName),
2266  dwLineNumber, plDisplacement, Line);
2267  return FALSE;
2268 }
2269 
2270 /******************************************************************
2271  * SymFromIndex (DBGHELP.@)
2272  *
2273  */
2275 {
2276  FIXME("hProcess = %p, BaseOfDll = %s, index = %d, symbol = %p\n",
2277  hProcess, wine_dbgstr_longlong(BaseOfDll), index, symbol);
2278 
2279  return FALSE;
2280 }
2281 
2282 /******************************************************************
2283  * SymFromIndexW (DBGHELP.@)
2284  *
2285  */
2287 {
2288  FIXME("hProcess = %p, BaseOfDll = %s, index = %d, symbol = %p\n",
2289  hProcess, wine_dbgstr_longlong(BaseOfDll), index, symbol);
2290 
2291  return FALSE;
2292 }
2293 
2294 /******************************************************************
2295  * SymSetHomeDirectory (DBGHELP.@)
2296  *
2297  */
2299 {
2300  FIXME("(%p, %s): stub\n", hProcess, dir);
2301 
2302  return NULL;
2303 }
2304 
2305 /******************************************************************
2306  * SymSetHomeDirectoryW (DBGHELP.@)
2307  *
2308  */
2310 {
2311  FIXME("(%p, %s): stub\n", hProcess, debugstr_w(dir));
2312 
2313  return NULL;
2314 }
static unsigned int block
Definition: xmlmemory.c:118
BOOL WINAPI SymGetSymPrev(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1561
static char * und_name(char *buffer, const char *mangled, int buflen, unsigned short flags)
Definition: symbol.c:1812
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
BOOL symt_get_address(const struct symt *type, ULONG64 *addr) DECLSPEC_HIDDEN
Definition: type.c:119
GLenum func
Definition: glext.h:6028
struct module * module_get_containee(const struct process *pcs, const struct module *inner) DECLSPEC_HIDDEN
Definition: module.c:349
SYMBOL_INFO * sym_info
Definition: symbol.c:744
DWORD64 addr
Definition: symbol.c:747
ULONG_PTR pc_offset
BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1630
ULONG Tag
Definition: compat.h:908
void * ctx
Definition: symbol.c:1234
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define LONG_PTR
Definition: treelist.c:79
struct hash_table_elt hash_elt
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
CHAR Name[1]
Definition: compat.h:911
static BOOL resort_symbols(struct module *module)
Definition: symbol.c:812
PWSTR WINAPI SymSetHomeDirectoryW(HANDLE hProcess, PCWSTR dir)
Definition: symbol.c:2309
struct symt_hierarchy_point * symt_new_label(struct module *module, struct symt_compiland *compiland, const char *name, ULONG_PTR address)
Definition: symbol.c:554
struct symt_data * symt_new_global_variable(struct module *module, struct symt_compiland *compiland, const char *name, unsigned is_static, struct location loc, ULONG_PTR size, struct symt *type)
Definition: symbol.c:256
HMODULE module
Definition: main.cpp:47
ULONG NameLen
Definition: compat.h:909
struct symt * container
static int cmp_addr(ULONG64 a1, ULONG64 a2)
Definition: symbol.c:43
Definition: compat.h:2157
struct symt_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx)
Definition: symbol.c:207
static BOOL symt_enum_locals(struct process *pcs, const WCHAR *mask, const struct sym_enum *se)
Definition: symbol.c:1000
ULONG64 Address
Definition: compat.h:1225
BOOL WINAPI SymGetSymPrev64(HANDLE hProcess, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1551
WCHAR * symt_get_nameW(const struct symt *sym) DECLSPEC_HIDDEN
Definition: type.c:106
ULONG MaxNameLen
Definition: compat.h:910
BOOL WINAPI SymSetScopeFromAddr(HANDLE hProcess, ULONG64 addr)
Definition: symbol.c:2163
BOOL WINAPI SymAddSymbolW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR name, DWORD64 addr, DWORD size, DWORD flags)
Definition: symbol.c:2144
static BOOL doSymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1120
#define WideCharToMultiByte
Definition: compat.h:111
BOOL WINAPI SymEnumSymbolsW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1192
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:935
int __cdecl symt_cmp_addr(const void *p1, const void *p2)
Definition: symbol.c:57
#define __cdecl
Definition: accygwin.h:79
struct vector vchildren
void copy_symbolW(SYMBOL_INFOW *siw, const SYMBOL_INFO *si)
Definition: symbol.c:1029
#define SYMFLAG_REGREL
Definition: compat.h:856
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
ULONG MaxNameLen
Definition: compat.h:1230
Definition: compat.h:2169
union symt_data::@363 u
ULONG64 ModBase
Definition: compat.h:1222
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
PVOID Key
Definition: compat.h:970
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:1220
struct symt symt
#define TRUE
Definition: types.h:120
Definition: match.c:28
void * vector_at(const struct vector *v, unsigned pos) DECLSPEC_HIDDEN
Definition: storage.c:162
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
Definition: symbol.c:2177
DWORD LineNumber
Definition: compat.h:1398
uint16_t * PWSTR
Definition: typedefs.h:56
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
#define CP_ACP
Definition: compat.h:109
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
ULONG_PTR address
#define SYMFLAG_TLSREL
Definition: compat.h:866
struct hash_table ht_symbols
ULONG Scope
Definition: compat.h:907
struct symt_function * symt_new_function(struct module *module, struct symt_compiland *compiland, const char *name, ULONG_PTR addr, ULONG_PTR size, struct symt *sig_type)
Definition: symbol.c:293
struct vector vsymt
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
BOOL WINAPI SymGetSymFromAddr64(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1338
struct symt * container
BOOL dbghelp_opt_native
Definition: dbghelp.c:74
BOOL symt_fill_func_line_info(const struct module *module, const struct symt_function *func, DWORD64 addr, IMAGEHLP_LINE64 *line)
Definition: symbol.c:1480
BOOL WINAPI SymGetLineFromName64(HANDLE hProcess, PCSTR ModuleName, PCSTR FileName, DWORD dwLineNumber, PLONG lpDisplacement, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:2254
static const WCHAR * re_match_one(const WCHAR *string, const WCHAR *elt, BOOL _case)
Definition: symbol.c:1894
GLintptr offset
Definition: glext.h:5920
#define CALLBACK
Definition: compat.h:35
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:291
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
ULONG Flags
Definition: compat.h:903
PSYM_ENUMSYMBOLS_CALLBACK cb
Definition: symbol.c:1208
BOOL(CALLBACK * PSYM_ENUMSYMBOLS_CALLBACK64)(PCSTR, DWORD64, ULONG, PVOID)
Definition: compat.h:1047
BOOL WINAPI SymEnumerateSymbols64(HANDLE hProcess, DWORD64 BaseOfDll, PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1247
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:2050
static int re_match_char(WCHAR ch1, WCHAR ch2, BOOL _case)
Definition: symbol.c:1889
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define SYMOPT_AUTO_PUBLICS
Definition: compat.h:853
ULONG TypeIndex
Definition: compat.h:898
#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:1848
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:905
struct vector vlines
BOOL WINAPI SymFromIndex(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFO symbol)
Definition: symbol.c:2274
const char * source_get(const struct module *module, unsigned idx) DECLSPEC_HIDDEN
Definition: source.c:130
DWORD LineNumber
Definition: compat.h:1380
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:1274
struct symt * container
BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
Definition: symbol.c:1614
const char * symt_get_name(const struct symt *sym) DECLSPEC_HIDDEN
Definition: type.c:81
BOOL WINAPI SymFromAddrW(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFOW Symbol)
Definition: symbol.c:1285
CHAR FileName[MAX_PATH+1]
Definition: compat.h:973
struct symt_public * symt_new_public(struct module *module, struct symt_compiland *compiland, const char *name, BOOL is_function, ULONG_PTR address, unsigned size)
Definition: symbol.c:224
#define SYMFLAG_PUBLIC_CODE
Definition: compat.h:874
unsigned num_symbols
DataKind
Definition: compat.h:1505
PSYM_ENUMSYMBOLS_CALLBACK64 cb
Definition: symbol.c:1235
enum OPTION_FLAGS Options
Definition: stats.c:44
static BOOL CALLBACK sym_enumerate_cb(PSYMBOL_INFO syminfo, ULONG size, void *ctx)
Definition: symbol.c:1211
#define lstrlenW
Definition: compat.h:609
#define UNDNAME_NAME_ONLY
Definition: compat.h:876
#define DWORD
Definition: nt_native.h:44
Definition: send.c:48
PCHAR FileName
Definition: compat.h:957
POINTL point
Definition: edittest.c:50
IMAGEHLP_STACK_FRAME ctx_frame
CHAR Obj[MAX_PATH+1]
Definition: compat.h:972
BOOL symt_get_func_line_next(const struct module *module, PIMAGEHLP_LINE64 line)
Definition: symbol.c:1734
enum module_type type
uint32_t ULONG_PTR
Definition: typedefs.h:65
PCHAR WINAPI SymSetHomeDirectory(HANDLE hProcess, PCSTR dir)
Definition: symbol.c:2298
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:89
struct hash_table_elt hash_elt
DWORD symt_ptr2index(struct module *module, const struct symt *sym)
Definition: symbol.c:68
ULONG NameLen
Definition: compat.h:1229
BOOL(CALLBACK * PSYM_ENUMSYMBOLS_CALLBACK)(PCSTR, ULONG, ULONG, PVOID)
Definition: compat.h:1092
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:883
ULONG64 Reserved[2]
Definition: compat.h:899
THUNK_ORDINAL ordinal
GLenum GLint GLuint mask
Definition: glext.h:6028
struct symt * symt_index2ptr(struct module *module, DWORD id)
Definition: symbol.c:110
BOOL WINAPI SymMatchStringW(PCWSTR string, PCWSTR re, BOOL _case)
Definition: symbol.c:2038
#define SYMOPT_CASE_INSENSITIVE
Definition: compat.h:846
struct _SYMBOL_INFO * PSYMBOL_INFO
ULONG64 Reserved[2]
Definition: compat.h:1219
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
#define FALSE
Definition: types.h:117
SymTagEnum
Definition: compat.h:1438
struct module * lmodules
ULONG_PTR address
unsigned int BOOL
Definition: ntddk_ex.h:94
WCHAR strW[12]
Definition: clipboard.c:2029
GLuint base
Definition: 3dtext.c:35
enum SymTagEnum tag
BOOL WINAPI SymSearch(HANDLE hProcess, ULONG64 BaseOfDll, DWORD Index, DWORD SymTag, PCSTR Mask, DWORD64 Address, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext, DWORD Options)
Definition: symbol.c:2077
int sortlist_valid
CHAR Name[1]
Definition: compat.h:1339
static void copy_line_64_from_32(IMAGEHLP_LINE64 *l64, const IMAGEHLP_LINE *l32)
Definition: symbol.c:1572
DWORD tag
Definition: symbol.c:746
#define debugstr_w
Definition: kernel32.h:32
ULONG SizeOfStruct
Definition: compat.h:1217
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:954
#define FIXME(fmt,...)
Definition: debug.h:111
static WCHAR * file_regex(const char *srcfile)
Definition: symbol.c:159
static PVOID ptr
Definition: dispmode.c:27
ULONG Scope
Definition: compat.h:1227
struct NameRec_ * Name
Definition: cdprocs.h:459
unsigned int idx
Definition: utils.c:41
DWORD64 ModBase
Definition: compat.h:971
void hash_table_iter_init(const struct hash_table *ht, struct hash_table_iter *hti, const char *name) DECLSPEC_HIDDEN
Definition: storage.c:405
ULONG64 ModBase
Definition: compat.h:902
ULONG Index
Definition: compat.h:900
unsigned char BOOLEAN
#define SYMFLAG_LOCAL
Definition: compat.h:859
#define LoadLibraryW(x)
Definition: compat.h:606
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:133
ULONG_PTR offset
static BOOL find_name(struct process *pcs, struct module *module, const char *name, SYMBOL_INFO *symbol)
Definition: symbol.c:1362
Definition: parser.c:48
static int re_fetch_char(const WCHAR **re)
Definition: symbol.c:1879
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:761
char buffer[sizeof(SYMBOL_INFO)+MAX_SYM_NAME]
Definition: symbol.c:748
#define SYMFLAG_VALUEPRESENT
Definition: compat.h:854
DWORD Address
Definition: compat.h:1382
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:1832
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:1175
static const WCHAR nameW[]
Definition: main.c:46
void * fetch_buffer(struct process *pcs, unsigned size)
Definition: dbghelp.c:128
__kernel_size_t size_t
Definition: linux.h:237
#define TRACE_(x)
Definition: compat.h:76
struct vector vchildren
static int cmp_sorttab_addr(struct module *module, int idx, ULONG64 addr)
Definition: symbol.c:50
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFO Symbol)
Definition: symbol.c:1263
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
BOOL module_get_debug(struct module_pair *) DECLSPEC_HIDDEN
Definition: module.c:374
static BOOL symt_grow_sorttab(struct module *module, unsigned sz)
Definition: symbol.c:120
void(* loc_compute)(struct process *pcs, const struct module_format *modfmt, const struct symt_function *func, struct location *loc)
__wchar_t WCHAR
Definition: xmlstorage.h:180
static void symt_get_length(struct module *module, const struct symt *symt, ULONG64 *size)
Definition: symbol.c:863
#define debugstr_a
Definition: kernel32.h:31
BOOL WINAPI SymGetLineNext64(HANDLE hProcess, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1759
ULONG_PTR is_last
static const struct update_accum a2
Definition: msg.c:586
BOOL WINAPI SymGetLinePrev64(HANDLE hProcess, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1673
DWORD LineNumber
Definition: compat.h:974
#define UNDNAME_COMPLETE
Definition: compat.h:875
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
struct symt * type
const GLubyte * c
Definition: glext.h:8905
struct _SYMBOL_INFO SYMBOL_INFO
static const UCHAR Index[8]
Definition: usbohci.c:18
#define MAX_SYM_NAME
Definition: compat.h:834
char * name
Definition: compiler.c:66
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:849
#define SetLastError(x)
Definition: compat.h:611
struct hash_table_elt hash_elt
void hash_table_add(struct hash_table *ht, struct hash_table_elt *elt) DECLSPEC_HIDDEN
Definition: storage.c:378
PVOID user
Definition: symbol.c:743
struct symt symt
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:1942
GLbitfield flags
Definition: glext.h:7161
ULONG64 Value
Definition: compat.h:1224
DWORD SizeOfStruct
Definition: compat.h:969
struct process * pcs
#define SYMOPT_UNDNAME
Definition: compat.h:847
Definition: ncftp.h:79
BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1310
unsigned __int64 ULONG64
Definition: imports.h:198
BOOL WINAPI SymGetLineFromAddrW64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINEW64 Line)
Definition: symbol.c:1657
unsigned reg
BOOL WINAPI SymGetSymFromName(HANDLE hProcess, PCSTR Name, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1456
static BOOL CALLBACK sym_enumerate_cb64(PSYMBOL_INFO syminfo, ULONG size, void *ctx)
Definition: symbol.c:1238
ULONG Index
Definition: compat.h:1220
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt)
ULONG64 InstructionOffset
Definition: compat.h:1235
int ret
GLenum const GLvoid * addr
Definition: glext.h:9621
DWORD64 Address
Definition: compat.h:975
static void copy_line_32_from_64(IMAGEHLP_LINE *l32, const IMAGEHLP_LINE64 *l64)
Definition: symbol.c:1601
struct location var
ULONG Flags
Definition: compat.h:1223
static BOOL CALLBACK sym_enumW(PSYMBOL_INFO si, ULONG size, PVOID ctx)
Definition: symbol.c:1179
static int state
Definition: maze.c:121
BOOL(CALLBACK * PSYM_ENUMLINES_CALLBACK)(PSRCCODEINFO, PVOID)
Definition: compat.h:977
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type) DECLSPEC_HIDDEN
Definition: module.c:420
BOOL WINAPI SymGetLineNext(HANDLE hProcess, PIMAGEHLP_LINE Line)
Definition: symbol.c:1780
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG SizeOfStruct
Definition: compat.h:897
GLenum GLsizei len
Definition: glext.h:6722
BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL sym, PSTR UnDecName, DWORD UnDecNameLength)
Definition: symbol.c:1794
BOOL(CALLBACK * PSYM_ENUMERATESYMBOLS_CALLBACKW)(PSYMBOL_INFOW, ULONG, PVOID)
Definition: compat.h:1325
void * hash_table_iter_up(struct hash_table_iter *hti) DECLSPEC_HIDDEN
Definition: storage.c:422
BOOL symt_normalize_function(struct module *module, const struct symt_function *func)
Definition: symbol.c:473
uint32_t DWORD_PTR
Definition: typedefs.h:65
struct pool pool
#define SYMFLAG_REGISTER
Definition: compat.h:855
char * pool_strdup(struct pool *a, const char *str) DECLSPEC_HIDDEN
Definition: storage.c:126
char string[160]
Definition: util.h:11
ULONG Register
Definition: compat.h:906
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:2107
BOOL WINAPI SymGetLineFromName(HANDLE hProcess, PCSTR ModuleName, PCSTR FileName, DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINE Line)
Definition: symbol.c:2246
DWORD index
Definition: symbol.c:745
unsigned kind
PSYMBOL_INFOW sym_info
Definition: symbol.c:1174
static void copy_line_W64_from_64(struct process *pcs, IMAGEHLP_LINEW64 *l64w, const IMAGEHLP_LINE64 *l64)
Definition: symbol.c:1585
struct _SYMBOL_INFOW SYMBOL_INFOW
void * vector_add(struct vector *v, struct pool *pool) DECLSPEC_HIDDEN
Definition: storage.c:171
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:953
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:536
uint64_t DWORD64
Definition: typedefs.h:67
const GLdouble * v
Definition: gl.h:2040
struct process * process
static int symt_get_best_at(struct module *module, int idx_sorttab)
Definition: symbol.c:876
ULONG TypeIndex
Definition: compat.h:1218
#define CDECL
Definition: compat.h:29
BOOL(CALLBACK * PSYM_ENUMERATESYMBOLS_CALLBACK)(PSYMBOL_INFO, ULONG, PVOID)
Definition: compat.h:978
DWORD LineNumber
Definition: compat.h:956
#define ARRAY_SIZE(a)
Definition: main.h:24
BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1147
ULONG_PTR address
BOOL WINAPI SymFromIndexW(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFOW symbol)
Definition: symbol.c:2286
#define HeapReAlloc
Definition: compat.h:593
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:861
PSYM_ENUMERATESYMBOLS_CALLBACKW cb
Definition: symbol.c:1172
static void symt_add_module_ht(struct module *module, struct symt_ht *ht)
Definition: symbol.c:143
#define min(a, b)
Definition: monoChain.cc:55
Definition: _pair.h:47
unsigned dbghelp_options
Definition: dbghelp.c:73
unsigned sorttab_size
struct hash_table_elt hash_elt
#define lstrcpynA
Definition: compat.h:610
ULONG_PTR size
static const WCHAR starW[]
Definition: symbol.c:41
DWORD * PDWORD
Definition: pedump.c:68
struct _SYMBOL_INFOW * PSYMBOL_INFOW
static void *CDECL und_alloc(size_t len)
Definition: symbol.c:1809
ULONG_PTR size
#define MultiByteToWideChar
Definition: compat.h:110
WCHAR Name[1]
Definition: compat.h:1231
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:751
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static void CDECL und_free(void *ptr)
Definition: symbol.c:1810
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
#define SYMFLAG_THUNK
Definition: compat.h:865
ULONG Register
Definition: compat.h:1226
BOOL WINAPI SymGetSymNext(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1541
ULONG64 Value
Definition: compat.h:904
BOOL WINAPI SymAddSymbol(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR name, DWORD64 addr, DWORD size, DWORD flags)
Definition: symbol.c:2131
BOOL WINAPI SymGetSymFromName64(HANDLE hProcess, PCSTR Name, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1434
Definition: name.c:38
ULONG_PTR is_first
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#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:67
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
BOOL WINAPI SymMatchStringA(PCSTR string, PCSTR re, BOOL _case)
Definition: symbol.c:2006
BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
Definition: symbol.c:1723
BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: symbol.c:1392
#define GetProcAddress(x, y)
Definition: compat.h:612
struct symt_ht ** addr_sorttab
PSYM_ENUMERATESYMBOLS_CALLBACK cb
Definition: symbol.c:742
const char * PCSTR
Definition: typedefs.h:52
static const struct update_accum a1
Definition: msg.c:578
#define towupper(c)
Definition: wctype.h:99
struct symt_thunk * symt_new_thunk(struct module *module, struct symt_compiland *compiland, const char *name, THUNK_ORDINAL ord, ULONG_PTR addr, ULONG_PTR size)
Definition: symbol.c:496
static BOOL sym_enum(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, const struct sym_enum *se)
Definition: symbol.c:1054
PCHAR FileName
Definition: compat.h:1381
GLfloat GLfloat p
Definition: glext.h:8902
#define WILDCHAR(x)
Definition: symbol.c:1877
WCHAR * LPWSTR
Definition: xmlstorage.h:184
void * ctx
Definition: symbol.c:1207
DWORD64 Address
Definition: compat.h:958
ULONG_PTR is_source_file
ULONG Tag
Definition: compat.h:1228
struct symt symt
BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecNameLength)
Definition: symbol.c:1803
static const WCHAR fileW[]
Definition: url.c:111
signed int * PLONG
Definition: retypes.h:5
IMAGEHLP_MODULEW64 module
WCHAR *CDECL wine_get_dos_file_name(LPCSTR str)
Definition: path.c:42
DWORD64 Address
Definition: compat.h:1400
void symt_add_func_line(struct module *module, struct symt_function *func, unsigned source_idx, int line_num, ULONG_PTR offset)
Definition: symbol.c:326
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define SYMFLAG_PARAMETER
Definition: compat.h:858
struct module * next
#define HeapFree(x, y, z)
Definition: compat.h:594
BOOL WINAPI SymGetSymNext64(HANDLE hProcess, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1525
static unsigned where_to_insert(struct module *module, unsigned high, const struct symt_ht *elt)
Definition: symbol.c:787
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:2262
unsigned vector_length(const struct vector *v) DECLSPEC_HIDDEN
Definition: storage.c:157
struct hash_table_elt hash_elt
ULONG Size
Definition: compat.h:901
Definition: compat.h:2156
struct symt_ht * symt_find_nearest(struct module *module, DWORD_PTR addr)
Definition: symbol.c:903
THUNK_ORDINAL
Definition: compat.h:2073
struct vector vchildren
struct symt symt
static int mod
Definition: i386-dis.c:1273
union line_info::@366 u
void * ctx
Definition: symbol.c:1173
Definition: fci.c:126
ULONG_PTR line_number
ULONG Size
Definition: compat.h:1221
GLuint const GLchar * name
Definition: glext.h:6031