Print out a slightly more informative message if an ELF module fails
[wine] / dlls / dbghelp / source.c
1 /*
2  * File source.c - source files management
3  *
4  * Copyright (C) 2004,      Eric Pouech.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21 #include "config.h"
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include "dbghelp_private.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
31
32 /******************************************************************
33  *              source_find
34  *
35  * check whether a source file has already been stored
36  */
37 static unsigned source_find(const struct module* module, const char* name)
38 {
39     char*       ptr = module->sources;
40
41     while (*ptr)
42     {
43         if (strcmp(ptr, name) == 0) return ptr - module->sources;
44         ptr += strlen(ptr) + 1;
45     }
46     return (unsigned)-1;
47 }
48
49 /******************************************************************
50  *              source_new
51  *
52  * checks if source exists. if not, add it
53  */
54 unsigned source_new(struct module* module, const char* name)
55 {
56     int         len;
57     unsigned    ret;
58
59     if (!name) return (unsigned)-1;
60     if (module->sources && (ret = source_find(module, name)) != (unsigned)-1)
61         return ret;
62
63     len = strlen(name) + 1;
64     if (module->sources_used + len + 1 > module->sources_alloc)
65     {
66         /* Alloc by block of 256 bytes */
67         module->sources_alloc = (module->sources_used + len + 1 + 255) & ~255;
68         if (!module->sources)
69             module->sources = HeapAlloc(GetProcessHeap(), 0, module->sources_alloc);
70         else
71             module->sources = HeapReAlloc(GetProcessHeap(), 0, module->sources,
72                                           module->sources_alloc);
73     }
74     ret = module->sources_used;
75     strcpy(module->sources + module->sources_used, name);
76     module->sources_used += len;
77     module->sources[module->sources_used] = '\0';
78     return ret;
79 }
80
81 /******************************************************************
82  *              source_get
83  *
84  * returns a stored source file name
85  */
86 const char* source_get(const struct module* module, unsigned idx)
87 {
88     if (idx == -1) return "";
89     assert(module->sources);
90     return module->sources + idx;
91 }
92
93 /******************************************************************
94  *              SymEnumSourceFiles (DBGHELP.@)
95  *
96  */
97 BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG ModBase, LPSTR Mask,
98                                PSYM_ENUMSOURCFILES_CALLBACK cbSrcFiles,
99                                void* UserContext)
100 {
101     struct process*     pcs;
102     struct module*      module;
103     SOURCEFILE          sf;
104     char*               ptr;
105     
106     if (!cbSrcFiles) return FALSE;
107     pcs = process_find_by_handle(hProcess);
108     if (!pcs) return FALSE;
109          
110     if (ModBase)
111     {
112         module = module_find_by_addr(pcs, ModBase, DMT_UNKNOWN);
113         if (!(module = module_get_debug(pcs, module))) return FALSE;
114     }
115     else
116     {
117         if (Mask[0] == '!')
118         {
119             module = module_find_by_name(pcs, Mask + 1, DMT_UNKNOWN);
120             if (!(module = module_get_debug(pcs, module))) return FALSE;
121         }
122         else
123         {
124             FIXME("Unsupported yet (should get info from current context)\n");
125             return FALSE;
126         }
127     }
128     if (!module->sources) return FALSE;
129     for (ptr = module->sources; *ptr; ptr += strlen(ptr) + 1)
130     {
131         /* FIXME: not using Mask */
132         sf.ModBase = ModBase;
133         sf.FileName = ptr;
134         if (!cbSrcFiles(&sf, UserContext)) break;
135     }
136
137     return TRUE;
138 }