ReactOS 0.4.15-dev-7788-g1ad9096
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
40const WCHAR S_ElfW[] = {'<','e','l','f','>','\0'};
41#ifndef __REACTOS__
42const WCHAR S_WineLoaderW[] = {'<','w','i','n','e','-','l','o','a','d','e','r','>','\0'};
43#endif
44static const WCHAR S_DotSoW[] = {'.','s','o','\0'};
45const WCHAR S_SlashW[] = {'/','\0'};
46
47static const WCHAR S_AcmW[] = {'.','a','c','m','\0'};
48static const WCHAR S_DllW[] = {'.','d','l','l','\0'};
49static const WCHAR S_DrvW[] = {'.','d','r','v','\0'};
50static const WCHAR S_ExeW[] = {'.','e','x','e','\0'};
51static const WCHAR S_OcxW[] = {'.','o','c','x','\0'};
52static const WCHAR S_VxdW[] = {'.','v','x','d','\0'};
53static const WCHAR * const ext[] = {S_AcmW, S_DllW, S_DrvW, S_ExeW, S_OcxW, S_VxdW, NULL};
54
55static 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
70static 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;
91 DWORD len;
92
93 if ((ptr = getenv("WINELOADER")))
94 {
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) );
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
118static 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
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) );
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
184static 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 */
198struct 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);
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),
217
218 pool_init(&module->pool, 65536);
219
220 module->process = pcs;
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;
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;
269 module->sources = 0;
271
272 return module;
273}
274
275/***********************************************************************
276 * module_find_by_nameW
277 *
278 */
279struct 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
291struct 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 */
303struct 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 */
329static 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 */
349struct 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 */
420struct 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)) ||
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 &&
437 addr < module->module.BaseOfImage + module->module.ImageSize)
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 */
451static 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;
461
462 for (module = pcs->lmodules; module; module = module->next)
463 {
464 if ((module->type == DMT_ELF || module->type == DMT_MACHO) &&
466 base < module->module.BaseOfImage + module->module.ImageSize)
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
481static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc)
482{
485#ifndef DBGHELP_STATIC_LIB
486 WCHAR *path;
487#endif
488 WORD magic;
489 BOOL ret;
490
491#ifndef DBGHELP_STATIC_LIB
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 */
543static 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);
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);
606 HeapFree(GetProcessHeap(), 0, fmap_link);
607 return FALSE;
608
609found:
610 TRACE("Located debug information file %s at %s\n", filename, debugstr_w(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 */
621static 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
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));
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");
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{
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
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 }
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 */
890{
891 struct module_format*modfmt;
892 struct module** p;
893 unsigned i;
894
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{
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
1148static 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{
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{
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{
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
1388static 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
1405{
1406 return FALSE;
1407}
1408
1410{
1416};
static WCHAR baseW[MAX_PATH]
Definition: FindFiles.c:24
unsigned int UINT32
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
_In_ ULONG _Out_writes_bytes_opt_ InformationLength PAUX_MODULE_EXTENDED_INFO ModuleInfo
Definition: aux_klib.h:65
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:33
int note(char *format,...)
Definition: util.c:12
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
r l[0]
Definition: byte_order.h:168
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
void hash_table_init(struct pool *pool, struct hash_table *ht, unsigned num_buckets) DECLSPEC_HIDDEN
Definition: storage.c:334
void vector_init(struct vector *v, unsigned elt_sz, unsigned bucket_sz) DECLSPEC_HIDDEN
Definition: storage.c:133
const char * file_nameA(const char *str) DECLSPEC_HIDDEN
Definition: path.c:37
struct module * pe_load_builtin_module(struct process *pcs, const WCHAR *name, DWORD64 base, DWORD64 size) DECLSPEC_HIDDEN
Definition: pe_module.c:896
WCHAR * get_dos_file_name(const WCHAR *filename) DECLSPEC_HIDDEN
Definition: path.c:671
int source_rb_compare(const void *key, const struct wine_rb_entry *entry) DECLSPEC_HIDDEN
Definition: source.c:40
void pool_init(struct pool *a, size_t arena_size) DECLSPEC_HIDDEN
Definition: storage.c:43
void pool_destroy(struct pool *a) DECLSPEC_HIDDEN
Definition: storage.c:50
@ DFI_LAST
BOOL(* enum_modules_cb)(const WCHAR *, ULONG_PTR addr, void *user)
struct module * pe_load_native_module(struct process *pcs, const WCHAR *name, HANDLE hFile, DWORD64 base, DWORD size) DECLSPEC_HIDDEN
Definition: pe_module.c:803
void hash_table_destroy(struct hash_table *ht) DECLSPEC_HIDDEN
Definition: storage.c:342
BOOL pe_load_debug_info(const struct process *pcs, struct module *module) DECLSPEC_HIDDEN
Definition: pe_module.c:751
module_type
@ DMT_UNKNOWN
@ DMT_PE
@ DMT_MACHO
@ DMT_ELF
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
#define CloseHandle
Definition: compat.h:739
#define CP_UNIXCP
Definition: compat.h:79
#define GetProcessHeap()
Definition: compat.h:736
#define FILE_BEGIN
Definition: compat.h:761
#define ERROR_MOD_NOT_FOUND
Definition: compat.h:104
#define wcsnicmp
Definition: compat.h:14
@ SymNone
Definition: compat.h:1056
@ SymDeferred
Definition: compat.h:1061
@ SymVirtual
Definition: compat.h:1064
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define SLMFLAG_VIRTUAL
Definition: compat.h:1026
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE
Definition: compat.h:977
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACK)(PCSTR, ULONG, ULONG, PVOID)
Definition: compat.h:1226
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE
Definition: compat.h:978
#define GENERIC_READ
Definition: compat.h:135
BOOL(CALLBACK * PSYM_ENUMMODULES_CALLBACK)(PCSTR, ULONG, PVOID)
Definition: compat.h:1232
BOOL(CALLBACK * PSYM_ENUMMODULES_CALLBACKW64)(PCWSTR, DWORD64, PVOID)
Definition: compat.h:1185
#define MAX_PATH
Definition: compat.h:34
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACK64)(PCSTR, DWORD64, ULONG, PVOID)
Definition: compat.h:1186
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
BOOL(CALLBACK * PENUMLOADED_MODULES_CALLBACKW64)(PCWSTR, DWORD64, ULONG, PVOID)
Definition: compat.h:1187
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define CBA_DEFERRED_SYMBOL_LOAD_START
Definition: compat.h:976
#define MultiByteToWideChar
Definition: compat.h:110
BOOL(CALLBACK * PSYM_ENUMMODULES_CALLBACK64)(PCSTR, DWORD64, PVOID)
Definition: compat.h:1184
#define FILE_SHARE_READ
Definition: compat.h:136
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
DWORD calc_crc32(HANDLE handle)
Definition: dbghelp.c:874
BOOL validate_addr64(DWORD64 addr)
Definition: dbghelp.c:112
BOOL pcs_callback(const struct process *pcs, ULONG action, void *data)
Definition: dbghelp.c:731
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
BOOL dbghelp_opt_native
Definition: dbghelp.c:74
struct cpu * dbghelp_current_cpu
Definition: dbghelp.c:169
BOOL WINAPI SymGetModuleInfoW(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULEW ModuleInfo)
Definition: module.c:1189
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 BOOL native_synchronize_module_list(struct process *pcs)
Definition: module.c:1383
DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
Definition: module.c:1302
static const WCHAR S_OcxW[]
Definition: module.c:51
BOOL WINAPI SymEnumerateModules(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, PVOID UserContext)
Definition: module.c:976
BOOL image_check_alternate(struct image_file_map *fmap, const struct module *module)
Definition: module.c:701
BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll)
Definition: module.c:928
static BOOL module_is_container_loaded(const struct process *pcs, const WCHAR *ImageName, DWORD64 base)
Definition: module.c:451
static struct module * module_get_container(const struct process *pcs, const struct module *inner)
Definition: module.c:329
const WCHAR S_ElfW[]
Definition: module.c:40
static BOOL image_check_debug_link(const WCHAR *file, struct image_file_map *fmap, DWORD link_crc)
Definition: module.c:481
DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageName, PCWSTR wModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll, PMODLOAD_DATA Data, DWORD Flags)
Definition: module.c:800
BOOL WINAPI SymGetModuleInfoW64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULEW64 ModuleInfo)
Definition: module.c:1269
static const WCHAR S_DllW[]
Definition: module.c:48
static const WCHAR S_ExeW[]
Definition: module.c:50
BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1112
static int match_ext(const WCHAR *ptr, size_t len)
Definition: module.c:55
PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
Definition: module.c:1363
void module_set_module(struct module *module, const WCHAR *name)
Definition: module.c:142
BOOL WINAPI EnumerateLoadedModules(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1096
PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase)
Definition: module.c:1371
BOOL WINAPI SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll)
Definition: module.c:944
BOOL WINAPI SymEnumerateModulesW64(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, PVOID UserContext)
Definition: module.c:1023
static struct module * native_load_module(struct process *pcs, const WCHAR *name, ULONG_PTR addr)
Definition: module.c:1388
DWORD64 WINAPI SymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr)
Definition: module.c:1313
static const WCHAR S_DotSoW[]
Definition: module.c:44
struct module * module_is_already_loaded(const struct process *pcs, const WCHAR *name)
Definition: module.c:303
static const char * get_module_type(enum module_type type, BOOL virtual)
Definition: module.c:184
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
struct module * module_find_by_addr(const struct process *pcs, DWORD64 addr, enum module_type type)
Definition: module.c:420
void module_reset_debug_info(struct module *module)
Definition: module.c:1328
struct module * module_get_containee(const struct process *pcs, const struct module *outer)
Definition: module.c:349
BOOL module_get_debug(struct module_pair *pair)
Definition: module.c:374
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 const WCHAR S_DrvW[]
Definition: module.c:49
DWORD64 WINAPI SymLoadModule64(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll)
Definition: module.c:878
static const WCHAR S_AcmW[]
Definition: module.c:47
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
const struct loader_ops no_loader_ops
Definition: module.c:1409
WCHAR * get_wine_loader_name(struct process *pcs)
Definition: module.c:150
BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
Definition: module.c:1349
static void dbghelp_str_WtoA(const WCHAR *src, char *dst, int dst_len)
Definition: module.c:1148
static BOOL native_load_debug_info(struct process *process, struct module *module)
Definition: module.c:1393
static const WCHAR S_VxdW[]
Definition: module.c:52
BOOL WINAPI SymEnumerateModules64(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, PVOID UserContext)
Definition: module.c:1007
static BOOL image_locate_build_id_target(struct image_file_map *fmap, const BYTE *id, unsigned idlen)
Definition: module.c:621
static const WCHAR * get_filename(const WCHAR *name, const WCHAR *endptr)
Definition: module.c:70
BOOL module_remove(struct process *pcs, struct module *module)
Definition: module.c:889
const WCHAR S_WineLoaderW[]
Definition: module.c:42
static BOOL native_enum_modules(struct process *process, enum_modules_cb cb, void *user)
Definition: module.c:1398
#define NOTE_GNU_BUILD_ID
Definition: module.c:38
BOOL WINAPI EnumerateLoadedModules64(HANDLE hProcess, PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, PVOID UserContext)
Definition: module.c:1065
static void module_fill_module(const WCHAR *in, WCHAR *out, size_t size)
Definition: module.c:118
BOOL WINAPI SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULE ModuleInfo)
Definition: module.c:1158
static const WCHAR *const ext[]
Definition: module.c:53
BOOL WINAPI SymGetModuleInfo64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULE64 ModuleInfo)
Definition: module.c:1219
const WCHAR S_SlashW[]
Definition: module.c:45
struct module * module_find_by_nameA(const struct process *pcs, const char *name)
Definition: module.c:291
static BOOL is_wine_loader(const WCHAR *module)
Definition: module.c:83
struct module * module_find_by_nameW(const struct process *pcs, const WCHAR *name)
Definition: module.c:279
DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
Definition: module.c:753
BOOL WINAPI EnumProcessModules(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded)
Definition: psapi.c:526
BOOL WINAPI GetModuleInformation(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb)
Definition: psapi.c:1064
DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess, HMODULE hModule, LPWSTR lpBaseName, DWORD nSize)
Definition: psapi.c:914
#define assert(x)
Definition: debug.h:53
BOOL elf_map_handle(HANDLE handle, struct image_file_map *fmap)
Definition: elf_module.c:582
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLdouble GLdouble z
Definition: glext.h:5874
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
BOOL pe_map_file(HANDLE file, struct image_file_map *fmap, enum module_type mt) DECLSPEC_HIDDEN
Definition: pe_module.c:245
#define IMAGE_NO_MAP
Definition: image_private.h:24
static void image_unmap_section(struct image_section_map *ism)
static BOOL image_find_section(struct image_file_map *fmap, const char *name, struct image_section_map *ism)
static const char * image_map_section(struct image_section_map *ism)
static void image_unmap_file(struct image_file_map *fmap)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
const char * filename
Definition: ioapi.h:137
#define e
Definition: ke_i.h:82
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
static WCHAR wineW[]
Definition: localmon.c:128
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
int load_addr
Definition: mkisofs.c:104
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static PVOID ptr
Definition: dispmode.c:27
static DWORD path_len
Definition: batch.c:31
static const char * ImageName
Definition: image.c:34
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define min(a, b)
Definition: monoChain.cc:55
_In_ HANDLE hFile
Definition: mswsock.h:90
u32_t magic(void)
static BOOL read_bytes(parse_buffer *buf, LPVOID data, DWORD size)
Definition: parsing.c:168
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
static FILE * out
Definition: regtests2xml.c:44
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static void wine_rb_init(struct wine_rb_tree *tree, wine_rb_compare_func_t compare)
Definition: rbtree.h:179
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR FileName[MAX_PATH+1]
Definition: compat.h:1167
SYM_TYPE SymType
Definition: compat.h:1244
DWORD TimeDateStamp
Definition: compat.h:1241
CHAR CVData[MAX_PATH *3]
Definition: compat.h:1250
DWORD SizeOfStruct
Definition: compat.h:1238
CHAR LoadedImageName[256]
Definition: compat.h:1247
DWORD64 BaseOfImage
Definition: compat.h:1239
CHAR LoadedPdbName[256]
Definition: compat.h:1248
CHAR ModuleName[32]
Definition: compat.h:1245
CHAR ImageName[256]
Definition: compat.h:1246
WCHAR ModuleName[32]
Definition: compat.h:1076
WCHAR CVData[MAX_PATH *3]
Definition: compat.h:1081
DWORD64 BaseOfImage
Definition: compat.h:1070
WCHAR LoadedImageName[256]
Definition: compat.h:1078
WCHAR LoadedPdbName[256]
Definition: compat.h:1079
WCHAR ImageName[256]
Definition: compat.h:1077
SYM_TYPE SymType
Definition: compat.h:1075
DWORD TimeDateStamp
Definition: compat.h:1218
WCHAR ModuleName[32]
Definition: compat.h:1222
WCHAR ImageName[256]
Definition: compat.h:1223
DWORD SizeOfStruct
Definition: compat.h:1215
SYM_TYPE SymType
Definition: compat.h:1221
DWORD BaseOfImage
Definition: compat.h:1216
WCHAR LoadedImageName[256]
Definition: compat.h:1224
PENUMLOADED_MODULES_CALLBACK cb
Definition: module.c:1083
PENUMLOADED_MODULES_CALLBACK64 cb
Definition: module.c:1051
PSYM_ENUMMODULES_CALLBACK cb
Definition: module.c:963
PVOID user
Definition: module.c:964
PVOID user
Definition: module.c:995
PSYM_ENUMMODULES_CALLBACK64 cb
Definition: module.c:994
Definition: fci.c:127
struct image_file_map * alternate
struct image_file_map * fmap
void(* remove)(struct process *pcs, struct module_format *modfmt)
unsigned num_sorttab
DWORD64 reloc_delta
unsigned num_symbols
WCHAR modulename[64]
unsigned short is_virtual
struct symt_ht ** addr_sorttab
struct wine_rb_tree sources_offsets_tree
IMAGEHLP_MODULEW64 module
int sortlist_valid
struct process * process
struct hash_table ht_types
unsigned sorttab_size
unsigned sources_used
char * sources
struct module_format * format_info[DFI_LAST]
unsigned sources_alloc
struct vector vsymt
struct hash_table ht_symbols
struct module * next
enum module_type type
WCHAR * real_path
struct pool pool
struct vector vtypes
Definition: name.c:39
Definition: _pair.h:47
const struct loader_ops * loader
struct module * lmodules
#define max(a, b)
Definition: svc.c:63
#define towlower(c)
Definition: wctype.h:97
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint64_t DWORD64
Definition: typedefs.h:67
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG_PTR
Definition: typedefs.h:65
HANDLE HMODULE
Definition: typedefs.h:77
uint32_t ULONG
Definition: typedefs.h:59
static const WCHAR modW[]
Definition: lex.c:66
int ret
static MONITORINFO mi
Definition: win.c:7338
#define WINAPI
Definition: msvc.h:6
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193