ReactOS 0.4.15-dev-7961-gdcf9eb0
dbghelp.c
Go to the documentation of this file.
1/*
2 * File dbghelp.c - generic routines (process) for dbghelp DLL
3 *
4 * Copyright (C) 2004, Eric Pouech
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#ifndef DBGHELP_STATIC_LIB
22
23#include <unistd.h>
24#include "dbghelp_private.h"
25#include "winternl.h"
26#include "winerror.h"
27#include "psapi.h"
28#include "wine/debug.h"
29#include "wdbgexts.h"
30#include "winnls.h"
31#else
32#include "dbghelp_private.h"
33#include "wdbgexts.h"
34#endif
35
37
38/* TODO
39 * - support for symbols' types is still partly missing
40 * + C++ support
41 * + we should store the underlying type for an enum in the symt_enum struct
42 * + for enums, we store the names & values (associated to the enum type),
43 * but those values are not directly usable from a debugger (that's why, I
44 * assume, that we have also to define constants for enum values, as
45 * Codeview does BTW.
46 * + SymEnumTypes should only return *user* defined types (UDT, typedefs...) not
47 * all the types stored/used in the modules (like char*)
48 * - SymGetLine{Next|Prev} don't work as expected (they don't seem to work across
49 * functions, and even across function blocks...). Basically, for *Next* to work
50 * it requires an address after the prolog of the func (the base address of the
51 * func doesn't work)
52 * - most options (dbghelp_options) are not used (loading lines...)
53 * - in symbol lookup by name, we don't use RE everywhere we should. Moreover, when
54 * we're supposed to use RE, it doesn't make use of our hash tables. Therefore,
55 * we could use hash if name isn't a RE, and fall back to a full search when we
56 * get a full RE
57 * - msc:
58 * + we should add parameters' types to the function's signature
59 * while processing a function's parameters
60 * + add support for function-less labels (as MSC seems to define them)
61 * + C++ management
62 * - stabs:
63 * + when, in a same module, the same definition is used in several compilation
64 * units, we get several definitions of the same object (especially
65 * struct/union). we should find a way not to duplicate them
66 * + in some cases (dlls/user/dialog16.c DIALOG_GetControl16), the same static
67 * global variable is defined several times (at different scopes). We are
68 * getting several of those while looking for a unique symbol. Part of the
69 * issue is that we don't give a scope to a static variable inside a function
70 * + C++ management
71 */
72
75#ifndef DBGHELP_STATIC_LIB
77#endif
78
79static struct process* process_first /* = NULL */;
80
81#ifndef DBGHELP_STATIC_LIB
83{
84 switch (reason)
85 {
89 break;
90 }
91 return TRUE;
92}
93#endif
94
95/******************************************************************
96 * process_find_by_handle
97 *
98 */
100{
101 struct process* p;
102
103 for (p = process_first; p && p->handle != hProcess; p = p->next);
105 return p;
106}
107
108/******************************************************************
109 * validate_addr64 (internal)
110 *
111 */
113{
114 if (sizeof(void*) == sizeof(int) && (addr >> 32))
115 {
116 FIXME("Unsupported address %s\n", wine_dbgstr_longlong(addr));
118 return FALSE;
119 }
120 return TRUE;
121}
122
123/******************************************************************
124 * fetch_buffer
125 *
126 * Ensures process' internal buffer is large enough.
127 */
128void* fetch_buffer(struct process* pcs, unsigned size)
129{
130 if (size > pcs->buffer_size)
131 {
132 if (pcs->buffer)
133 pcs->buffer = HeapReAlloc(GetProcessHeap(), 0, pcs->buffer, size);
134 else
135 pcs->buffer = HeapAlloc(GetProcessHeap(), 0, size);
136 pcs->buffer_size = (pcs->buffer) ? size : 0;
137 }
138 return pcs->buffer;
139}
140
141#ifndef DBGHELP_STATIC_LIB
142const char* wine_dbgstr_addr(const ADDRESS64* addr)
143{
144 if (!addr) return "(null)";
145 switch (addr->Mode)
146 {
147 case AddrModeFlat:
148 return wine_dbg_sprintf("flat<%s>", wine_dbgstr_longlong(addr->Offset));
149 case AddrMode1616:
150 return wine_dbg_sprintf("1616<%04x:%04x>", addr->Segment, (DWORD)addr->Offset);
151 case AddrMode1632:
152 return wine_dbg_sprintf("1632<%04x:%08x>", addr->Segment, (DWORD)addr->Offset);
153 case AddrModeReal:
154 return wine_dbg_sprintf("real<%04x:%04x>", addr->Segment, (DWORD)addr->Offset);
155 default:
156 return "unknown";
157 }
158}
159#endif
160
161extern struct cpu cpu_i386, cpu_x86_64, cpu_arm, cpu_arm64;
162
163#ifndef DBGHELP_STATIC_LIB
165#else
166static struct cpu* dbghelp_cpus[] = {&cpu_i386, NULL};
167#endif
168
170#if defined(__i386__) || defined(DBGHELP_STATIC_LIB)
171 &cpu_i386
172#elif defined(__x86_64__)
174#elif defined(__arm__)
175 &cpu_arm
176#elif defined(__aarch64__)
177 &cpu_arm64
178#else
179#error define support for your CPU
180#endif
181 ;
182
184{
185 struct cpu** cpu;
186
187 for (cpu = dbghelp_cpus ; *cpu; cpu++)
188 {
189 if (cpu[0]->machine == machine) return cpu[0];
190 }
191 return NULL;
192}
193
195{
196 WCHAR* search_path;
197 WCHAR* p;
198 unsigned sym_path_len;
199 unsigned alt_sym_path_len;
200
201 sym_path_len = GetEnvironmentVariableW(L"_NT_SYMBOL_PATH", NULL, 0);
202 alt_sym_path_len = GetEnvironmentVariableW(L"_NT_ALT_SYMBOL_PATH", NULL, 0);
203
204 /* The default symbol path is ".[;%_NT_SYMBOL_PATH%][;%_NT_ALT_SYMBOL_PATH%]".
205 * If the variables exist, the lengths include a null-terminator. We use that
206 * space for the semicolons, and only add the initial dot and the final null. */
207 search_path = HeapAlloc(GetProcessHeap(), 0,
208 (1 + sym_path_len + alt_sym_path_len + 1) * sizeof(WCHAR));
209 if (!search_path) return NULL;
210
211 p = search_path;
212 *p++ = L'.';
213 if (sym_path_len)
214 {
215 *p++ = L';';
216 GetEnvironmentVariableW(L"_NT_SYMBOL_PATH", p, sym_path_len);
217 p += sym_path_len - 1;
218 }
219
220 if (alt_sym_path_len)
221 {
222 *p++ = L';';
223 GetEnvironmentVariableW(L"_NT_ALT_SYMBOL_PATH", p, alt_sym_path_len);
224 p += alt_sym_path_len - 1;
225 }
226 *p = L'\0';
227
228 return search_path;
229}
230
231/******************************************************************
232 * SymSetSearchPathW (DBGHELP.@)
233 *
234 */
236{
238 WCHAR* search_path_buffer;
239
240 if (!pcs) return FALSE;
241
242 if (searchPath)
243 {
244 search_path_buffer = HeapAlloc(GetProcessHeap(), 0,
245 (lstrlenW(searchPath) + 1) * sizeof(WCHAR));
246 if (!search_path_buffer) return FALSE;
247 lstrcpyW(search_path_buffer, searchPath);
248 }
249 else
250 {
251 search_path_buffer = make_default_search_path();
252 if (!search_path_buffer) return FALSE;
253 }
255 pcs->search_path = search_path_buffer;
256 return TRUE;
257}
258
259/******************************************************************
260 * SymSetSearchPath (DBGHELP.@)
261 *
262 */
264{
265 BOOL ret = FALSE;
266 unsigned len;
267 WCHAR* sp = NULL;
268
269 if (searchPath)
270 {
271 len = MultiByteToWideChar(CP_ACP, 0, searchPath, -1, NULL, 0);
272 sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
273 if (!sp) return FALSE;
274 MultiByteToWideChar(CP_ACP, 0, searchPath, -1, sp, len);
275 }
276
278
280 return ret;
281}
282
283/***********************************************************************
284 * SymGetSearchPathW (DBGHELP.@)
285 */
287 DWORD SearchPathLength)
288{
290 if (!pcs) return FALSE;
291
292 lstrcpynW(szSearchPath, pcs->search_path, SearchPathLength);
293 return TRUE;
294}
295
296/***********************************************************************
297 * SymGetSearchPath (DBGHELP.@)
298 */
300 DWORD SearchPathLength)
301{
302 WCHAR* buffer = HeapAlloc(GetProcessHeap(), 0, SearchPathLength * sizeof(WCHAR));
303 BOOL ret = FALSE;
304
305 if (buffer)
306 {
307 ret = SymGetSearchPathW(hProcess, buffer, SearchPathLength);
308 if (ret)
309 WideCharToMultiByte(CP_ACP, 0, buffer, SearchPathLength,
310 szSearchPath, SearchPathLength, NULL, NULL);
312 }
313 return ret;
314}
315
316#ifndef DBGHELP_STATIC_LIB
317/******************************************************************
318 * invade_process
319 *
320 * SymInitialize helper: loads in dbghelp all known (and loaded modules)
321 * this assumes that hProcess is a handle on a valid process
322 */
324{
325 WCHAR tmp[MAX_PATH];
327
329 lstrcpynW(tmp, name, ARRAY_SIZE(tmp));
330
331 SymLoadModuleExW(hProcess, 0, tmp, name, base, size, NULL, 0);
332 return TRUE;
333}
334
335const WCHAR *process_getenv(const struct process *process, const WCHAR *name)
336{
337 size_t name_len;
338 const WCHAR *iter;
339
340 if (!process->environment) return NULL;
341 name_len = lstrlenW(name);
342
343 for (iter = process->environment; *iter; iter += lstrlenW(iter) + 1)
344 {
345 if (!wcsnicmp(iter, name, name_len) && iter[name_len] == '=')
346 return iter + name_len + 1;
347 }
348
349 return NULL;
350}
351
352/******************************************************************
353 * check_live_target
354 *
355 */
356static BOOL check_live_target(struct process* pcs)
357{
359 ULONG_PTR base = 0, env = 0;
360
361 if (!GetProcessId(pcs->handle)) return FALSE;
362 if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE;
363
365 &pbi, sizeof(pbi), NULL ))
366 return FALSE;
367
368 if (!pcs->is_64bit)
369 {
370 DWORD env32;
371 PEB32 peb32;
372 C_ASSERT(sizeof(void*) != 4 || FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment) == 0x48);
373 if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb32, sizeof(peb32), NULL)) return FALSE;
374 base = peb32.Reserved[0];
375 if (read_process_memory(pcs, peb32.ProcessParameters + 0x48, &env32, sizeof(env32))) env = env32;
376 }
377 else
378 {
379 PEB peb;
380 if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb, sizeof(peb), NULL)) return FALSE;
381 base = peb.Reserved[0];
383 }
384
385#ifdef __REACTOS__
386 /* Wine store their loader base address in peb.reserved[0] and load its symbol from there.
387 * ReactOS does not care about it, we are just happy if we managed to read the value */
388 base = 1;
389#endif
390
391 /* read debuggee environment block */
392 if (env)
393 {
394 size_t buf_size = 0, i, last_null = -1;
395 WCHAR *buf = NULL;
396
397 do
398 {
400 if (buf)
401 {
402 WCHAR *new_buf;
403 if (!(new_buf = realloc(buf, buf_size + read_size))) break;
404 buf = new_buf;
405 }
406 else if(!(buf = malloc(read_size))) break;
407
408 if (!read_process_memory(pcs, env, (char*)buf + buf_size, read_size)) break;
409 for (i = buf_size / sizeof(WCHAR); i < (buf_size + read_size) / sizeof(WCHAR); i++)
410 {
411 if (buf[i]) continue;
412 if (last_null + 1 == i)
413 {
414 pcs->environment = realloc(buf, (i + 1) * sizeof(WCHAR));
415 buf = NULL;
416 break;
417 }
418 last_null = i;
419 }
420 env += read_size;
421 buf_size += read_size;
422 }
423 while (buf);
424 free(buf);
425 }
426
427 if (!base) return FALSE;
428
429 TRACE("got debug info address %#lx from PEB %p\n", base, pbi.PebBaseAddress);
430#ifndef __REACTOS__
432 WARN("couldn't load process debug info at %#lx\n", base);
433#endif
434 return TRUE;
435}
436#endif
437
438/******************************************************************
439 * SymInitializeW (DBGHELP.@)
440 *
441 * The initialisation of a dbghelp's context.
442 * Note that hProcess doesn't need to be a valid process handle (except
443 * when fInvadeProcess is TRUE).
444 * Since we also allow loading ELF (pure) libraries and Wine ELF libraries
445 * containing PE (and NE) module(s), here's how we handle it:
446 * - we load every module (ELF, NE, PE) passed in SymLoadModule
447 * - in fInvadeProcess (in SymInitialize) is TRUE, we set up what is called ELF
448 * synchronization: hProcess should be a valid process handle, and we hook
449 * ourselves on hProcess's loaded ELF-modules, and keep this list in sync with
450 * our internal ELF modules representation (loading / unloading). This way,
451 * we'll pair every loaded builtin PE module with its ELF counterpart (and
452 * access its debug information).
453 * - if fInvadeProcess (in SymInitialize) is FALSE, we check anyway if the
454 * hProcess refers to a running process. We use some heuristics here, so YMMV.
455 * If we detect a live target, then we get the same handling as if
456 * fInvadeProcess is TRUE (except that the modules are not loaded). Otherwise,
457 * we won't be able to make the peering between a builtin PE module and its ELF
458 * counterpart. Hence we won't be able to provide the requested debug
459 * information. We'll however be able to load native PE modules (and their
460 * debug information) without any trouble.
461 * Note also that this scheme can be intertwined with the deferred loading
462 * mechanism (ie only load the debug information when we actually need it).
463 */
464BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess)
465{
466 struct process* pcs;
467 BOOL wow64, child_wow64;
468
469 TRACE("(%p %s %u)\n", hProcess, debugstr_w(UserSearchPath), fInvadeProcess);
470
472 {
473 WARN("the symbols for this process have already been initialized!\n");
474
475 /* MSDN says to only call this function once unless SymCleanup() has been called since the last call.
476 It also says to call SymRefreshModuleList() instead if you just want the module list refreshed.
477 Native still returns TRUE even if the process has already been initialized. */
478 return TRUE;
479 }
480
482
483 if (GetProcessId(hProcess) && !IsWow64Process(hProcess, &child_wow64))
484 return FALSE;
485
486 pcs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pcs));
487 if (!pcs) return FALSE;
488
489 pcs->handle = hProcess;
490 pcs->is_64bit = (sizeof(void *) == 8 || wow64) && !child_wow64;
491 pcs->loader = &no_loader_ops; /* platform-specific initialization will override it if loader debug info can be found */
492
493 if (UserSearchPath)
494 {
496 (lstrlenW(UserSearchPath) + 1) * sizeof(WCHAR)),
497 UserSearchPath);
498 }
499 else
500 {
502 }
503
504 pcs->lmodules = NULL;
505 pcs->dbg_hdr_addr = 0;
506 pcs->next = process_first;
507 process_first = pcs;
508
509#ifndef DBGHELP_STATIC_LIB
510 if (check_live_target(pcs))
511 {
512 if (fInvadeProcess)
514 if (pcs->loader) pcs->loader->synchronize_module_list(pcs);
515 }
516 else if (fInvadeProcess)
517#else
518 if (fInvadeProcess)
519#endif
520 {
523 return FALSE;
524 }
525
526 return TRUE;
527}
528
529/******************************************************************
530 * SymInitialize (DBGHELP.@)
531 *
532 *
533 */
534BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
535{
536 WCHAR* sp = NULL;
537 BOOL ret;
538
539 if (UserSearchPath)
540 {
541 unsigned len;
542
543 len = MultiByteToWideChar(CP_ACP, 0, UserSearchPath, -1, NULL, 0);
544 sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
545 MultiByteToWideChar(CP_ACP, 0, UserSearchPath, -1, sp, len);
546 }
547
548 ret = SymInitializeW(hProcess, sp, fInvadeProcess);
550 return ret;
551}
552
553/******************************************************************
554 * SymCleanup (DBGHELP.@)
555 *
556 */
558{
559 struct process** ppcs;
560 struct process* next;
561
562 for (ppcs = &process_first; *ppcs; ppcs = &(*ppcs)->next)
563 {
564 if ((*ppcs)->handle == hProcess)
565 {
566 while ((*ppcs)->lmodules) module_remove(*ppcs, (*ppcs)->lmodules);
567
568 HeapFree(GetProcessHeap(), 0, (*ppcs)->search_path);
569 free((*ppcs)->environment);
570 next = (*ppcs)->next;
571 HeapFree(GetProcessHeap(), 0, *ppcs);
572 *ppcs = next;
573 return TRUE;
574 }
575 }
576
577 ERR("this process has not had SymInitialize() called for it!\n");
578 return FALSE;
579}
580
581/******************************************************************
582 * SymSetOptions (DBGHELP.@)
583 *
584 */
586{
587 struct process* pcs;
588
589 for (pcs = process_first; pcs; pcs = pcs->next)
590 {
591 pcs_callback(pcs, CBA_SET_OPTIONS, &opts);
592 }
593 return dbghelp_options = opts;
594}
595
596/******************************************************************
597 * SymGetOptions (DBGHELP.@)
598 *
599 */
601{
602 return dbghelp_options;
603}
604
605/******************************************************************
606 * SymSetExtendedOption (DBGHELP.@)
607 *
608 */
610{
611 BOOL old = FALSE;
612
613 switch(option)
614 {
616 old = dbghelp_opt_native;
618 break;
619 default:
620 FIXME("Unsupported option %d with value %d\n", option, value);
621 }
622
623 return old;
624}
625
626/******************************************************************
627 * SymGetExtendedOption (DBGHELP.@)
628 *
629 */
631{
632 switch(option)
633 {
635 return dbghelp_opt_native;
636 default:
637 FIXME("Unsupported option %d\n", option);
638 }
639
640 return FALSE;
641}
642
643/******************************************************************
644 * SymSetParentWindow (DBGHELP.@)
645 *
646 */
648{
649 /* Save hwnd so it can be used as parent window */
650 FIXME("(%p): stub\n", hwnd);
651 return TRUE;
652}
653
654/******************************************************************
655 * SymSetContext (DBGHELP.@)
656 *
657 */
660{
662 if (!pcs) return FALSE;
663
664 if (pcs->ctx_frame.ReturnOffset == StackFrame->ReturnOffset &&
665 pcs->ctx_frame.FrameOffset == StackFrame->FrameOffset &&
666 pcs->ctx_frame.StackOffset == StackFrame->StackOffset)
667 {
668 TRACE("Setting same frame {rtn=%s frm=%s stk=%s}\n",
673 SetLastError(ERROR_ACCESS_DENIED); /* latest MSDN says ERROR_SUCCESS */
674 return FALSE;
675 }
676
677 pcs->ctx_frame = *StackFrame;
678 /* MSDN states that Context is not (no longer?) used */
679 return TRUE;
680}
681
682/******************************************************************
683 * reg_cb64to32 (internal)
684 *
685 * Registered callback for converting information from 64 bit to 32 bit
686 */
688{
690 void* data32;
693
694 if (!pcs) return FALSE;
695 switch (action)
696 {
697 case CBA_DEBUG_INFO:
699 case CBA_SET_OPTIONS:
701 data32 = (void*)(DWORD_PTR)data;
702 break;
708 if (!validate_addr64(idsl64->BaseOfImage))
709 return FALSE;
710 idsl.SizeOfStruct = sizeof(idsl);
711 idsl.BaseOfImage = (DWORD)idsl64->BaseOfImage;
712 idsl.CheckSum = idsl64->CheckSum;
713 idsl.TimeDateStamp = idsl64->TimeDateStamp;
714 memcpy(idsl.FileName, idsl64->FileName, sizeof(idsl.FileName));
715 idsl.Reparse = idsl64->Reparse;
716 data32 = &idsl;
717 break;
719 case CBA_EVENT:
720 case CBA_READ_MEMORY:
721 default:
722 FIXME("No mapping for action %u\n", action);
723 return FALSE;
724 }
726}
727
728/******************************************************************
729 * pcs_callback (internal)
730 */
731BOOL pcs_callback(const struct process* pcs, ULONG action, void* data)
732{
734
735 TRACE("%p %u %p\n", pcs, action, data);
736
737 if (!pcs->reg_cb) return FALSE;
738 if (!pcs->reg_is_unicode)
739 {
741
742 switch (action)
743 {
744 case CBA_DEBUG_INFO:
746 case CBA_SET_OPTIONS:
748 break;
753 idslW = data;
754 idsl.SizeOfStruct = sizeof(idsl);
755 idsl.BaseOfImage = idslW->BaseOfImage;
756 idsl.CheckSum = idslW->CheckSum;
757 idsl.TimeDateStamp = idslW->TimeDateStamp;
758 WideCharToMultiByte(CP_ACP, 0, idslW->FileName, -1,
759 idsl.FileName, sizeof(idsl.FileName), NULL, NULL);
760 idsl.Reparse = idslW->Reparse;
761 data = &idsl;
762 break;
764 case CBA_EVENT:
765 case CBA_READ_MEMORY:
766 default:
767 FIXME("No mapping for action %u\n", action);
768 return FALSE;
769 }
770 }
771 return pcs->reg_cb(pcs->handle, action, (ULONG64)(DWORD_PTR)data, pcs->reg_user);
772}
773
774/******************************************************************
775 * sym_register_cb
776 *
777 * Helper for registering a callback.
778 */
782 DWORD64 user, BOOL unicode)
783{
785
786 if (!pcs) return FALSE;
787 pcs->reg_cb = cb;
788 pcs->reg_cb32 = cb32;
789 pcs->reg_is_unicode = unicode;
790 pcs->reg_user = user;
791
792 return TRUE;
793}
794
795/***********************************************************************
796 * SymRegisterCallback (DBGHELP.@)
797 */
800 PVOID UserContext)
801{
802 TRACE("(%p, %p, %p)\n",
803 hProcess, CallbackFunction, UserContext);
805}
806
807/***********************************************************************
808 * SymRegisterCallback64 (DBGHELP.@)
809 */
812 ULONG64 UserContext)
813{
814 TRACE("(%p, %p, %s)\n",
816 return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, FALSE);
817}
818
819/***********************************************************************
820 * SymRegisterCallbackW64 (DBGHELP.@)
821 */
824 ULONG64 UserContext)
825{
826 TRACE("(%p, %p, %s)\n",
828 return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, TRUE);
829}
830
831/* This is imagehlp version not dbghelp !! */
832static API_VERSION api_version = { 4, 0, 2, 0 };
833
834/***********************************************************************
835 * ImagehlpApiVersion (DBGHELP.@)
836 */
838{
839 return &api_version;
840}
841
842/***********************************************************************
843 * ImagehlpApiVersionEx (DBGHELP.@)
844 */
846{
847 if (!AppVersion) return NULL;
848
851 AppVersion->Revision = api_version.Revision;
852 AppVersion->Reserved = api_version.Reserved;
853
854 return AppVersion;
855}
856
857/******************************************************************
858 * ExtensionApiVersion (DBGHELP.@)
859 */
861{
862 static EXT_API_VERSION eav = {5, 5, 5, 0};
863 return &eav;
864}
865
866/******************************************************************
867 * WinDbgExtensionDllInit (DBGHELP.@)
868 */
870 unsigned short major, unsigned short minor)
871{
872}
873
875{
876 BYTE buffer[8192];
877 DWORD crc = 0;
878 DWORD len;
879
881 while (ReadFile(handle, buffer, sizeof(buffer), &len, NULL) && len)
882 crc = RtlComputeCrc32(crc, buffer, len);
883 return crc;
884}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
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
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
DECLSPEC_HIDDEN struct cpu cpu_arm
Definition: cpu_arm.c:258
DECLSPEC_HIDDEN struct cpu cpu_i386
Definition: cpu_i386.c:706
DECLSPEC_HIDDEN struct cpu cpu_x86_64
Definition: cpu_x86_64.c:962
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
LPAPI_VERSION WINAPI ImagehlpApiVersion(void)
Definition: dbghelp.c:837
static BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size)
BOOL elf_read_wine_loader_dbg_info(struct process *pcs, ULONG_PTR addr) DECLSPEC_HIDDEN
Definition: elf_module.c:1753
BOOL macho_read_wine_loader_dbg_info(struct process *pcs, ULONG_PTR addr) DECLSPEC_HIDDEN
BOOL module_remove(struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: module.c:889
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:40
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define FILE_BEGIN
Definition: compat.h:761
#define GetModuleFileNameExW(w, x, y, z)
Definition: compat.h:922
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
BOOL(CALLBACK * PSYMBOL_REGISTERED_CALLBACK)(HANDLE, ULONG, PVOID, PVOID)
Definition: compat.h:1227
#define wcsnicmp
Definition: compat.h:14
#define CBA_DUPLICATE_SYMBOL
Definition: compat.h:980
#define RtlComputeCrc32
Definition: compat.h:810
IMAGEHLP_EXTENDED_OPTIONS
Definition: compat.h:1102
@ SYMOPT_EX_WINE_NATIVE_MODULES
Definition: compat.h:1106
#define CP_ACP
Definition: compat.h:109
#define CBA_SYMBOLS_UNLOADED
Definition: compat.h:979
#define CBA_SET_OPTIONS
Definition: compat.h:983
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE
Definition: compat.h:977
@ AddrModeReal
Definition: compat.h:1158
@ AddrModeFlat
Definition: compat.h:1159
@ AddrMode1616
Definition: compat.h:1156
@ AddrMode1632
Definition: compat.h:1157
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define GetCurrentProcess()
Definition: compat.h:759
#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE
Definition: compat.h:978
#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL
Definition: compat.h:982
#define CBA_DEBUG_INFO
Definition: compat.h:986
#define IsWow64Process
Definition: compat.h:760
#define GetProcessId(x)
Definition: compat.h:737
BOOL(CALLBACK * PSYMBOL_REGISTERED_CALLBACK64)(HANDLE, ULONG, ULONG64, ULONG64)
Definition: compat.h:1182
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define SYMOPT_UNDNAME
Definition: compat.h:988
#define CBA_READ_MEMORY
Definition: compat.h:981
#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL
Definition: compat.h:985
#define CBA_EVENT
Definition: compat.h:984
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define CBA_DEFERRED_SYMBOL_LOAD_START
Definition: compat.h:976
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:754
#define MultiByteToWideChar
Definition: compat.h:110
DWORD64 WINAPI SymLoadModuleExW(HANDLE, HANDLE, PCWSTR, PCWSTR, DWORD64, DWORD, PMODLOAD_DATA, DWORD)
Definition: module.c:800
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI SymGetSearchPathW(HANDLE hProcess, PWSTR szSearchPath, DWORD SearchPathLength)
Definition: dbghelp.c:286
BOOL WINAPI SymSetContext(HANDLE hProcess, PIMAGEHLP_STACK_FRAME StackFrame, PIMAGEHLP_CONTEXT Context)
Definition: dbghelp.c:658
static struct process * process_first
Definition: dbghelp.c:79
LPAPI_VERSION WINAPI ImagehlpApiVersionEx(LPAPI_VERSION AppVersion)
Definition: dbghelp.c:845
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
Definition: dbghelp.c:82
DWORD calc_crc32(HANDLE handle)
Definition: dbghelp.c:874
BOOL WINAPI SymSetSearchPath(HANDLE hProcess, PCSTR searchPath)
Definition: dbghelp.c:263
const char * wine_dbgstr_addr(const ADDRESS64 *addr)
Definition: dbghelp.c:142
unsigned dbghelp_options
Definition: dbghelp.c:73
BOOL WINAPI SymCleanup(HANDLE hProcess)
Definition: dbghelp.c:557
BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:534
static BOOL CALLBACK reg_cb64to32(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 user)
Definition: dbghelp.c:687
static WCHAR * make_default_search_path(void)
Definition: dbghelp.c:194
LPEXT_API_VERSION WINAPI ExtensionApiVersion(void)
Definition: dbghelp.c:860
BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:464
struct cpu * cpu_find(DWORD machine)
Definition: dbghelp.c:183
BOOL WINAPI SymRegisterCallbackW64(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ULONG64 UserContext)
Definition: dbghelp.c:822
void WINAPI WinDbgExtensionDllInit(PWINDBG_EXTENSION_APIS lpExtensionApis, unsigned short major, unsigned short minor)
Definition: dbghelp.c:869
BOOL validate_addr64(DWORD64 addr)
Definition: dbghelp.c:112
SYSTEM_INFO sysinfo
Definition: dbghelp.c:76
DWORD WINAPI SymGetOptions(void)
Definition: dbghelp.c:600
BOOL WINAPI SymGetSearchPath(HANDLE hProcess, PSTR szSearchPath, DWORD SearchPathLength)
Definition: dbghelp.c:299
BOOL WINAPI SymRegisterCallback64(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ULONG64 UserContext)
Definition: dbghelp.c:810
BOOL WINAPI SymSetParentWindow(HWND hwnd)
Definition: dbghelp.c:647
BOOL pcs_callback(const struct process *pcs, ULONG action, void *data)
Definition: dbghelp.c:731
static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user)
Definition: dbghelp.c:323
static BOOL check_live_target(struct process *pcs)
Definition: dbghelp.c:356
struct cpu cpu_i386 cpu_x86_64 cpu_arm cpu_arm64
Definition: cpu_arm64.c:283
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
BOOL WINAPI SymGetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option)
Definition: dbghelp.c:630
static API_VERSION api_version
Definition: dbghelp.c:832
void * fetch_buffer(struct process *pcs, unsigned size)
Definition: dbghelp.c:128
BOOL WINAPI SymSetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option, BOOL value)
Definition: dbghelp.c:609
static struct cpu * dbghelp_cpus[]
Definition: dbghelp.c:164
BOOL dbghelp_opt_native
Definition: dbghelp.c:74
BOOL WINAPI SymRegisterCallback(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK CallbackFunction, PVOID UserContext)
Definition: dbghelp.c:798
static BOOL sym_register_cb(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 cb, PSYMBOL_REGISTERED_CALLBACK cb32, DWORD64 user, BOOL unicode)
Definition: dbghelp.c:779
DWORD WINAPI SymSetOptions(DWORD opts)
Definition: dbghelp.c:585
BOOL WINAPI SymSetSearchPathW(HANDLE hProcess, PCWSTR searchPath)
Definition: dbghelp.c:235
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
const WCHAR * process_getenv(const struct process *process, const WCHAR *name)
Definition: dbghelp.c:335
BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1112
const struct loader_ops no_loader_ops
Definition: module.c:1409
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
const WCHAR * action
Definition: action.c:7479
r reserved
Definition: btrfs.c:3006
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
@ ProcessBasicInformation
Definition: winternl.h:394
#define C_ASSERT(e)
Definition: intsafe.h:73
#define debugstr_w
Definition: kernel32.h:32
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned __int64 ULONG64
Definition: imports.h:198
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static const char machine[]
Definition: profile.c:104
static const WCHAR sp[]
Definition: suminfo.c:287
static BYTE data32[]
Definition: misc.c:535
#define DWORD
Definition: nt_native.h:44
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define L(x)
Definition: ntvdm.h:50
#define minor(rdev)
Definition: propsheet.cpp:929
#define major(rdev)
Definition: propsheet.cpp:928
static BOOL wow64
Definition: psapi_main.c:44
static unsigned __int64 next
Definition: rand_nt.c:6
#define TRACE(s)
Definition: solgame.cpp:4
USHORT MajorVersion
Definition: compat.h:1571
USHORT Revision
Definition: compat.h:1573
USHORT Reserved
Definition: compat.h:1574
USHORT MinorVersion
Definition: compat.h:1572
WCHAR FileName[MAX_PATH+1]
Definition: compat.h:1167
ULONG64 InstructionOffset
Definition: compat.h:1376
ULONG64 ReturnOffset
Definition: compat.h:1377
DWORD ProcessParameters
ULONG Reserved[2]
ULONG Reserved[2]
Definition: winternl.h:310
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
DWORD dwAllocationGranularity
Definition: winbase.h:1179
Definition: name.c:39
Definition: getopt.h:109
const struct loader_ops * loader
WCHAR * environment
IMAGEHLP_STACK_FRAME ctx_frame
HANDLE handle
PSYMBOL_REGISTERED_CALLBACK64 reg_cb
struct module * lmodules
ULONG_PTR dbg_hdr_addr
void * buffer
BOOL reg_is_unicode
unsigned buffer_size
PSYMBOL_REGISTERED_CALLBACK reg_cb32
struct process * next
DWORD64 reg_user
WCHAR * search_path
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
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t DWORD64
Definition: typedefs.h:67
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
int ret
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
_In_ PCALLBACK_FUNCTION CallbackFunction
Definition: exfuncs.h:1034
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193