ReactOS  0.4.15-dev-3193-g74513a7
module.c
Go to the documentation of this file.
1 /*
2  * File module.c - module handling for the wine debugger
3  *
4  * Copyright (C) 1993, Eric Youngdale.
5  * 2000-2007, 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 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <assert.h>
26 
27 #include "dbghelp_private.h"
28 #include "image_private.h"
29 #ifndef DBGHELP_STATIC_LIB
30 #include "psapi.h"
31 #include "winternl.h"
32 #include "wine/debug.h"
33 #include "wine/heap.h"
34 #endif
35 
37 
38 #define NOTE_GNU_BUILD_ID 3
39 
40 const WCHAR S_ElfW[] = {'<','e','l','f','>','\0'};
41 #ifndef __REACTOS__
42 const WCHAR S_WineLoaderW[] = {'<','w','i','n','e','-','l','o','a','d','e','r','>','\0'};
43 #endif
44 static const WCHAR S_DotSoW[] = {'.','s','o','\0'};
45 const WCHAR S_SlashW[] = {'/','\0'};
46 
47 static const WCHAR S_AcmW[] = {'.','a','c','m','\0'};
48 static const WCHAR S_DllW[] = {'.','d','l','l','\0'};
49 static const WCHAR S_DrvW[] = {'.','d','r','v','\0'};
50 static const WCHAR S_ExeW[] = {'.','e','x','e','\0'};
51 static const WCHAR S_OcxW[] = {'.','o','c','x','\0'};
52 static const WCHAR S_VxdW[] = {'.','v','x','d','\0'};
53 static const WCHAR * const ext[] = {S_AcmW, S_DllW, S_DrvW, S_ExeW, S_OcxW, S_VxdW, NULL};
54 
55 static int match_ext(const WCHAR* ptr, size_t len)
56 {
57  const WCHAR* const *e;
58  size_t l;
59 
60  for (e = ext; *e; e++)
61  {
62  l = lstrlenW(*e);
63  if (l >= len) return 0;
64  if (wcsnicmp(&ptr[len - l], *e, l)) continue;
65  return l;
66  }
67  return 0;
68 }
69 
70 static const WCHAR* get_filename(const WCHAR* name, const WCHAR* endptr)
71 {
72  const WCHAR* ptr;
73 
74  if (!endptr) endptr = name + lstrlenW(name);
75  for (ptr = endptr - 1; ptr >= name; ptr--)
76  {
77  if (*ptr == '/' || *ptr == '\\') break;
78  }
79  return ++ptr;
80 }
81 
82 #ifndef __REACTOS__
84 {
85  static const WCHAR wineW[] = {'w','i','n','e',0};
86  static const WCHAR suffixW[] = {'6','4',0};
88  const char *ptr;
89  BOOL ret = FALSE;
90  WCHAR *buffer;
91  DWORD len;
92 
93  if ((ptr = getenv("WINELOADER")))
94  {
95  ptr = file_nameA(ptr);
96  len = 2 + MultiByteToWideChar( CP_UNIXCP, 0, ptr, -1, NULL, 0 );
97  buffer = heap_alloc( len * sizeof(WCHAR) );
99  }
100  else
101  {
102  buffer = heap_alloc( sizeof(wineW) + 2 * sizeof(WCHAR) );
103  lstrcpyW( buffer, wineW );
104  }
105 
106  if (!wcscmp( filename, buffer ))
107  ret = TRUE;
108 
109  lstrcatW( buffer, suffixW );
110  if (!wcscmp( filename, buffer ))
111  ret = TRUE;
112 
113  heap_free( buffer );
114  return ret;
115 }
116 #endif
117 
118 static void module_fill_module(const WCHAR* in, WCHAR* out, size_t size)
119 {
120  const WCHAR *ptr, *endptr;
121  size_t len, l;
122 
123  ptr = get_filename(in, endptr = in + lstrlenW(in));
124  len = min(endptr - ptr, size - 1);
125  memcpy(out, ptr, len * sizeof(WCHAR));
126  out[len] = '\0';
127  if (len > 4 && (l = match_ext(out, len)))
128  out[len - l] = '\0';
129 #ifndef __REACTOS__
130  else if (is_wine_loader(out))
132 #endif
133  else
134  {
135  if (len > 3 && !wcsicmp(&out[len - 3], S_DotSoW) &&
136  (l = match_ext(out, len - 3)))
137  lstrcpyW(&out[len - l - 3], S_ElfW);
138  }
139  while ((*out = towlower(*out))) out++;
140 }
141 
142 void module_set_module(struct module* module, const WCHAR* name)
143 {
146 }
147 
148 #ifndef __REACTOS__
149 /* Returned string must be freed by caller */
151 {
152  static const WCHAR wineW[] = {'w','i','n','e',0};
153  static const WCHAR suffixW[] = {'6','4',0};
154  WCHAR *buffer, *p;
155  const char *env;
156 
157  /* All binaries are loaded with WINELOADER (if run from tree) or by the
158  * main executable
159  */
160  if ((env = getenv("WINELOADER")))
161  {
162  DWORD len = 2 + MultiByteToWideChar( CP_UNIXCP, 0, env, -1, NULL, 0 );
163  buffer = heap_alloc( len * sizeof(WCHAR) );
165  }
166  else
167  {
168  buffer = heap_alloc( sizeof(wineW) + 2 * sizeof(WCHAR) );
169  lstrcpyW( buffer, wineW );
170  }
171 
172  p = buffer + lstrlenW( buffer ) - lstrlenW( suffixW );
173  if (p > buffer && !wcscmp( p, suffixW ))
174  *p = 0;
175 
176  if (pcs->is_64bit)
177  lstrcatW(buffer, suffixW);
178 
179  TRACE( "returning %s\n", debugstr_w(buffer) );
180  return buffer;
181 }
182 #endif
183 
184 static const char* get_module_type(enum module_type type, BOOL virtual)
185 {
186  switch (type)
187  {
188  case DMT_ELF: return virtual ? "Virtual ELF" : "ELF";
189  case DMT_PE: return virtual ? "Virtual PE" : "PE";
190  case DMT_MACHO: return virtual ? "Virtual Mach-O" : "Mach-O";
191  default: return "---";
192  }
193 }
194 
195 /***********************************************************************
196  * Creates and links a new module to a process
197  */
198 struct module* module_new(struct process* pcs, const WCHAR* name,
199  enum module_type type, BOOL virtual,
200  DWORD64 mod_addr, DWORD64 size,
202 {
203  struct module* module;
204  unsigned i;
205 
206  assert(type == DMT_ELF || type == DMT_PE || type == DMT_MACHO);
207  if (!(module = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*module))))
208  return NULL;
209 
210  module->next = pcs->lmodules;
211  pcs->lmodules = module;
212 
213  TRACE("=> %s %s-%s %s\n",
214  get_module_type(type, virtual),
215  wine_dbgstr_longlong(mod_addr), wine_dbgstr_longlong(mod_addr + size),
216  debugstr_w(name));
217 
218  pool_init(&module->pool, 65536);
219 
220  module->process = pcs;
221  module->module.SizeOfStruct = sizeof(module->module);
222  module->module.BaseOfImage = mod_addr;
225  module->module.ImageName[0] = '\0';
228  module->module.NumSyms = 0;
229  module->module.TimeDateStamp = stamp;
231 
233  module->module.CVSig = 0;
234  memset(module->module.CVData, 0, sizeof(module->module.CVData));
235  module->module.PdbSig = 0;
237  module->module.PdbAge = 0;
245 
246  module->reloc_delta = 0;
247  module->type = type;
248  module->is_virtual = virtual;
249  for (i = 0; i < DFI_LAST; i++) module->format_info[i] = NULL;
251  module->sorttab_size = 0;
253  module->num_sorttab = 0;
254  module->num_symbols = 0;
255 
256  vector_init(&module->vsymt, sizeof(struct symt*), 128);
257  /* FIXME: this seems a bit too high (on a per module basis)
258  * need some statistics about this
259  */
262 #ifdef __x86_64__
263  hash_table_init(&module->pool, &module->ht_symaddr, 4096);
264 #endif
265  vector_init(&module->vtypes, sizeof(struct symt*), 32);
266 
267  module->sources_used = 0;
268  module->sources_alloc = 0;
269  module->sources = 0;
271 
272  return module;
273 }
274 
275 /***********************************************************************
276  * module_find_by_nameW
277  *
278  */
279 struct module* module_find_by_nameW(const struct process* pcs, const WCHAR* name)
280 {
281  struct module* module;
282 
283  for (module = pcs->lmodules; module; module = module->next)
284  {
285  if (!wcsicmp(name, module->module.ModuleName)) return module;
286  }
288  return NULL;
289 }
290 
291 struct module* module_find_by_nameA(const struct process* pcs, const char* name)
292 {
293  WCHAR wname[MAX_PATH];
294 
295  MultiByteToWideChar(CP_ACP, 0, name, -1, wname, ARRAY_SIZE(wname));
296  return module_find_by_nameW(pcs, wname);
297 }
298 
299 /***********************************************************************
300  * module_is_already_loaded
301  *
302  */
303 struct module* module_is_already_loaded(const struct process* pcs, const WCHAR* name)
304 {
305  struct module* module;
306  const WCHAR* filename;
307 
308  /* first compare the loaded image name... */
309  for (module = pcs->lmodules; module; module = module->next)
310  {
312  return module;
313  }
314  /* then compare the standard filenames (without the path) ... */
316  for (module = pcs->lmodules; module; module = module->next)
317  {
319  return module;
320  }
322  return NULL;
323 }
324 
325 /***********************************************************************
326  * module_get_container
327  *
328  */
329 static struct module* module_get_container(const struct process* pcs,
330  const struct module* inner)
331 {
332  struct module* module;
333 
334  for (module = pcs->lmodules; module; module = module->next)
335  {
336  if (module != inner &&
339  inner->module.BaseOfImage + inner->module.ImageSize)
340  return module;
341  }
342  return NULL;
343 }
344 
345 /***********************************************************************
346  * module_get_containee
347  *
348  */
349 struct module* module_get_containee(const struct process* pcs, const struct module* outer)
350 {
351  struct module* module;
352 
353  for (module = pcs->lmodules; module; module = module->next)
354  {
355  if (module != outer &&
357  outer->module.BaseOfImage + outer->module.ImageSize >=
359  return module;
360  }
361  return NULL;
362 }
363 
364 /******************************************************************
365  * module_get_debug
366  *
367  * get the debug information from a module:
368  * - if the module's type is deferred, then force loading of debug info (and return
369  * the module itself)
370  * - if the module has no debug info and has an ELF container, then return the ELF
371  * container (and also force the ELF container's debug info loading if deferred)
372  * - otherwise return the module itself if it has some debug info
373  */
375 {
377 
378  if (!pair->requested) return FALSE;
379  /* for a PE builtin, always get info from container */
380  if (!(pair->effective = module_get_container(pair->pcs, pair->requested)))
381  pair->effective = pair->requested;
382  /* if deferred, force loading */
383  if (pair->effective->module.SymType == SymDeferred)
384  {
385  BOOL ret;
386 
387  if (pair->effective->is_virtual) ret = FALSE;
388  else if (pair->effective->type == DMT_PE)
389  {
390  idslW64.SizeOfStruct = sizeof(idslW64);
391  idslW64.BaseOfImage = pair->effective->module.BaseOfImage;
392  idslW64.CheckSum = pair->effective->module.CheckSum;
393  idslW64.TimeDateStamp = pair->effective->module.TimeDateStamp;
394  memcpy(idslW64.FileName, pair->effective->module.ImageName,
395  sizeof(pair->effective->module.ImageName));
396  idslW64.Reparse = FALSE;
397  idslW64.hFile = INVALID_HANDLE_VALUE;
398 
400  ret = pe_load_debug_info(pair->pcs, pair->effective);
401  pcs_callback(pair->pcs,
403  &idslW64);
404  }
405  else ret = pair->pcs->loader->load_debug_info(pair->pcs, pair->effective);
406 
407  if (!ret) pair->effective->module.SymType = SymNone;
408  assert(pair->effective->module.SymType != SymDeferred);
409  pair->effective->module.NumSyms = pair->effective->ht_symbols.num_elts;
410  }
411  return pair->effective->module.SymType != SymNone;
412 }
413 
414 /***********************************************************************
415  * module_find_by_addr
416  *
417  * either the addr where module is loaded, or any address inside the
418  * module
419  */
420 struct module* module_find_by_addr(const struct process* pcs, DWORD64 addr,
421  enum module_type type)
422 {
423  struct module* module;
424 
425  if (type == DMT_UNKNOWN)
426  {
427  if ((module = module_find_by_addr(pcs, addr, DMT_PE)) ||
428  (module = module_find_by_addr(pcs, addr, DMT_ELF)) ||
430  return module;
431  }
432  else
433  {
434  for (module = pcs->lmodules; module; module = module->next)
435  {
436  if (type == module->type && addr >= module->module.BaseOfImage &&
438  return module;
439  }
440  }
442  return module;
443 }
444 
445 /******************************************************************
446  * module_is_container_loaded
447  *
448  * checks whether the native container, for a (supposed) PE builtin is
449  * already loaded
450  */
451 static BOOL module_is_container_loaded(const struct process* pcs,
452  const WCHAR* ImageName, DWORD64 base)
453 {
454  size_t len;
455  struct module* module;
456  PCWSTR filename, modname;
457 
458  if (!base) return FALSE;
460  len = lstrlenW(filename);
461 
462  for (module = pcs->lmodules; module; module = module->next)
463  {
464  if ((module->type == DMT_ELF || module->type == DMT_MACHO) &&
467  {
469  if (!wcsnicmp(modname, filename, len) &&
470  !memcmp(modname + len, S_DotSoW, 3 * sizeof(WCHAR)))
471  {
472  return TRUE;
473  }
474  }
475  }
476  /* likely a native PE module */
477  WARN("Couldn't find container for %s\n", debugstr_w(ImageName));
478  return FALSE;
479 }
480 
481 static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc)
482 {
484  HANDLE handle;
485 #ifndef DBGHELP_STATIC_LIB
486  WCHAR *path;
487 #endif
488  WORD magic;
489  BOOL ret;
490 
491 #ifndef DBGHELP_STATIC_LIB
494  heap_free(path);
495 #else
497 #endif
498  if (handle == INVALID_HANDLE_VALUE) return FALSE;
499 
500  if (link_crc)
501  {
502  DWORD crc = calc_crc32(handle);
503  if (crc != link_crc)
504  {
505  WARN("Bad CRC for file %s (got %08x while expecting %08x)\n", debugstr_w(file), crc, link_crc);
507  return FALSE;
508  }
509  }
510 
513  ret = pe_map_file(handle, fmap, DMT_PE);
514  else
515 #ifndef __REACTOS__
516  ret = elf_map_handle(handle, fmap);
517 #else
518  ret = FALSE;
519 #endif
521  return ret;
522 }
523 
524 /******************************************************************
525  * image_locate_debug_link
526  *
527  * Locate a filename from a .gnu_debuglink section, using the same
528  * strategy as gdb:
529  * "If the full name of the directory containing the executable is
530  * execdir, and the executable has a debug link that specifies the
531  * name debugfile, then GDB will automatically search for the
532  * debugging information file in three places:
533  * - the directory containing the executable file (that is, it
534  * will look for a file named `execdir/debugfile',
535  * - a subdirectory of that directory named `.debug' (that is, the
536  * file `execdir/.debug/debugfile', and
537  * - a subdirectory of the global debug file directory that includes
538  * the executable's full path, and the name from the link (that is,
539  * the file `globaldebugdir/execdir/debugfile', where globaldebugdir
540  * is the global debug file directory, and execdir has been turned
541  * into a relative path)." (from GDB manual)
542  */
543 static BOOL image_locate_debug_link(const struct module* module, struct image_file_map* fmap, const char* filename, DWORD crc)
544 {
545 #ifndef __REACTOS__
546  static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
547 #else
548  static const WCHAR globalDebugDirW[] = {'\0'};
549 #endif
550  static const WCHAR dotDebugW[] = {'.','d','e','b','u','g','/'};
551  const size_t globalDebugDirLen = ARRAY_SIZE(globalDebugDirW);
552  size_t filename_len, path_len;
553  WCHAR* p = NULL;
554  WCHAR* slash;
555  WCHAR* slash2;
556  struct image_file_map* fmap_link = NULL;
557 
558  fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
559  if (!fmap_link) return FALSE;
560 
561  filename_len = MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, NULL, 0);
564  p = HeapAlloc(GetProcessHeap(), 0,
565  (globalDebugDirLen + path_len + 6 + 1 + filename_len + 1) * sizeof(WCHAR));
566  if (!p) goto found;
567 
568  /* we prebuild the string with "execdir" */
570  slash = p;
571  if ((slash2 = wcsrchr(slash, '/'))) slash = slash2 + 1;
572  if ((slash2 = wcsrchr(slash, '\\'))) slash = slash2 + 1;
573 
574  /* testing execdir/filename */
575  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
576  if (image_check_debug_link(p, fmap_link, crc)) goto found;
577 
578  /* testing execdir/.debug/filename */
579  memcpy(slash, dotDebugW, sizeof(dotDebugW));
580  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash + ARRAY_SIZE(dotDebugW), filename_len);
581  if (image_check_debug_link(p, fmap_link, crc)) goto found;
582 
583  if (module->real_path)
584  {
586  slash = p;
587  if ((slash2 = wcsrchr(slash, '/'))) slash = slash2 + 1;
588  if ((slash2 = wcsrchr(slash, '\\'))) slash = slash2 + 1;
589  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
590  if (image_check_debug_link(p, fmap_link, crc)) goto found;
591  }
592 
593  /* testing globaldebugdir/execdir/filename */
594  memmove(p + globalDebugDirLen, p, (slash - p) * sizeof(WCHAR));
595  memcpy(p, globalDebugDirW, globalDebugDirLen * sizeof(WCHAR));
596  slash += globalDebugDirLen;
597  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
598  if (image_check_debug_link(p, fmap_link, crc)) goto found;
599 
600  /* finally testing filename */
601  if (image_check_debug_link(slash, fmap_link, crc)) goto found;
602 
603 
604  WARN("Couldn't locate or map %s\n", filename);
605  HeapFree(GetProcessHeap(), 0, p);
606  HeapFree(GetProcessHeap(), 0, fmap_link);
607  return FALSE;
608 
609 found:
610  TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p));
611  HeapFree(GetProcessHeap(), 0, p);
612  fmap->alternate = fmap_link;
613  return TRUE;
614 }
615 
616 /******************************************************************
617  * image_locate_build_id_target
618  *
619  * Try to find the .so file containing the debug info out of the build-id note information
620  */
621 static BOOL image_locate_build_id_target(struct image_file_map* fmap, const BYTE* id, unsigned idlen)
622 {
623  static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
624  static const WCHAR buildidW[] = {'.','b','u','i','l','d','-','i','d','/'};
625  static const WCHAR dotDebug0W[] = {'.','d','e','b','u','g',0};
626  struct image_file_map* fmap_link = NULL;
627  WCHAR* p;
628  WCHAR* z;
629  const BYTE* idend = id + idlen;
630 
631  fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
632  if (!fmap_link) return FALSE;
633 
634  p = HeapAlloc(GetProcessHeap(), 0,
635  sizeof(globalDebugDirW) + sizeof(buildidW) +
636  (idlen * 2 + 1) * sizeof(WCHAR) + sizeof(dotDebug0W));
637  z = p;
638  memcpy(z, globalDebugDirW, sizeof(globalDebugDirW));
639  z += ARRAY_SIZE(globalDebugDirW);
640  memcpy(z, buildidW, sizeof(buildidW));
641  z += ARRAY_SIZE(buildidW);
642 
643  if (id < idend)
644  {
645  *z++ = "0123456789abcdef"[*id >> 4 ];
646  *z++ = "0123456789abcdef"[*id & 0x0F];
647  id++;
648  }
649  if (id < idend)
650  *z++ = '/';
651  while (id < idend)
652  {
653  *z++ = "0123456789abcdef"[*id >> 4 ];
654  *z++ = "0123456789abcdef"[*id & 0x0F];
655  id++;
656  }
657  memcpy(z, dotDebug0W, sizeof(dotDebug0W));
658  TRACE("checking %s\n", wine_dbgstr_w(p));
659 
660  if (image_check_debug_link(p, fmap_link, 0))
661  {
662  struct image_section_map buildid_sect;
663  if (image_find_section(fmap_link, ".note.gnu.build-id", &buildid_sect))
664  {
665  const UINT32* note;
666 
667  note = (const UINT32*)image_map_section(&buildid_sect);
668  if (note != IMAGE_NO_MAP)
669  {
670  /* the usual ELF note structure: name-size desc-size type <name> <desc> */
671  if (note[2] == NOTE_GNU_BUILD_ID)
672  {
673  if (note[1] == idlen &&
674  !memcmp(note + 3 + ((note[0] + 3) >> 2), idend - idlen, idlen))
675  {
676  TRACE("Located debug information file at %s\n", debugstr_w(p));
677  HeapFree(GetProcessHeap(), 0, p);
678  fmap->alternate = fmap_link;
679  return TRUE;
680  }
681  WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(p));
682  }
683  }
684  image_unmap_section(&buildid_sect);
685  }
686  image_unmap_file(fmap_link);
687  }
688 
689  TRACE("not found\n");
690  HeapFree(GetProcessHeap(), 0, p);
691  HeapFree(GetProcessHeap(), 0, fmap_link);
692  return FALSE;
693 }
694 
695 /******************************************************************
696  * image_check_alternate
697  *
698  * Load alternate files for a given image file, looking at either .note.gnu_build-id
699  * or .gnu_debuglink sections.
700  */
702 {
703  BOOL ret = FALSE;
704  BOOL found = FALSE;
705  struct image_section_map buildid_sect, debuglink_sect;
706 
707  /* if present, add the .gnu_debuglink file as an alternate to current one */
708  if (image_find_section(fmap, ".note.gnu.build-id", &buildid_sect))
709  {
710  const UINT32* note;
711 
712  found = TRUE;
713  note = (const UINT32*)image_map_section(&buildid_sect);
714  if (note != IMAGE_NO_MAP)
715  {
716  /* the usual ELF note structure: name-size desc-size type <name> <desc> */
717  if (note[2] == NOTE_GNU_BUILD_ID)
718  {
719  ret = image_locate_build_id_target(fmap, (const BYTE*)(note + 3 + ((note[0] + 3) >> 2)), note[1]);
720  }
721  }
722  image_unmap_section(&buildid_sect);
723  }
724  /* if present, add the .gnu_debuglink file as an alternate to current one */
725  if (!ret && image_find_section(fmap, ".gnu_debuglink", &debuglink_sect))
726  {
727  const char* dbg_link;
728 
729  found = TRUE;
730  dbg_link = (const char*)image_map_section(&debuglink_sect);
731  if (dbg_link != IMAGE_NO_MAP)
732  {
733  /* The content of a debug link section is:
734  * 1/ a NULL terminated string, containing the file name for the
735  * debug info
736  * 2/ padding on 4 byte boundary
737  * 3/ CRC of the linked file
738  */
739  DWORD crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
740  ret = image_locate_debug_link(module, fmap, dbg_link, crc);
741  if (!ret)
742  WARN("Couldn't load linked debug file for %s\n",
744  }
745  image_unmap_section(&debuglink_sect);
746  }
747  return found ? ret : TRUE;
748 }
749 
750 /***********************************************************************
751  * SymLoadModule (DBGHELP.@)
752  */
754  PCSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
755 {
756  return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll,
757  SizeOfDll, NULL, 0);
758 }
759 
760 /***********************************************************************
761  * SymLoadModuleEx (DBGHELP.@)
762  */
764  PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize,
766 {
767  PWSTR wImageName, wModuleName;
768  unsigned len;
769  DWORD64 ret;
770 
771  TRACE("(%p %p %s %s %s %08x %p %08x)\n",
773  wine_dbgstr_longlong(BaseOfDll), DllSize, Data, Flags);
774 
775  if (ImageName)
776  {
778  wImageName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
779  MultiByteToWideChar(CP_ACP, 0, ImageName, -1, wImageName, len);
780  }
781  else wImageName = NULL;
782  if (ModuleName)
783  {
785  wModuleName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
786  MultiByteToWideChar(CP_ACP, 0, ModuleName, -1, wModuleName, len);
787  }
788  else wModuleName = NULL;
789 
790  ret = SymLoadModuleExW(hProcess, hFile, wImageName, wModuleName,
791  BaseOfDll, DllSize, Data, Flags);
792  HeapFree(GetProcessHeap(), 0, wImageName);
793  HeapFree(GetProcessHeap(), 0, wModuleName);
794  return ret;
795 }
796 
797 /***********************************************************************
798  * SymLoadModuleExW (DBGHELP.@)
799  */
801  PCWSTR wModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll,
803 {
804  struct process* pcs;
805  struct module* module = NULL;
806 
807  TRACE("(%p %p %s %s %s %08x %p %08x)\n",
808  hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName),
809  wine_dbgstr_longlong(BaseOfDll), SizeOfDll, Data, Flags);
810 
811  if (Data)
812  FIXME("Unsupported load data parameter %p for %s\n",
813  Data, debugstr_w(wImageName));
814  if (!validate_addr64(BaseOfDll)) return FALSE;
815 
816  if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
817 
818  if (Flags & SLMFLAG_VIRTUAL)
819  {
820  if (!wImageName) return FALSE;
821  module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0);
822  if (!module) return FALSE;
823  if (wModuleName) module_set_module(module, wModuleName);
825 
826  return TRUE;
827  }
828  if (Flags & ~(SLMFLAG_VIRTUAL))
829  FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName));
830 
831  pcs->loader->synchronize_module_list(pcs);
832 
833  /* this is a Wine extension to the API just to redo the synchronisation */
834  if (!wImageName && !hFile) return 0;
835 
836  /* check if the module is already loaded, or if it's a builtin PE module with
837  * an containing ELF module
838  */
839  if (wImageName)
840  {
841  module = module_is_already_loaded(pcs, wImageName);
842  if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll))
843  {
844  /* force the loading of DLL as builtin */
845  module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
846  }
847  }
848  if (!module)
849  {
850  /* otherwise, try a regular PE module */
851  if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)) &&
852  wImageName)
853  {
854  /* and finally an ELF or Mach-O module */
855  module = pcs->loader->load_module(pcs, wImageName, BaseOfDll);
856  }
857  }
858  if (!module)
859  {
860  WARN("Couldn't locate %s\n", debugstr_w(wImageName));
861  return 0;
862  }
863  module->module.NumSyms = module->ht_symbols.num_elts;
864  /* by default module_new fills module.ModuleName from a derivation
865  * of LoadedImageName. Overwrite it, if we have better information
866  */
867  if (wModuleName)
868  module_set_module(module, wModuleName);
869  if (wImageName)
871 
872  return module->module.BaseOfImage;
873 }
874 
875 /***********************************************************************
876  * SymLoadModule64 (DBGHELP.@)
877  */
879  PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll)
880 {
881  return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll,
882  NULL, 0);
883 }
884 
885 /******************************************************************
886  * module_remove
887  *
888  */
889 BOOL module_remove(struct process* pcs, struct module* module)
890 {
891  struct module_format*modfmt;
892  struct module** p;
893  unsigned i;
894 
895  TRACE("%s (%p)\n", debugstr_w(module->module.ModuleName), module);
896 
897  for (i = 0; i < DFI_LAST; i++)
898  {
899  if ((modfmt = module->format_info[i]) && modfmt->remove)
900  modfmt->remove(pcs, module->format_info[i]);
901  }
908  /* native dbghelp doesn't invoke registered callback(,CBA_SYMBOLS_UNLOADED,) here
909  * so do we
910  */
911  for (p = &pcs->lmodules; *p; p = &(*p)->next)
912  {
913  if (*p == module)
914  {
915  *p = module->next;
917  return TRUE;
918  }
919  }
920  FIXME("This shouldn't happen\n");
921  return FALSE;
922 }
923 
924 /******************************************************************
925  * SymUnloadModule (DBGHELP.@)
926  *
927  */
929 {
930  struct process* pcs;
931  struct module* module;
932 
934  if (!pcs) return FALSE;
935  module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
936  if (!module) return FALSE;
937  return module_remove(pcs, module);
938 }
939 
940 /******************************************************************
941  * SymUnloadModule64 (DBGHELP.@)
942  *
943  */
945 {
946  struct process* pcs;
947  struct module* module;
948 
950  if (!pcs) return FALSE;
951  if (!validate_addr64(BaseOfDll)) return FALSE;
952  module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
953  if (!module) return FALSE;
954  return module_remove(pcs, module);
955 }
956 
957 /******************************************************************
958  * SymEnumerateModules (DBGHELP.@)
959  *
960  */
962 {
966 };
967 
969 {
970  struct enum_modW64_32* x = user;
971 
972  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
973  return x->cb(x->module, (DWORD)base, x->user);
974 }
975 
977  PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
978  PVOID UserContext)
979 {
980  struct enum_modW64_32 x;
981 
982  x.cb = EnumModulesCallback;
983  x.user = UserContext;
984 
986 }
987 
988 /******************************************************************
989  * SymEnumerateModules64 (DBGHELP.@)
990  *
991  */
993 {
997 };
998 
1000 {
1001  struct enum_modW64_64* x = user;
1002 
1003  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
1004  return x->cb(x->module, base, x->user);
1005 }
1006 
1008  PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
1009  PVOID UserContext)
1010 {
1011  struct enum_modW64_64 x;
1012 
1013  x.cb = EnumModulesCallback;
1014  x.user = UserContext;
1015 
1017 }
1018 
1019 /******************************************************************
1020  * SymEnumerateModulesW64 (DBGHELP.@)
1021  *
1022  */
1024  PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback,
1025  PVOID UserContext)
1026 {
1027  struct process* pcs = process_find_by_handle(hProcess);
1028  struct module* module;
1029 
1030  if (!pcs) return FALSE;
1031 
1032  for (module = pcs->lmodules; module; module = module->next)
1033  {
1034  if (!dbghelp_opt_native &&
1035  (module->type == DMT_ELF || module->type == DMT_MACHO))
1036  continue;
1037  if (!EnumModulesCallback(module->modulename,
1038  module->module.BaseOfImage, UserContext))
1039  break;
1040  }
1041  return TRUE;
1042 }
1043 
1044 #ifndef DBGHELP_STATIC_LIB
1045 /******************************************************************
1046  * EnumerateLoadedModules64 (DBGHELP.@)
1047  *
1048  */
1050 {
1054 };
1055 
1057  PVOID user)
1058 {
1059  struct enum_load_modW64_64* x = user;
1060 
1061  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
1062  return x->cb(x->module, base, size, x->user);
1063 }
1064 
1066  PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
1067  PVOID UserContext)
1068 {
1069  struct enum_load_modW64_64 x;
1070 
1071  x.cb = EnumLoadedModulesCallback;
1072  x.user = UserContext;
1073 
1075 }
1076 
1077 /******************************************************************
1078  * EnumerateLoadedModules (DBGHELP.@)
1079  *
1080  */
1082 {
1086 };
1087 
1089  PVOID user)
1090 {
1091  struct enum_load_modW64_32* x = user;
1092  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
1093  return x->cb(x->module, (DWORD)base, size, x->user);
1094 }
1095 
1097  PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
1098  PVOID UserContext)
1099 {
1100  struct enum_load_modW64_32 x;
1101 
1102  x.cb = EnumLoadedModulesCallback;
1103  x.user = UserContext;
1104 
1106 }
1107 
1108 /******************************************************************
1109  * EnumerateLoadedModulesW64 (DBGHELP.@)
1110  *
1111  */
1113  PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
1114  PVOID UserContext)
1115 {
1116  HMODULE* hMods;
1117  WCHAR baseW[256], modW[256];
1118  DWORD i, sz;
1119  MODULEINFO mi;
1120 
1121  hMods = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(hMods[0]));
1122  if (!hMods) return FALSE;
1123 
1124  if (!EnumProcessModules(hProcess, hMods, 256 * sizeof(hMods[0]), &sz))
1125  {
1126  /* hProcess should also be a valid process handle !! */
1127  FIXME("If this happens, bump the number in mod\n");
1128  HeapFree(GetProcessHeap(), 0, hMods);
1129  return FALSE;
1130  }
1131  sz /= sizeof(HMODULE);
1132  for (i = 0; i < sz; i++)
1133  {
1134  if (!GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) ||
1136  continue;
1138  EnumLoadedModulesCallback(modW, (DWORD_PTR)mi.lpBaseOfDll, mi.SizeOfImage,
1139  UserContext);
1140  }
1141  HeapFree(GetProcessHeap(), 0, hMods);
1142 
1143  return sz != 0 && i == sz;
1144 }
1145 
1146 #endif /* DBGHELP_STATIC_LIB */
1147 
1148 static void dbghelp_str_WtoA(const WCHAR *src, char *dst, int dst_len)
1149 {
1150  WideCharToMultiByte(CP_ACP, 0, src, -1, dst, dst_len - 1, NULL, NULL);
1151  dst[dst_len - 1] = 0;
1152 }
1153 
1154 /******************************************************************
1155  * SymGetModuleInfo (DBGHELP.@)
1156  *
1157  */
1160 {
1162  IMAGEHLP_MODULEW64 miw64;
1163 
1164  if (sizeof(mi) < ModuleInfo->SizeOfStruct) FIXME("Wrong size\n");
1165 
1166  miw64.SizeOfStruct = sizeof(miw64);
1167  if (!SymGetModuleInfoW64(hProcess, dwAddr, &miw64)) return FALSE;
1168 
1169  mi.SizeOfStruct = ModuleInfo->SizeOfStruct;
1170  mi.BaseOfImage = miw64.BaseOfImage;
1171  mi.ImageSize = miw64.ImageSize;
1172  mi.TimeDateStamp = miw64.TimeDateStamp;
1173  mi.CheckSum = miw64.CheckSum;
1174  mi.NumSyms = miw64.NumSyms;
1175  mi.SymType = miw64.SymType;
1176  dbghelp_str_WtoA(miw64.ModuleName, mi.ModuleName, sizeof(mi.ModuleName));
1177  dbghelp_str_WtoA(miw64.ImageName, mi.ImageName, sizeof(mi.ImageName));
1178  dbghelp_str_WtoA(miw64.LoadedImageName, mi.LoadedImageName, sizeof(mi.LoadedImageName));
1179 
1180  memcpy(ModuleInfo, &mi, ModuleInfo->SizeOfStruct);
1181 
1182  return TRUE;
1183 }
1184 
1185 /******************************************************************
1186  * SymGetModuleInfoW (DBGHELP.@)
1187  *
1188  */
1191 {
1192  IMAGEHLP_MODULEW64 miw64;
1193  IMAGEHLP_MODULEW miw;
1194 
1195  if (sizeof(miw) < ModuleInfo->SizeOfStruct) FIXME("Wrong size\n");
1196 
1197  miw64.SizeOfStruct = sizeof(miw64);
1198  if (!SymGetModuleInfoW64(hProcess, dwAddr, &miw64)) return FALSE;
1199 
1200  miw.SizeOfStruct = ModuleInfo->SizeOfStruct;
1201  miw.BaseOfImage = miw64.BaseOfImage;
1202  miw.ImageSize = miw64.ImageSize;
1203  miw.TimeDateStamp = miw64.TimeDateStamp;
1204  miw.CheckSum = miw64.CheckSum;
1205  miw.NumSyms = miw64.NumSyms;
1206  miw.SymType = miw64.SymType;
1207  lstrcpyW(miw.ModuleName, miw64.ModuleName);
1208  lstrcpyW(miw.ImageName, miw64.ImageName);
1210  memcpy(ModuleInfo, &miw, ModuleInfo->SizeOfStruct);
1211 
1212  return TRUE;
1213 }
1214 
1215 /******************************************************************
1216  * SymGetModuleInfo64 (DBGHELP.@)
1217  *
1218  */
1221 {
1222  IMAGEHLP_MODULE64 mi64;
1223  IMAGEHLP_MODULEW64 miw64;
1224 
1225  if (sizeof(mi64) < ModuleInfo->SizeOfStruct)
1226  {
1227  SetLastError(ERROR_MOD_NOT_FOUND); /* NOTE: native returns this error */
1228  WARN("Wrong size %u\n", ModuleInfo->SizeOfStruct);
1229  return FALSE;
1230  }
1231 
1232  miw64.SizeOfStruct = sizeof(miw64);
1233  if (!SymGetModuleInfoW64(hProcess, dwAddr, &miw64)) return FALSE;
1234 
1235  mi64.SizeOfStruct = ModuleInfo->SizeOfStruct;
1236  mi64.BaseOfImage = miw64.BaseOfImage;
1237  mi64.ImageSize = miw64.ImageSize;
1238  mi64.TimeDateStamp = miw64.TimeDateStamp;
1239  mi64.CheckSum = miw64.CheckSum;
1240  mi64.NumSyms = miw64.NumSyms;
1241  mi64.SymType = miw64.SymType;
1242  dbghelp_str_WtoA(miw64.ModuleName, mi64.ModuleName, sizeof(mi64.ModuleName));
1243  dbghelp_str_WtoA(miw64.ImageName, mi64.ImageName, sizeof(mi64.ImageName));
1245  dbghelp_str_WtoA(miw64.LoadedPdbName, mi64.LoadedPdbName, sizeof(mi64.LoadedPdbName));
1246 
1247  mi64.CVSig = miw64.CVSig;
1248  dbghelp_str_WtoA(miw64.CVData, mi64.CVData, sizeof(mi64.CVData));
1249  mi64.PdbSig = miw64.PdbSig;
1250  mi64.PdbSig70 = miw64.PdbSig70;
1251  mi64.PdbAge = miw64.PdbAge;
1252  mi64.PdbUnmatched = miw64.PdbUnmatched;
1253  mi64.DbgUnmatched = miw64.DbgUnmatched;
1254  mi64.LineNumbers = miw64.LineNumbers;
1255  mi64.GlobalSymbols = miw64.GlobalSymbols;
1256  mi64.TypeInfo = miw64.TypeInfo;
1257  mi64.SourceIndexed = miw64.SourceIndexed;
1258  mi64.Publics = miw64.Publics;
1259 
1260  memcpy(ModuleInfo, &mi64, ModuleInfo->SizeOfStruct);
1261 
1262  return TRUE;
1263 }
1264 
1265 /******************************************************************
1266  * SymGetModuleInfoW64 (DBGHELP.@)
1267  *
1268  */
1271 {
1272  struct process* pcs = process_find_by_handle(hProcess);
1273  struct module* module;
1274  IMAGEHLP_MODULEW64 miw64;
1275 
1276  TRACE("%p %s %p\n", hProcess, wine_dbgstr_longlong(dwAddr), ModuleInfo);
1277 
1278  if (!pcs) return FALSE;
1279  if (ModuleInfo->SizeOfStruct > sizeof(*ModuleInfo)) return FALSE;
1280  module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
1281  if (!module) return FALSE;
1282 
1283  miw64 = module->module;
1284 
1285  /* update debug information from container if any */
1286  if (module->module.SymType == SymNone)
1287  {
1289  if (module && module->module.SymType != SymNone)
1290  {
1291  miw64.SymType = module->module.SymType;
1292  miw64.NumSyms = module->module.NumSyms;
1293  }
1294  }
1295  memcpy(ModuleInfo, &miw64, ModuleInfo->SizeOfStruct);
1296  return TRUE;
1297 }
1298 
1299 /***********************************************************************
1300  * SymGetModuleBase (DBGHELP.@)
1301  */
1303 {
1304  DWORD64 ret;
1305 
1306  ret = SymGetModuleBase64(hProcess, dwAddr);
1307  return validate_addr64(ret) ? ret : 0;
1308 }
1309 
1310 /***********************************************************************
1311  * SymGetModuleBase64 (DBGHELP.@)
1312  */
1314 {
1315  struct process* pcs = process_find_by_handle(hProcess);
1316  struct module* module;
1317 
1318  if (!pcs) return 0;
1319  module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
1320  if (!module) return 0;
1321  return module->module.BaseOfImage;
1322 }
1323 
1324 /******************************************************************
1325  * module_reset_debug_info
1326  * Removes any debug information linked to a given module.
1327  */
1329 {
1331  module->sorttab_size = 0;
1335  module->ht_symbols.num_buckets = 0;
1336  module->ht_symbols.buckets = NULL;
1338  module->ht_types.num_buckets = 0;
1339  module->ht_types.buckets = NULL;
1340  module->vtypes.num_elts = 0;
1343  module->sources = NULL;
1344 }
1345 
1346 /******************************************************************
1347  * SymRefreshModuleList (DBGHELP.@)
1348  */
1350 {
1351  struct process* pcs;
1352 
1353  TRACE("(%p)\n", hProcess);
1354 
1355  if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
1356 
1357  return pcs->loader->synchronize_module_list(pcs);
1358 }
1359 
1360 /***********************************************************************
1361  * SymFunctionTableAccess (DBGHELP.@)
1362  */
1364 {
1365  return SymFunctionTableAccess64(hProcess, AddrBase);
1366 }
1367 
1368 /***********************************************************************
1369  * SymFunctionTableAccess64 (DBGHELP.@)
1370  */
1372 {
1373  struct process* pcs = process_find_by_handle(hProcess);
1374  struct module* module;
1375 
1376  if (!pcs || !dbghelp_current_cpu->find_runtime_function) return NULL;
1377  module = module_find_by_addr(pcs, AddrBase, DMT_UNKNOWN);
1378  if (!module) return NULL;
1379 
1380  return dbghelp_current_cpu->find_runtime_function(module, AddrBase);
1381 }
1382 
1384 {
1385  return FALSE;
1386 }
1387 
1388 static struct module* native_load_module(struct process* pcs, const WCHAR* name, ULONG_PTR addr)
1389 {
1390  return NULL;
1391 }
1392 
1394 {
1395  return FALSE;
1396 }
1397 
1399 {
1400  return FALSE;
1401 }
1402 
1404  DWORD* size, DWORD* checksum)
1405 {
1406  return FALSE;
1407 }
1408 
1410 {
1416 };
WCHAR * get_wine_loader_name(struct process *pcs)
Definition: module.c:150
void(* remove)(struct process *pcs, struct module_format *modfmt)
BOOL WINAPI SymEnumerateModules(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, PVOID UserContext)
Definition: module.c:976
SYM_TYPE SymType
Definition: compat.h:1103
const uint16_t * PCWSTR
Definition: typedefs.h:57
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACKW64)(PCWSTR, DWORD64, ULONG, PVOID)
Definition: compat.h:1046
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define max(a, b)
Definition: svc.c:63
BOOL pcs_callback(const struct process *pcs, ULONG action, void *data)
Definition: dbghelp.c:705
static void dbghelp_str_WtoA(const WCHAR *src, char *dst, int dst_len)
Definition: module.c:1148
BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll)
Definition: module.c:928
struct module * module_find_by_nameW(const struct process *pcs, const WCHAR *name)
Definition: module.c:279
static struct module * native_load_module(struct process *pcs, const WCHAR *name, ULONG_PTR addr)
Definition: module.c:1388
#define CloseHandle
Definition: compat.h:598
BOOL WINAPI SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULE ModuleInfo)
Definition: module.c:1158
static BOOL image_check_debug_link(const WCHAR *file, struct image_file_map *fmap, DWORD link_crc)
Definition: module.c:481
WCHAR * real_path
BOOL image_check_alternate(struct image_file_map *fmap, const struct module *module)
Definition: module.c:701
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
unsigned sources_alloc
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACK64)(PCSTR, DWORD64, ULONG, PVOID)
Definition: compat.h:1045
#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE
Definition: compat.h:836
#define WideCharToMultiByte
Definition: compat.h:111
WCHAR ModuleName[32]
Definition: compat.h:935
void module_reset_debug_info(struct module *module)
Definition: module.c:1328
static BOOL native_load_debug_info(struct process *process, struct module *module)
Definition: module.c:1393
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type)
Definition: module.c:420
#define TRUE
Definition: types.h:120
DWORD64 BaseOfImage
Definition: compat.h:929
GLsizei const GLchar ** path
Definition: glext.h:7234
static struct module * module_get_container(const struct process *pcs, const struct module *inner)
Definition: module.c:329
uint16_t * PWSTR
Definition: typedefs.h:56
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
unsigned sources_used
#define CP_ACP
Definition: compat.h:109
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
struct hash_table ht_symbols
BOOL WINAPI SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll)
Definition: module.c:944
DWORD BaseOfImage
Definition: compat.h:1075
CHAR LoadedPdbName[256]
Definition: compat.h:1107
#define WARN(fmt,...)
Definition: debug.h:112
struct vector vsymt
CHAR ModuleName[32]
Definition: compat.h:1104
struct module * module_is_already_loaded(const struct process *pcs, const WCHAR *name)
Definition: module.c:303
static HMODULE module
Definition: module.c:32
BOOL dbghelp_opt_native
Definition: dbghelp.c:74
WCHAR ImageName[256]
Definition: compat.h:1082
#define CALLBACK
Definition: compat.h:35
struct image_file_map * fmap
DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageName, PCWSTR wModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll, PMODLOAD_DATA Data, DWORD Flags)
Definition: module.c:800
#define NOTE_GNU_BUILD_ID
Definition: module.c:38
BOOL validate_addr64(DWORD64 addr)
Definition: dbghelp.c:112
u32_t magic(void)
static int match_ext(const WCHAR *ptr, size_t len)
Definition: module.c:55
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define assert(x)
Definition: debug.h:53
#define SLMFLAG_VIRTUAL
Definition: compat.h:885
const WCHAR S_SlashW[]
Definition: module.c:45
GLuint buffer
Definition: glext.h:5915
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static BOOL CALLBACK enum_modW64_64(PCWSTR name, DWORD64 base, PVOID user)
Definition: module.c:999
BOOL WINAPI SymGetModuleInfoW(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULEW ModuleInfo)
Definition: module.c:1189
static BOOL read_bytes(parse_buffer *buf, LPVOID data, DWORD size)
Definition: parsing.c:168
static MONITORINFO mi
Definition: win.c:7339
struct wine_rb_tree sources_offsets_tree
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1274
#define FILE_BEGIN
Definition: compat.h:620
static const WCHAR S_OcxW[]
Definition: module.c:51
static BOOL image_locate_build_id_target(struct image_file_map *fmap, const BYTE *id, unsigned idlen)
Definition: module.c:621
unsigned num_symbols
const char * filename
Definition: ioapi.h:135
static BOOL CALLBACK enum_load_modW64_64(PCWSTR name, DWORD64 base, ULONG size, PVOID user)
Definition: module.c:1056
char * sources
#define lstrlenW
Definition: compat.h:609
BOOL WINAPI EnumerateLoadedModules(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1096
int load_addr
Definition: mkisofs.c:104
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACK)(PCSTR, ULONG, ULONG, PVOID)
Definition: compat.h:1085
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD64 WINAPI SymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr)
Definition: module.c:1313
#define lstrcpynW
Definition: compat.h:597
WCHAR FileName[MAX_PATH+1]
Definition: compat.h:1026
DWORD TimeDateStamp
Definition: compat.h:1100
enum module_type type
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IMAGE_NO_MAP
Definition: image_private.h:24
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
Definition: module.c:753
WCHAR LoadedImageName[256]
Definition: compat.h:937
BOOL WINAPI SymEnumerateModules64(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, PVOID UserContext)
Definition: module.c:1007
BOOL module_get_debug(struct module_pair *pair)
Definition: module.c:374
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
static const WCHAR S_ExeW[]
Definition: module.c:50
static WCHAR wineW[]
Definition: localmon.c:128
#define FALSE
Definition: types.h:117
struct module * lmodules
unsigned int UINT32
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL pe_load_debug_info(const struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: pe_module.c:747
#define e
Definition: ke_i.h:82
BOOL(CALLBACK * PSYM_ENUMMODULES_CALLBACK)(PCSTR, ULONG, PVOID)
Definition: compat.h:1091
BOOL(CALLBACK * PSYM_ENUMMODULES_CALLBACKW64)(PCWSTR, DWORD64, PVOID)
Definition: compat.h:1044
int sortlist_valid
int source_rb_compare(const void *key, const struct wine_rb_entry *entry) DECLSPEC_HIDDEN
Definition: source.c:40
const char * file_nameA(const char *str) DECLSPEC_HIDDEN
Definition: path.c:37
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR * get_filename(const WCHAR *name, const WCHAR *endptr)
Definition: module.c:70
static BOOL native_enum_modules(struct process *process, enum_modules_cb cb, void *user)
Definition: module.c:1398
GLdouble GLdouble z
Definition: glext.h:5874
_In_ ULONG _Out_writes_bytes_opt_ InformationLength PAUX_MODULE_EXTENDED_INFO ModuleInfo
Definition: aux_klib.h:65
int note(char *format,...)
Definition: util.c:12
static BOOL is_wine_loader(const WCHAR *module)
Definition: module.c:83
PENUMLOADED_MODULES_CALLBACK64 cb
Definition: module.c:1051
static const WCHAR S_DrvW[]
Definition: module.c:49
void vector_init(struct vector *v, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:133
#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE
Definition: compat.h:837
BOOL WINAPI EnumerateLoadedModules64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1065
unsigned num_sorttab
DWORD SizeOfStruct
Definition: compat.h:1097
DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess, HMODULE hModule, LPWSTR lpBaseName, DWORD nSize)
Definition: psapi.c:914
PVOID user
Definition: module.c:964
#define OPEN_EXISTING
Definition: compat.h:634
BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1112
BOOL WINAPI SymEnumerateModulesW64(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, PVOID UserContext)
Definition: module.c:1023
r l[0]
Definition: byte_order.h:167
static void wine_rb_init(struct wine_rb_tree *tree, wine_rb_compare_func_t compare)
Definition: rbtree.h:179
struct module * pe_load_native_module(struct process *pcs, const WCHAR *name, HANDLE hFile, DWORD64 base, DWORD size) DECLSPEC_HIDDEN
Definition: pe_module.c:799
static BOOL module_is_container_loaded(const struct process *pcs, const WCHAR *ImageName, DWORD64 base)
Definition: module.c:451
DWORD64 WINAPI SymLoadModule64(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll)
Definition: module.c:878
#define TRACE(s)
Definition: solgame.cpp:4
struct image_file_map * alternate
GLsizeiptr size
Definition: glext.h:5919
DWORD64 reloc_delta
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static const WCHAR S_AcmW[]
Definition: module.c:47
BOOL WINAPI EnumProcessModules(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded)
Definition: psapi.c:526
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define CP_UNIXCP
Definition: compat.h:79
__wchar_t WCHAR
Definition: xmlstorage.h:180
const struct loader_ops * loader
WCHAR LoadedImageName[256]
Definition: compat.h:1083
#define debugstr_a
Definition: kernel32.h:31
DWORD64 BaseOfImage
Definition: compat.h:1098
const WCHAR S_ElfW[]
Definition: module.c:40
BOOL elf_map_handle(HANDLE handle, struct image_file_map *fmap)
Definition: elf_module.c:582
WCHAR modulename[64]
struct vector vtypes
static BOOL CALLBACK enum_modW64_32(PCWSTR name, DWORD64 base, PVOID user)
Definition: module.c:968
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
unsigned short WORD
Definition: ntddk_ex.h:93
static FILE * out
Definition: regtests2xml.c:44
WCHAR ImageName[256]
Definition: compat.h:936
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD SizeOfStruct
Definition: compat.h:1074
#define SetLastError(x)
Definition: compat.h:611
SYM_TYPE SymType
Definition: compat.h:1080
PVOID user
Definition: module.c:995
struct module * pe_load_builtin_module(struct process *pcs, const WCHAR *name, DWORD64 base, DWORD64 size) DECLSPEC_HIDDEN
Definition: pe_module.c:892
static void image_unmap_file(struct image_file_map *fmap)
void module_set_module(struct module *module, const WCHAR *name)
Definition: module.c:142
#define wcsicmp
Definition: compat.h:15
WCHAR ModuleName[32]
Definition: compat.h:1081
PSYM_ENUMMODULES_CALLBACK cb
Definition: module.c:963
int ret
static const char * ImageName
Definition: image.c:34
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:43
BOOL WINAPI SymGetModuleInfoW64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULEW64 ModuleInfo)
Definition: module.c:1269
#define wcsnicmp
Definition: compat.h:14
static const char * get_module_type(enum module_type type, BOOL virtual)
Definition: module.c:184
DWORD SizeOfStruct
Definition: compat.h:928
SYM_TYPE SymType
Definition: compat.h:934
GLenum const GLvoid * addr
Definition: glext.h:9621
static void image_unmap_section(struct image_section_map *ism)
BOOL module_remove(struct process *pcs, struct module *module)
Definition: module.c:889
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
struct module * module_new(struct process *pcs, const WCHAR *name, enum module_type type, BOOL virtual, DWORD64 mod_addr, DWORD64 size, ULONG_PTR stamp, ULONG_PTR checksum)
Definition: module.c:198
#define GENERIC_READ
Definition: compat.h:135
module_type
GLenum src
Definition: glext.h:6340
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
static BOOL image_find_section(struct image_file_map *fmap, const char *name, struct image_section_map *ism)
#define wcsrchr
Definition: compat.h:16
uint32_t DWORD_PTR
Definition: typedefs.h:65
_In_ HANDLE hFile
Definition: mswsock.h:90
struct pool pool
static const char * image_map_section(struct image_section_map *ism)
unsigned char BYTE
Definition: xxhash.c:193
static const WCHAR S_DotSoW[]
Definition: module.c:44
static const WCHAR modW[]
Definition: lex.c:66
const struct loader_ops no_loader_ops
Definition: module.c:1409
void hash_table_destroy(struct hash_table *ht) DECLSPEC_HIDDEN
Definition: storage.c:342
HANDLE HMODULE
Definition: typedefs.h:77
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static const WCHAR S_VxdW[]
Definition: module.c:52
PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase)
Definition: module.c:1371
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
static DWORD path_len
Definition: batch.c:31
uint64_t DWORD64
Definition: typedefs.h:67
struct process * process
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:50
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
GLuint in
Definition: glext.h:9616
#define lstrcpyW
Definition: compat.h:608
BOOL pe_map_file(HANDLE file, struct image_file_map *fmap, enum module_type mt) DECLSPEC_HIDDEN
Definition: pe_module.c:241
PSYM_ENUMMODULES_CALLBACK64 cb
Definition: module.c:994
struct module * module_get_containee(const struct process *pcs, const struct module *outer)
Definition: module.c:349
#define ARRAY_SIZE(a)
Definition: main.h:24
const WCHAR S_WineLoaderW[]
Definition: module.c:42
unsigned short is_virtual
BOOL(CALLBACK * PSYM_ENUMMODULES_CALLBACK64)(PCSTR, DWORD64, PVOID)
Definition: compat.h:1043
GLenum GLenum dst
Definition: glext.h:6340
CHAR CVData[MAX_PATH *3]
Definition: compat.h:1109
DWORD TimeDateStamp
Definition: compat.h:931
struct hash_table ht_types
#define ReadFile(a, b, c, d, e)
Definition: compat.h:601
WCHAR CVData[MAX_PATH *3]
Definition: compat.h:940
DWORD calc_crc32(HANDLE handle)
Definition: dbghelp.c:848
#define CBA_DEFERRED_SYMBOL_LOAD_START
Definition: compat.h:835
Definition: _pair.h:47
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
DWORD TimeDateStamp
Definition: compat.h:1077
unsigned sorttab_size
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL WINAPI GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb)
Definition: psapi.c:1064
WCHAR LoadedPdbName[256]
Definition: compat.h:938
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define MultiByteToWideChar
Definition: compat.h:110
void hash_table_init(struct pool *pool, struct hash_table *ht, unsigned num_buckets) DECLSPEC_HIDDEN
Definition: storage.c:334
#define CreateFileW
Definition: compat.h:600
DWORD64 WINAPI SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize, PMODLOAD_DATA Data, DWORD Flags)
Definition: module.c:763
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
static void module_fill_module(const WCHAR *in, WCHAR *out, size_t size)
Definition: module.c:118
CHAR ImageName[256]
Definition: compat.h:1105
Definition: name.c:38
static const WCHAR S_DllW[]
Definition: module.c:48
BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
Definition: module.c:1349
static WCHAR baseW[MAX_PATH]
Definition: FindFiles.c:24
#define ERROR_MOD_NOT_FOUND
Definition: compat.h:104
unsigned int ULONG
Definition: retypes.h:1
PENUMLOADED_MODULES_CALLBACK cb
Definition: module.c:1083
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define towlower(c)
Definition: wctype.h:97
#define ERROR_INVALID_NAME
Definition: compat.h:103
struct module * module_find_by_nameA(const struct process *pcs, const char *name)
Definition: module.c:291
WCHAR * get_dos_file_name(const WCHAR *filename) DECLSPEC_HIDDEN
Definition: path.c:671
struct symt_ht ** addr_sorttab
const char * PCSTR
Definition: typedefs.h:52
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
Definition: module.c:1302
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
Definition: module.c:1363
static const WCHAR *const ext[]
Definition: module.c:53
struct module_format * format_info[DFI_LAST]
IMAGEHLP_MODULEW64 module
void user(int argc, const char *argv[])
Definition: cmds.c:1350
struct module * next
#define HeapFree(x, y, z)
Definition: compat.h:594
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
#define SetFilePointer
Definition: compat.h:602
CHAR LoadedImageName[256]
Definition: compat.h:1106
BOOL WINAPI SymGetModuleInfo64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULE64 ModuleInfo)
Definition: module.c:1219
static BOOL CALLBACK enum_load_modW64_32(PCWSTR name, DWORD64 base, ULONG size, PVOID user)
Definition: module.c:1088
static BOOL image_locate_debug_link(const struct module *module, struct image_file_map *fmap, const char *filename, DWORD crc)
Definition: module.c:543
static BOOL native_fetch_file_info(struct process *process, const WCHAR *name, ULONG_PTR load_addr, DWORD_PTR *base, DWORD *size, DWORD *checksum)
Definition: module.c:1403
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static BOOL native_synchronize_module_list(struct process *pcs)
Definition: module.c:1383
BOOL(* enum_modules_cb)(const WCHAR *, ULONG_PTR addr, void *user)
Definition: fci.c:126
GLuint const GLchar * name
Definition: glext.h:6031