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