Added support for 'loading' virtual modules.
[wine] / dlls / dbghelp / module.c
1 /*
2  * File module.c - module handling for the wine debugger
3  *
4  * Copyright (C) 1993,      Eric Youngdale.
5  *               2000-2004, 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
27
28 #include "dbghelp_private.h"
29 #include "psapi.h"
30 #include "winreg.h"
31 #include "winternl.h"
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
35
36 static void module_fill_module(const char* in, char* out, unsigned size)
37 {
38     const char          *ptr,*endptr;
39     unsigned            len;
40
41     endptr = in + strlen(in);
42     for (ptr = endptr - 1;
43          ptr >= in && *ptr != '/' && *ptr != '\\';
44          ptr--);
45     ptr++;
46     len = min(endptr-ptr,size-1);
47     memcpy(out, ptr, len);
48     out[len] = '\0';
49     if (len > 4 && 
50         (!strcasecmp(&out[len - 4], ".dll") || !strcasecmp(&out[len - 4], ".exe")))
51         out[len - 4] = '\0';
52     else if (((len > 12 && out[len - 13] == '/') || len == 12) && 
53              (!strcasecmp(out + len - 12, "wine-pthread") || 
54               !strcasecmp(out + len - 12, "wine-kthread")))
55         lstrcpynA(out, "<wine-loader>",size);
56     else
57     {
58         if (len > 7 && 
59             (!strcasecmp(&out[len - 7], ".dll.so") || !strcasecmp(&out[len - 7], ".exe.so")))
60             strcpy(&out[len - 7], "<elf>");
61         else if (len > 7 &&
62                  out[len - 7] == '.' && !strcasecmp(&out[len - 3], ".so"))
63         {
64             if (len + 3 < size) strcpy(&out[len - 3], "<elf>");
65             else WARN("Buffer too short: %s\n", out);
66         }
67     }
68     while ((*out = tolower(*out))) out++;
69 }
70
71 static const char*      get_module_type(enum module_type type)
72 {
73     switch (type)
74     {
75     case DMT_ELF: return "ELF";
76     case DMT_PE: return "PE";
77     case DMT_VIRTUAL: return "Virtual";
78     default: return "---";
79     }
80 }
81
82 /***********************************************************************
83  * Creates and links a new module to a process 
84  */
85 struct module* module_new(struct process* pcs, const char* name, 
86                           enum module_type type, 
87                           unsigned long mod_addr, unsigned long size,
88                           unsigned long stamp, unsigned long checksum) 
89 {
90     struct module*      module;
91
92     assert(type == DMT_ELF || type == DMT_PE || type == DMT_VIRTUAL);
93     if (!(module = HeapAlloc(GetProcessHeap(), 0, sizeof(*module))))
94         return NULL;
95
96     memset(module, 0, sizeof(*module));
97
98     module->next = pcs->lmodules;
99     pcs->lmodules = module;
100
101     TRACE("=> %s %08lx-%08lx %s\n", 
102           get_module_type(type), mod_addr, mod_addr + size, name);
103
104     pool_init(&module->pool, 65536);
105     
106     module->module.SizeOfStruct = sizeof(module->module);
107     module->module.BaseOfImage = mod_addr;
108     module->module.ImageSize = size;
109     module_fill_module(name, module->module.ModuleName,
110                        sizeof(module->module.ModuleName));
111     module->module.ImageName[0] = '\0';
112     lstrcpynA(module->module.LoadedImageName, name, sizeof(module->module.LoadedImageName));
113     module->module.SymType = SymNone;
114     module->module.NumSyms = 0;
115     module->module.TimeDateStamp = stamp;
116     module->module.CheckSum = checksum;
117
118     module->type              = type;
119     module->sortlist_valid    = FALSE;
120     module->addr_sorttab      = NULL;
121     /* FIXME: this seems a bit too high (on a per module basis)
122      * need some statistics about this
123      */
124     hash_table_init(&module->pool, &module->ht_symbols, 4096);
125     hash_table_init(&module->pool, &module->ht_types,   4096);
126     vector_init(&module->vtypes, sizeof(struct symt*),  32);
127
128     module->sources_used      = 0;
129     module->sources_alloc     = 0;
130     module->sources           = 0;
131
132     return module;
133 }
134
135 /***********************************************************************
136  *      module_find_by_name
137  *
138  */
139 struct module* module_find_by_name(const struct process* pcs, 
140                                    const char* name, enum module_type type)
141 {
142     struct module*      module;
143
144     if (type == DMT_UNKNOWN)
145     {
146         if ((module = module_find_by_name(pcs, name, DMT_PE)) ||
147             (module = module_find_by_name(pcs, name, DMT_ELF)) ||
148             (module = module_find_by_name(pcs, name, DMT_VIRTUAL)))
149             return module;
150     }
151     else
152     {
153         char                modname[MAX_PATH];
154
155         for (module = pcs->lmodules; module; module = module->next)
156         {
157             if (type == module->type &&
158                 !strcasecmp(name, module->module.LoadedImageName)) 
159                 return module;
160         }
161         module_fill_module(name, modname, sizeof(modname));
162         for (module = pcs->lmodules; module; module = module->next)
163         {
164             if (type == module->type &&
165                 !strcasecmp(modname, module->module.ModuleName)) 
166                 return module;
167         }
168     }
169     SetLastError(ERROR_INVALID_NAME);
170     return NULL;
171 }
172
173 /***********************************************************************
174  *           module_get_container
175  *
176  */
177 struct module* module_get_container(const struct process* pcs, 
178                                     const struct module* inner)
179 {
180     struct module*      module;
181      
182     for (module = pcs->lmodules; module; module = module->next)
183     {
184         if (module != inner &&
185             module->module.BaseOfImage <= inner->module.BaseOfImage &&
186             module->module.BaseOfImage + module->module.ImageSize >=
187             inner->module.BaseOfImage + inner->module.ImageSize)
188             return module;
189     }
190     return NULL;
191 }
192
193 /***********************************************************************
194  *           module_get_containee
195  *
196  */
197 struct module* module_get_containee(const struct process* pcs, 
198                                     const struct module* outter)
199 {
200     struct module*      module;
201      
202     for (module = pcs->lmodules; module; module = module->next)
203     {
204         if (module != outter &&
205             outter->module.BaseOfImage <= module->module.BaseOfImage &&
206             outter->module.BaseOfImage + outter->module.ImageSize >=
207             module->module.BaseOfImage + module->module.ImageSize)
208             return module;
209     }
210     return NULL;
211 }
212
213 /******************************************************************
214  *              module_get_debug
215  *
216  * get the debug information from a module:
217  * - if the module's type is deferred, then force loading of debug info (and return
218  *   the module itself)
219  * - if the module has no debug info and has an ELF container, then return the ELF
220  *   container (and also force the ELF container's debug info loading if deferred)
221  * - otherwise return the module itself if it has some debug info
222  */
223 struct module* module_get_debug(const struct process* pcs, struct module* module)
224 {
225     struct module*      parent;
226
227     if (!module) return NULL;
228     /* for a PE builtin, always get info from parent */
229     if ((parent = module_get_container(pcs, module)))
230         module = parent;
231     /* if deferred, force loading */
232     if (module->module.SymType == SymDeferred)
233     {
234         BOOL ret;
235
236         switch (module->type)
237         {
238         case DMT_ELF: ret = elf_load_debug_info(module, NULL);  break;
239         case DMT_PE:  ret = pe_load_debug_info(pcs, module);    break;
240         case DMT_VIRTUAL: /* fall through */
241         default:      ret = FALSE;                              break;
242         }
243         if (!ret) module->module.SymType = SymNone;
244         assert(module->module.SymType != SymDeferred);
245     }
246     return (module && module->module.SymType != SymNone) ? module : NULL;
247 }
248
249 /***********************************************************************
250  *      module_find_by_addr
251  *
252  * either the addr where module is loaded, or any address inside the 
253  * module
254  */
255 struct module* module_find_by_addr(const struct process* pcs, unsigned long addr, 
256                                    enum module_type type)
257 {
258     struct module*      module;
259     
260     if (type == DMT_UNKNOWN)
261     {
262         if ((module = module_find_by_addr(pcs, addr, DMT_PE)) ||
263             (module = module_find_by_addr(pcs, addr, DMT_ELF)) ||
264             (module = module_find_by_addr(pcs, addr, DMT_VIRTUAL)))
265             return module;
266     }
267     else
268     {
269         for (module = pcs->lmodules; module; module = module->next)
270         {
271             if (type == module->type && addr >= module->module.BaseOfImage &&
272                 addr < module->module.BaseOfImage + module->module.ImageSize) 
273                 return module;
274         }
275     }
276     SetLastError(ERROR_INVALID_ADDRESS);
277     return module;
278 }
279
280 static BOOL module_is_elf_container_loaded(struct process* pcs, const char* ImageName,
281                                            const char* ModuleName)
282 {
283     char                buffer[MAX_PATH];
284     size_t              len;
285     struct module*      module;
286
287     if (!ModuleName)
288     {
289         module_fill_module(ImageName, buffer, sizeof(buffer));
290         ModuleName = buffer;
291     }
292     len = strlen(ModuleName);
293     for (module = pcs->lmodules; module; module = module->next)
294     {
295         if (!strncasecmp(module->module.ModuleName, ModuleName, len) &&
296             module->type == DMT_ELF &&
297             !strcmp(module->module.ModuleName + len, "<elf>"))
298             return TRUE;
299     }
300     return FALSE;
301 }
302
303 /******************************************************************
304  *              module_get_type_by_name
305  *
306  * Guesses a filename type from its extension
307  */
308 enum module_type module_get_type_by_name(const char* name)
309 {
310     const char* ptr;
311     int         len = strlen(name);
312
313     /* check for terminating .so or .so.[digit] */
314     ptr = strrchr(name, '.');
315     if (ptr)
316     {
317         if (!strcmp(ptr, ".so") ||
318             (isdigit(ptr[1]) && !ptr[2] && ptr >= name + 3 && !memcmp(ptr - 3, ".so", 3)))
319             return DMT_ELF;
320         else if (!strcasecmp(ptr, ".pdb"))
321             return DMT_PDB;
322     }
323     /* wine-[kp]thread is also an ELF module */
324     else if (((len > 12 && name[len - 13] == '/') || len == 12) && 
325              (!strcasecmp(name + len - 12, "wine-pthread") || 
326               !strcasecmp(name + len - 12, "wine-kthread")))
327     {
328         return DMT_ELF;
329     }
330     return DMT_PE;
331 }
332
333 /***********************************************************************
334  *                      SymLoadModule (DBGHELP.@)
335  */
336 DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, char* ImageName,
337                            char* ModuleName, DWORD BaseOfDll, DWORD SizeOfDll)
338 {
339     struct process*     pcs;
340     struct module*      module = NULL;
341
342     TRACE("(%p %p %s %s %08lx %08lx)\n", 
343           hProcess, hFile, debugstr_a(ImageName), debugstr_a(ModuleName), 
344           BaseOfDll, SizeOfDll);
345
346     pcs = process_find_by_handle(hProcess);
347     if (!pcs) return FALSE;
348
349     /* force transparent ELF loading / unloading */
350     elf_synchronize_module_list(pcs);
351
352     /* this is a Wine extension to the API just to redo the synchronisation */
353     if (!ImageName && !hFile) return 0;
354
355     if (module_is_elf_container_loaded(pcs, ImageName, ModuleName))
356     {
357         /* force the loading of DLL as builtin */
358         if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName,
359                                               BaseOfDll, SizeOfDll)))
360             goto done;
361         WARN("Couldn't locate %s\n", ImageName);
362         return 0;
363     }
364     TRACE("Assuming %s as native DLL\n", ImageName);
365     if (!(module = pe_load_module(pcs, ImageName, hFile, BaseOfDll, SizeOfDll)))
366     {
367         if (module_get_type_by_name(ImageName) == DMT_ELF &&
368             (module = elf_load_module(pcs, ImageName, BaseOfDll)))
369             goto done;
370         FIXME("Should have successfully loaded debug information for image %s\n",
371               ImageName);
372         if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName,
373                                               BaseOfDll, SizeOfDll)))
374             goto done;
375         WARN("Couldn't locate %s\n", ImageName);
376         return 0;
377     }
378
379 done:
380     /* by default pe_load_module fills module.ModuleName from a derivation 
381      * of ImageName. Overwrite it, if we have better information
382      */
383     if (ModuleName)
384         lstrcpynA(module->module.ModuleName, ModuleName, sizeof(module->module.ModuleName));
385     lstrcpynA(module->module.ImageName, ImageName, sizeof(module->module.ImageName));
386
387     return module->module.BaseOfImage;
388 }
389
390 /***********************************************************************
391  *                      SymLoadModuleEx (DBGHELP.@)
392  */
393 DWORD64 WINAPI  SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, PCSTR ImageName,
394                                 PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize,
395                                 PMODLOAD_DATA Data, DWORD Flags)
396 {
397     if (Data)
398         FIXME("Unsupported load data parameter %p for %s\n", Data, ImageName);
399     if (!validate_addr64(BaseOfDll)) return FALSE;
400     if (Flags & SLMFLAG_VIRTUAL)
401     {
402         struct process* pcs = process_find_by_handle(hProcess);
403         struct module* module;
404         if (!pcs) return FALSE;
405
406         module = module_new(pcs, ImageName, DMT_VIRTUAL, (DWORD)BaseOfDll, DllSize, 0, 0);
407         if (!module) return FALSE;
408         if (ModuleName)
409             lstrcpynA(module->module.ModuleName, ModuleName, sizeof(module->module.ModuleName));
410
411         return TRUE;
412     }
413     if (Flags & ~(SLMFLAG_VIRTUAL))
414         FIXME("Unsupported Flags %08lx for %s\n", Flags, ImageName);
415
416     return SymLoadModule(hProcess, hFile, (char*)ImageName, (char*)ModuleName,
417                          (DWORD)BaseOfDll, DllSize);
418 }
419
420 /***********************************************************************
421  *                     SymLoadModule64 (DBGHELP.@)
422  */
423 DWORD WINAPI SymLoadModule64(HANDLE hProcess, HANDLE hFile, char* ImageName,
424                              char* ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll)
425 {
426     if (!validate_addr64(BaseOfDll)) return FALSE;
427     return SymLoadModule(hProcess, hFile, ImageName, ModuleName, (DWORD)BaseOfDll, SizeOfDll);
428 }
429
430 /******************************************************************
431  *              module_remove
432  *
433  */
434 BOOL module_remove(struct process* pcs, struct module* module)
435 {
436     struct module**     p;
437
438     TRACE("%s (%p)\n", module->module.ModuleName, module);
439     hash_table_destroy(&module->ht_symbols);
440     hash_table_destroy(&module->ht_types);
441     HeapFree(GetProcessHeap(), 0, (char*)module->sources);
442     HeapFree(GetProcessHeap(), 0, module->addr_sorttab);
443     pool_destroy(&module->pool);
444
445     for (p = &pcs->lmodules; *p; p = &(*p)->next)
446     {
447         if (*p == module)
448         {
449             *p = module->next;
450             HeapFree(GetProcessHeap(), 0, module);
451             return TRUE;
452         }
453     }
454     FIXME("This shouldn't happen\n");
455     return FALSE;
456 }
457
458 /******************************************************************
459  *              SymUnloadModule (DBGHELP.@)
460  *
461  */
462 BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll)
463 {
464     struct process*     pcs;
465     struct module*      module;
466
467     pcs = process_find_by_handle(hProcess);
468     if (!pcs) return FALSE;
469     module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
470     if (!module) return FALSE;
471     return module_remove(pcs, module);
472 }
473
474 /******************************************************************
475  *              SymUnloadModule64 (DBGHELP.@)
476  *
477  */
478 BOOL WINAPI SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll)
479 {
480     struct process*     pcs;
481     struct module*      module;
482
483     pcs = process_find_by_handle(hProcess);
484     if (!pcs) return FALSE;
485     if (!validate_addr64(BaseOfDll)) return FALSE;
486     module = module_find_by_addr(pcs, (DWORD)BaseOfDll, DMT_UNKNOWN);
487     if (!module) return FALSE;
488     return module_remove(pcs, module);
489 }
490
491 /******************************************************************
492  *              SymEnumerateModules (DBGHELP.@)
493  *
494  */
495 BOOL  WINAPI SymEnumerateModules(HANDLE hProcess,
496                                  PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,  
497                                  PVOID UserContext)
498 {
499     struct process*     pcs = process_find_by_handle(hProcess);
500     struct module*      module;
501
502     if (!pcs) return FALSE;
503     
504     for (module = pcs->lmodules; module; module = module->next)
505     {
506         if (!(dbghelp_options & SYMOPT_WINE_WITH_ELF_MODULES) && module->type == DMT_ELF)
507             continue;
508         if (!EnumModulesCallback(module->module.ModuleName, 
509                                  module->module.BaseOfImage, UserContext))
510             break;
511     }
512     return TRUE;
513 }
514
515 /******************************************************************
516  *              EnumerateLoadedModules (DBGHELP.@)
517  *
518  */
519 BOOL  WINAPI EnumerateLoadedModules(HANDLE hProcess,
520                                     PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
521                                     PVOID UserContext)
522 {
523     HMODULE*    hMods;
524     char        base[256], mod[256];
525     DWORD       i, sz;
526     MODULEINFO  mi;
527
528     hMods = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(hMods[0]));
529     if (!hMods) return FALSE;
530
531     if (!EnumProcessModules(hProcess, hMods, 256 * sizeof(hMods[0]), &sz))
532     {
533         /* hProcess should also be a valid process handle !! */
534         FIXME("If this happens, bump the number in mod\n");
535         HeapFree(GetProcessHeap(), 0, hMods);
536         return FALSE;
537     }
538     sz /= sizeof(HMODULE);
539     for (i = 0; i < sz; i++)
540     {
541         if (!GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) ||
542             !GetModuleBaseNameA(hProcess, hMods[i], base, sizeof(base)))
543             continue;
544         module_fill_module(base, mod, sizeof(mod));
545         EnumLoadedModulesCallback(mod, (DWORD)mi.lpBaseOfDll, mi.SizeOfImage, 
546                                   UserContext);
547     }
548     HeapFree(GetProcessHeap(), 0, hMods);
549
550     return sz != 0 && i == sz;
551 }
552
553 /******************************************************************
554  *              SymGetModuleInfo (DBGHELP.@)
555  *
556  */
557 BOOL  WINAPI SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, 
558                               PIMAGEHLP_MODULE ModuleInfo)
559 {
560     struct process*     pcs = process_find_by_handle(hProcess);
561     struct module*      module;
562
563     if (!pcs) return FALSE;
564     if (ModuleInfo->SizeOfStruct < sizeof(*ModuleInfo)) return FALSE;
565     module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
566     if (!module) return FALSE;
567
568     *ModuleInfo = module->module;
569     if (module->module.SymType == SymNone)
570     {
571         module = module_get_container(pcs, module);
572         if (module && module->module.SymType != SymNone)
573             ModuleInfo->SymType = module->module.SymType;
574     }
575
576     return TRUE;
577 }
578
579 /******************************************************************
580  *              SymGetModuleInfo64 (DBGHELP.@)
581  *
582  */
583 BOOL  WINAPI SymGetModuleInfo64(HANDLE hProcess, DWORD64 dwAddr, 
584                                 PIMAGEHLP_MODULE64 ModuleInfo)
585 {
586     struct process*     pcs = process_find_by_handle(hProcess);
587     struct module*      module;
588     DWORD               sz;
589     IMAGEHLP_MODULE64   mod;
590
591     TRACE("%p %s %p\n", hProcess, wine_dbgstr_longlong(dwAddr), ModuleInfo);
592
593     if (!pcs) return FALSE;
594     if (ModuleInfo->SizeOfStruct > sizeof(*ModuleInfo)) return FALSE;
595     module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
596     if (!module) return FALSE;
597
598     mod.BaseOfImage = module->module.BaseOfImage;
599     mod.ImageSize = module->module.ImageSize;
600     mod.TimeDateStamp = module->module.TimeDateStamp;
601     mod.CheckSum = module->module.CheckSum;
602     mod.NumSyms = module->module.NumSyms;
603     mod.SymType = module->module.SymType;
604     strcpy(mod.ModuleName, module->module.ModuleName);
605     strcpy(mod.ImageName, module->module.ImageName);
606     strcpy(mod.LoadedImageName, module->module.LoadedImageName);
607     /* FIXME: all following attributes need to be set */
608     mod.LoadedPdbName[0] = '\0';
609     mod.CVSig = 0;
610     memset(mod.CVData, 0, sizeof(mod.CVData));
611     mod.PdbSig = 0;
612     memset(&mod.PdbSig70, 0, sizeof(mod.PdbSig70));
613     mod.PdbAge = 0;
614     mod.PdbUnmatched = 0;
615     mod.DbgUnmatched = 0;
616     mod.LineNumbers = 0;
617     mod.GlobalSymbols = 0;
618     mod.TypeInfo = 0;
619     mod.SourceIndexed = 0;
620     mod.Publics = 0;
621
622     if (module->module.SymType == SymNone)
623     {
624         module = module_get_container(pcs, module);
625         if (module && module->module.SymType != SymNone)
626             mod.SymType = module->module.SymType;
627     }
628     sz = ModuleInfo->SizeOfStruct;
629     memcpy(ModuleInfo, &mod, sz);
630     ModuleInfo->SizeOfStruct = sz;
631     return TRUE;
632 }
633
634 /***********************************************************************
635  *              SymGetModuleBase (IMAGEHLP.@)
636  */
637 DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
638 {
639     struct process*     pcs = process_find_by_handle(hProcess);
640     struct module*      module;
641
642     if (!pcs) return 0;
643     module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
644     if (!module) return 0;
645     return module->module.BaseOfImage;
646 }
647
648 /******************************************************************
649  *              module_reset_debug_info
650  * Removes any debug information linked to a given module.
651  */
652 void module_reset_debug_info(struct module* module)
653 {
654     module->sortlist_valid = TRUE;
655     module->addr_sorttab = NULL;
656     hash_table_destroy(&module->ht_symbols);
657     module->ht_symbols.num_buckets = 0;
658     module->ht_symbols.buckets = NULL;
659     hash_table_destroy(&module->ht_types);
660     module->ht_types.num_buckets = 0;
661     module->ht_types.buckets = NULL;
662     module->vtypes.num_elts = 0;
663     hash_table_destroy(&module->ht_symbols);
664     module->sources_used = module->sources_alloc = 0;
665     module->sources = NULL;
666 }