ReactOS  0.4.15-dev-1201-gb2cf5a4
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 
79 static struct process* process_first /* = NULL */;
80 
81 #ifndef DBGHELP_STATIC_LIB
83 {
84  switch (reason)
85  {
86  case DLL_PROCESS_ATTACH:
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  */
128 void* 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
142 const 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 
161 extern struct cpu cpu_i386, cpu_x86_64, cpu_arm, cpu_arm64;
162 
163 #ifndef DBGHELP_STATIC_LIB
164 static struct cpu* dbghelp_cpus[] = {&cpu_i386, &cpu_x86_64, &cpu_arm, &cpu_arm64, NULL};
165 #else
166 static 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__)
173  &cpu_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 
194 /******************************************************************
195  * SymSetSearchPathW (DBGHELP.@)
196  *
197  */
199 {
200  struct process* pcs = process_find_by_handle(hProcess);
201 
202  if (!pcs) return FALSE;
203  if (!searchPath) return FALSE;
204 
205  HeapFree(GetProcessHeap(), 0, pcs->search_path);
207  (lstrlenW(searchPath) + 1) * sizeof(WCHAR)),
208  searchPath);
209  return TRUE;
210 }
211 
212 /******************************************************************
213  * SymSetSearchPath (DBGHELP.@)
214  *
215  */
217 {
218  BOOL ret = FALSE;
219  unsigned len;
220  WCHAR* sp;
221 
222  len = MultiByteToWideChar(CP_ACP, 0, searchPath, -1, NULL, 0);
223  if ((sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
224  {
225  MultiByteToWideChar(CP_ACP, 0, searchPath, -1, sp, len);
226 
228  HeapFree(GetProcessHeap(), 0, sp);
229  }
230  return ret;
231 }
232 
233 /***********************************************************************
234  * SymGetSearchPathW (DBGHELP.@)
235  */
237  DWORD SearchPathLength)
238 {
239  struct process* pcs = process_find_by_handle(hProcess);
240  if (!pcs) return FALSE;
241 
242  lstrcpynW(szSearchPath, pcs->search_path, SearchPathLength);
243  return TRUE;
244 }
245 
246 /***********************************************************************
247  * SymGetSearchPath (DBGHELP.@)
248  */
250  DWORD SearchPathLength)
251 {
252  WCHAR* buffer = HeapAlloc(GetProcessHeap(), 0, SearchPathLength * sizeof(WCHAR));
253  BOOL ret = FALSE;
254 
255  if (buffer)
256  {
257  ret = SymGetSearchPathW(hProcess, buffer, SearchPathLength);
258  if (ret)
259  WideCharToMultiByte(CP_ACP, 0, buffer, SearchPathLength,
260  szSearchPath, SearchPathLength, NULL, NULL);
262  }
263  return ret;
264 }
265 
266 #ifndef DBGHELP_STATIC_LIB
267 /******************************************************************
268  * invade_process
269  *
270  * SymInitialize helper: loads in dbghelp all known (and loaded modules)
271  * this assumes that hProcess is a handle on a valid process
272  */
274 {
275  WCHAR tmp[MAX_PATH];
276  HANDLE hProcess = user;
277 
279  lstrcpynW(tmp, name, ARRAY_SIZE(tmp));
280 
281  SymLoadModuleExW(hProcess, 0, tmp, name, base, size, NULL, 0);
282  return TRUE;
283 }
284 
285 const WCHAR *process_getenv(const struct process *process, const WCHAR *name)
286 {
287  size_t name_len;
288  const WCHAR *iter;
289 
290  if (!process->environment) return NULL;
291  name_len = lstrlenW(name);
292 
293  for (iter = process->environment; *iter; iter += lstrlenW(iter) + 1)
294  {
295  if (!wcsnicmp(iter, name, name_len) && iter[name_len] == '=')
296  return iter + name_len + 1;
297  }
298 
299  return NULL;
300 }
301 
302 /******************************************************************
303  * check_live_target
304  *
305  */
306 static BOOL check_live_target(struct process* pcs)
307 {
309  ULONG_PTR base = 0, env = 0;
310 
311  if (!GetProcessId(pcs->handle)) return FALSE;
312  if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE;
313 
315  &pbi, sizeof(pbi), NULL ))
316  return FALSE;
317 
318  if (!pcs->is_64bit)
319  {
320  DWORD env32;
321  PEB32 peb32;
322  C_ASSERT(sizeof(void*) != 4 || FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment) == 0x48);
323  if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb32, sizeof(peb32), NULL)) return FALSE;
324  base = peb32.Reserved[0];
325  if (read_process_memory(pcs, peb32.ProcessParameters + 0x48, &env32, sizeof(env32))) env = env32;
326  }
327  else
328  {
329  PEB peb;
330  if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb, sizeof(peb), NULL)) return FALSE;
331  base = peb.Reserved[0];
333  }
334 
335 #ifdef __REACTOS__
336  /* Wine store their loader base address in peb.reserved[0] and load its symbol from there.
337  * ReactOS does not care about it, we are just happy if we managed to read the value */
338  base = 1;
339 #endif
340 
341  /* read debuggee environment block */
342  if (env)
343  {
344  size_t buf_size = 0, i, last_null = -1;
345  WCHAR *buf = NULL;
346 
347  do
348  {
349  size_t read_size = sysinfo.dwAllocationGranularity - (env & (sysinfo.dwAllocationGranularity - 1));
350  if (buf)
351  {
352  WCHAR *new_buf;
353  if (!(new_buf = realloc(buf, buf_size + read_size))) break;
354  buf = new_buf;
355  }
356  else if(!(buf = malloc(read_size))) break;
357 
358  if (!read_process_memory(pcs, env, (char*)buf + buf_size, read_size)) break;
359  for (i = buf_size / sizeof(WCHAR); i < (buf_size + read_size) / sizeof(WCHAR); i++)
360  {
361  if (buf[i]) continue;
362  if (last_null + 1 == i)
363  {
364  pcs->environment = realloc(buf, (i + 1) * sizeof(WCHAR));
365  buf = NULL;
366  break;
367  }
368  last_null = i;
369  }
370  env += read_size;
371  buf_size += read_size;
372  }
373  while (buf);
374  free(buf);
375  }
376 
377  if (!base) return FALSE;
378 
379  TRACE("got debug info address %#lx from PEB %p\n", base, pbi.PebBaseAddress);
380 #ifndef __REACTOS__
382  WARN("couldn't load process debug info at %#lx\n", base);
383 #endif
384  return TRUE;
385 }
386 #endif
387 
388 /******************************************************************
389  * SymInitializeW (DBGHELP.@)
390  *
391  * The initialisation of a dbghelp's context.
392  * Note that hProcess doesn't need to be a valid process handle (except
393  * when fInvadeProcess is TRUE).
394  * Since we also allow loading ELF (pure) libraries and Wine ELF libraries
395  * containing PE (and NE) module(s), here's how we handle it:
396  * - we load every module (ELF, NE, PE) passed in SymLoadModule
397  * - in fInvadeProcess (in SymInitialize) is TRUE, we set up what is called ELF
398  * synchronization: hProcess should be a valid process handle, and we hook
399  * ourselves on hProcess's loaded ELF-modules, and keep this list in sync with
400  * our internal ELF modules representation (loading / unloading). This way,
401  * we'll pair every loaded builtin PE module with its ELF counterpart (and
402  * access its debug information).
403  * - if fInvadeProcess (in SymInitialize) is FALSE, we check anyway if the
404  * hProcess refers to a running process. We use some heuristics here, so YMMV.
405  * If we detect a live target, then we get the same handling as if
406  * fInvadeProcess is TRUE (except that the modules are not loaded). Otherwise,
407  * we won't be able to make the peering between a builtin PE module and its ELF
408  * counterpart. Hence we won't be able to provide the requested debug
409  * information. We'll however be able to load native PE modules (and their
410  * debug information) without any trouble.
411  * Note also that this scheme can be intertwined with the deferred loading
412  * mechanism (ie only load the debug information when we actually need it).
413  */
414 BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess)
415 {
416  struct process* pcs;
417  BOOL wow64, child_wow64;
418 
419  TRACE("(%p %s %u)\n", hProcess, debugstr_w(UserSearchPath), fInvadeProcess);
420 
422  {
423  WARN("the symbols for this process have already been initialized!\n");
424 
425  /* MSDN says to only call this function once unless SymCleanup() has been called since the last call.
426  It also says to call SymRefreshModuleList() instead if you just want the module list refreshed.
427  Native still returns TRUE even if the process has already been initialized. */
428  return TRUE;
429  }
430 
432 
433  if (GetProcessId(hProcess) && !IsWow64Process(hProcess, &child_wow64))
434  return FALSE;
435 
436  pcs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pcs));
437  if (!pcs) return FALSE;
438 
439  pcs->handle = hProcess;
440  pcs->is_64bit = (sizeof(void *) == 8 || wow64) && !child_wow64;
441  pcs->loader = &no_loader_ops; /* platform-specific initialization will override it if loader debug info can be found */
442 
443  if (UserSearchPath)
444  {
446  (lstrlenW(UserSearchPath) + 1) * sizeof(WCHAR)),
447  UserSearchPath);
448  }
449  else
450  {
451  unsigned size;
452  unsigned len;
453  static const WCHAR sym_path[] = {'_','N','T','_','S','Y','M','B','O','L','_','P','A','T','H',0};
454  static const WCHAR alt_sym_path[] = {'_','N','T','_','A','L','T','E','R','N','A','T','E','_','S','Y','M','B','O','L','_','P','A','T','H',0};
455 
456  pcs->search_path = HeapAlloc(GetProcessHeap(), 0, (len = MAX_PATH) * sizeof(WCHAR));
457  while ((size = GetCurrentDirectoryW(len, pcs->search_path)) >= len)
458  pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (len *= 2) * sizeof(WCHAR));
459  pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1) * sizeof(WCHAR));
460 
461  len = GetEnvironmentVariableW(sym_path, NULL, 0);
462  if (len)
463  {
464  pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1 + len + 1) * sizeof(WCHAR));
465  pcs->search_path[size] = ';';
466  GetEnvironmentVariableW(sym_path, pcs->search_path + size + 1, len);
467  size += 1 + len;
468  }
469  len = GetEnvironmentVariableW(alt_sym_path, NULL, 0);
470  if (len)
471  {
472  pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1 + len + 1) * sizeof(WCHAR));
473  pcs->search_path[size] = ';';
474  GetEnvironmentVariableW(alt_sym_path, pcs->search_path + size + 1, len);
475  }
476  }
477 
478  pcs->lmodules = NULL;
479  pcs->dbg_hdr_addr = 0;
480  pcs->next = process_first;
481  process_first = pcs;
482 
483 #ifndef DBGHELP_STATIC_LIB
484  if (check_live_target(pcs))
485  {
486  if (fInvadeProcess)
488  if (pcs->loader) pcs->loader->synchronize_module_list(pcs);
489  }
490  else if (fInvadeProcess)
491 #else
492  if (fInvadeProcess)
493 #endif
494  {
497  return FALSE;
498  }
499 
500  return TRUE;
501 }
502 
503 /******************************************************************
504  * SymInitialize (DBGHELP.@)
505  *
506  *
507  */
508 BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
509 {
510  WCHAR* sp = NULL;
511  BOOL ret;
512 
513  if (UserSearchPath)
514  {
515  unsigned len;
516 
517  len = MultiByteToWideChar(CP_ACP, 0, UserSearchPath, -1, NULL, 0);
518  sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
519  MultiByteToWideChar(CP_ACP, 0, UserSearchPath, -1, sp, len);
520  }
521 
522  ret = SymInitializeW(hProcess, sp, fInvadeProcess);
523  HeapFree(GetProcessHeap(), 0, sp);
524  return ret;
525 }
526 
527 /******************************************************************
528  * SymCleanup (DBGHELP.@)
529  *
530  */
532 {
533  struct process** ppcs;
534  struct process* next;
535 
536  for (ppcs = &process_first; *ppcs; ppcs = &(*ppcs)->next)
537  {
538  if ((*ppcs)->handle == hProcess)
539  {
540  while ((*ppcs)->lmodules) module_remove(*ppcs, (*ppcs)->lmodules);
541 
542  HeapFree(GetProcessHeap(), 0, (*ppcs)->search_path);
543  free((*ppcs)->environment);
544  next = (*ppcs)->next;
545  HeapFree(GetProcessHeap(), 0, *ppcs);
546  *ppcs = next;
547  return TRUE;
548  }
549  }
550 
551  ERR("this process has not had SymInitialize() called for it!\n");
552  return FALSE;
553 }
554 
555 /******************************************************************
556  * SymSetOptions (DBGHELP.@)
557  *
558  */
560 {
561  struct process* pcs;
562 
563  for (pcs = process_first; pcs; pcs = pcs->next)
564  {
565  pcs_callback(pcs, CBA_SET_OPTIONS, &opts);
566  }
567  return dbghelp_options = opts;
568 }
569 
570 /******************************************************************
571  * SymGetOptions (DBGHELP.@)
572  *
573  */
575 {
576  return dbghelp_options;
577 }
578 
579 /******************************************************************
580  * SymSetExtendedOption (DBGHELP.@)
581  *
582  */
584 {
585  BOOL old = FALSE;
586 
587  switch(option)
588  {
590  old = dbghelp_opt_native;
592  break;
593  default:
594  FIXME("Unsupported option %d with value %d\n", option, value);
595  }
596 
597  return old;
598 }
599 
600 /******************************************************************
601  * SymGetExtendedOption (DBGHELP.@)
602  *
603  */
605 {
606  switch(option)
607  {
609  return dbghelp_opt_native;
610  default:
611  FIXME("Unsupported option %d\n", option);
612  }
613 
614  return FALSE;
615 }
616 
617 /******************************************************************
618  * SymSetParentWindow (DBGHELP.@)
619  *
620  */
622 {
623  /* Save hwnd so it can be used as parent window */
624  FIXME("(%p): stub\n", hwnd);
625  return TRUE;
626 }
627 
628 /******************************************************************
629  * SymSetContext (DBGHELP.@)
630  *
631  */
634 {
635  struct process* pcs = process_find_by_handle(hProcess);
636  if (!pcs) return FALSE;
637 
638  if (pcs->ctx_frame.ReturnOffset == StackFrame->ReturnOffset &&
639  pcs->ctx_frame.FrameOffset == StackFrame->FrameOffset &&
640  pcs->ctx_frame.StackOffset == StackFrame->StackOffset)
641  {
642  TRACE("Setting same frame {rtn=%s frm=%s stk=%s}\n",
646  pcs->ctx_frame.InstructionOffset = StackFrame->InstructionOffset;
647  SetLastError(ERROR_ACCESS_DENIED); /* latest MSDN says ERROR_SUCCESS */
648  return FALSE;
649  }
650 
651  pcs->ctx_frame = *StackFrame;
652  /* MSDN states that Context is not (no longer?) used */
653  return TRUE;
654 }
655 
656 /******************************************************************
657  * reg_cb64to32 (internal)
658  *
659  * Registered callback for converting information from 64 bit to 32 bit
660  */
662 {
663  struct process* pcs = process_find_by_handle(hProcess);
664  void* data32;
667 
668  if (!pcs) return FALSE;
669  switch (action)
670  {
671  case CBA_DEBUG_INFO:
673  case CBA_SET_OPTIONS:
675  data32 = (void*)(DWORD_PTR)data;
676  break;
682  if (!validate_addr64(idsl64->BaseOfImage))
683  return FALSE;
684  idsl.SizeOfStruct = sizeof(idsl);
685  idsl.BaseOfImage = (DWORD)idsl64->BaseOfImage;
686  idsl.CheckSum = idsl64->CheckSum;
687  idsl.TimeDateStamp = idsl64->TimeDateStamp;
688  memcpy(idsl.FileName, idsl64->FileName, sizeof(idsl.FileName));
689  idsl.Reparse = idsl64->Reparse;
690  data32 = &idsl;
691  break;
693  case CBA_EVENT:
694  case CBA_READ_MEMORY:
695  default:
696  FIXME("No mapping for action %u\n", action);
697  return FALSE;
698  }
699  return pcs->reg_cb32(hProcess, action, data32, (PVOID)(DWORD_PTR)user);
700 }
701 
702 /******************************************************************
703  * pcs_callback (internal)
704  */
705 BOOL pcs_callback(const struct process* pcs, ULONG action, void* data)
706 {
708 
709  TRACE("%p %u %p\n", pcs, action, data);
710 
711  if (!pcs->reg_cb) return FALSE;
712  if (!pcs->reg_is_unicode)
713  {
715 
716  switch (action)
717  {
718  case CBA_DEBUG_INFO:
720  case CBA_SET_OPTIONS:
722  break;
727  idslW = data;
728  idsl.SizeOfStruct = sizeof(idsl);
729  idsl.BaseOfImage = idslW->BaseOfImage;
730  idsl.CheckSum = idslW->CheckSum;
731  idsl.TimeDateStamp = idslW->TimeDateStamp;
732  WideCharToMultiByte(CP_ACP, 0, idslW->FileName, -1,
733  idsl.FileName, sizeof(idsl.FileName), NULL, NULL);
734  idsl.Reparse = idslW->Reparse;
735  data = &idsl;
736  break;
738  case CBA_EVENT:
739  case CBA_READ_MEMORY:
740  default:
741  FIXME("No mapping for action %u\n", action);
742  return FALSE;
743  }
744  }
745  return pcs->reg_cb(pcs->handle, action, (ULONG64)(DWORD_PTR)data, pcs->reg_user);
746 }
747 
748 /******************************************************************
749  * sym_register_cb
750  *
751  * Helper for registering a callback.
752  */
756  DWORD64 user, BOOL unicode)
757 {
758  struct process* pcs = process_find_by_handle(hProcess);
759 
760  if (!pcs) return FALSE;
761  pcs->reg_cb = cb;
762  pcs->reg_cb32 = cb32;
763  pcs->reg_is_unicode = unicode;
764  pcs->reg_user = user;
765 
766  return TRUE;
767 }
768 
769 /***********************************************************************
770  * SymRegisterCallback (DBGHELP.@)
771  */
774  PVOID UserContext)
775 {
776  TRACE("(%p, %p, %p)\n",
777  hProcess, CallbackFunction, UserContext);
779 }
780 
781 /***********************************************************************
782  * SymRegisterCallback64 (DBGHELP.@)
783  */
786  ULONG64 UserContext)
787 {
788  TRACE("(%p, %p, %s)\n",
790  return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, FALSE);
791 }
792 
793 /***********************************************************************
794  * SymRegisterCallbackW64 (DBGHELP.@)
795  */
798  ULONG64 UserContext)
799 {
800  TRACE("(%p, %p, %s)\n",
802  return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, TRUE);
803 }
804 
805 /* This is imagehlp version not dbghelp !! */
806 static API_VERSION api_version = { 4, 0, 2, 0 };
807 
808 /***********************************************************************
809  * ImagehlpApiVersion (DBGHELP.@)
810  */
812 {
813  return &api_version;
814 }
815 
816 /***********************************************************************
817  * ImagehlpApiVersionEx (DBGHELP.@)
818  */
820 {
821  if (!AppVersion) return NULL;
822 
823  AppVersion->MajorVersion = api_version.MajorVersion;
824  AppVersion->MinorVersion = api_version.MinorVersion;
825  AppVersion->Revision = api_version.Revision;
826  AppVersion->Reserved = api_version.Reserved;
827 
828  return AppVersion;
829 }
830 
831 /******************************************************************
832  * ExtensionApiVersion (DBGHELP.@)
833  */
835 {
836  static EXT_API_VERSION eav = {5, 5, 5, 0};
837  return &eav;
838 }
839 
840 /******************************************************************
841  * WinDbgExtensionDllInit (DBGHELP.@)
842  */
844  unsigned short major, unsigned short minor)
845 {
846 }
847 
849 {
850  BYTE buffer[8192];
851  DWORD crc = 0;
852  DWORD len;
853 
855  while (ReadFile(handle, buffer, sizeof(buffer), &len, NULL) && len)
856  crc = RtlComputeCrc32(crc, buffer, len);
857  return crc;
858 }
#define realloc
Definition: debug_ros.c:6
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
BOOL WINAPI SymGetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option)
Definition: dbghelp.c:604
const uint16_t * PCWSTR
Definition: typedefs.h:57
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:45
BOOL pcs_callback(const struct process *pcs, ULONG action, void *data)
Definition: dbghelp.c:705
WCHAR * search_path
DWORD64 WINAPI SymLoadModuleExW(HANDLE, HANDLE, PCWSTR, PCWSTR, DWORD64, DWORD, PMODLOAD_DATA, DWORD)
Definition: module.c:796
#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE
Definition: compat.h:836
#define WideCharToMultiByte
Definition: compat.h:111
USHORT MajorVersion
Definition: compat.h:1430
DECLSPEC_HIDDEN struct cpu cpu_arm
Definition: cpu_arm.c:258
DWORD dwAllocationGranularity
Definition: winbase.h:1145
IMAGEHLP_EXTENDED_OPTIONS
Definition: compat.h:960
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
#define CP_ACP
Definition: compat.h:109
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
#define free
Definition: debug_ros.c:5
#define WARN(fmt,...)
Definition: debug.h:112
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
BOOL dbghelp_opt_native
Definition: dbghelp.c:74
USHORT MinorVersion
Definition: compat.h:1431
LPAPI_VERSION WINAPI ImagehlpApiVersionEx(LPAPI_VERSION AppVersion)
Definition: dbghelp.c:819
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:615
#define CALLBACK
Definition: compat.h:35
DWORD WINAPI SymSetOptions(DWORD opts)
Definition: dbghelp.c:559
BOOL validate_addr64(DWORD64 addr)
Definition: dbghelp.c:112
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
GLuint buffer
Definition: glext.h:5915
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
unsigned buffer_size
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:617
static API_VERSION api_version
Definition: dbghelp.c:806
static BOOL sym_register_cb(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 cb, PSYMBOL_REGISTERED_CALLBACK cb32, DWORD64 user, BOOL unicode)
Definition: dbghelp.c:753
#define FILE_BEGIN
Definition: compat.h:620
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1959
struct cpu * cpu_find(DWORD machine)
Definition: dbghelp.c:183
#define CBA_EVENT
Definition: compat.h:843
#define lstrlenW
Definition: compat.h:609
#define DWORD
Definition: nt_native.h:44
_In_ PCALLBACK_FUNCTION CallbackFunction
Definition: exfuncs.h:1034
IMAGEHLP_STACK_FRAME ctx_frame
#define lstrcpynW
Definition: compat.h:597
WCHAR FileName[MAX_PATH+1]
Definition: compat.h:1026
LPEXT_API_VERSION WINAPI ExtensionApiVersion(void)
Definition: dbghelp.c:834
uint32_t ULONG_PTR
Definition: typedefs.h:65
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
static BOOL wow64
Definition: psapi_main.c:44
#define CBA_READ_MEMORY
Definition: compat.h:840
USHORT Revision
Definition: compat.h:1432
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
struct module * lmodules
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
ULONG_PTR dbg_hdr_addr
static BOOL check_live_target(struct process *pcs)
Definition: dbghelp.c:306
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI SymCleanup(HANDLE hProcess)
Definition: dbghelp.c:531
#define debugstr_w
Definition: kernel32.h:32
struct cpu cpu_i386 cpu_x86_64 cpu_arm cpu_arm64
Definition: cpu_arm64.c:283
#define FIXME(fmt,...)
Definition: debug.h:111
WCHAR * environment
r reserved
Definition: btrfs.c:2940
void WINAPI WinDbgExtensionDllInit(PWINDBG_EXTENSION_APIS lpExtensionApis, unsigned short major, unsigned short minor)
Definition: dbghelp.c:843
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
Definition: dbghelp.c:82
#define GetModuleFileNameExW(w, x, y, z)
Definition: compat.h:781
smooth NULL
Definition: ftsmooth.c:416
Definition: getopt.h:108
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
const char * wine_dbgstr_addr(const ADDRESS64 *addr)
Definition: dbghelp.c:142
PSYMBOL_REGISTERED_CALLBACK reg_cb32
#define C_ASSERT(e)
Definition: intsafe.h:71
#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE
Definition: compat.h:837
#define CBA_SYMBOLS_UNLOADED
Definition: compat.h:838
DWORD64 reg_user
BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1108
void * fetch_buffer(struct process *pcs, unsigned size)
Definition: dbghelp.c:128
BOOL WINAPI IsWow64Process(IN HANDLE hProcess, OUT PBOOL Wow64Process)
Definition: proc.c:1976
BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:508
#define TRACE(s)
Definition: solgame.cpp:4
const WCHAR * process_getenv(const struct process *process, const WCHAR *name)
Definition: dbghelp.c:285
GLsizeiptr size
Definition: glext.h:5919
PSYMBOL_REGISTERED_CALLBACK64 reg_cb
#define CBA_DEBUG_INFO
Definition: compat.h:845
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:613
static struct process * process_first
Definition: dbghelp.c:79
__wchar_t WCHAR
Definition: xmlstorage.h:180
const struct loader_ops * loader
BOOL WINAPI SymSetSearchPath(HANDLE hProcess, PCSTR searchPath)
Definition: dbghelp.c:216
SYSTEM_INFO sysinfo
Definition: dbghelp.c:76
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
void * buffer
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI SymSetSearchPathW(HANDLE hProcess, PCWSTR searchPath)
Definition: dbghelp.c:198
#define SetLastError(x)
Definition: compat.h:611
BOOL WINAPI SymGetSearchPathW(HANDLE hProcess, PWSTR szSearchPath, DWORD SearchPathLength)
Definition: dbghelp.c:236
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user)
Definition: dbghelp.c:273
#define SYMOPT_UNDNAME
Definition: compat.h:847
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
unsigned __int64 ULONG64
Definition: imports.h:198
ULONG Reserved[2]
ULONG64 InstructionOffset
Definition: compat.h:1235
int ret
#define wcsnicmp
Definition: compat.h:14
GLenum const GLvoid * addr
Definition: glext.h:9621
BOOL WINAPI SymSetParentWindow(HWND hwnd)
Definition: dbghelp.c:621
DECLSPEC_HIDDEN struct cpu cpu_i386
Definition: cpu_i386.c:706
#define CBA_DUPLICATE_SYMBOL
Definition: compat.h:839
static const char machine[]
Definition: profile.c:104
BOOL WINAPI SymRegisterCallback(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK CallbackFunction, PVOID UserContext)
Definition: dbghelp.c:772
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static struct cpu * dbghelp_cpus[]
Definition: dbghelp.c:164
GLenum GLsizei len
Definition: glext.h:6722
#define GetCurrentProcess()
Definition: compat.h:618
ULONG Reserved[2]
Definition: winternl.h:310
static BOOL CALLBACK reg_cb64to32(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 user)
Definition: dbghelp.c:661
uint32_t DWORD_PTR
Definition: typedefs.h:65
GLsizei const GLfloat * value
Definition: glext.h:6069
unsigned char BYTE
Definition: xxhash.c:193
const struct loader_ops no_loader_ops
Definition: module.c:1405
BOOL WINAPI SymRegisterCallback64(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ULONG64 UserContext)
Definition: dbghelp.c:784
#define RtlComputeCrc32
Definition: compat.h:669
#define ERR(fmt,...)
Definition: debug.h:110
USHORT Reserved
Definition: compat.h:1433
#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL
Definition: compat.h:844
static unsigned __int64 next
Definition: rand_nt.c:6
const WCHAR * action
Definition: action.c:7783
struct process * next
uint64_t DWORD64
Definition: typedefs.h:67
#define lstrcpyW
Definition: compat.h:608
#define ARRAY_SIZE(a)
Definition: main.h:24
BOOL(CALLBACK * PSYMBOL_REGISTERED_CALLBACK64)(HANDLE, ULONG, ULONG64, ULONG64)
Definition: compat.h:1041
DWORD WINAPI SymGetOptions(void)
Definition: dbghelp.c:574
#define major(rdev)
Definition: propsheet.cpp:916
BOOL(CALLBACK * PSYMBOL_REGISTERED_CALLBACK)(HANDLE, ULONG, PVOID, PVOID)
Definition: compat.h:1086
#define HeapReAlloc
Definition: compat.h:593
static HINSTANCE instance
Definition: main.c:40
signed char * PSTR
Definition: retypes.h:7
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:142
static BYTE data32[]
Definition: misc.c:535
#define ReadFile(a, b, c, d, e)
Definition: compat.h:601
DWORD calc_crc32(HANDLE handle)
Definition: dbghelp.c:848
#define CBA_DEFERRED_SYMBOL_LOAD_START
Definition: compat.h:835
unsigned dbghelp_options
Definition: dbghelp.c:73
BOOL module_remove(struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: module.c:885
#define CBA_SET_OPTIONS
Definition: compat.h:842
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:168
#define MultiByteToWideChar
Definition: compat.h:110
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
BOOL WINAPI SymSetContext(HANDLE hProcess, PIMAGEHLP_STACK_FRAME StackFrame, PIMAGEHLP_CONTEXT Context)
Definition: dbghelp.c:632
Definition: name.c:38
unsigned int ULONG
Definition: retypes.h:1
HANDLE handle
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define minor(rdev)
Definition: propsheet.cpp:917
static const WCHAR sp[]
Definition: suminfo.c:288
BOOL macho_read_wine_loader_dbg_info(struct process *pcs, ULONG_PTR addr) DECLSPEC_HIDDEN
#define malloc
Definition: debug_ros.c:4
const char * PCSTR
Definition: typedefs.h:52
#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL
Definition: compat.h:841
BOOL WINAPI SymSetExtendedOption(IMAGEHLP_EXTENDED_OPTIONS option, BOOL value)
Definition: dbghelp.c:583
GLfloat GLfloat p
Definition: glext.h:8902
ULONG64 ReturnOffset
Definition: compat.h:1236
DECLSPEC_HIDDEN struct cpu cpu_x86_64
Definition: cpu_x86_64.c:962
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:614
BOOL WINAPI SymGetSearchPath(HANDLE hProcess, PSTR szSearchPath, DWORD SearchPathLength)
Definition: dbghelp.c:249
BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:414
DWORD ProcessParameters
DWORD WINAPI GetProcessId(IN HANDLE Process)
Definition: proc.c:1200
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
static BOOL read_process_memory(const struct process *process, UINT64 addr, void *buf, size_t size)
void user(int argc, const char *argv[])
Definition: cmds.c:1350
BOOL reg_is_unicode
#define HeapFree(x, y, z)
Definition: compat.h:594
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
#define SetFilePointer
Definition: compat.h:602
BOOL WINAPI SymRegisterCallbackW64(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ULONG64 UserContext)
Definition: dbghelp.c:796
LPAPI_VERSION WINAPI ImagehlpApiVersion(VOID)
Definition: dbghelp.c:811
BOOL elf_read_wine_loader_dbg_info(struct process *pcs, ULONG_PTR addr) DECLSPEC_HIDDEN
Definition: elf_module.c:1753