ReactOS  0.4.15-dev-1070-ge1a01de
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  static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
546  static const WCHAR dotDebugW[] = {'.','d','e','b','u','g','/'};
547  const size_t globalDebugDirLen = ARRAY_SIZE(globalDebugDirW);
548  size_t filename_len, path_len;
549  WCHAR* p = NULL;
550  WCHAR* slash;
551  WCHAR* slash2;
552  struct image_file_map* fmap_link = NULL;
553 
554  fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
555  if (!fmap_link) return FALSE;
556 
557  filename_len = MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, NULL, 0);
560  p = HeapAlloc(GetProcessHeap(), 0,
561  (globalDebugDirLen + path_len + 6 + 1 + filename_len + 1) * sizeof(WCHAR));
562  if (!p) goto found;
563 
564  /* we prebuild the string with "execdir" */
566  slash = p;
567  if ((slash2 = wcsrchr(slash, '/'))) slash = slash2 + 1;
568  if ((slash2 = wcsrchr(slash, '\\'))) slash = slash2 + 1;
569 
570  /* testing execdir/filename */
571  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
572  if (image_check_debug_link(p, fmap_link, crc)) goto found;
573 
574  /* testing execdir/.debug/filename */
575  memcpy(slash, dotDebugW, sizeof(dotDebugW));
576  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash + ARRAY_SIZE(dotDebugW), filename_len);
577  if (image_check_debug_link(p, fmap_link, crc)) goto found;
578 
579  if (module->real_path)
580  {
582  slash = p;
583  if ((slash2 = wcsrchr(slash, '/'))) slash = slash2 + 1;
584  if ((slash2 = wcsrchr(slash, '\\'))) slash = slash2 + 1;
585  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
586  if (image_check_debug_link(p, fmap_link, crc)) goto found;
587  }
588 
589  /* testing globaldebugdir/execdir/filename */
590  memmove(p + globalDebugDirLen, p, (slash - p) * sizeof(WCHAR));
591  memcpy(p, globalDebugDirW, globalDebugDirLen * sizeof(WCHAR));
592  slash += globalDebugDirLen;
593  MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
594  if (image_check_debug_link(p, fmap_link, crc)) goto found;
595 
596  /* finally testing filename */
597  if (image_check_debug_link(slash, fmap_link, crc)) goto found;
598 
599 
600  WARN("Couldn't locate or map %s\n", filename);
601  HeapFree(GetProcessHeap(), 0, p);
602  HeapFree(GetProcessHeap(), 0, fmap_link);
603  return FALSE;
604 
605 found:
606  TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p));
607  HeapFree(GetProcessHeap(), 0, p);
608  fmap->alternate = fmap_link;
609  return TRUE;
610 }
611 
612 /******************************************************************
613  * image_locate_build_id_target
614  *
615  * Try to find the .so file containing the debug info out of the build-id note information
616  */
617 static BOOL image_locate_build_id_target(struct image_file_map* fmap, const BYTE* id, unsigned idlen)
618 {
619  static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
620  static const WCHAR buildidW[] = {'.','b','u','i','l','d','-','i','d','/'};
621  static const WCHAR dotDebug0W[] = {'.','d','e','b','u','g',0};
622  struct image_file_map* fmap_link = NULL;
623  WCHAR* p;
624  WCHAR* z;
625  const BYTE* idend = id + idlen;
626 
627  fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
628  if (!fmap_link) return FALSE;
629 
630  p = HeapAlloc(GetProcessHeap(), 0,
631  sizeof(globalDebugDirW) + sizeof(buildidW) +
632  (idlen * 2 + 1) * sizeof(WCHAR) + sizeof(dotDebug0W));
633  z = p;
634  memcpy(z, globalDebugDirW, sizeof(globalDebugDirW));
635  z += ARRAY_SIZE(globalDebugDirW);
636  memcpy(z, buildidW, sizeof(buildidW));
637  z += ARRAY_SIZE(buildidW);
638 
639  if (id < idend)
640  {
641  *z++ = "0123456789abcdef"[*id >> 4 ];
642  *z++ = "0123456789abcdef"[*id & 0x0F];
643  id++;
644  }
645  if (id < idend)
646  *z++ = '/';
647  while (id < idend)
648  {
649  *z++ = "0123456789abcdef"[*id >> 4 ];
650  *z++ = "0123456789abcdef"[*id & 0x0F];
651  id++;
652  }
653  memcpy(z, dotDebug0W, sizeof(dotDebug0W));
654  TRACE("checking %s\n", wine_dbgstr_w(p));
655 
656  if (image_check_debug_link(p, fmap_link, 0))
657  {
658  struct image_section_map buildid_sect;
659  if (image_find_section(fmap_link, ".note.gnu.build-id", &buildid_sect))
660  {
661  const UINT32* note;
662 
663  note = (const UINT32*)image_map_section(&buildid_sect);
664  if (note != IMAGE_NO_MAP)
665  {
666  /* the usual ELF note structure: name-size desc-size type <name> <desc> */
667  if (note[2] == NOTE_GNU_BUILD_ID)
668  {
669  if (note[1] == idlen &&
670  !memcmp(note + 3 + ((note[0] + 3) >> 2), idend - idlen, idlen))
671  {
672  TRACE("Located debug information file at %s\n", debugstr_w(p));
673  HeapFree(GetProcessHeap(), 0, p);
674  fmap->alternate = fmap_link;
675  return TRUE;
676  }
677  WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(p));
678  }
679  }
680  image_unmap_section(&buildid_sect);
681  }
682  image_unmap_file(fmap_link);
683  }
684 
685  TRACE("not found\n");
686  HeapFree(GetProcessHeap(), 0, p);
687  HeapFree(GetProcessHeap(), 0, fmap_link);
688  return FALSE;
689 }
690 
691 /******************************************************************
692  * image_check_alternate
693  *
694  * Load alternate files for a given image file, looking at either .note.gnu_build-id
695  * or .gnu_debuglink sections.
696  */
698 {
699  BOOL ret = FALSE;
700  BOOL found = FALSE;
701  struct image_section_map buildid_sect, debuglink_sect;
702 
703  /* if present, add the .gnu_debuglink file as an alternate to current one */
704  if (image_find_section(fmap, ".note.gnu.build-id", &buildid_sect))
705  {
706  const UINT32* note;
707 
708  found = TRUE;
709  note = (const UINT32*)image_map_section(&buildid_sect);
710  if (note != IMAGE_NO_MAP)
711  {
712  /* the usual ELF note structure: name-size desc-size type <name> <desc> */
713  if (note[2] == NOTE_GNU_BUILD_ID)
714  {
715  ret = image_locate_build_id_target(fmap, (const BYTE*)(note + 3 + ((note[0] + 3) >> 2)), note[1]);
716  }
717  }
718  image_unmap_section(&buildid_sect);
719  }
720  /* if present, add the .gnu_debuglink file as an alternate to current one */
721  if (!ret && image_find_section(fmap, ".gnu_debuglink", &debuglink_sect))
722  {
723  const char* dbg_link;
724 
725  found = TRUE;
726  dbg_link = (const char*)image_map_section(&debuglink_sect);
727  if (dbg_link != IMAGE_NO_MAP)
728  {
729  /* The content of a debug link section is:
730  * 1/ a NULL terminated string, containing the file name for the
731  * debug info
732  * 2/ padding on 4 byte boundary
733  * 3/ CRC of the linked file
734  */
735  DWORD crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
736  ret = image_locate_debug_link(module, fmap, dbg_link, crc);
737  if (!ret)
738  WARN("Couldn't load linked debug file for %s\n",
740  }
741  image_unmap_section(&debuglink_sect);
742  }
743  return found ? ret : TRUE;
744 }
745 
746 /***********************************************************************
747  * SymLoadModule (DBGHELP.@)
748  */
750  PCSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
751 {
752  return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll,
753  SizeOfDll, NULL, 0);
754 }
755 
756 /***********************************************************************
757  * SymLoadModuleEx (DBGHELP.@)
758  */
760  PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize,
762 {
763  PWSTR wImageName, wModuleName;
764  unsigned len;
765  DWORD64 ret;
766 
767  TRACE("(%p %p %s %s %s %08x %p %08x)\n",
769  wine_dbgstr_longlong(BaseOfDll), DllSize, Data, Flags);
770 
771  if (ImageName)
772  {
774  wImageName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
775  MultiByteToWideChar(CP_ACP, 0, ImageName, -1, wImageName, len);
776  }
777  else wImageName = NULL;
778  if (ModuleName)
779  {
781  wModuleName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
782  MultiByteToWideChar(CP_ACP, 0, ModuleName, -1, wModuleName, len);
783  }
784  else wModuleName = NULL;
785 
786  ret = SymLoadModuleExW(hProcess, hFile, wImageName, wModuleName,
787  BaseOfDll, DllSize, Data, Flags);
788  HeapFree(GetProcessHeap(), 0, wImageName);
789  HeapFree(GetProcessHeap(), 0, wModuleName);
790  return ret;
791 }
792 
793 /***********************************************************************
794  * SymLoadModuleExW (DBGHELP.@)
795  */
797  PCWSTR wModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll,
799 {
800  struct process* pcs;
801  struct module* module = NULL;
802 
803  TRACE("(%p %p %s %s %s %08x %p %08x)\n",
804  hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName),
805  wine_dbgstr_longlong(BaseOfDll), SizeOfDll, Data, Flags);
806 
807  if (Data)
808  FIXME("Unsupported load data parameter %p for %s\n",
809  Data, debugstr_w(wImageName));
810  if (!validate_addr64(BaseOfDll)) return FALSE;
811 
812  if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
813 
814  if (Flags & SLMFLAG_VIRTUAL)
815  {
816  if (!wImageName) return FALSE;
817  module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0);
818  if (!module) return FALSE;
819  if (wModuleName) module_set_module(module, wModuleName);
821 
822  return TRUE;
823  }
824  if (Flags & ~(SLMFLAG_VIRTUAL))
825  FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName));
826 
827  pcs->loader->synchronize_module_list(pcs);
828 
829  /* this is a Wine extension to the API just to redo the synchronisation */
830  if (!wImageName && !hFile) return 0;
831 
832  /* check if the module is already loaded, or if it's a builtin PE module with
833  * an containing ELF module
834  */
835  if (wImageName)
836  {
837  module = module_is_already_loaded(pcs, wImageName);
838  if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll))
839  {
840  /* force the loading of DLL as builtin */
841  module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
842  }
843  }
844  if (!module)
845  {
846  /* otherwise, try a regular PE module */
847  if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)) &&
848  wImageName)
849  {
850  /* and finally an ELF or Mach-O module */
851  module = pcs->loader->load_module(pcs, wImageName, BaseOfDll);
852  }
853  }
854  if (!module)
855  {
856  WARN("Couldn't locate %s\n", debugstr_w(wImageName));
857  return 0;
858  }
859  module->module.NumSyms = module->ht_symbols.num_elts;
860  /* by default module_new fills module.ModuleName from a derivation
861  * of LoadedImageName. Overwrite it, if we have better information
862  */
863  if (wModuleName)
864  module_set_module(module, wModuleName);
865  if (wImageName)
867 
868  return module->module.BaseOfImage;
869 }
870 
871 /***********************************************************************
872  * SymLoadModule64 (DBGHELP.@)
873  */
875  PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll)
876 {
877  return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll,
878  NULL, 0);
879 }
880 
881 /******************************************************************
882  * module_remove
883  *
884  */
885 BOOL module_remove(struct process* pcs, struct module* module)
886 {
887  struct module_format*modfmt;
888  struct module** p;
889  unsigned i;
890 
891  TRACE("%s (%p)\n", debugstr_w(module->module.ModuleName), module);
892 
893  for (i = 0; i < DFI_LAST; i++)
894  {
895  if ((modfmt = module->format_info[i]) && modfmt->remove)
896  modfmt->remove(pcs, module->format_info[i]);
897  }
904  /* native dbghelp doesn't invoke registered callback(,CBA_SYMBOLS_UNLOADED,) here
905  * so do we
906  */
907  for (p = &pcs->lmodules; *p; p = &(*p)->next)
908  {
909  if (*p == module)
910  {
911  *p = module->next;
913  return TRUE;
914  }
915  }
916  FIXME("This shouldn't happen\n");
917  return FALSE;
918 }
919 
920 /******************************************************************
921  * SymUnloadModule (DBGHELP.@)
922  *
923  */
925 {
926  struct process* pcs;
927  struct module* module;
928 
930  if (!pcs) return FALSE;
931  module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
932  if (!module) return FALSE;
933  return module_remove(pcs, module);
934 }
935 
936 /******************************************************************
937  * SymUnloadModule64 (DBGHELP.@)
938  *
939  */
941 {
942  struct process* pcs;
943  struct module* module;
944 
946  if (!pcs) return FALSE;
947  if (!validate_addr64(BaseOfDll)) return FALSE;
948  module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
949  if (!module) return FALSE;
950  return module_remove(pcs, module);
951 }
952 
953 /******************************************************************
954  * SymEnumerateModules (DBGHELP.@)
955  *
956  */
958 {
962 };
963 
965 {
966  struct enum_modW64_32* x = user;
967 
968  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
969  return x->cb(x->module, (DWORD)base, x->user);
970 }
971 
973  PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
974  PVOID UserContext)
975 {
976  struct enum_modW64_32 x;
977 
978  x.cb = EnumModulesCallback;
979  x.user = UserContext;
980 
982 }
983 
984 /******************************************************************
985  * SymEnumerateModules64 (DBGHELP.@)
986  *
987  */
989 {
993 };
994 
996 {
997  struct enum_modW64_64* x = user;
998 
999  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
1000  return x->cb(x->module, base, x->user);
1001 }
1002 
1004  PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
1005  PVOID UserContext)
1006 {
1007  struct enum_modW64_64 x;
1008 
1009  x.cb = EnumModulesCallback;
1010  x.user = UserContext;
1011 
1013 }
1014 
1015 /******************************************************************
1016  * SymEnumerateModulesW64 (DBGHELP.@)
1017  *
1018  */
1020  PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback,
1021  PVOID UserContext)
1022 {
1023  struct process* pcs = process_find_by_handle(hProcess);
1024  struct module* module;
1025 
1026  if (!pcs) return FALSE;
1027 
1028  for (module = pcs->lmodules; module; module = module->next)
1029  {
1030  if (!dbghelp_opt_native &&
1031  (module->type == DMT_ELF || module->type == DMT_MACHO))
1032  continue;
1033  if (!EnumModulesCallback(module->modulename,
1034  module->module.BaseOfImage, UserContext))
1035  break;
1036  }
1037  return TRUE;
1038 }
1039 
1040 #ifndef DBGHELP_STATIC_LIB
1041 /******************************************************************
1042  * EnumerateLoadedModules64 (DBGHELP.@)
1043  *
1044  */
1046 {
1050 };
1051 
1053  PVOID user)
1054 {
1055  struct enum_load_modW64_64* x = user;
1056 
1057  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
1058  return x->cb(x->module, base, size, x->user);
1059 }
1060 
1062  PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
1063  PVOID UserContext)
1064 {
1065  struct enum_load_modW64_64 x;
1066 
1067  x.cb = EnumLoadedModulesCallback;
1068  x.user = UserContext;
1069 
1071 }
1072 
1073 /******************************************************************
1074  * EnumerateLoadedModules (DBGHELP.@)
1075  *
1076  */
1078 {
1082 };
1083 
1085  PVOID user)
1086 {
1087  struct enum_load_modW64_32* x = user;
1088  WideCharToMultiByte(CP_ACP, 0, name, -1, x->module, sizeof(x->module), NULL, NULL);
1089  return x->cb(x->module, (DWORD)base, size, x->user);
1090 }
1091 
1093  PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
1094  PVOID UserContext)
1095 {
1096  struct enum_load_modW64_32 x;
1097 
1098  x.cb = EnumLoadedModulesCallback;
1099  x.user = UserContext;
1100 
1102 }
1103 
1104 /******************************************************************
1105  * EnumerateLoadedModulesW64 (DBGHELP.@)
1106  *
1107  */
1109  PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback,
1110  PVOID UserContext)
1111 {
1112  HMODULE* hMods;
1113  WCHAR baseW[256], modW[256];
1114  DWORD i, sz;
1115  MODULEINFO mi;
1116 
1117  hMods = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(hMods[0]));
1118  if (!hMods) return FALSE;
1119 
1120  if (!EnumProcessModules(hProcess, hMods, 256 * sizeof(hMods[0]), &sz))
1121  {
1122  /* hProcess should also be a valid process handle !! */
1123  FIXME("If this happens, bump the number in mod\n");
1124  HeapFree(GetProcessHeap(), 0, hMods);
1125  return FALSE;
1126  }
1127  sz /= sizeof(HMODULE);
1128  for (i = 0; i < sz; i++)
1129  {
1130  if (!GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) ||
1132  continue;
1134  EnumLoadedModulesCallback(modW, (DWORD_PTR)mi.lpBaseOfDll, mi.SizeOfImage,
1135  UserContext);
1136  }
1137  HeapFree(GetProcessHeap(), 0, hMods);
1138 
1139  return sz != 0 && i == sz;
1140 }
1141 
1142 #endif /* DBGHELP_STATIC_LIB */
1143 
1144 static void dbghelp_str_WtoA(const WCHAR *src, char *dst, int dst_len)
1145 {
1146  WideCharToMultiByte(CP_ACP, 0, src, -1, dst, dst_len - 1, NULL, NULL);
1147  dst[dst_len - 1] = 0;
1148 }
1149 
1150 /******************************************************************
1151  * SymGetModuleInfo (DBGHELP.@)
1152  *
1153  */
1155  PIMAGEHLP_MODULE ModuleInfo)
1156 {
1158  IMAGEHLP_MODULEW64 miw64;
1159 
1160  if (sizeof(mi) < ModuleInfo->SizeOfStruct) FIXME("Wrong size\n");
1161 
1162  miw64.SizeOfStruct = sizeof(miw64);
1163  if (!SymGetModuleInfoW64(hProcess, dwAddr, &miw64)) return FALSE;
1164 
1165  mi.SizeOfStruct = ModuleInfo->SizeOfStruct;
1166  mi.BaseOfImage = miw64.BaseOfImage;
1167  mi.ImageSize = miw64.ImageSize;
1168  mi.TimeDateStamp = miw64.TimeDateStamp;
1169  mi.CheckSum = miw64.CheckSum;
1170  mi.NumSyms = miw64.NumSyms;
1171  mi.SymType = miw64.SymType;
1172  dbghelp_str_WtoA(miw64.ModuleName, mi.ModuleName, sizeof(mi.ModuleName));
1173  dbghelp_str_WtoA(miw64.ImageName, mi.ImageName, sizeof(mi.ImageName));
1174  dbghelp_str_WtoA(miw64.LoadedImageName, mi.LoadedImageName, sizeof(mi.LoadedImageName));
1175 
1176  memcpy(ModuleInfo, &mi, ModuleInfo->SizeOfStruct);
1177 
1178  return TRUE;
1179 }
1180 
1181 /******************************************************************
1182  * SymGetModuleInfoW (DBGHELP.@)
1183  *
1184  */
1186  PIMAGEHLP_MODULEW ModuleInfo)
1187 {
1188  IMAGEHLP_MODULEW64 miw64;
1189  IMAGEHLP_MODULEW miw;
1190 
1191  if (sizeof(miw) < ModuleInfo->SizeOfStruct) FIXME("Wrong size\n");
1192 
1193  miw64.SizeOfStruct = sizeof(miw64);
1194  if (!SymGetModuleInfoW64(hProcess, dwAddr, &miw64)) return FALSE;
1195 
1196  miw.SizeOfStruct = ModuleInfo->SizeOfStruct;
1197  miw.BaseOfImage = miw64.BaseOfImage;
1198  miw.ImageSize = miw64.ImageSize;
1199  miw.TimeDateStamp = miw64.TimeDateStamp;
1200  miw.CheckSum = miw64.CheckSum;
1201  miw.NumSyms = miw64.NumSyms;
1202  miw.SymType = miw64.SymType;
1203  lstrcpyW(miw.ModuleName, miw64.ModuleName);
1204  lstrcpyW(miw.ImageName, miw64.ImageName);
1206  memcpy(ModuleInfo, &miw, ModuleInfo->SizeOfStruct);
1207 
1208  return TRUE;
1209 }
1210 
1211 /******************************************************************
1212  * SymGetModuleInfo64 (DBGHELP.@)
1213  *
1214  */
1216  PIMAGEHLP_MODULE64 ModuleInfo)
1217 {
1218  IMAGEHLP_MODULE64 mi64;
1219  IMAGEHLP_MODULEW64 miw64;
1220 
1221  if (sizeof(mi64) < ModuleInfo->SizeOfStruct)
1222  {
1223  SetLastError(ERROR_MOD_NOT_FOUND); /* NOTE: native returns this error */
1224  WARN("Wrong size %u\n", ModuleInfo->SizeOfStruct);
1225  return FALSE;
1226  }
1227 
1228  miw64.SizeOfStruct = sizeof(miw64);
1229  if (!SymGetModuleInfoW64(hProcess, dwAddr, &miw64)) return FALSE;
1230 
1231  mi64.SizeOfStruct = ModuleInfo->SizeOfStruct;
1232  mi64.BaseOfImage = miw64.BaseOfImage;
1233  mi64.ImageSize = miw64.ImageSize;
1234  mi64.TimeDateStamp = miw64.TimeDateStamp;
1235  mi64.CheckSum = miw64.CheckSum;
1236  mi64.NumSyms = miw64.NumSyms;
1237  mi64.SymType = miw64.SymType;
1238  dbghelp_str_WtoA(miw64.ModuleName, mi64.ModuleName, sizeof(mi64.ModuleName));
1239  dbghelp_str_WtoA(miw64.ImageName, mi64.ImageName, sizeof(mi64.ImageName));
1241  dbghelp_str_WtoA(miw64.LoadedPdbName, mi64.LoadedPdbName, sizeof(mi64.LoadedPdbName));
1242 
1243  mi64.CVSig = miw64.CVSig;
1244  dbghelp_str_WtoA(miw64.CVData, mi64.CVData, sizeof(mi64.CVData));
1245  mi64.PdbSig = miw64.PdbSig;
1246  mi64.PdbSig70 = miw64.PdbSig70;
1247  mi64.PdbAge = miw64.PdbAge;
1248  mi64.PdbUnmatched = miw64.PdbUnmatched;
1249  mi64.DbgUnmatched = miw64.DbgUnmatched;
1250  mi64.LineNumbers = miw64.LineNumbers;
1251  mi64.GlobalSymbols = miw64.GlobalSymbols;
1252  mi64.TypeInfo = miw64.TypeInfo;
1253  mi64.SourceIndexed = miw64.SourceIndexed;
1254  mi64.Publics = miw64.Publics;
1255 
1256  memcpy(ModuleInfo, &mi64, ModuleInfo->SizeOfStruct);
1257 
1258  return TRUE;
1259 }
1260 
1261 /******************************************************************
1262  * SymGetModuleInfoW64 (DBGHELP.@)
1263  *
1264  */
1266  PIMAGEHLP_MODULEW64 ModuleInfo)
1267 {
1268  struct process* pcs = process_find_by_handle(hProcess);
1269  struct module* module;
1270  IMAGEHLP_MODULEW64 miw64;
1271 
1272  TRACE("%p %s %p\n", hProcess, wine_dbgstr_longlong(dwAddr), ModuleInfo);
1273 
1274  if (!pcs) return FALSE;
1275  if (ModuleInfo->SizeOfStruct > sizeof(*ModuleInfo)) return FALSE;
1276  module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
1277  if (!module) return FALSE;
1278 
1279  miw64 = module->module;
1280 
1281  /* update debug information from container if any */
1282  if (module->module.SymType == SymNone)
1283  {
1285  if (module && module->module.SymType != SymNone)
1286  {
1287  miw64.SymType = module->module.SymType;
1288  miw64.NumSyms = module->module.NumSyms;
1289  }
1290  }
1291  memcpy(ModuleInfo, &miw64, ModuleInfo->SizeOfStruct);
1292  return TRUE;
1293 }
1294 
1295 /***********************************************************************
1296  * SymGetModuleBase (DBGHELP.@)
1297  */
1299 {
1300  DWORD64 ret;
1301 
1302  ret = SymGetModuleBase64(hProcess, dwAddr);
1303  return validate_addr64(ret) ? ret : 0;
1304 }
1305 
1306 /***********************************************************************
1307  * SymGetModuleBase64 (DBGHELP.@)
1308  */
1310 {
1311  struct process* pcs = process_find_by_handle(hProcess);
1312  struct module* module;
1313 
1314  if (!pcs) return 0;
1315  module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
1316  if (!module) return 0;
1317  return module->module.BaseOfImage;
1318 }
1319 
1320 /******************************************************************
1321  * module_reset_debug_info
1322  * Removes any debug information linked to a given module.
1323  */
1325 {
1327  module->sorttab_size = 0;
1331  module->ht_symbols.num_buckets = 0;
1332  module->ht_symbols.buckets = NULL;
1334  module->ht_types.num_buckets = 0;
1335  module->ht_types.buckets = NULL;
1336  module->vtypes.num_elts = 0;
1339  module->sources = NULL;
1340 }
1341 
1342 /******************************************************************
1343  * SymRefreshModuleList (DBGHELP.@)
1344  */
1346 {
1347  struct process* pcs;
1348 
1349  TRACE("(%p)\n", hProcess);
1350 
1351  if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
1352 
1353  return pcs->loader->synchronize_module_list(pcs);
1354 }
1355 
1356 /***********************************************************************
1357  * SymFunctionTableAccess (DBGHELP.@)
1358  */
1360 {
1361  return SymFunctionTableAccess64(hProcess, AddrBase);
1362 }
1363 
1364 /***********************************************************************
1365  * SymFunctionTableAccess64 (DBGHELP.@)
1366  */
1368 {
1369  struct process* pcs = process_find_by_handle(hProcess);
1370  struct module* module;
1371 
1372  if (!pcs || !dbghelp_current_cpu->find_runtime_function) return NULL;
1373  module = module_find_by_addr(pcs, AddrBase, DMT_UNKNOWN);
1374  if (!module) return NULL;
1375 
1376  return dbghelp_current_cpu->find_runtime_function(module, AddrBase);
1377 }
1378 
1380 {
1381  return FALSE;
1382 }
1383 
1384 static struct module* native_load_module(struct process* pcs, const WCHAR* name, ULONG_PTR addr)
1385 {
1386  return NULL;
1387 }
1388 
1390 {
1391  return FALSE;
1392 }
1393 
1395 {
1396  return FALSE;
1397 }
1398 
1400  DWORD* size, DWORD* checksum)
1401 {
1402  return FALSE;
1403 }
1404 
1406 {
1412 };
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:972
SYM_TYPE SymType
Definition: compat.h:992
const uint16_t * PCWSTR
Definition: typedefs.h:57
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACKW64)(PCWSTR, DWORD64, ULONG, PVOID)
Definition: compat.h:935
#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:1144
BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll)
Definition: module.c:924
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
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:1384
#define CloseHandle
Definition: compat.h:487
BOOL WINAPI SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULE ModuleInfo)
Definition: module.c:1154
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:697
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:934
#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE
Definition: compat.h:725
#define WideCharToMultiByte
Definition: compat.h:111
WCHAR ModuleName[32]
Definition: compat.h:824
void module_reset_debug_info(struct module *module)
Definition: module.c:1324
static BOOL native_load_debug_info(struct process *process, struct module *module)
Definition: module.c:1389
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:818
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:940
DWORD BaseOfImage
Definition: compat.h:964
CHAR LoadedPdbName[256]
Definition: compat.h:996
#define WARN(fmt,...)
Definition: debug.h:112
struct vector vsymt
CHAR ModuleName[32]
Definition: compat.h:993
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:971
#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:796
#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
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
#define assert(x)
Definition: debug.h:53
#define SLMFLAG_VIRTUAL
Definition: compat.h:774
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:995
BOOL WINAPI SymGetModuleInfoW(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULEW ModuleInfo)
Definition: module.c:1185
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:509
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:617
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:1052
char * sources
#define lstrlenW
Definition: compat.h:498
BOOL WINAPI EnumerateLoadedModules(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1092
int load_addr
Definition: mkisofs.c:104
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACK)(PCSTR, ULONG, ULONG, PVOID)
Definition: compat.h:974
DWORD CheckSum
Definition: compat.h:967
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:1309
#define lstrcpynW
Definition: compat.h:486
WCHAR FileName[MAX_PATH+1]
Definition: compat.h:915
DWORD TimeDateStamp
Definition: compat.h:989
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:749
WCHAR LoadedImageName[256]
Definition: compat.h:826
BOOL WINAPI SymEnumerateModules64(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, PVOID UserContext)
Definition: module.c:1003
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
BOOL module_get_debug(struct module_pair *pair)
Definition: module.c:374
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const 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:980
BOOL(CALLBACK * PSYM_ENUMMODULES_CALLBACKW64)(PCWSTR, DWORD64, PVOID)
Definition: compat.h:933
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:1394
GLdouble GLdouble z
Definition: glext.h:5874
int note(char *format,...)
Definition: util.c:12
static BOOL is_wine_loader(const WCHAR *module)
Definition: module.c:83
smooth NULL
Definition: ftsmooth.c:416
PENUMLOADED_MODULES_CALLBACK64 cb
Definition: module.c:1047
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:726
BOOL WINAPI EnumerateLoadedModules64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1061
unsigned num_sorttab
DWORD SizeOfStruct
Definition: compat.h:986
DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess, HMODULE hModule, LPWSTR lpBaseName, DWORD nSize)
Definition: psapi.c:930
PVOID user
Definition: module.c:960
#define OPEN_EXISTING
Definition: compat.h:523
BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1108
BOOL WINAPI SymEnumerateModulesW64(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, PVOID UserContext)
Definition: module.c:1019
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:874
#define TRACE(s)
Definition: solgame.cpp:4
struct image_file_map * alternate
GLsizeiptr size
Definition: glext.h:5919
DWORD64 reloc_delta
static const WCHAR S_AcmW[]
Definition: module.c:47
BOOL WINAPI EnumProcessModules(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded)
Definition: psapi.c:542
#define GetProcessHeap()
Definition: compat.h:484
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:972
#define debugstr_a
Definition: kernel32.h:31
DWORD64 BaseOfImage
Definition: compat.h:987
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:964
#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:825
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD SizeOfStruct
Definition: compat.h:963
#define SetLastError(x)
Definition: compat.h:500
SYM_TYPE SymType
Definition: compat.h:969
PVOID user
Definition: module.c:991
DWORD ImageSize
Definition: compat.h:965
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:970
PSYM_ENUMMODULES_CALLBACK cb
Definition: module.c:959
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:1265
#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:817
SYM_TYPE SymType
Definition: compat.h:823
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:885
#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:1405
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:1367
_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
GLuint in
Definition: glext.h:9616
#define lstrcpyW
Definition: compat.h:497
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:990
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:932
GLenum GLenum dst
Definition: glext.h:6340
CHAR CVData[MAX_PATH *3]
Definition: compat.h:998
DWORD TimeDateStamp
Definition: compat.h:820
struct hash_table ht_types
#define ReadFile(a, b, c, d, e)
Definition: compat.h:490
WCHAR CVData[MAX_PATH *3]
Definition: compat.h:829
DWORD calc_crc32(HANDLE handle)
Definition: dbghelp.c:848
#define CBA_DEFERRED_SYMBOL_LOAD_START
Definition: compat.h:724
Definition: _pair.h:47
#define min(a, b)
Definition: monoChain.cc:55
DWORD TimeDateStamp
Definition: compat.h:966
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:1080
WCHAR LoadedPdbName[256]
Definition: compat.h:827
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:168
#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:489
DWORD64 WINAPI SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize, PMODLOAD_DATA Data, DWORD Flags)
Definition: module.c:759
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:994
Definition: name.c:38
static const WCHAR S_DllW[]
Definition: module.c:48
BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
Definition: module.c:1345
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:1079
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
DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
Definition: module.c:1298
GLfloat GLfloat p
Definition: glext.h:8902
DWORD SizeOfStruct
Definition: compat.h:950
#define memset(x, y, z)
Definition: compat.h:39
PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
Definition: module.c:1359
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:483
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
#define SetFilePointer
Definition: compat.h:491
CHAR LoadedImageName[256]
Definition: compat.h:995
BOOL WINAPI SymGetModuleInfo64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULE64 ModuleInfo)
Definition: module.c:1215
static BOOL CALLBACK enum_load_modW64_32(PCWSTR name, DWORD64 base, ULONG size, PVOID user)
Definition: module.c:1084
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:1399
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static BOOL native_synchronize_module_list(struct process *pcs)
Definition: module.c:1379
BOOL(* enum_modules_cb)(const WCHAR *, ULONG_PTR addr, void *user)
Definition: fci.c:126
GLuint const GLchar * name
Definition: glext.h:6031