ReactOS 0.4.15-dev-7788-g1ad9096
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
40
41static const WCHAR starW[] = {'*','\0'};
42
43static 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
50static inline int cmp_sorttab_addr(struct module* module, int idx, ULONG64 addr)
51{
54 return cmp_addr(ref, addr);
55}
56
57int __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
68DWORD symt_ptr2index(struct module* module, const struct symt* sym)
69{
70#ifdef __x86_64__
71 const struct symt** c;
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
111{
112#if defined(__x86_64__) || defined(__arm64__)
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
120static 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
143static void symt_add_module_ht(struct module* module, struct symt_ht* ht)
144{
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
159static 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",
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 */
583 const struct symt_function* func,
584 const struct symt* sym, SYMBOL_INFO* sym_info)
585{
586 const char* name;
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),
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;
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
741{
749};
750
751static BOOL send_symbol(const struct sym_enum* se, struct module_pair* pair,
752 const struct symt_function* func, const struct symt* sym)
753{
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
787static inline unsigned where_to_insert(struct module* module, unsigned high, const struct symt_ht* elt)
788{
789 unsigned low = 0, mid = high / 2;
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 */
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
863static 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) &&
872 *size = 0x1000; /* arbitrary value */
873}
874
875/* needed by symt_find_nearest */
876static 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:
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
1000static 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 */
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 }
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
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",
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
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
1362static 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{
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 */
1419 {
1420 for (module = pcs->lmodules; module; module = module->next)
1421 {
1422 if ((module->type == DMT_ELF || module->type == DMT_MACHO) &&
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 {
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 */
1585static 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 */
1794BOOL 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 */
1803BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecNameLength)
1804{
1805 return UnDecorateSymbolName(sym->Name, UnDecName, UnDecNameLength,
1806 UNDNAME_COMPLETE) != 0;
1807}
1808
1809static void * CDECL und_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); }
1810static void CDECL und_free (void* ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
1811
1812static 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 */
1832DWORD 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 */
1848DWORD 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 }
1872 }
1873
1874 return ret;
1875}
1876
1877#define WILDCHAR(x) (-(x))
1878
1879static 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
1889static inline int re_match_char(WCHAR ch1, WCHAR ch2, BOOL _case)
1890{
1891 return _case ? ch1 - ch2 : towupper(ch1) - towupper(ch2);
1892}
1893
1894static 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 */
1942static 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
1996found:
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);
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
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
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';
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}
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 * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
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
struct NameRec_ * Name
Definition: cdprocs.h:460
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:46
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
Definition: Symbol.h:9
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
#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
__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
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLuint address
Definition: glext.h:9393
GLuint buffer
Definition: glext.h:5915
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
GLintptr offset
Definition: glext.h:5920
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
static int mod
Definition: i386-dis.c:1288
#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: cpp.c:47
WCHAR strW[12]
Definition: clipboard.c:2029
#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
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 *))
#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
ULONG_PTR pc_offset
ULONG_PTR is_first
ULONG_PTR line_number
ULONG_PTR is_last
union line_info::@375 u
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:1175
void * ctx
Definition: symbol.c:1173
PSYMBOL_INFOW sym_info
Definition: symbol.c:1174
PSYM_ENUMERATESYMBOLS_CALLBACKW cb
Definition: symbol.c:1172
char buffer[sizeof(SYMBOL_INFO)+MAX_SYM_NAME]
Definition: symbol.c:748
DWORD64 addr
Definition: symbol.c:747
DWORD tag
Definition: symbol.c:746
SYMBOL_INFO * sym_info
Definition: symbol.c:744
PVOID user
Definition: symbol.c:743
DWORD index
Definition: symbol.c:745
PSYM_ENUMERATESYMBOLS_CALLBACK cb
Definition: symbol.c:742
PSYM_ENUMSYMBOLS_CALLBACK64 cb
Definition: symbol.c:1235
void * ctx
Definition: symbol.c:1234
PSYM_ENUMSYMBOLS_CALLBACK cb
Definition: symbol.c:1208
void * ctx
Definition: symbol.c:1207
struct vector vchildren
struct symt symt
struct symt symt
struct vector vchildren
struct symt * type
union symt_data::@372 u
struct symt symt
struct symt * container
struct hash_table_elt hash_elt
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:812
static const WCHAR starW[]
Definition: symbol.c:41
BOOL WINAPI SymGetSymFromName(HANDLE hProcess, PCSTR Name, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1456
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFO Symbol)
Definition: symbol.c:1263
BOOL WINAPI SymGetLineNext(HANDLE hProcess, PIMAGEHLP_LINE Line)
Definition: symbol.c:1780
BOOL WINAPI SymMatchStringA(PCSTR string, PCSTR re, BOOL _case)
Definition: symbol.c:2006
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
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
BOOL WINAPI SymGetLineNext64(HANDLE hProcess, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1759
struct symt * symt_index2ptr(struct module *module, DWORD id)
Definition: symbol.c:110
static void copy_line_32_from_64(IMAGEHLP_LINE *l32, const IMAGEHLP_LINE64 *l64)
Definition: symbol.c:1601
static unsigned where_to_insert(struct module *module, unsigned high, const struct symt_ht *elt)
Definition: symbol.c:787
BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL sym, PSTR UnDecName, DWORD UnDecNameLength)
Definition: symbol.c:1794
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
BOOL WINAPI SymGetLinePrev64(HANDLE hProcess, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1673
BOOL WINAPI SymGetLineFromName64(HANDLE hProcess, PCSTR ModuleName, PCSTR FileName, DWORD dwLineNumber, PLONG lpDisplacement, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:2254
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
BOOL WINAPI SymGetSymPrev(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1561
BOOL WINAPI SymEnumerateSymbols(HANDLE hProcess, DWORD BaseOfDll, PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1220
BOOL WINAPI SymEnumerateSymbols64(HANDLE hProcess, DWORD64 BaseOfDll, PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1247
static void copy_line_64_from_32(IMAGEHLP_LINE64 *l64, const IMAGEHLP_LINE *l32)
Definition: symbol.c:1572
DWORD symt_ptr2index(struct module *module, const struct symt *sym)
Definition: symbol.c:68
static BOOL symt_enum_module(struct module_pair *pair, const WCHAR *match, const struct sym_enum *se)
Definition: symbol.c:761
static BOOL symt_grow_sorttab(struct module *module, unsigned sz)
Definition: symbol.c:120
static void *CDECL und_alloc(size_t len)
Definition: symbol.c:1809
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_block * symt_close_func_block(struct module *module, const struct symt_function *func, struct symt_block *block, unsigned pc)
Definition: symbol.c:440
BOOL WINAPI SymGetLineFromNameW64(HANDLE hProcess, PCWSTR ModuleName, PCWSTR FileName, DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINEW64 Line)
Definition: symbol.c:2262
#define WILDCHAR(x)
Definition: symbol.c:1877
BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1147
static WCHAR * file_regex(const char *srcfile)
Definition: symbol.c:159
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 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
BOOL symt_get_func_line_next(const struct module *module, PIMAGEHLP_LINE64 line)
Definition: symbol.c:1734
BOOL WINAPI SymAddSymbol(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR name, DWORD64 addr, DWORD size, DWORD flags)
Definition: symbol.c:2131
BOOL WINAPI SymGetSymNext(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1541
struct symt_compiland * symt_new_compiland(struct module *module, ULONG_PTR address, unsigned src_idx)
Definition: symbol.c:207
BOOL WINAPI SymGetSymPrev64(HANDLE hProcess, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1551
BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
Definition: symbol.c:1723
static int re_match_char(WCHAR ch1, WCHAR ch2, BOOL _case)
Definition: symbol.c:1889
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
PWSTR WINAPI SymSetHomeDirectoryW(HANDLE hProcess, PCWSTR dir)
Definition: symbol.c:2309
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 SymFromIndexW(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFOW symbol)
Definition: symbol.c:2286
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
BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
Definition: symbol.c:1310
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
static const WCHAR * re_match_one(const WCHAR *string, const WCHAR *elt, BOOL _case)
Definition: symbol.c:1894
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
BOOL WINAPI SymGetLineFromAddrW64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINEW64 Line)
Definition: symbol.c:1657
BOOL symt_normalize_function(struct module *module, const struct symt_function *func)
Definition: symbol.c:473
static int cmp_sorttab_addr(struct module *module, int idx, ULONG64 addr)
Definition: symbol.c:50
static void CDECL und_free(void *ptr)
Definition: symbol.c:1810
static BOOL symt_enum_locals(struct process *pcs, const WCHAR *mask, const struct sym_enum *se)
Definition: symbol.c:1000
struct symt_ht * symt_find_nearest(struct module *module, DWORD_PTR addr)
Definition: symbol.c:903
static int re_fetch_char(const WCHAR **re)
Definition: symbol.c:1879
BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecNameLength)
Definition: symbol.c:1803
static BOOL doSymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1120
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
BOOL WINAPI SymFromIndex(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFO symbol)
Definition: symbol.c:2274
BOOL WINAPI SymGetSymNext64(HANDLE hProcess, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1525
PCHAR WINAPI SymSetHomeDirectory(HANDLE hProcess, PCSTR dir)
Definition: symbol.c:2298
BOOL WINAPI SymSetScopeFromAddr(HANDLE hProcess, ULONG64 addr)
Definition: symbol.c:2163
BOOL WINAPI SymGetSymFromName64(HANDLE hProcess, PCSTR Name, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1434
static BOOL re_match_multi(const WCHAR **pstring, const WCHAR **pre, BOOL _case)
Definition: symbol.c:1942
static int symt_get_best_at(struct module *module, int idx_sorttab)
Definition: symbol.c:876
BOOL WINAPI SymAddSymbolW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR name, DWORD64 addr, DWORD size, DWORD flags)
Definition: symbol.c:2144
BOOL WINAPI SymMatchStringW(PCWSTR string, PCWSTR re, BOOL _case)
Definition: symbol.c:2038
BOOL WINAPI SymGetLineFromName(HANDLE hProcess, PCSTR ModuleName, PCSTR FileName, DWORD dwLineNumber, PLONG plDisplacement, PIMAGEHLP_LINE Line)
Definition: symbol.c:2246
DWORD WINAPI UnDecorateSymbolName(const char *decorated_name, char *undecorated_name, DWORD undecorated_length, DWORD flags)
Definition: symbol.c:1832
BOOL WINAPI SymFromAddrW(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFOW Symbol)
Definition: symbol.c:1285
int __cdecl symt_cmp_addr(const void *p1, const void *p2)
Definition: symbol.c:57
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
static void symt_get_length(struct module *module, const struct symt *symt, ULONG64 *size)
Definition: symbol.c:863
BOOL WINAPI SymFromName(HANDLE hProcess, PCSTR Name, PSYMBOL_INFO Symbol)
Definition: symbol.c:1392
BOOL WINAPI SymGetSymFromAddr64(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol)
Definition: symbol.c:1338
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
Definition: symbol.c:2177
static int cmp_addr(ULONG64 a1, ULONG64 a2)
Definition: symbol.c:43
static void copy_line_W64_from_64(struct process *pcs, IMAGEHLP_LINEW64 *l64w, const IMAGEHLP_LINE64 *l64)
Definition: symbol.c:1585
BOOL symt_fill_func_line_info(const struct module *module, const struct symt_function *func, DWORD64 addr, IMAGEHLP_LINE64 *line)
Definition: symbol.c:1480
static BOOL CALLBACK sym_enumerate_cb(PSYMBOL_INFO syminfo, ULONG size, void *ctx)
Definition: symbol.c:1211
static void symt_add_module_ht(struct module *module, struct symt_ht *ht)
Definition: symbol.c:143
DWORD WINAPI UnDecorateSymbolNameW(const WCHAR *decorated_name, WCHAR *undecorated_name, DWORD undecorated_length, DWORD flags)
Definition: symbol.c:1848
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
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
BOOL WINAPI SymEnumSymbolsW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1192
static BOOL CALLBACK sym_enumerate_cb64(PSYMBOL_INFO syminfo, ULONG size, void *ctx)
Definition: symbol.c:1238
static char * und_name(char *buffer, const char *mangled, int buflen, unsigned short flags)
Definition: symbol.c:1812
BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
Definition: symbol.c:1614
BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line)
Definition: symbol.c:1630
void copy_symbolW(SYMBOL_INFOW *siw, const SYMBOL_INFO *si)
Definition: symbol.c:1029
#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::@2290 u
int ret
_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