xref: /reactos/dll/win32/dbghelp/msc.c (revision 8540ab04)
1 /*
2  * File msc.c - read VC++ debug information from COFF and eventually
3  * from PDB files.
4  *
5  * Copyright (C) 1996,      Eric Youngdale.
6  * Copyright (C) 1999-2000, Ulrich Weigand.
7  * Copyright (C) 2004-2009, Eric Pouech.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 /*
25  * Note - this handles reading debug information for 32 bit applications
26  * that run under Windows-NT for example.  I doubt that this would work well
27  * for 16 bit applications, but I don't think it really matters since the
28  * file format is different, and we should never get in here in such cases.
29  *
30  * TODO:
31  *	Get 16 bit CV stuff working.
32  *	Add symbol size to internal symbol table.
33  */
34 
35 #define NONAMELESSUNION
36 
37 #include "config.h"
38 #include "wine/port.h"
39 
40 #include <assert.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 
44 #include <string.h>
45 #ifdef HAVE_UNISTD_H
46 # include <unistd.h>
47 #endif
48 
49 #include <stdarg.h>
50 #include "windef.h"
51 #include "winbase.h"
52 #include "winternl.h"
53 
54 #include "wine/exception.h"
55 #include "wine/debug.h"
56 #include "dbghelp_private.h"
57 #include "wine/mscvpdb.h"
58 
59 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
60 
61 struct pdb_stream_name
62 {
63     const char* name;
64     unsigned    index;
65 };
66 
67 struct pdb_file_info
68 {
69     enum pdb_kind               kind;
70     DWORD                       age;
71     HANDLE                      hMap;
72     const char*                 image;
73     struct pdb_stream_name*     stream_dict;
74     unsigned                    fpoext_stream;
75     union
76     {
77         struct
78         {
79             DWORD               timestamp;
80             struct PDB_JG_TOC*  toc;
81         } jg;
82         struct
83         {
84             GUID                guid;
85             struct PDB_DS_TOC*  toc;
86         } ds;
87     } u;
88 };
89 
90 /* FIXME: don't make it static */
91 #define CV_MAX_MODULES          32
92 struct pdb_module_info
93 {
94     unsigned                    used_subfiles;
95     struct pdb_file_info        pdb_files[CV_MAX_MODULES];
96 };
97 
98 /*========================================================================
99  * Debug file access helper routines
100  */
101 
102 static void dump(const void* ptr, unsigned len)
103 {
104     unsigned int i, j;
105     char        msg[128];
106     const char* hexof = "0123456789abcdef";
107     const BYTE* x = ptr;
108 
109     for (i = 0; i < len; i += 16)
110     {
111         sprintf(msg, "%08x: ", i);
112         memset(msg + 10, ' ', 3 * 16 + 1 + 16);
113         for (j = 0; j < min(16, len - i); j++)
114         {
115             msg[10 + 3 * j + 0] = hexof[x[i + j] >> 4];
116             msg[10 + 3 * j + 1] = hexof[x[i + j] & 15];
117             msg[10 + 3 * j + 2] = ' ';
118             msg[10 + 3 * 16 + 1 + j] = (x[i + j] >= 0x20 && x[i + j] < 0x7f) ?
119                 x[i + j] : '.';
120         }
121         msg[10 + 3 * 16] = ' ';
122         msg[10 + 3 * 16 + 1 + 16] = '\0';
123         FIXME("%s\n", msg);
124     }
125 }
126 
127 /*========================================================================
128  * Process CodeView type information.
129  */
130 
131 #define MAX_BUILTIN_TYPES	0x06FF
132 #define FIRST_DEFINABLE_TYPE    0x1000
133 
134 static struct symt*     cv_basic_types[MAX_BUILTIN_TYPES];
135 
136 struct cv_defined_module
137 {
138     BOOL                allowed;
139     unsigned int        num_defined_types;
140     struct symt**       defined_types;
141 };
142 /* FIXME: don't make it static */
143 #define CV_MAX_MODULES          32
144 static struct cv_defined_module cv_zmodules[CV_MAX_MODULES];
145 static struct cv_defined_module*cv_current_module;
146 
147 static void codeview_init_basic_types(struct module* module)
148 {
149     /*
150      * These are the common builtin types that are used by VC++.
151      */
152     cv_basic_types[T_NOTYPE] = NULL;
153     cv_basic_types[T_ABS]    = NULL;
154     cv_basic_types[T_VOID]   = &symt_new_basic(module, btVoid,  "void", 0)->symt;
155     cv_basic_types[T_CHAR]   = &symt_new_basic(module, btChar,  "char", 1)->symt;
156     cv_basic_types[T_SHORT]  = &symt_new_basic(module, btInt,   "short int", 2)->symt;
157     cv_basic_types[T_LONG]   = &symt_new_basic(module, btInt,   "long int", 4)->symt;
158     cv_basic_types[T_QUAD]   = &symt_new_basic(module, btInt,   "long long int", 8)->symt;
159     cv_basic_types[T_UCHAR]  = &symt_new_basic(module, btUInt,  "unsigned char", 1)->symt;
160     cv_basic_types[T_USHORT] = &symt_new_basic(module, btUInt,  "unsigned short", 2)->symt;
161     cv_basic_types[T_ULONG]  = &symt_new_basic(module, btUInt,  "unsigned long", 4)->symt;
162     cv_basic_types[T_UQUAD]  = &symt_new_basic(module, btUInt,  "unsigned long long", 8)->symt;
163     cv_basic_types[T_BOOL08] = &symt_new_basic(module, btBool,  "BOOL08", 1)->symt;
164     cv_basic_types[T_BOOL16] = &symt_new_basic(module, btBool,  "BOOL16", 2)->symt;
165     cv_basic_types[T_BOOL32] = &symt_new_basic(module, btBool,  "BOOL32", 4)->symt;
166     cv_basic_types[T_BOOL64] = &symt_new_basic(module, btBool,  "BOOL64", 8)->symt;
167     cv_basic_types[T_REAL32] = &symt_new_basic(module, btFloat, "float", 4)->symt;
168     cv_basic_types[T_REAL64] = &symt_new_basic(module, btFloat, "double", 8)->symt;
169     cv_basic_types[T_REAL80] = &symt_new_basic(module, btFloat, "long double", 10)->symt;
170     cv_basic_types[T_RCHAR]  = &symt_new_basic(module, btInt,   "signed char", 1)->symt;
171     cv_basic_types[T_WCHAR]  = &symt_new_basic(module, btWChar, "wchar_t", 2)->symt;
172     cv_basic_types[T_CHAR16] = &symt_new_basic(module, btChar16,"char16_t", 2)->symt;
173     cv_basic_types[T_CHAR32] = &symt_new_basic(module, btChar32,"char32_t", 4)->symt;
174     cv_basic_types[T_INT2]   = &symt_new_basic(module, btInt,   "INT2", 2)->symt;
175     cv_basic_types[T_UINT2]  = &symt_new_basic(module, btUInt,  "UINT2", 2)->symt;
176     cv_basic_types[T_INT4]   = &symt_new_basic(module, btInt,   "INT4", 4)->symt;
177     cv_basic_types[T_UINT4]  = &symt_new_basic(module, btUInt,  "UINT4", 4)->symt;
178     cv_basic_types[T_INT8]   = &symt_new_basic(module, btInt,   "INT8", 8)->symt;
179     cv_basic_types[T_UINT8]  = &symt_new_basic(module, btUInt,  "UINT8", 8)->symt;
180     cv_basic_types[T_HRESULT]= &symt_new_basic(module, btUInt,  "HRESULT", 4)->symt;
181 
182     cv_basic_types[T_32PVOID]   = &symt_new_pointer(module, cv_basic_types[T_VOID], 4)->symt;
183     cv_basic_types[T_32PCHAR]   = &symt_new_pointer(module, cv_basic_types[T_CHAR], 4)->symt;
184     cv_basic_types[T_32PSHORT]  = &symt_new_pointer(module, cv_basic_types[T_SHORT], 4)->symt;
185     cv_basic_types[T_32PLONG]   = &symt_new_pointer(module, cv_basic_types[T_LONG], 4)->symt;
186     cv_basic_types[T_32PQUAD]   = &symt_new_pointer(module, cv_basic_types[T_QUAD], 4)->symt;
187     cv_basic_types[T_32PUCHAR]  = &symt_new_pointer(module, cv_basic_types[T_UCHAR], 4)->symt;
188     cv_basic_types[T_32PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT], 4)->symt;
189     cv_basic_types[T_32PULONG]  = &symt_new_pointer(module, cv_basic_types[T_ULONG], 4)->symt;
190     cv_basic_types[T_32PUQUAD]  = &symt_new_pointer(module, cv_basic_types[T_UQUAD], 4)->symt;
191     cv_basic_types[T_32PBOOL08] = &symt_new_pointer(module, cv_basic_types[T_BOOL08], 4)->symt;
192     cv_basic_types[T_32PBOOL16] = &symt_new_pointer(module, cv_basic_types[T_BOOL16], 4)->symt;
193     cv_basic_types[T_32PBOOL32] = &symt_new_pointer(module, cv_basic_types[T_BOOL32], 4)->symt;
194     cv_basic_types[T_32PBOOL64] = &symt_new_pointer(module, cv_basic_types[T_BOOL64], 4)->symt;
195     cv_basic_types[T_32PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32], 4)->symt;
196     cv_basic_types[T_32PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64], 4)->symt;
197     cv_basic_types[T_32PREAL80] = &symt_new_pointer(module, cv_basic_types[T_REAL80], 4)->symt;
198     cv_basic_types[T_32PRCHAR]  = &symt_new_pointer(module, cv_basic_types[T_RCHAR], 4)->symt;
199     cv_basic_types[T_32PWCHAR]  = &symt_new_pointer(module, cv_basic_types[T_WCHAR], 4)->symt;
200     cv_basic_types[T_32PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], 4)->symt;
201     cv_basic_types[T_32PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], 4)->symt;
202     cv_basic_types[T_32PINT2]   = &symt_new_pointer(module, cv_basic_types[T_INT2], 4)->symt;
203     cv_basic_types[T_32PUINT2]  = &symt_new_pointer(module, cv_basic_types[T_UINT2], 4)->symt;
204     cv_basic_types[T_32PINT4]   = &symt_new_pointer(module, cv_basic_types[T_INT4], 4)->symt;
205     cv_basic_types[T_32PUINT4]  = &symt_new_pointer(module, cv_basic_types[T_UINT4], 4)->symt;
206     cv_basic_types[T_32PINT8]   = &symt_new_pointer(module, cv_basic_types[T_INT8], 4)->symt;
207     cv_basic_types[T_32PUINT8]  = &symt_new_pointer(module, cv_basic_types[T_UINT8], 4)->symt;
208     cv_basic_types[T_32PHRESULT]= &symt_new_pointer(module, cv_basic_types[T_HRESULT], 4)->symt;
209 
210     cv_basic_types[T_64PVOID]   = &symt_new_pointer(module, cv_basic_types[T_VOID], 8)->symt;
211     cv_basic_types[T_64PCHAR]   = &symt_new_pointer(module, cv_basic_types[T_CHAR], 8)->symt;
212     cv_basic_types[T_64PSHORT]  = &symt_new_pointer(module, cv_basic_types[T_SHORT], 8)->symt;
213     cv_basic_types[T_64PLONG]   = &symt_new_pointer(module, cv_basic_types[T_LONG], 8)->symt;
214     cv_basic_types[T_64PQUAD]   = &symt_new_pointer(module, cv_basic_types[T_QUAD], 8)->symt;
215     cv_basic_types[T_64PUCHAR]  = &symt_new_pointer(module, cv_basic_types[T_UCHAR], 8)->symt;
216     cv_basic_types[T_64PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT], 8)->symt;
217     cv_basic_types[T_64PULONG]  = &symt_new_pointer(module, cv_basic_types[T_ULONG], 8)->symt;
218     cv_basic_types[T_64PUQUAD]  = &symt_new_pointer(module, cv_basic_types[T_UQUAD], 8)->symt;
219     cv_basic_types[T_64PBOOL08] = &symt_new_pointer(module, cv_basic_types[T_BOOL08], 8)->symt;
220     cv_basic_types[T_64PBOOL16] = &symt_new_pointer(module, cv_basic_types[T_BOOL16], 8)->symt;
221     cv_basic_types[T_64PBOOL32] = &symt_new_pointer(module, cv_basic_types[T_BOOL32], 8)->symt;
222     cv_basic_types[T_64PBOOL64] = &symt_new_pointer(module, cv_basic_types[T_BOOL64], 8)->symt;
223     cv_basic_types[T_64PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32], 8)->symt;
224     cv_basic_types[T_64PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64], 8)->symt;
225     cv_basic_types[T_64PREAL80] = &symt_new_pointer(module, cv_basic_types[T_REAL80], 8)->symt;
226     cv_basic_types[T_64PRCHAR]  = &symt_new_pointer(module, cv_basic_types[T_RCHAR], 8)->symt;
227     cv_basic_types[T_64PWCHAR]  = &symt_new_pointer(module, cv_basic_types[T_WCHAR], 8)->symt;
228     cv_basic_types[T_64PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], 8)->symt;
229     cv_basic_types[T_64PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], 8)->symt;
230     cv_basic_types[T_64PINT2]   = &symt_new_pointer(module, cv_basic_types[T_INT2], 8)->symt;
231     cv_basic_types[T_64PUINT2]  = &symt_new_pointer(module, cv_basic_types[T_UINT2], 8)->symt;
232     cv_basic_types[T_64PINT4]   = &symt_new_pointer(module, cv_basic_types[T_INT4], 8)->symt;
233     cv_basic_types[T_64PUINT4]  = &symt_new_pointer(module, cv_basic_types[T_UINT4], 8)->symt;
234     cv_basic_types[T_64PINT8]   = &symt_new_pointer(module, cv_basic_types[T_INT8], 8)->symt;
235     cv_basic_types[T_64PUINT8]  = &symt_new_pointer(module, cv_basic_types[T_UINT8], 8)->symt;
236     cv_basic_types[T_64PHRESULT]= &symt_new_pointer(module, cv_basic_types[T_HRESULT], 8)->symt;
237 
238     cv_basic_types[T_PVOID]   = &symt_new_pointer(module, cv_basic_types[T_VOID],   sizeof(void*))->symt;
239     cv_basic_types[T_PCHAR]   = &symt_new_pointer(module, cv_basic_types[T_CHAR],   sizeof(void*))->symt;
240     cv_basic_types[T_PSHORT]  = &symt_new_pointer(module, cv_basic_types[T_SHORT],  sizeof(void*))->symt;
241     cv_basic_types[T_PLONG]   = &symt_new_pointer(module, cv_basic_types[T_LONG],   sizeof(void*))->symt;
242     cv_basic_types[T_PQUAD]   = &symt_new_pointer(module, cv_basic_types[T_QUAD],   sizeof(void*))->symt;
243     cv_basic_types[T_PUCHAR]  = &symt_new_pointer(module, cv_basic_types[T_UCHAR],  sizeof(void*))->symt;
244     cv_basic_types[T_PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT], sizeof(void*))->symt;
245     cv_basic_types[T_PULONG]  = &symt_new_pointer(module, cv_basic_types[T_ULONG],  sizeof(void*))->symt;
246     cv_basic_types[T_PUQUAD]  = &symt_new_pointer(module, cv_basic_types[T_UQUAD],  sizeof(void*))->symt;
247     cv_basic_types[T_PBOOL08] = &symt_new_pointer(module, cv_basic_types[T_BOOL08], sizeof(void*))->symt;
248     cv_basic_types[T_PBOOL16] = &symt_new_pointer(module, cv_basic_types[T_BOOL16], sizeof(void*))->symt;
249     cv_basic_types[T_PBOOL32] = &symt_new_pointer(module, cv_basic_types[T_BOOL32], sizeof(void*))->symt;
250     cv_basic_types[T_PBOOL64] = &symt_new_pointer(module, cv_basic_types[T_BOOL64], sizeof(void*))->symt;
251     cv_basic_types[T_PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32], sizeof(void*))->symt;
252     cv_basic_types[T_PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64], sizeof(void*))->symt;
253     cv_basic_types[T_PREAL80] = &symt_new_pointer(module, cv_basic_types[T_REAL80], sizeof(void*))->symt;
254     cv_basic_types[T_PRCHAR]  = &symt_new_pointer(module, cv_basic_types[T_RCHAR],  sizeof(void*))->symt;
255     cv_basic_types[T_PWCHAR]  = &symt_new_pointer(module, cv_basic_types[T_WCHAR],  sizeof(void*))->symt;
256     cv_basic_types[T_PCHAR16] = &symt_new_pointer(module, cv_basic_types[T_CHAR16], sizeof(void*))->symt;
257     cv_basic_types[T_PCHAR32] = &symt_new_pointer(module, cv_basic_types[T_CHAR32], sizeof(void*))->symt;
258     cv_basic_types[T_PINT2]   = &symt_new_pointer(module, cv_basic_types[T_INT2],   sizeof(void*))->symt;
259     cv_basic_types[T_PUINT2]  = &symt_new_pointer(module, cv_basic_types[T_UINT2],  sizeof(void*))->symt;
260     cv_basic_types[T_PINT4]   = &symt_new_pointer(module, cv_basic_types[T_INT4],   sizeof(void*))->symt;
261     cv_basic_types[T_PUINT4]  = &symt_new_pointer(module, cv_basic_types[T_UINT4],  sizeof(void*))->symt;
262     cv_basic_types[T_PINT8]   = &symt_new_pointer(module, cv_basic_types[T_INT8],   sizeof(void*))->symt;
263     cv_basic_types[T_PUINT8]  = &symt_new_pointer(module, cv_basic_types[T_UINT8],  sizeof(void*))->symt;
264 }
265 
266 static int leaf_as_variant(VARIANT* v, const unsigned short int* leaf)
267 {
268     unsigned short int type = *leaf++;
269     int length = 2;
270 
271     if (type < LF_NUMERIC)
272     {
273         v->n1.n2.vt = VT_UINT;
274         v->n1.n2.n3.uintVal = type;
275     }
276     else
277     {
278         switch (type)
279         {
280         case LF_CHAR:
281             length += 1;
282             v->n1.n2.vt = VT_I1;
283             v->n1.n2.n3.cVal = *(const char*)leaf;
284             break;
285 
286         case LF_SHORT:
287             length += 2;
288             v->n1.n2.vt = VT_I2;
289             v->n1.n2.n3.iVal = *(const short*)leaf;
290             break;
291 
292         case LF_USHORT:
293             length += 2;
294             v->n1.n2.vt = VT_UI2;
295             v->n1.n2.n3.uiVal = *leaf;
296             break;
297 
298         case LF_LONG:
299             length += 4;
300             v->n1.n2.vt = VT_I4;
301             v->n1.n2.n3.lVal = *(const int*)leaf;
302             break;
303 
304         case LF_ULONG:
305             length += 4;
306             v->n1.n2.vt = VT_UI4;
307             v->n1.n2.n3.uiVal = *(const unsigned int*)leaf;
308             break;
309 
310         case LF_QUADWORD:
311             length += 8;
312             v->n1.n2.vt = VT_I8;
313             v->n1.n2.n3.llVal = *(const long long int*)leaf;
314             break;
315 
316         case LF_UQUADWORD:
317             length += 8;
318             v->n1.n2.vt = VT_UI8;
319             v->n1.n2.n3.ullVal = *(const long long unsigned int*)leaf;
320             break;
321 
322         case LF_REAL32:
323             length += 4;
324             v->n1.n2.vt = VT_R4;
325             v->n1.n2.n3.fltVal = *(const float*)leaf;
326             break;
327 
328         case LF_REAL48:
329 	    FIXME("Unsupported numeric leaf type %04x\n", type);
330             length += 6;
331             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
332             break;
333 
334         case LF_REAL64:
335             length += 8;
336             v->n1.n2.vt = VT_R8;
337             v->n1.n2.n3.fltVal = *(const double*)leaf;
338             break;
339 
340         case LF_REAL80:
341 	    FIXME("Unsupported numeric leaf type %04x\n", type);
342             length += 10;
343             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
344             break;
345 
346         case LF_REAL128:
347 	    FIXME("Unsupported numeric leaf type %04x\n", type);
348             length += 16;
349             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
350             break;
351 
352         case LF_COMPLEX32:
353 	    FIXME("Unsupported numeric leaf type %04x\n", type);
354             length += 4;
355             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
356             break;
357 
358         case LF_COMPLEX64:
359 	    FIXME("Unsupported numeric leaf type %04x\n", type);
360             length += 8;
361             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
362             break;
363 
364         case LF_COMPLEX80:
365 	    FIXME("Unsupported numeric leaf type %04x\n", type);
366             length += 10;
367             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
368             break;
369 
370         case LF_COMPLEX128:
371 	    FIXME("Unsupported numeric leaf type %04x\n", type);
372             length += 16;
373             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
374             break;
375 
376         case LF_VARSTRING:
377 	    FIXME("Unsupported numeric leaf type %04x\n", type);
378             length += 2 + *leaf;
379             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
380             break;
381 
382         default:
383 	    FIXME("Unknown numeric leaf type %04x\n", type);
384             v->n1.n2.vt = VT_EMPTY;     /* FIXME */
385             break;
386         }
387     }
388 
389     return length;
390 }
391 
392 static int numeric_leaf(int* value, const unsigned short int* leaf)
393 {
394     unsigned short int type = *leaf++;
395     int length = 2;
396 
397     if (type < LF_NUMERIC)
398     {
399         *value = type;
400     }
401     else
402     {
403         switch (type)
404         {
405         case LF_CHAR:
406             length += 1;
407             *value = *(const char*)leaf;
408             break;
409 
410         case LF_SHORT:
411             length += 2;
412             *value = *(const short*)leaf;
413             break;
414 
415         case LF_USHORT:
416             length += 2;
417             *value = *leaf;
418             break;
419 
420         case LF_LONG:
421             length += 4;
422             *value = *(const int*)leaf;
423             break;
424 
425         case LF_ULONG:
426             length += 4;
427             *value = *(const unsigned int*)leaf;
428             break;
429 
430         case LF_QUADWORD:
431         case LF_UQUADWORD:
432 	    FIXME("Unsupported numeric leaf type %04x\n", type);
433             length += 8;
434             *value = 0;    /* FIXME */
435             break;
436 
437         case LF_REAL32:
438 	    FIXME("Unsupported numeric leaf type %04x\n", type);
439             length += 4;
440             *value = 0;    /* FIXME */
441             break;
442 
443         case LF_REAL48:
444 	    FIXME("Unsupported numeric leaf type %04x\n", type);
445             length += 6;
446             *value = 0;    /* FIXME */
447             break;
448 
449         case LF_REAL64:
450 	    FIXME("Unsupported numeric leaf type %04x\n", type);
451             length += 8;
452             *value = 0;    /* FIXME */
453             break;
454 
455         case LF_REAL80:
456 	    FIXME("Unsupported numeric leaf type %04x\n", type);
457             length += 10;
458             *value = 0;    /* FIXME */
459             break;
460 
461         case LF_REAL128:
462 	    FIXME("Unsupported numeric leaf type %04x\n", type);
463             length += 16;
464             *value = 0;    /* FIXME */
465             break;
466 
467         case LF_COMPLEX32:
468 	    FIXME("Unsupported numeric leaf type %04x\n", type);
469             length += 4;
470             *value = 0;    /* FIXME */
471             break;
472 
473         case LF_COMPLEX64:
474 	    FIXME("Unsupported numeric leaf type %04x\n", type);
475             length += 8;
476             *value = 0;    /* FIXME */
477             break;
478 
479         case LF_COMPLEX80:
480 	    FIXME("Unsupported numeric leaf type %04x\n", type);
481             length += 10;
482             *value = 0;    /* FIXME */
483             break;
484 
485         case LF_COMPLEX128:
486 	    FIXME("Unsupported numeric leaf type %04x\n", type);
487             length += 16;
488             *value = 0;    /* FIXME */
489             break;
490 
491         case LF_VARSTRING:
492 	    FIXME("Unsupported numeric leaf type %04x\n", type);
493             length += 2 + *leaf;
494             *value = 0;    /* FIXME */
495             break;
496 
497         default:
498 	    FIXME("Unknown numeric leaf type %04x\n", type);
499             *value = 0;
500             break;
501         }
502     }
503 
504     return length;
505 }
506 
507 /* convert a pascal string (as stored in debug information) into
508  * a C string (null terminated).
509  */
510 static const char* terminate_string(const struct p_string* p_name)
511 {
512     static char symname[256];
513 
514     memcpy(symname, p_name->name, p_name->namelen);
515     symname[p_name->namelen] = '\0';
516 
517     return (!*symname || strcmp(symname, "__unnamed") == 0) ? NULL : symname;
518 }
519 
520 static struct symt*  codeview_get_type(unsigned int typeno, BOOL quiet)
521 {
522     struct symt*        symt = NULL;
523 
524     /*
525      * Convert Codeview type numbers into something we can grok internally.
526      * Numbers < FIRST_DEFINABLE_TYPE are all fixed builtin types.
527      * Numbers from FIRST_DEFINABLE_TYPE and up are all user defined (structs, etc).
528      */
529     if (typeno < FIRST_DEFINABLE_TYPE)
530     {
531         if (typeno < MAX_BUILTIN_TYPES)
532 	    symt = cv_basic_types[typeno];
533     }
534     else
535     {
536         unsigned        mod_index = typeno >> 24;
537         unsigned        mod_typeno = typeno & 0x00FFFFFF;
538         struct cv_defined_module*       mod;
539 
540         mod = (mod_index == 0) ? cv_current_module : &cv_zmodules[mod_index];
541 
542         if (mod_index >= CV_MAX_MODULES || !mod->allowed)
543             FIXME("Module of index %d isn't loaded yet (%x)\n", mod_index, typeno);
544         else
545         {
546             if (mod_typeno - FIRST_DEFINABLE_TYPE < mod->num_defined_types)
547                 symt = mod->defined_types[mod_typeno - FIRST_DEFINABLE_TYPE];
548         }
549     }
550     if (!quiet && !symt && typeno) FIXME("Returning NULL symt for type-id %x\n", typeno);
551     return symt;
552 }
553 
554 struct codeview_type_parse
555 {
556     struct module*      module;
557     const BYTE*         table;
558     const DWORD*        offset;
559     DWORD               num;
560 };
561 
562 static inline const void* codeview_jump_to_type(const struct codeview_type_parse* ctp, DWORD idx)
563 {
564     if (idx < FIRST_DEFINABLE_TYPE) return NULL;
565     idx -= FIRST_DEFINABLE_TYPE;
566     return (idx >= ctp->num) ? NULL : (ctp->table + ctp->offset[idx]);
567 }
568 
569 static int codeview_add_type(unsigned int typeno, struct symt* dt)
570 {
571     if (typeno < FIRST_DEFINABLE_TYPE)
572         FIXME("What the heck\n");
573     if (!cv_current_module)
574     {
575         FIXME("Adding %x to non allowed module\n", typeno);
576         return FALSE;
577     }
578     if ((typeno >> 24) != 0)
579         FIXME("No module index while inserting type-id assumption is wrong %x\n",
580               typeno);
581     if (typeno - FIRST_DEFINABLE_TYPE >= cv_current_module->num_defined_types)
582     {
583         if (cv_current_module->defined_types)
584         {
585             cv_current_module->num_defined_types = max( cv_current_module->num_defined_types * 2,
586                                                         typeno - FIRST_DEFINABLE_TYPE + 1 );
587             cv_current_module->defined_types = HeapReAlloc(GetProcessHeap(),
588                             HEAP_ZERO_MEMORY, cv_current_module->defined_types,
589                             cv_current_module->num_defined_types * sizeof(struct symt*));
590         }
591         else
592         {
593             cv_current_module->num_defined_types = max( 256, typeno - FIRST_DEFINABLE_TYPE + 1 );
594             cv_current_module->defined_types = HeapAlloc(GetProcessHeap(),
595                             HEAP_ZERO_MEMORY,
596                             cv_current_module->num_defined_types * sizeof(struct symt*));
597         }
598         if (cv_current_module->defined_types == NULL) return FALSE;
599     }
600     if (cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE])
601     {
602         if (cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE] != dt)
603             FIXME("Overwriting at %x\n", typeno);
604     }
605     cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE] = dt;
606     return TRUE;
607 }
608 
609 static void codeview_clear_type_table(void)
610 {
611     int i;
612 
613     for (i = 0; i < CV_MAX_MODULES; i++)
614     {
615         if (cv_zmodules[i].allowed)
616             HeapFree(GetProcessHeap(), 0, cv_zmodules[i].defined_types);
617         cv_zmodules[i].allowed = FALSE;
618         cv_zmodules[i].defined_types = NULL;
619         cv_zmodules[i].num_defined_types = 0;
620     }
621     cv_current_module = NULL;
622 }
623 
624 static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp,
625                                             unsigned curr_type,
626                                             const union codeview_type* type, BOOL details);
627 
628 static void* codeview_cast_symt(struct symt* symt, enum SymTagEnum tag)
629 {
630     if (symt->tag != tag)
631     {
632         FIXME("Bad tag. Expected %d, but got %d\n", tag, symt->tag);
633         return NULL;
634     }
635     return symt;
636 }
637 
638 static struct symt* codeview_fetch_type(struct codeview_type_parse* ctp,
639                                         unsigned typeno, BOOL details)
640 {
641     struct symt*                symt;
642     const union codeview_type*  p;
643 
644     if (!typeno) return NULL;
645     if ((symt = codeview_get_type(typeno, TRUE))) return symt;
646 
647     /* forward declaration */
648     if (!(p = codeview_jump_to_type(ctp, typeno)))
649     {
650         FIXME("Cannot locate type %x\n", typeno);
651         return NULL;
652     }
653     symt = codeview_parse_one_type(ctp, typeno, p, details);
654     if (!symt) FIXME("Couldn't load forward type %x\n", typeno);
655     return symt;
656 }
657 
658 static struct symt* codeview_add_type_pointer(struct codeview_type_parse* ctp,
659                                               struct symt* existing,
660                                               unsigned int pointee_type)
661 {
662     struct symt* pointee;
663 
664     if (existing)
665     {
666         existing = codeview_cast_symt(existing, SymTagPointerType);
667         return existing;
668     }
669     pointee = codeview_fetch_type(ctp, pointee_type, FALSE);
670     return &symt_new_pointer(ctp->module, pointee, sizeof(void *))->symt;
671 }
672 
673 static struct symt* codeview_add_type_array(struct codeview_type_parse* ctp,
674                                             const char* name,
675                                             unsigned int elemtype,
676                                             unsigned int indextype,
677                                             unsigned int arr_len)
678 {
679     struct symt*        elem = codeview_fetch_type(ctp, elemtype, FALSE);
680     struct symt*        index = codeview_fetch_type(ctp, indextype, FALSE);
681 
682     return &symt_new_array(ctp->module, 0, -arr_len, elem, index)->symt;
683 }
684 
685 static BOOL codeview_add_type_enum_field_list(struct module* module,
686                                               struct symt_enum* symt,
687                                               const union codeview_reftype* ref_type)
688 {
689     const unsigned char*                ptr = ref_type->fieldlist.list;
690     const unsigned char*                last = (const BYTE*)ref_type + ref_type->generic.len + 2;
691     const union codeview_fieldtype*     type;
692 
693     while (ptr < last)
694     {
695         if (*ptr >= 0xf0)       /* LF_PAD... */
696         {
697             ptr += *ptr & 0x0f;
698             continue;
699         }
700 
701         type = (const union codeview_fieldtype*)ptr;
702 
703         switch (type->generic.id)
704         {
705         case LF_ENUMERATE_V1:
706         {
707             int value, vlen = numeric_leaf(&value, &type->enumerate_v1.value);
708             const struct p_string* p_name = (const struct p_string*)((const unsigned char*)&type->enumerate_v1.value + vlen);
709 
710             symt_add_enum_element(module, symt, terminate_string(p_name), value);
711             ptr += 2 + 2 + vlen + (1 + p_name->namelen);
712             break;
713         }
714         case LF_ENUMERATE_V3:
715         {
716             int value, vlen = numeric_leaf(&value, &type->enumerate_v3.value);
717             const char* name = (const char*)&type->enumerate_v3.value + vlen;
718 
719             symt_add_enum_element(module, symt, name, value);
720             ptr += 2 + 2 + vlen + (1 + strlen(name));
721             break;
722         }
723 
724         default:
725             FIXME("Unsupported type %04x in ENUM field list\n", type->generic.id);
726             return FALSE;
727         }
728     }
729     return TRUE;
730 }
731 
732 static void codeview_add_udt_element(struct codeview_type_parse* ctp,
733                                      struct symt_udt* symt, const char* name,
734                                      int value, unsigned type)
735 {
736     struct symt*                subtype;
737     const union codeview_reftype*cv_type;
738 
739     if ((cv_type = codeview_jump_to_type(ctp, type)))
740     {
741         switch (cv_type->generic.id)
742         {
743         case LF_BITFIELD_V1:
744             symt_add_udt_element(ctp->module, symt, name,
745                                  codeview_fetch_type(ctp, cv_type->bitfield_v1.type, FALSE),
746                                  (value << 3) + cv_type->bitfield_v1.bitoff,
747                                  cv_type->bitfield_v1.nbits);
748             return;
749         case LF_BITFIELD_V2:
750             symt_add_udt_element(ctp->module, symt, name,
751                                  codeview_fetch_type(ctp, cv_type->bitfield_v2.type, FALSE),
752                                  (value << 3) + cv_type->bitfield_v2.bitoff,
753                                  cv_type->bitfield_v2.nbits);
754             return;
755         }
756     }
757     subtype = codeview_fetch_type(ctp, type, FALSE);
758 
759     if (subtype)
760     {
761         DWORD64 elem_size = 0;
762         symt_get_info(ctp->module, subtype, TI_GET_LENGTH, &elem_size);
763         symt_add_udt_element(ctp->module, symt, name, subtype,
764                              value << 3, (DWORD)elem_size << 3);
765     }
766 }
767 
768 static int codeview_add_type_struct_field_list(struct codeview_type_parse* ctp,
769                                                struct symt_udt* symt,
770                                                unsigned fieldlistno)
771 {
772     const unsigned char*        ptr;
773     const unsigned char*        last;
774     int                         value, leaf_len;
775     const struct p_string*      p_name;
776     const char*                 c_name;
777     const union codeview_reftype*type_ref;
778     const union codeview_fieldtype* type;
779 
780     if (!fieldlistno) return TRUE;
781     type_ref = codeview_jump_to_type(ctp, fieldlistno);
782     ptr = type_ref->fieldlist.list;
783     last = (const BYTE*)type_ref + type_ref->generic.len + 2;
784 
785     while (ptr < last)
786     {
787         if (*ptr >= 0xf0)       /* LF_PAD... */
788         {
789             ptr += *ptr & 0x0f;
790             continue;
791         }
792 
793         type = (const union codeview_fieldtype*)ptr;
794 
795         switch (type->generic.id)
796         {
797         case LF_BCLASS_V1:
798             leaf_len = numeric_leaf(&value, &type->bclass_v1.offset);
799 
800             /* FIXME: ignored for now */
801 
802             ptr += 2 + 2 + 2 + leaf_len;
803             break;
804 
805         case LF_BCLASS_V2:
806             leaf_len = numeric_leaf(&value, &type->bclass_v2.offset);
807 
808             /* FIXME: ignored for now */
809 
810             ptr += 2 + 2 + 4 + leaf_len;
811             break;
812 
813         case LF_VBCLASS_V1:
814         case LF_IVBCLASS_V1:
815             {
816                 const unsigned short int* p_vboff;
817                 int vpoff, vplen;
818                 leaf_len = numeric_leaf(&value, &type->vbclass_v1.vbpoff);
819                 p_vboff = (const unsigned short int*)((const char*)&type->vbclass_v1.vbpoff + leaf_len);
820                 vplen = numeric_leaf(&vpoff, p_vboff);
821 
822                 /* FIXME: ignored for now */
823 
824                 ptr += 2 + 2 + 2 + 2 + leaf_len + vplen;
825             }
826             break;
827 
828         case LF_VBCLASS_V2:
829         case LF_IVBCLASS_V2:
830             {
831                 const unsigned short int* p_vboff;
832                 int vpoff, vplen;
833                 leaf_len = numeric_leaf(&value, &type->vbclass_v2.vbpoff);
834                 p_vboff = (const unsigned short int*)((const char*)&type->vbclass_v2.vbpoff + leaf_len);
835                 vplen = numeric_leaf(&vpoff, p_vboff);
836 
837                 /* FIXME: ignored for now */
838 
839                 ptr += 2 + 2 + 4 + 4 + leaf_len + vplen;
840             }
841             break;
842 
843         case LF_MEMBER_V1:
844             leaf_len = numeric_leaf(&value, &type->member_v1.offset);
845             p_name = (const struct p_string*)((const char*)&type->member_v1.offset + leaf_len);
846 
847             codeview_add_udt_element(ctp, symt, terminate_string(p_name), value,
848                                      type->member_v1.type);
849 
850             ptr += 2 + 2 + 2 + leaf_len + (1 + p_name->namelen);
851             break;
852 
853         case LF_MEMBER_V2:
854             leaf_len = numeric_leaf(&value, &type->member_v2.offset);
855             p_name = (const struct p_string*)((const unsigned char*)&type->member_v2.offset + leaf_len);
856 
857             codeview_add_udt_element(ctp, symt, terminate_string(p_name), value,
858                                      type->member_v2.type);
859 
860             ptr += 2 + 2 + 4 + leaf_len + (1 + p_name->namelen);
861             break;
862 
863         case LF_MEMBER_V3:
864             leaf_len = numeric_leaf(&value, &type->member_v3.offset);
865             c_name = (const char*)&type->member_v3.offset + leaf_len;
866 
867             codeview_add_udt_element(ctp, symt, c_name, value, type->member_v3.type);
868 
869             ptr += 2 + 2 + 4 + leaf_len + (strlen(c_name) + 1);
870             break;
871 
872         case LF_STMEMBER_V1:
873             /* FIXME: ignored for now */
874             ptr += 2 + 2 + 2 + (1 + type->stmember_v1.p_name.namelen);
875             break;
876 
877         case LF_STMEMBER_V2:
878             /* FIXME: ignored for now */
879             ptr += 2 + 4 + 2 + (1 + type->stmember_v2.p_name.namelen);
880             break;
881 
882         case LF_STMEMBER_V3:
883             /* FIXME: ignored for now */
884             ptr += 2 + 4 + 2 + (strlen(type->stmember_v3.name) + 1);
885             break;
886 
887         case LF_METHOD_V1:
888             /* FIXME: ignored for now */
889             ptr += 2 + 2 + 2 + (1 + type->method_v1.p_name.namelen);
890             break;
891 
892         case LF_METHOD_V2:
893             /* FIXME: ignored for now */
894             ptr += 2 + 2 + 4 + (1 + type->method_v2.p_name.namelen);
895             break;
896 
897         case LF_METHOD_V3:
898             /* FIXME: ignored for now */
899             ptr += 2 + 2 + 4 + (strlen(type->method_v3.name) + 1);
900             break;
901 
902         case LF_NESTTYPE_V1:
903             /* FIXME: ignored for now */
904             ptr += 2 + 2 + (1 + type->nesttype_v1.p_name.namelen);
905             break;
906 
907         case LF_NESTTYPE_V2:
908             /* FIXME: ignored for now */
909             ptr += 2 + 2 + 4 + (1 + type->nesttype_v2.p_name.namelen);
910             break;
911 
912         case LF_NESTTYPE_V3:
913             /* FIXME: ignored for now */
914             ptr += 2 + 2 + 4 + (strlen(type->nesttype_v3.name) + 1);
915             break;
916 
917         case LF_VFUNCTAB_V1:
918             /* FIXME: ignored for now */
919             ptr += 2 + 2;
920             break;
921 
922         case LF_VFUNCTAB_V2:
923             /* FIXME: ignored for now */
924             ptr += 2 + 2 + 4;
925             break;
926 
927         case LF_ONEMETHOD_V1:
928             /* FIXME: ignored for now */
929             switch ((type->onemethod_v1.attribute >> 2) & 7)
930             {
931             case 4: case 6: /* (pure) introducing virtual method */
932                 ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt_v1.p_name.namelen);
933                 break;
934 
935             default:
936                 ptr += 2 + 2 + 2 + (1 + type->onemethod_v1.p_name.namelen);
937                 break;
938             }
939             break;
940 
941         case LF_ONEMETHOD_V2:
942             /* FIXME: ignored for now */
943             switch ((type->onemethod_v2.attribute >> 2) & 7)
944             {
945             case 4: case 6: /* (pure) introducing virtual method */
946                 ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod_virt_v2.p_name.namelen);
947                 break;
948 
949             default:
950                 ptr += 2 + 2 + 4 + (1 + type->onemethod_v2.p_name.namelen);
951                 break;
952             }
953             break;
954 
955         case LF_ONEMETHOD_V3:
956             /* FIXME: ignored for now */
957             switch ((type->onemethod_v3.attribute >> 2) & 7)
958             {
959             case 4: case 6: /* (pure) introducing virtual method */
960                 ptr += 2 + 2 + 4 + 4 + (strlen(type->onemethod_virt_v3.name) + 1);
961                 break;
962 
963             default:
964                 ptr += 2 + 2 + 4 + (strlen(type->onemethod_v3.name) + 1);
965                 break;
966             }
967             break;
968 
969         case LF_INDEX_V1:
970             if (!codeview_add_type_struct_field_list(ctp, symt, type->index_v1.ref))
971                 return FALSE;
972             ptr += 2 + 2;
973             break;
974 
975         case LF_INDEX_V2:
976             if (!codeview_add_type_struct_field_list(ctp, symt, type->index_v2.ref))
977                 return FALSE;
978             ptr += 2 + 2 + 4;
979             break;
980 
981         default:
982             FIXME("Unsupported type %04x in STRUCT field list\n", type->generic.id);
983             return FALSE;
984         }
985     }
986 
987     return TRUE;
988 }
989 
990 static struct symt* codeview_add_type_enum(struct codeview_type_parse* ctp,
991                                            struct symt* existing,
992                                            const char* name,
993                                            unsigned fieldlistno,
994                                            unsigned basetype)
995 {
996     struct symt_enum*   symt;
997 
998     if (existing)
999     {
1000         if (!(symt = codeview_cast_symt(existing, SymTagEnum))) return NULL;
1001         /* should also check that all fields are the same */
1002     }
1003     else
1004     {
1005         symt = symt_new_enum(ctp->module, name,
1006                              codeview_fetch_type(ctp, basetype, FALSE));
1007         if (fieldlistno)
1008         {
1009             const union codeview_reftype* fieldlist;
1010             fieldlist = codeview_jump_to_type(ctp, fieldlistno);
1011             codeview_add_type_enum_field_list(ctp->module, symt, fieldlist);
1012         }
1013     }
1014     return &symt->symt;
1015 }
1016 
1017 static struct symt* codeview_add_type_struct(struct codeview_type_parse* ctp,
1018                                              struct symt* existing,
1019                                              const char* name, int structlen,
1020                                              enum UdtKind kind, unsigned property)
1021 {
1022     struct symt_udt*    symt;
1023 
1024     /* if we don't have an existing type, try to find one with same name
1025      * FIXME: what to do when several types in different CUs have same name ?
1026      */
1027     if (!existing)
1028     {
1029         void*                       ptr;
1030         struct symt_ht*             type;
1031         struct hash_table_iter      hti;
1032 
1033         hash_table_iter_init(&ctp->module->ht_types, &hti, name);
1034         while ((ptr = hash_table_iter_up(&hti)))
1035         {
1036             type = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt);
1037 
1038             if (type->symt.tag == SymTagUDT &&
1039                 type->hash_elt.name && !strcmp(type->hash_elt.name, name))
1040             {
1041                 existing = &type->symt;
1042                 break;
1043             }
1044         }
1045     }
1046     if (existing)
1047     {
1048         if (!(symt = codeview_cast_symt(existing, SymTagUDT))) return NULL;
1049         /* should also check that all fields are the same */
1050         if (!(property & 0x80)) /* 0x80 = forward declaration */
1051         {
1052             if (!symt->size) /* likely prior forward declaration, set UDT size */
1053                 symt_set_udt_size(ctp->module, symt, structlen);
1054             else /* different UDT with same name, create a new type */
1055                 existing = NULL;
1056         }
1057     }
1058     if (!existing) symt = symt_new_udt(ctp->module, name, structlen, kind);
1059 
1060     return &symt->symt;
1061 }
1062 
1063 static struct symt* codeview_new_func_signature(struct codeview_type_parse* ctp,
1064                                                 struct symt* existing,
1065                                                 enum CV_call_e call_conv)
1066 {
1067     struct symt_function_signature*     sym;
1068 
1069     if (existing)
1070     {
1071         sym = codeview_cast_symt(existing, SymTagFunctionType);
1072         if (!sym) return NULL;
1073     }
1074     else
1075     {
1076         sym = symt_new_function_signature(ctp->module, NULL, call_conv);
1077     }
1078     return &sym->symt;
1079 }
1080 
1081 static void codeview_add_func_signature_args(struct codeview_type_parse* ctp,
1082                                              struct symt_function_signature* sym,
1083                                              unsigned ret_type,
1084                                              unsigned args_list)
1085 {
1086     const union codeview_reftype*       reftype;
1087 
1088     sym->rettype = codeview_fetch_type(ctp, ret_type, FALSE);
1089     if (args_list && (reftype = codeview_jump_to_type(ctp, args_list)))
1090     {
1091         unsigned int i;
1092         switch (reftype->generic.id)
1093         {
1094         case LF_ARGLIST_V1:
1095             for (i = 0; i < reftype->arglist_v1.num; i++)
1096                 symt_add_function_signature_parameter(ctp->module, sym,
1097                                                       codeview_fetch_type(ctp, reftype->arglist_v1.args[i], FALSE));
1098             break;
1099         case LF_ARGLIST_V2:
1100             for (i = 0; i < reftype->arglist_v2.num; i++)
1101                 symt_add_function_signature_parameter(ctp->module, sym,
1102                                                       codeview_fetch_type(ctp, reftype->arglist_v2.args[i], FALSE));
1103             break;
1104         default:
1105             FIXME("Unexpected leaf %x for signature's pmt\n", reftype->generic.id);
1106         }
1107     }
1108 }
1109 
1110 static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp,
1111                                             unsigned curr_type,
1112                                             const union codeview_type* type, BOOL details)
1113 {
1114     struct symt*                symt;
1115     int                         value, leaf_len;
1116     const struct p_string*      p_name;
1117     const char*                 c_name;
1118     struct symt*                existing;
1119 
1120     existing = codeview_get_type(curr_type, TRUE);
1121 
1122     switch (type->generic.id)
1123     {
1124     case LF_MODIFIER_V1:
1125         /* FIXME: we don't handle modifiers,
1126          * but read previous type on the curr_type
1127          */
1128         WARN("Modifier on %x: %s%s%s%s\n",
1129              type->modifier_v1.type,
1130              type->modifier_v1.attribute & 0x01 ? "const " : "",
1131              type->modifier_v1.attribute & 0x02 ? "volatile " : "",
1132              type->modifier_v1.attribute & 0x04 ? "unaligned " : "",
1133              type->modifier_v1.attribute & ~0x07 ? "unknown " : "");
1134         symt = codeview_fetch_type(ctp, type->modifier_v1.type, details);
1135         break;
1136     case LF_MODIFIER_V2:
1137         /* FIXME: we don't handle modifiers, but readd previous type on the curr_type */
1138         WARN("Modifier on %x: %s%s%s%s\n",
1139              type->modifier_v2.type,
1140              type->modifier_v2.attribute & 0x01 ? "const " : "",
1141              type->modifier_v2.attribute & 0x02 ? "volatile " : "",
1142              type->modifier_v2.attribute & 0x04 ? "unaligned " : "",
1143              type->modifier_v2.attribute & ~0x07 ? "unknown " : "");
1144         symt = codeview_fetch_type(ctp, type->modifier_v2.type, details);
1145         break;
1146 
1147     case LF_POINTER_V1:
1148         symt = codeview_add_type_pointer(ctp, existing, type->pointer_v1.datatype);
1149         break;
1150     case LF_POINTER_V2:
1151         symt = codeview_add_type_pointer(ctp, existing, type->pointer_v2.datatype);
1152         break;
1153 
1154     case LF_ARRAY_V1:
1155         if (existing) symt = codeview_cast_symt(existing, SymTagArrayType);
1156         else
1157         {
1158             leaf_len = numeric_leaf(&value, &type->array_v1.arrlen);
1159             p_name = (const struct p_string*)((const unsigned char*)&type->array_v1.arrlen + leaf_len);
1160             symt = codeview_add_type_array(ctp, terminate_string(p_name),
1161                                            type->array_v1.elemtype,
1162                                            type->array_v1.idxtype, value);
1163         }
1164         break;
1165     case LF_ARRAY_V2:
1166         if (existing) symt = codeview_cast_symt(existing, SymTagArrayType);
1167         else
1168         {
1169             leaf_len = numeric_leaf(&value, &type->array_v2.arrlen);
1170             p_name = (const struct p_string*)((const unsigned char*)&type->array_v2.arrlen + leaf_len);
1171 
1172             symt = codeview_add_type_array(ctp, terminate_string(p_name),
1173                                            type->array_v2.elemtype,
1174                                            type->array_v2.idxtype, value);
1175         }
1176         break;
1177     case LF_ARRAY_V3:
1178         if (existing) symt = codeview_cast_symt(existing, SymTagArrayType);
1179         else
1180         {
1181             leaf_len = numeric_leaf(&value, &type->array_v3.arrlen);
1182             c_name = (const char*)&type->array_v3.arrlen + leaf_len;
1183 
1184             symt = codeview_add_type_array(ctp, c_name,
1185                                            type->array_v3.elemtype,
1186                                            type->array_v3.idxtype, value);
1187         }
1188         break;
1189 
1190     case LF_STRUCTURE_V1:
1191     case LF_CLASS_V1:
1192         leaf_len = numeric_leaf(&value, &type->struct_v1.structlen);
1193         p_name = (const struct p_string*)((const unsigned char*)&type->struct_v1.structlen + leaf_len);
1194         symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name), value,
1195                                         type->generic.id == LF_CLASS_V1 ? UdtClass : UdtStruct,
1196                                         type->struct_v1.property);
1197         if (details)
1198         {
1199             codeview_add_type(curr_type, symt);
1200             if (!(type->struct_v1.property & 0x80)) /* 0x80 = forward declaration */
1201                 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1202                                                     type->struct_v1.fieldlist);
1203         }
1204         break;
1205 
1206     case LF_STRUCTURE_V2:
1207     case LF_CLASS_V2:
1208         leaf_len = numeric_leaf(&value, &type->struct_v2.structlen);
1209         p_name = (const struct p_string*)((const unsigned char*)&type->struct_v2.structlen + leaf_len);
1210         symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name), value,
1211                                         type->generic.id == LF_CLASS_V2 ? UdtClass : UdtStruct,
1212                                         type->struct_v2.property);
1213         if (details)
1214         {
1215             codeview_add_type(curr_type, symt);
1216             if (!(type->struct_v2.property & 0x80)) /* 0x80 = forward declaration */
1217                 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1218                                                     type->struct_v2.fieldlist);
1219         }
1220         break;
1221 
1222     case LF_STRUCTURE_V3:
1223     case LF_CLASS_V3:
1224         leaf_len = numeric_leaf(&value, &type->struct_v3.structlen);
1225         c_name = (const char*)&type->struct_v3.structlen + leaf_len;
1226         symt = codeview_add_type_struct(ctp, existing, c_name, value,
1227                                         type->generic.id == LF_CLASS_V3 ? UdtClass : UdtStruct,
1228                                         type->struct_v3.property);
1229         if (details)
1230         {
1231             codeview_add_type(curr_type, symt);
1232             if (!(type->struct_v3.property & 0x80)) /* 0x80 = forward declaration */
1233                 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1234                                                     type->struct_v3.fieldlist);
1235         }
1236         break;
1237 
1238     case LF_UNION_V1:
1239         leaf_len = numeric_leaf(&value, &type->union_v1.un_len);
1240         p_name = (const struct p_string*)((const unsigned char*)&type->union_v1.un_len + leaf_len);
1241         symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name),
1242                                         value, UdtUnion, type->union_v1.property);
1243         if (details)
1244         {
1245             codeview_add_type(curr_type, symt);
1246             codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1247                                                 type->union_v1.fieldlist);
1248         }
1249         break;
1250 
1251     case LF_UNION_V2:
1252         leaf_len = numeric_leaf(&value, &type->union_v2.un_len);
1253         p_name = (const struct p_string*)((const unsigned char*)&type->union_v2.un_len + leaf_len);
1254         symt = codeview_add_type_struct(ctp, existing, terminate_string(p_name),
1255                                         value, UdtUnion, type->union_v2.property);
1256         if (details)
1257         {
1258             codeview_add_type(curr_type, symt);
1259             codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1260                                                 type->union_v2.fieldlist);
1261         }
1262         break;
1263 
1264     case LF_UNION_V3:
1265         leaf_len = numeric_leaf(&value, &type->union_v3.un_len);
1266         c_name = (const char*)&type->union_v3.un_len + leaf_len;
1267         symt = codeview_add_type_struct(ctp, existing, c_name,
1268                                         value, UdtUnion, type->union_v3.property);
1269         if (details)
1270         {
1271             codeview_add_type(curr_type, symt);
1272             codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1273                                                 type->union_v3.fieldlist);
1274         }
1275         break;
1276 
1277     case LF_ENUM_V1:
1278         symt = codeview_add_type_enum(ctp, existing,
1279                                       terminate_string(&type->enumeration_v1.p_name),
1280                                       type->enumeration_v1.fieldlist,
1281                                       type->enumeration_v1.type);
1282         break;
1283 
1284     case LF_ENUM_V2:
1285         symt = codeview_add_type_enum(ctp, existing,
1286                                       terminate_string(&type->enumeration_v2.p_name),
1287                                       type->enumeration_v2.fieldlist,
1288                                       type->enumeration_v2.type);
1289         break;
1290 
1291     case LF_ENUM_V3:
1292         symt = codeview_add_type_enum(ctp, existing, type->enumeration_v3.name,
1293                                       type->enumeration_v3.fieldlist,
1294                                       type->enumeration_v3.type);
1295         break;
1296 
1297     case LF_PROCEDURE_V1:
1298         symt = codeview_new_func_signature(ctp, existing, type->procedure_v1.call);
1299         if (details)
1300         {
1301             codeview_add_type(curr_type, symt);
1302             codeview_add_func_signature_args(ctp,
1303                                              (struct symt_function_signature*)symt,
1304                                              type->procedure_v1.rvtype,
1305                                              type->procedure_v1.arglist);
1306         }
1307         break;
1308     case LF_PROCEDURE_V2:
1309         symt = codeview_new_func_signature(ctp, existing,type->procedure_v2.call);
1310         if (details)
1311         {
1312             codeview_add_type(curr_type, symt);
1313             codeview_add_func_signature_args(ctp,
1314                                              (struct symt_function_signature*)symt,
1315                                              type->procedure_v2.rvtype,
1316                                              type->procedure_v2.arglist);
1317         }
1318         break;
1319 
1320     case LF_MFUNCTION_V1:
1321         /* FIXME: for C++, this is plain wrong, but as we don't use arg types
1322          * nor class information, this would just do for now
1323          */
1324         symt = codeview_new_func_signature(ctp, existing, type->mfunction_v1.call);
1325         if (details)
1326         {
1327             codeview_add_type(curr_type, symt);
1328             codeview_add_func_signature_args(ctp,
1329                                              (struct symt_function_signature*)symt,
1330                                              type->mfunction_v1.rvtype,
1331                                              type->mfunction_v1.arglist);
1332         }
1333         break;
1334     case LF_MFUNCTION_V2:
1335         /* FIXME: for C++, this is plain wrong, but as we don't use arg types
1336          * nor class information, this would just do for now
1337          */
1338         symt = codeview_new_func_signature(ctp, existing, type->mfunction_v2.call);
1339         if (details)
1340         {
1341             codeview_add_type(curr_type, symt);
1342             codeview_add_func_signature_args(ctp,
1343                                              (struct symt_function_signature*)symt,
1344                                              type->mfunction_v2.rvtype,
1345                                              type->mfunction_v2.arglist);
1346         }
1347         break;
1348 
1349     case LF_VTSHAPE_V1:
1350         /* this is an ugly hack... FIXME when we have C++ support */
1351         if (!(symt = existing))
1352         {
1353             char    buf[128];
1354             snprintf(buf, sizeof(buf), "__internal_vt_shape_%x\n", curr_type);
1355             symt = &symt_new_udt(ctp->module, buf, 0, UdtStruct)->symt;
1356         }
1357         break;
1358     default:
1359         FIXME("Unsupported type-id leaf %x\n", type->generic.id);
1360         dump(type, 2 + type->generic.len);
1361         return NULL;
1362     }
1363     return codeview_add_type(curr_type, symt) ? symt : NULL;
1364 }
1365 
1366 static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp)
1367 {
1368     unsigned int                curr_type = FIRST_DEFINABLE_TYPE;
1369     const union codeview_type*  type;
1370 
1371     for (curr_type = FIRST_DEFINABLE_TYPE; curr_type < FIRST_DEFINABLE_TYPE + ctp->num; curr_type++)
1372     {
1373         type = codeview_jump_to_type(ctp, curr_type);
1374 
1375         /* type records we're interested in are the ones referenced by symbols
1376          * The known ranges are (X mark the ones we want):
1377          *   X  0000-0016       for V1 types
1378          *      0200-020c       for V1 types referenced by other types
1379          *      0400-040f       for V1 types (complex lists & sets)
1380          *   X  1000-100f       for V2 types
1381          *      1200-120c       for V2 types referenced by other types
1382          *      1400-140f       for V1 types (complex lists & sets)
1383          *   X  1500-150d       for V3 types
1384          *      8000-8010       for numeric leafes
1385          */
1386         if (!(type->generic.id & 0x8600) || (type->generic.id & 0x0100))
1387             codeview_parse_one_type(ctp, curr_type, type, TRUE);
1388     }
1389 
1390     return TRUE;
1391 }
1392 
1393 /*========================================================================
1394  * Process CodeView line number information.
1395  */
1396 static unsigned long codeview_get_address(const struct msc_debug_info* msc_dbg,
1397                                           unsigned seg, unsigned offset);
1398 
1399 static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const BYTE* linetab,
1400                                    int size, BOOL pascal_str)
1401 {
1402     const BYTE*                 ptr = linetab;
1403     int				nfile, nseg;
1404     int                         i, j;
1405     unsigned int                k;
1406     const unsigned int*         filetab;
1407     const unsigned int*         lt_ptr;
1408     const unsigned short*       linenos;
1409     const struct startend*      start;
1410     unsigned                    source;
1411     unsigned long               addr, func_addr0;
1412     struct symt_function*       func;
1413     const struct codeview_linetab_block* ltb;
1414 
1415     nfile = *(const short*)linetab;
1416     filetab = (const unsigned int*)(linetab + 2 * sizeof(short));
1417 
1418     for (i = 0; i < nfile; i++)
1419     {
1420         ptr = linetab + filetab[i];
1421         nseg = *(const short*)ptr;
1422         lt_ptr = (const unsigned int*)(ptr + 2 * sizeof(short));
1423         start = (const struct startend*)(lt_ptr + nseg);
1424 
1425         /*
1426          * Now snarf the filename for all of the segments for this file.
1427          */
1428         if (pascal_str)
1429             source = source_new(msc_dbg->module, NULL, terminate_string((const struct p_string*)(start + nseg)));
1430         else
1431             source = source_new(msc_dbg->module, NULL, (const char*)(start + nseg));
1432 
1433         for (j = 0; j < nseg; j++)
1434 	{
1435             ltb = (const struct codeview_linetab_block*)(linetab + *lt_ptr++);
1436             linenos = (const unsigned short*)&ltb->offsets[ltb->num_lines];
1437             func_addr0 = codeview_get_address(msc_dbg, ltb->seg, start[j].start);
1438             if (!func_addr0) continue;
1439             for (func = NULL, k = 0; k < ltb->num_lines; k++)
1440             {
1441                 /* now locate function (if any) */
1442                 addr = func_addr0 + ltb->offsets[k] - start[j].start;
1443                 /* unfortunately, we can have several functions in the same block, if there's no
1444                  * gap between them... find the new function if needed
1445                  */
1446                 if (!func || addr >= func->address + func->size)
1447                 {
1448                     func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
1449                     /* FIXME: at least labels support line numbers */
1450                     if (!func || func->symt.tag != SymTagFunction)
1451                     {
1452                         WARN("--not a func at %04x:%08x %lx tag=%d\n",
1453                              ltb->seg, ltb->offsets[k], addr, func ? func->symt.tag : -1);
1454                         func = NULL;
1455                         break;
1456                     }
1457                 }
1458                 symt_add_func_line(msc_dbg->module, func, source,
1459                                    linenos[k], addr - func->address);
1460             }
1461 	}
1462     }
1463 }
1464 
1465 static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const BYTE* linetab, DWORD size,
1466                                     const char* strimage, DWORD strsize)
1467 {
1468     unsigned    i;
1469     DWORD_PTR       addr;
1470     const struct codeview_linetab2*     lt2;
1471     const struct codeview_linetab2*     lt2_files = NULL;
1472     const struct codeview_lt2blk_lines* lines_blk;
1473     const struct codeview_linetab2_file*fd;
1474     unsigned    source;
1475     struct symt_function* func;
1476 
1477     /* locate LT2_FILES_BLOCK (if any) */
1478     lt2 = (const struct codeview_linetab2*)linetab;
1479     while ((const BYTE*)(lt2 + 1) < linetab + size)
1480     {
1481         if (lt2->header == LT2_FILES_BLOCK)
1482         {
1483             lt2_files = lt2;
1484             break;
1485         }
1486         lt2 = codeview_linetab2_next_block(lt2);
1487     }
1488     if (!lt2_files)
1489     {
1490         TRACE("No LT2_FILES_BLOCK found\n");
1491         return;
1492     }
1493 
1494     lt2 = (const struct codeview_linetab2*)linetab;
1495     while ((const BYTE*)(lt2 + 1) < linetab + size)
1496     {
1497         /* FIXME: should also check that whole lines_blk fits in linetab + size */
1498         switch (lt2->header)
1499         {
1500         case LT2_LINES_BLOCK:
1501             /* Skip blocks that are too small - Intel C Compiler generates these. */
1502             if (lt2->size_of_block < sizeof (struct codeview_lt2blk_lines)) break;
1503             lines_blk = (const struct codeview_lt2blk_lines*)lt2;
1504             /* FIXME: should check that file_offset is within the LT2_FILES_BLOCK we've seen */
1505             addr = codeview_get_address(msc_dbg, lines_blk->seg, lines_blk->start);
1506             TRACE("block from %04x:%08x #%x (%x lines)\n",
1507                   lines_blk->seg, lines_blk->start, lines_blk->size, lines_blk->nlines);
1508             fd = (const struct codeview_linetab2_file*)((const char*)lt2_files + 8 + lines_blk->file_offset);
1509             /* FIXME: should check that string is within strimage + strsize */
1510             source = source_new(msc_dbg->module, NULL, strimage + fd->offset);
1511             func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
1512             /* FIXME: at least labels support line numbers */
1513             if (!func || func->symt.tag != SymTagFunction)
1514             {
1515                 WARN("--not a func at %04x:%08x %lx tag=%d\n",
1516                      lines_blk->seg, lines_blk->start, addr, func ? func->symt.tag : -1);
1517                 break;
1518             }
1519             for (i = 0; i < lines_blk->nlines; i++)
1520             {
1521                 symt_add_func_line(msc_dbg->module, func, source,
1522                                    lines_blk->l[i].lineno ^ 0x80000000,
1523                                    lines_blk->l[i].offset);
1524             }
1525             break;
1526         case LT2_FILES_BLOCK: /* skip */
1527             break;
1528         default:
1529             TRACE("Block end %x\n", lt2->header);
1530             lt2 = (const struct codeview_linetab2*)((const char*)linetab + size);
1531             continue;
1532         }
1533         lt2 = codeview_linetab2_next_block(lt2);
1534     }
1535 }
1536 
1537 /*========================================================================
1538  * Process CodeView symbol information.
1539  */
1540 
1541 static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
1542                                         unsigned int offset)
1543 {
1544     int                 nomap = msc_dbg->nomap;
1545     const OMAP_DATA*    omapp = msc_dbg->omapp;
1546     int                 i;
1547 
1548     if (!nomap || !omapp) return offset;
1549 
1550     /* FIXME: use binary search */
1551     for (i = 0; i < nomap - 1; i++)
1552         if (omapp[i].from <= offset && omapp[i+1].from > offset)
1553             return !omapp[i].to ? 0 : omapp[i].to + (offset - omapp[i].from);
1554 
1555     return 0;
1556 }
1557 
1558 static unsigned long codeview_get_address(const struct msc_debug_info* msc_dbg,
1559                                           unsigned seg, unsigned offset)
1560 {
1561     int			        nsect = msc_dbg->nsect;
1562     const IMAGE_SECTION_HEADER* sectp = msc_dbg->sectp;
1563 
1564     if (!seg || seg > nsect) return 0;
1565     return msc_dbg->module->module.BaseOfImage +
1566         codeview_map_offset(msc_dbg, sectp[seg-1].VirtualAddress + offset);
1567 }
1568 
1569 static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
1570                                          struct symt_compiland* compiland,
1571                                          const char* name,
1572                                          unsigned segment, unsigned offset,
1573                                          unsigned symtype, BOOL is_local, BOOL in_tls, BOOL force)
1574 {
1575     if (name && *name)
1576     {
1577         struct location loc;
1578 
1579         loc.kind = in_tls ? loc_tlsrel : loc_absolute;
1580         loc.reg = 0;
1581         loc.offset = in_tls ? offset : codeview_get_address(msc_dbg, segment, offset);
1582         if (force || in_tls || !symt_find_nearest(msc_dbg->module, loc.offset))
1583         {
1584             symt_new_global_variable(msc_dbg->module, compiland,
1585                                      name, is_local, loc, 0,
1586                                      codeview_get_type(symtype, FALSE));
1587         }
1588     }
1589 }
1590 
1591 static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root,
1592                            int offset, int size, BOOL do_globals)
1593 {
1594     struct symt_function*               curr_func = NULL;
1595     int                                 i, length;
1596     struct symt_block*                  block = NULL;
1597     struct symt*                        symt;
1598     struct symt_compiland*              compiland = NULL;
1599     struct location                     loc;
1600 
1601     /*
1602      * Loop over the different types of records and whenever we
1603      * find something we are interested in, record it and move on.
1604      */
1605     for (i = offset; i < size; i += length)
1606     {
1607         const union codeview_symbol* sym = (const union codeview_symbol*)(root + i);
1608         length = sym->generic.len + 2;
1609         if (i + length > size) break;
1610         if (!sym->generic.id || length < 4) break;
1611         if (length & 3) FIXME("unpadded len %u\n", length);
1612 
1613         switch (sym->generic.id)
1614         {
1615         /*
1616          * Global and local data symbols.  We don't associate these
1617          * with any given source file.
1618          */
1619 	case S_GDATA_V1:
1620 	case S_LDATA_V1:
1621             if (do_globals)
1622                 codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->data_v1.p_name),
1623                                       sym->data_v1.segment, sym->data_v1.offset, sym->data_v1.symtype,
1624                                       sym->generic.id == S_LDATA_V1, FALSE, TRUE);
1625 	    break;
1626 	case S_GDATA_V2:
1627 	case S_LDATA_V2:
1628             if (do_globals)
1629                 codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->data_v2.p_name),
1630                                       sym->data_v2.segment, sym->data_v2.offset, sym->data_v2.symtype,
1631                                       sym->generic.id == S_LDATA_V2, FALSE, TRUE);
1632 	    break;
1633 	case S_GDATA_V3:
1634 	case S_LDATA_V3:
1635             if (do_globals)
1636                 codeview_add_variable(msc_dbg, compiland, sym->data_v3.name,
1637                                       sym->data_v3.segment, sym->data_v3.offset, sym->data_v3.symtype,
1638                                       sym->generic.id == S_LDATA_V3, FALSE, TRUE);
1639 	    break;
1640 
1641         /* variables with thread storage */
1642 	case S_GTHREAD_V1:
1643 	case S_LTHREAD_V1:
1644             if (do_globals)
1645                 codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->thread_v1.p_name),
1646                                       sym->thread_v1.segment, sym->thread_v1.offset, sym->thread_v1.symtype,
1647                                       sym->generic.id == S_LTHREAD_V1, TRUE, TRUE);
1648 	    break;
1649 	case S_GTHREAD_V2:
1650 	case S_LTHREAD_V2:
1651             if (do_globals)
1652                 codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->thread_v2.p_name),
1653                                       sym->thread_v2.segment, sym->thread_v2.offset, sym->thread_v2.symtype,
1654                                       sym->generic.id == S_LTHREAD_V2, TRUE, TRUE);
1655 	    break;
1656 	case S_GTHREAD_V3:
1657 	case S_LTHREAD_V3:
1658             if (do_globals)
1659                 codeview_add_variable(msc_dbg, compiland, sym->thread_v3.name,
1660                                       sym->thread_v3.segment, sym->thread_v3.offset, sym->thread_v3.symtype,
1661                                       sym->generic.id == S_LTHREAD_V3, TRUE, TRUE);
1662 	    break;
1663 
1664         /* Public symbols */
1665 	case S_PUB_V1:
1666 	case S_PUB_V2:
1667         case S_PUB_V3:
1668         case S_PUB_FUNC1_V3:
1669         case S_PUB_FUNC2_V3:
1670             /* will be handled later on in codeview_snarf_public */
1671             break;
1672 
1673         /*
1674          * Sort of like a global function, but it just points
1675          * to a thunk, which is a stupid name for what amounts to
1676          * a PLT slot in the normal jargon that everyone else uses.
1677          */
1678 	case S_THUNK_V1:
1679             symt_new_thunk(msc_dbg->module, compiland,
1680                            terminate_string(&sym->thunk_v1.p_name), sym->thunk_v1.thtype,
1681                            codeview_get_address(msc_dbg, sym->thunk_v1.segment, sym->thunk_v1.offset),
1682                            sym->thunk_v1.thunk_len);
1683 	    break;
1684 	case S_THUNK_V3:
1685             symt_new_thunk(msc_dbg->module, compiland,
1686                            sym->thunk_v3.name, sym->thunk_v3.thtype,
1687                            codeview_get_address(msc_dbg, sym->thunk_v3.segment, sym->thunk_v3.offset),
1688                            sym->thunk_v3.thunk_len);
1689 	    break;
1690 
1691         /*
1692          * Global and static functions.
1693          */
1694 	case S_GPROC_V1:
1695 	case S_LPROC_V1:
1696             if (curr_func) FIXME("nested function\n");
1697             curr_func = symt_new_function(msc_dbg->module, compiland,
1698                                           terminate_string(&sym->proc_v1.p_name),
1699                                           codeview_get_address(msc_dbg, sym->proc_v1.segment, sym->proc_v1.offset),
1700                                           sym->proc_v1.proc_len,
1701                                           codeview_get_type(sym->proc_v1.proctype, FALSE));
1702             loc.kind = loc_absolute;
1703             loc.offset = sym->proc_v1.debug_start;
1704             symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, &loc, NULL);
1705             loc.offset = sym->proc_v1.debug_end;
1706             symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugEnd, &loc, NULL);
1707 	    break;
1708 	case S_GPROC_V2:
1709 	case S_LPROC_V2:
1710             if (curr_func) FIXME("nested function\n");
1711             curr_func = symt_new_function(msc_dbg->module, compiland,
1712                                           terminate_string(&sym->proc_v2.p_name),
1713                                           codeview_get_address(msc_dbg, sym->proc_v2.segment, sym->proc_v2.offset),
1714                                           sym->proc_v2.proc_len,
1715                                           codeview_get_type(sym->proc_v2.proctype, FALSE));
1716             loc.kind = loc_absolute;
1717             loc.offset = sym->proc_v2.debug_start;
1718             symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, &loc, NULL);
1719             loc.offset = sym->proc_v2.debug_end;
1720             symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugEnd, &loc, NULL);
1721 	    break;
1722 	case S_GPROC_V3:
1723 	case S_LPROC_V3:
1724             if (curr_func) FIXME("nested function\n");
1725             curr_func = symt_new_function(msc_dbg->module, compiland,
1726                                           sym->proc_v3.name,
1727                                           codeview_get_address(msc_dbg, sym->proc_v3.segment, sym->proc_v3.offset),
1728                                           sym->proc_v3.proc_len,
1729                                           codeview_get_type(sym->proc_v3.proctype, FALSE));
1730             loc.kind = loc_absolute;
1731             loc.offset = sym->proc_v3.debug_start;
1732             symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, &loc, NULL);
1733             loc.offset = sym->proc_v3.debug_end;
1734             symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugEnd, &loc, NULL);
1735 	    break;
1736         /*
1737          * Function parameters and stack variables.
1738          */
1739 	case S_BPREL_V1:
1740             loc.kind = loc_regrel;
1741             /* Yes, it's i386 dependent, but that's the symbol purpose. S_REGREL is used on other CPUs */
1742             loc.reg = CV_REG_EBP;
1743             loc.offset = sym->stack_v1.offset;
1744             symt_add_func_local(msc_dbg->module, curr_func,
1745                                 sym->stack_v1.offset > 0 ? DataIsParam : DataIsLocal,
1746                                 &loc, block,
1747                                 codeview_get_type(sym->stack_v1.symtype, FALSE),
1748                                 terminate_string(&sym->stack_v1.p_name));
1749             break;
1750 	case S_BPREL_V2:
1751             loc.kind = loc_regrel;
1752             /* Yes, it's i386 dependent, but that's the symbol purpose. S_REGREL is used on other CPUs */
1753             loc.reg = CV_REG_EBP;
1754             loc.offset = sym->stack_v2.offset;
1755             symt_add_func_local(msc_dbg->module, curr_func,
1756                                 sym->stack_v2.offset > 0 ? DataIsParam : DataIsLocal,
1757                                 &loc, block,
1758                                 codeview_get_type(sym->stack_v2.symtype, FALSE),
1759                                 terminate_string(&sym->stack_v2.p_name));
1760             break;
1761 	case S_BPREL_V3:
1762             loc.kind = loc_regrel;
1763             /* Yes, it's i386 dependent, but that's the symbol purpose. S_REGREL is used on other CPUs */
1764             loc.reg = CV_REG_EBP;
1765             loc.offset = sym->stack_v3.offset;
1766             symt_add_func_local(msc_dbg->module, curr_func,
1767                                 sym->stack_v3.offset > 0 ? DataIsParam : DataIsLocal,
1768                                 &loc, block,
1769                                 codeview_get_type(sym->stack_v3.symtype, FALSE),
1770                                 sym->stack_v3.name);
1771             break;
1772 	case S_REGREL_V3:
1773             loc.kind = loc_regrel;
1774             loc.reg = sym->regrel_v3.reg;
1775             loc.offset = sym->regrel_v3.offset;
1776             symt_add_func_local(msc_dbg->module, curr_func,
1777                                 /* FIXME this is wrong !!! */
1778                                 sym->regrel_v3.offset > 0 ? DataIsParam : DataIsLocal,
1779                                 &loc, block,
1780                                 codeview_get_type(sym->regrel_v3.symtype, FALSE),
1781                                 sym->regrel_v3.name);
1782             break;
1783 
1784         case S_REGISTER_V1:
1785             loc.kind = loc_register;
1786             loc.reg = sym->register_v1.reg;
1787             loc.offset = 0;
1788             symt_add_func_local(msc_dbg->module, curr_func,
1789                                 DataIsLocal, &loc,
1790                                 block, codeview_get_type(sym->register_v1.type, FALSE),
1791                                 terminate_string(&sym->register_v1.p_name));
1792             break;
1793         case S_REGISTER_V2:
1794             loc.kind = loc_register;
1795             loc.reg = sym->register_v2.reg;
1796             loc.offset = 0;
1797             symt_add_func_local(msc_dbg->module, curr_func,
1798                                 DataIsLocal, &loc,
1799                                 block, codeview_get_type(sym->register_v2.type, FALSE),
1800                                 terminate_string(&sym->register_v2.p_name));
1801             break;
1802         case S_REGISTER_V3:
1803             loc.kind = loc_register;
1804             loc.reg = sym->register_v3.reg;
1805             loc.offset = 0;
1806             symt_add_func_local(msc_dbg->module, curr_func,
1807                                 DataIsLocal, &loc,
1808                                 block, codeview_get_type(sym->register_v3.type, FALSE),
1809                                 sym->register_v3.name);
1810             break;
1811 
1812         case S_BLOCK_V1:
1813             block = symt_open_func_block(msc_dbg->module, curr_func, block,
1814                                          codeview_get_address(msc_dbg, sym->block_v1.segment, sym->block_v1.offset),
1815                                          sym->block_v1.length);
1816             break;
1817         case S_BLOCK_V3:
1818             block = symt_open_func_block(msc_dbg->module, curr_func, block,
1819                                          codeview_get_address(msc_dbg, sym->block_v3.segment, sym->block_v3.offset),
1820                                          sym->block_v3.length);
1821             break;
1822 
1823         case S_END_V1:
1824             if (block)
1825             {
1826                 block = symt_close_func_block(msc_dbg->module, curr_func, block, 0);
1827             }
1828             else if (curr_func)
1829             {
1830                 symt_normalize_function(msc_dbg->module, curr_func);
1831                 curr_func = NULL;
1832             }
1833             break;
1834 
1835         case S_COMPILAND_V1:
1836             TRACE("S-Compiland-V1 %x %s\n",
1837                   sym->compiland_v1.unknown, terminate_string(&sym->compiland_v1.p_name));
1838             break;
1839 
1840         case S_COMPILAND_V2:
1841             TRACE("S-Compiland-V2 %s\n", terminate_string(&sym->compiland_v2.p_name));
1842             if (TRACE_ON(dbghelp_msc))
1843             {
1844                 const char* ptr1 = sym->compiland_v2.p_name.name + sym->compiland_v2.p_name.namelen;
1845                 const char* ptr2;
1846                 while (*ptr1)
1847                 {
1848                     ptr2 = ptr1 + strlen(ptr1) + 1;
1849                     TRACE("\t%s => %s\n", ptr1, debugstr_a(ptr2));
1850                     ptr1 = ptr2 + strlen(ptr2) + 1;
1851                 }
1852             }
1853             break;
1854         case S_COMPILAND_V3:
1855             TRACE("S-Compiland-V3 %s\n", sym->compiland_v3.name);
1856             if (TRACE_ON(dbghelp_msc))
1857             {
1858                 const char* ptr1 = sym->compiland_v3.name + strlen(sym->compiland_v3.name);
1859                 const char* ptr2;
1860                 while (*ptr1)
1861                 {
1862                     ptr2 = ptr1 + strlen(ptr1) + 1;
1863                     TRACE("\t%s => %s\n", ptr1, debugstr_a(ptr2));
1864                     ptr1 = ptr2 + strlen(ptr2) + 1;
1865                 }
1866             }
1867             break;
1868 
1869         case S_OBJNAME_V1:
1870             TRACE("S-ObjName %s\n", terminate_string(&sym->objname_v1.p_name));
1871             compiland = symt_new_compiland(msc_dbg->module, 0 /* FIXME */,
1872                                            source_new(msc_dbg->module, NULL,
1873                                                       terminate_string(&sym->objname_v1.p_name)));
1874             break;
1875 
1876         case S_LABEL_V1:
1877             if (curr_func)
1878             {
1879                 loc.kind = loc_absolute;
1880                 loc.offset = codeview_get_address(msc_dbg, sym->label_v1.segment, sym->label_v1.offset) - curr_func->address;
1881                 symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel, &loc,
1882                                         terminate_string(&sym->label_v1.p_name));
1883             }
1884             else symt_new_label(msc_dbg->module, compiland,
1885                                 terminate_string(&sym->label_v1.p_name),
1886                                 codeview_get_address(msc_dbg, sym->label_v1.segment, sym->label_v1.offset));
1887             break;
1888         case S_LABEL_V3:
1889             if (curr_func)
1890             {
1891                 loc.kind = loc_absolute;
1892                 loc.offset = codeview_get_address(msc_dbg, sym->label_v3.segment, sym->label_v3.offset) - curr_func->address;
1893                 symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel,
1894                                         &loc, sym->label_v3.name);
1895             }
1896             else symt_new_label(msc_dbg->module, compiland, sym->label_v3.name,
1897                                 codeview_get_address(msc_dbg, sym->label_v3.segment, sym->label_v3.offset));
1898             break;
1899 
1900         case S_CONSTANT_V1:
1901             {
1902                 int                     vlen;
1903                 const struct p_string*  name;
1904                 struct symt*            se;
1905                 VARIANT                 v;
1906 
1907                 vlen = leaf_as_variant(&v, &sym->constant_v1.cvalue);
1908                 name = (const struct p_string*)((const char*)&sym->constant_v1.cvalue + vlen);
1909                 se = codeview_get_type(sym->constant_v1.type, FALSE);
1910 
1911                 TRACE("S-Constant-V1 %u %s %x\n",
1912                       v.n1.n2.n3.intVal, terminate_string(name), sym->constant_v1.type);
1913                 symt_new_constant(msc_dbg->module, compiland, terminate_string(name),
1914                                   se, &v);
1915             }
1916             break;
1917         case S_CONSTANT_V2:
1918             {
1919                 int                     vlen;
1920                 const struct p_string*  name;
1921                 struct symt*            se;
1922                 VARIANT                 v;
1923 
1924                 vlen = leaf_as_variant(&v, &sym->constant_v2.cvalue);
1925                 name = (const struct p_string*)((const char*)&sym->constant_v2.cvalue + vlen);
1926                 se = codeview_get_type(sym->constant_v2.type, FALSE);
1927 
1928                 TRACE("S-Constant-V2 %u %s %x\n",
1929                       v.n1.n2.n3.intVal, terminate_string(name), sym->constant_v2.type);
1930                 symt_new_constant(msc_dbg->module, compiland, terminate_string(name),
1931                                   se, &v);
1932             }
1933             break;
1934         case S_CONSTANT_V3:
1935             {
1936                 int                     vlen;
1937                 const char*             name;
1938                 struct symt*            se;
1939                 VARIANT                 v;
1940 
1941                 vlen = leaf_as_variant(&v, &sym->constant_v3.cvalue);
1942                 name = (const char*)&sym->constant_v3.cvalue + vlen;
1943                 se = codeview_get_type(sym->constant_v3.type, FALSE);
1944 
1945                 TRACE("S-Constant-V3 %u %s %x\n",
1946                       v.n1.n2.n3.intVal, name, sym->constant_v3.type);
1947                 /* FIXME: we should add this as a constant value */
1948                 symt_new_constant(msc_dbg->module, compiland, name, se, &v);
1949             }
1950             break;
1951 
1952         case S_UDT_V1:
1953             if (sym->udt_v1.type)
1954             {
1955                 if ((symt = codeview_get_type(sym->udt_v1.type, FALSE)))
1956                     symt_new_typedef(msc_dbg->module, symt,
1957                                      terminate_string(&sym->udt_v1.p_name));
1958                 else
1959                     FIXME("S-Udt %s: couldn't find type 0x%x\n",
1960                           terminate_string(&sym->udt_v1.p_name), sym->udt_v1.type);
1961             }
1962             break;
1963         case S_UDT_V2:
1964             if (sym->udt_v2.type)
1965             {
1966                 if ((symt = codeview_get_type(sym->udt_v2.type, FALSE)))
1967                     symt_new_typedef(msc_dbg->module, symt,
1968                                      terminate_string(&sym->udt_v2.p_name));
1969                 else
1970                     FIXME("S-Udt %s: couldn't find type 0x%x\n",
1971                           terminate_string(&sym->udt_v2.p_name), sym->udt_v2.type);
1972             }
1973             break;
1974         case S_UDT_V3:
1975             if (sym->udt_v3.type)
1976             {
1977                 if ((symt = codeview_get_type(sym->udt_v3.type, FALSE)))
1978                     symt_new_typedef(msc_dbg->module, symt, sym->udt_v3.name);
1979                 else
1980                     FIXME("S-Udt %s: couldn't find type 0x%x\n",
1981                           sym->udt_v3.name, sym->udt_v3.type);
1982             }
1983             break;
1984 
1985          /*
1986          * These are special, in that they are always followed by an
1987          * additional length-prefixed string which is *not* included
1988          * into the symbol length count.  We need to skip it.
1989          */
1990 	case S_PROCREF_V1:
1991 	case S_DATAREF_V1:
1992 	case S_LPROCREF_V1:
1993             {
1994                 const char* name;
1995 
1996                 name = (const char*)sym + length;
1997                 length += (*name + 1 + 3) & ~3;
1998                 break;
1999             }
2000 
2001         case S_MSTOOL_V3: /* just to silence a few warnings */
2002         case S_MSTOOLINFO_V3:
2003         case S_MSTOOLENV_V3:
2004             break;
2005 
2006         case S_SSEARCH_V1:
2007             TRACE("Start search: seg=0x%x at offset 0x%08x\n",
2008                   sym->ssearch_v1.segment, sym->ssearch_v1.offset);
2009             break;
2010 
2011         case S_ALIGN_V1:
2012             TRACE("S-Align V1\n");
2013             break;
2014 
2015         /* the symbols we can safely ignore for now */
2016         case S_TRAMPOLINE:
2017         case S_FRAMEINFO_V2:
2018         case S_SECUCOOKIE_V3:
2019         case S_SECTINFO_V3:
2020         case S_SUBSECTINFO_V3:
2021         case S_ENTRYPOINT_V3:
2022         case S_LOCAL_VS2013:
2023         case S_CALLSITEINFO:
2024         case S_DEFRANGE_REGISTER:
2025         case S_DEFRANGE_FRAMEPOINTER_REL:
2026         case S_DEFRANGE_SUBFIELD_REGISTER:
2027         case S_FPOFF_VS2013:
2028         case S_DEFRANGE_REGISTER_REL:
2029         case S_BUILDINFO:
2030         case S_INLINESITE:
2031         case S_INLINESITE_END:
2032         case S_FILESTATIC:
2033         case S_CALLEES:
2034             TRACE("Unsupported symbol id %x\n", sym->generic.id);
2035             break;
2036 
2037         default:
2038             FIXME("Unsupported symbol id %x\n", sym->generic.id);
2039             dump(sym, 2 + sym->generic.len);
2040             break;
2041         }
2042     }
2043 
2044     if (curr_func) symt_normalize_function(msc_dbg->module, curr_func);
2045 
2046     return TRUE;
2047 }
2048 
2049 static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYTE* root,
2050                                   int offset, int size)
2051 
2052 {
2053     int                                 i, length;
2054     struct symt_compiland*              compiland = NULL;
2055 
2056     /*
2057      * Loop over the different types of records and whenever we
2058      * find something we are interested in, record it and move on.
2059      */
2060     for (i = offset; i < size; i += length)
2061     {
2062         const union codeview_symbol* sym = (const union codeview_symbol*)(root + i);
2063         length = sym->generic.len + 2;
2064         if (i + length > size) break;
2065         if (!sym->generic.id || length < 4) break;
2066         if (length & 3) FIXME("unpadded len %u\n", length);
2067 
2068         switch (sym->generic.id)
2069         {
2070 	case S_PUB_V1: /* FIXME is this really a 'data_v1' structure ?? */
2071             if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
2072             {
2073                 symt_new_public(msc_dbg->module, compiland,
2074                                 terminate_string(&sym->data_v1.p_name),
2075                                 codeview_get_address(msc_dbg, sym->data_v1.segment, sym->data_v1.offset), 1);
2076             }
2077             break;
2078 	case S_PUB_V2: /* FIXME is this really a 'data_v2' structure ?? */
2079             if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
2080             {
2081                 symt_new_public(msc_dbg->module, compiland,
2082                                 terminate_string(&sym->data_v2.p_name),
2083                                 codeview_get_address(msc_dbg, sym->data_v2.segment, sym->data_v2.offset), 1);
2084             }
2085 	    break;
2086 
2087         case S_PUB_V3:
2088             if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
2089             {
2090                 symt_new_public(msc_dbg->module, compiland,
2091                                 sym->data_v3.name,
2092                                 codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset), 1);
2093             }
2094             break;
2095         case S_PUB_FUNC1_V3:
2096         case S_PUB_FUNC2_V3: /* using a data_v3 isn't what we'd expect */
2097 #if 0
2098             /* FIXME: this is plain wrong (from a simple test) */
2099             if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
2100             {
2101                 symt_new_public(msc_dbg->module, compiland,
2102                                 sym->data_v3.name,
2103                                 codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset), 1);
2104             }
2105 #endif
2106             break;
2107         /*
2108          * Global and local data symbols.  We don't associate these
2109          * with any given source file.
2110          */
2111 	case S_GDATA_V1:
2112 	case S_LDATA_V1:
2113             codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->data_v1.p_name),
2114                                   sym->data_v1.segment, sym->data_v1.offset, sym->data_v1.symtype,
2115                                   sym->generic.id == S_LDATA_V1, FALSE, FALSE);
2116 	    break;
2117 	case S_GDATA_V2:
2118 	case S_LDATA_V2:
2119             codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->data_v2.p_name),
2120                                   sym->data_v2.segment, sym->data_v2.offset, sym->data_v2.symtype,
2121                                   sym->generic.id == S_LDATA_V2, FALSE, FALSE);
2122 	    break;
2123 	case S_GDATA_V3:
2124 	case S_LDATA_V3:
2125             codeview_add_variable(msc_dbg, compiland, sym->data_v3.name,
2126                                   sym->data_v3.segment, sym->data_v3.offset, sym->data_v3.symtype,
2127                                   sym->generic.id == S_LDATA_V3, FALSE, FALSE);
2128 	    break;
2129 
2130         /* variables with thread storage */
2131 	case S_GTHREAD_V1:
2132 	case S_LTHREAD_V1:
2133             codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->thread_v1.p_name),
2134                                   sym->thread_v1.segment, sym->thread_v1.offset, sym->thread_v1.symtype,
2135                                   sym->generic.id == S_LTHREAD_V1, TRUE, FALSE);
2136 	    break;
2137 	case S_GTHREAD_V2:
2138 	case S_LTHREAD_V2:
2139             codeview_add_variable(msc_dbg, compiland, terminate_string(&sym->thread_v2.p_name),
2140                                   sym->thread_v2.segment, sym->thread_v2.offset, sym->thread_v2.symtype,
2141                                   sym->generic.id == S_LTHREAD_V2, TRUE, FALSE);
2142 	    break;
2143 	case S_GTHREAD_V3:
2144 	case S_LTHREAD_V3:
2145             codeview_add_variable(msc_dbg, compiland, sym->thread_v3.name,
2146                                   sym->thread_v3.segment, sym->thread_v3.offset, sym->thread_v3.symtype,
2147                                   sym->generic.id == S_LTHREAD_V3, TRUE, FALSE);
2148 	    break;
2149 
2150         /*
2151          * These are special, in that they are always followed by an
2152          * additional length-prefixed string which is *not* included
2153          * into the symbol length count.  We need to skip it.
2154          */
2155 	case S_PROCREF_V1:
2156 	case S_DATAREF_V1:
2157 	case S_LPROCREF_V1:
2158             length += (((const char*)sym)[length] + 1 + 3) & ~3;
2159             break;
2160         }
2161         msc_dbg->module->sortlist_valid = TRUE;
2162     }
2163     msc_dbg->module->sortlist_valid = FALSE;
2164     return TRUE;
2165 }
2166 
2167 /*========================================================================
2168  * Process PDB file.
2169  */
2170 
2171 static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list,
2172                          int size)
2173 {
2174     int                         i, num_blocks;
2175     BYTE*                       buffer;
2176 
2177     if (!size) return NULL;
2178 
2179     num_blocks = (size + pdb->block_size - 1) / pdb->block_size;
2180     buffer = HeapAlloc(GetProcessHeap(), 0, num_blocks * pdb->block_size);
2181 
2182     for (i = 0; i < num_blocks; i++)
2183         memcpy(buffer + i * pdb->block_size,
2184                (const char*)pdb + block_list[i] * pdb->block_size, pdb->block_size);
2185 
2186     return buffer;
2187 }
2188 
2189 static void* pdb_ds_read(const struct PDB_DS_HEADER* pdb, const DWORD* block_list,
2190                          int size)
2191 {
2192     int                         i, num_blocks;
2193     BYTE*                       buffer;
2194 
2195     if (!size) return NULL;
2196 
2197     num_blocks = (size + pdb->block_size - 1) / pdb->block_size;
2198     buffer = HeapAlloc(GetProcessHeap(), 0, num_blocks * pdb->block_size);
2199 
2200     for (i = 0; i < num_blocks; i++)
2201         memcpy(buffer + i * pdb->block_size,
2202                (const char*)pdb + block_list[i] * pdb->block_size, pdb->block_size);
2203 
2204     return buffer;
2205 }
2206 
2207 static void* pdb_read_jg_file(const struct PDB_JG_HEADER* pdb,
2208                               const struct PDB_JG_TOC* toc, DWORD file_nr)
2209 {
2210     const WORD*                 block_list;
2211     DWORD                       i;
2212 
2213     if (!toc || file_nr >= toc->num_files) return NULL;
2214 
2215     block_list = (const WORD*) &toc->file[toc->num_files];
2216     for (i = 0; i < file_nr; i++)
2217         block_list += (toc->file[i].size + pdb->block_size - 1) / pdb->block_size;
2218 
2219     return pdb_jg_read(pdb, block_list, toc->file[file_nr].size);
2220 }
2221 
2222 static void* pdb_read_ds_file(const struct PDB_DS_HEADER* pdb,
2223                               const struct PDB_DS_TOC* toc, DWORD file_nr)
2224 {
2225     const DWORD*                block_list;
2226     DWORD                       i;
2227 
2228     if (!toc || file_nr >= toc->num_files) return NULL;
2229     if (toc->file_size[file_nr] == 0 || toc->file_size[file_nr] == 0xFFFFFFFF) return NULL;
2230 
2231     block_list = &toc->file_size[toc->num_files];
2232     for (i = 0; i < file_nr; i++)
2233         block_list += (toc->file_size[i] + pdb->block_size - 1) / pdb->block_size;
2234 
2235     return pdb_ds_read(pdb, block_list, toc->file_size[file_nr]);
2236 }
2237 
2238 static void* pdb_read_file(const struct pdb_file_info* pdb_file,
2239                            DWORD file_nr)
2240 {
2241     switch (pdb_file->kind)
2242     {
2243     case PDB_JG:
2244         return pdb_read_jg_file((const struct PDB_JG_HEADER*)pdb_file->image,
2245                                 pdb_file->u.jg.toc, file_nr);
2246     case PDB_DS:
2247         return pdb_read_ds_file((const struct PDB_DS_HEADER*)pdb_file->image,
2248                                 pdb_file->u.ds.toc, file_nr);
2249     }
2250     return NULL;
2251 }
2252 
2253 static unsigned pdb_get_file_size(const struct pdb_file_info* pdb_file, DWORD file_nr)
2254 {
2255     switch (pdb_file->kind)
2256     {
2257     case PDB_JG: return pdb_file->u.jg.toc->file[file_nr].size;
2258     case PDB_DS: return pdb_file->u.ds.toc->file_size[file_nr];
2259     }
2260     return 0;
2261 }
2262 
2263 static void pdb_free(void* buffer)
2264 {
2265     HeapFree(GetProcessHeap(), 0, buffer);
2266 }
2267 
2268 static void pdb_free_file(struct pdb_file_info* pdb_file)
2269 {
2270     switch (pdb_file->kind)
2271     {
2272     case PDB_JG:
2273         pdb_free(pdb_file->u.jg.toc);
2274         pdb_file->u.jg.toc = NULL;
2275         break;
2276     case PDB_DS:
2277         pdb_free(pdb_file->u.ds.toc);
2278         pdb_file->u.ds.toc = NULL;
2279         break;
2280     }
2281     HeapFree(GetProcessHeap(), 0, pdb_file->stream_dict);
2282 }
2283 
2284 static void pdb_load_stream_name_table(struct pdb_file_info* pdb_file, const char* str, unsigned cb)
2285 {
2286     DWORD*      pdw;
2287     DWORD*      ok_bits;
2288     DWORD       count, numok;
2289     unsigned    i, j;
2290     char*       cpstr;
2291 
2292     pdw = (DWORD*)(str + cb);
2293     numok = *pdw++;
2294     count = *pdw++;
2295 
2296     pdb_file->stream_dict = HeapAlloc(GetProcessHeap(), 0, (numok + 1) * sizeof(struct pdb_stream_name) + cb);
2297     if (!pdb_file->stream_dict) return;
2298     cpstr = (char*)(pdb_file->stream_dict + numok + 1);
2299     memcpy(cpstr, str, cb);
2300 
2301     /* bitfield: first dword is len (in dword), then data */
2302     ok_bits = pdw;
2303     pdw += *ok_bits++ + 1;
2304     if (*pdw++ != 0)
2305     {
2306         FIXME("unexpected value\n");
2307         return;
2308     }
2309 
2310     for (i = j = 0; i < count; i++)
2311     {
2312         if (ok_bits[i / 32] & (1 << (i % 32)))
2313         {
2314             if (j >= numok) break;
2315             pdb_file->stream_dict[j].name = &cpstr[*pdw++];
2316             pdb_file->stream_dict[j].index = *pdw++;
2317             j++;
2318         }
2319     }
2320     /* add sentinel */
2321     pdb_file->stream_dict[numok].name = NULL;
2322     pdb_file->fpoext_stream = -1;
2323 }
2324 
2325 static unsigned pdb_get_stream_by_name(const struct pdb_file_info* pdb_file, const char* name)
2326 {
2327     struct pdb_stream_name*     psn;
2328 
2329     for (psn = pdb_file->stream_dict; psn && psn->name; psn++)
2330     {
2331         if (!strcmp(psn->name, name)) return psn->index;
2332     }
2333     return -1;
2334 }
2335 
2336 static void* pdb_read_strings(const struct pdb_file_info* pdb_file)
2337 {
2338     unsigned idx;
2339     void *ret;
2340 
2341     idx = pdb_get_stream_by_name(pdb_file, "/names");
2342     if (idx != -1)
2343     {
2344         ret = pdb_read_file( pdb_file, idx );
2345         if (ret && *(const DWORD *)ret == 0xeffeeffe) return ret;
2346         pdb_free( ret );
2347     }
2348     WARN("string table not found\n");
2349     return NULL;
2350 }
2351 
2352 static void pdb_module_remove(struct process* pcsn, struct module_format* modfmt)
2353 {
2354     unsigned    i;
2355 
2356     for (i = 0; i < modfmt->u.pdb_info->used_subfiles; i++)
2357     {
2358         pdb_free_file(&modfmt->u.pdb_info->pdb_files[i]);
2359         if (modfmt->u.pdb_info->pdb_files[i].image)
2360             UnmapViewOfFile(modfmt->u.pdb_info->pdb_files[i].image);
2361         if (modfmt->u.pdb_info->pdb_files[i].hMap)
2362             CloseHandle(modfmt->u.pdb_info->pdb_files[i].hMap);
2363     }
2364     HeapFree(GetProcessHeap(), 0, modfmt);
2365 }
2366 
2367 static void pdb_convert_types_header(PDB_TYPES* types, const BYTE* image)
2368 {
2369     memset(types, 0, sizeof(PDB_TYPES));
2370     if (!image) return;
2371 
2372     if (*(const DWORD*)image < 19960000)   /* FIXME: correct version? */
2373     {
2374         /* Old version of the types record header */
2375         const PDB_TYPES_OLD*    old = (const PDB_TYPES_OLD*)image;
2376         types->version     = old->version;
2377         types->type_offset = sizeof(PDB_TYPES_OLD);
2378         types->type_size   = old->type_size;
2379         types->first_index = old->first_index;
2380         types->last_index  = old->last_index;
2381         types->file        = old->file;
2382     }
2383     else
2384     {
2385         /* New version of the types record header */
2386         *types = *(const PDB_TYPES*)image;
2387     }
2388 }
2389 
2390 static void pdb_convert_symbols_header(PDB_SYMBOLS* symbols,
2391                                        int* header_size, const BYTE* image)
2392 {
2393     memset(symbols, 0, sizeof(PDB_SYMBOLS));
2394     if (!image) return;
2395 
2396     if (*(const DWORD*)image != 0xffffffff)
2397     {
2398         /* Old version of the symbols record header */
2399         const PDB_SYMBOLS_OLD*  old = (const PDB_SYMBOLS_OLD*)image;
2400         symbols->version         = 0;
2401         symbols->module_size     = old->module_size;
2402         symbols->offset_size     = old->offset_size;
2403         symbols->hash_size       = old->hash_size;
2404         symbols->srcmodule_size  = old->srcmodule_size;
2405         symbols->pdbimport_size  = 0;
2406         symbols->hash1_file      = old->hash1_file;
2407         symbols->hash2_file      = old->hash2_file;
2408         symbols->gsym_file       = old->gsym_file;
2409 
2410         *header_size = sizeof(PDB_SYMBOLS_OLD);
2411     }
2412     else
2413     {
2414         /* New version of the symbols record header */
2415         *symbols = *(const PDB_SYMBOLS*)image;
2416         *header_size = sizeof(PDB_SYMBOLS);
2417     }
2418 }
2419 
2420 static void pdb_convert_symbol_file(const PDB_SYMBOLS* symbols,
2421                                     PDB_SYMBOL_FILE_EX* sfile,
2422                                     unsigned* size, const void* image)
2423 
2424 {
2425     if (symbols->version < 19970000)
2426     {
2427         const PDB_SYMBOL_FILE *sym_file = image;
2428         memset(sfile, 0, sizeof(*sfile));
2429         sfile->file        = sym_file->file;
2430         sfile->range.index = sym_file->range.index;
2431         sfile->symbol_size = sym_file->symbol_size;
2432         sfile->lineno_size = sym_file->lineno_size;
2433         *size = sizeof(PDB_SYMBOL_FILE) - 1;
2434     }
2435     else
2436     {
2437         memcpy(sfile, image, sizeof(PDB_SYMBOL_FILE_EX));
2438         *size = sizeof(PDB_SYMBOL_FILE_EX) - 1;
2439     }
2440 }
2441 
2442 static HANDLE map_pdb_file(const struct process* pcs,
2443                            const struct pdb_lookup* lookup,
2444                            struct module* module)
2445 {
2446     HANDLE      hFile, hMap = NULL;
2447     char        dbg_file_path[MAX_PATH];
2448     BOOL        ret = FALSE;
2449 
2450     switch (lookup->kind)
2451     {
2452     case PDB_JG:
2453         ret = path_find_symbol_file(pcs, lookup->filename, NULL, lookup->timestamp,
2454                                     lookup->age, dbg_file_path, &module->module.PdbUnmatched);
2455         break;
2456     case PDB_DS:
2457         ret = path_find_symbol_file(pcs, lookup->filename, &lookup->guid, 0,
2458                                     lookup->age, dbg_file_path, &module->module.PdbUnmatched);
2459         break;
2460     }
2461     if (!ret)
2462     {
2463         WARN("\tCouldn't find %s\n", lookup->filename);
2464         return NULL;
2465     }
2466     if ((hFile = CreateFileA(dbg_file_path, GENERIC_READ, FILE_SHARE_READ, NULL,
2467                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
2468     {
2469         hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
2470         CloseHandle(hFile);
2471     }
2472     return hMap;
2473 }
2474 
2475 static void pdb_process_types(const struct msc_debug_info* msc_dbg,
2476                               const struct pdb_file_info* pdb_file)
2477 {
2478     BYTE*       types_image = NULL;
2479 
2480     types_image = pdb_read_file(pdb_file, 2);
2481     if (types_image)
2482     {
2483         PDB_TYPES               types;
2484         struct codeview_type_parse      ctp;
2485         DWORD                   total;
2486         const BYTE*             ptr;
2487         DWORD*                  offset;
2488 
2489         pdb_convert_types_header(&types, types_image);
2490 
2491         /* Check for unknown versions */
2492         switch (types.version)
2493         {
2494         case 19950410:      /* VC 4.0 */
2495         case 19951122:
2496         case 19961031:      /* VC 5.0 / 6.0 */
2497         case 19990903:      /* VC 7.0 */
2498         case 20040203:      /* VC 8.0 */
2499             break;
2500         default:
2501             ERR("-Unknown type info version %d\n", types.version);
2502         }
2503 
2504         ctp.module = msc_dbg->module;
2505         /* reconstruct the types offset...
2506          * FIXME: maybe it's present in the newest PDB_TYPES structures
2507          */
2508         total = types.last_index - types.first_index + 1;
2509         offset = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * total);
2510         ctp.table = ptr = types_image + types.type_offset;
2511         ctp.num = 0;
2512         while (ptr < ctp.table + types.type_size && ctp.num < total)
2513         {
2514             offset[ctp.num++] = ptr - ctp.table;
2515             ptr += ((const union codeview_type*)ptr)->generic.len + 2;
2516         }
2517         ctp.offset = offset;
2518 
2519         /* Read type table */
2520         codeview_parse_type_table(&ctp);
2521         HeapFree(GetProcessHeap(), 0, offset);
2522         pdb_free(types_image);
2523     }
2524 }
2525 
2526 static const char       PDB_JG_IDENT[] = "Microsoft C/C++ program database 2.00\r\n\032JG\0";
2527 static const char       PDB_DS_IDENT[] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0";
2528 
2529 /******************************************************************
2530  *		pdb_init
2531  *
2532  * Tries to load a pdb file
2533  * 'matched' is filled with the number of correct matches for this file:
2534  *      - age counts for one
2535  *      - timestamp or guid depending on kind counts for one
2536  * a wrong kind of file returns FALSE (FIXME ?)
2537  */
2538 static BOOL pdb_init(const struct pdb_lookup* pdb_lookup, struct pdb_file_info* pdb_file,
2539                      const char* image, unsigned* matched)
2540 {
2541     BOOL        ret = TRUE;
2542 
2543     /* check the file header, and if ok, load the TOC */
2544     TRACE("PDB(%s): %.40s\n", pdb_lookup->filename, debugstr_an(image, 40));
2545 
2546     *matched = 0;
2547     if (!memcmp(image, PDB_JG_IDENT, sizeof(PDB_JG_IDENT)))
2548     {
2549         const struct PDB_JG_HEADER* pdb = (const struct PDB_JG_HEADER*)image;
2550         struct PDB_JG_ROOT*         root;
2551 
2552         pdb_file->u.jg.toc = pdb_jg_read(pdb, pdb->toc_block, pdb->toc.size);
2553         root = pdb_read_jg_file(pdb, pdb_file->u.jg.toc, 1);
2554         if (!root)
2555         {
2556             ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
2557             return FALSE;
2558         }
2559         switch (root->Version)
2560         {
2561         case 19950623:      /* VC 4.0 */
2562         case 19950814:
2563         case 19960307:      /* VC 5.0 */
2564         case 19970604:      /* VC 6.0 */
2565             break;
2566         default:
2567             ERR("-Unknown root block version %d\n", root->Version);
2568         }
2569         if (pdb_lookup->kind != PDB_JG)
2570         {
2571             WARN("Found %s, but wrong PDB kind\n", pdb_lookup->filename);
2572             pdb_free(root);
2573             return FALSE;
2574         }
2575         pdb_file->kind = PDB_JG;
2576         pdb_file->u.jg.timestamp = root->TimeDateStamp;
2577         pdb_file->age = root->Age;
2578         if (root->TimeDateStamp == pdb_lookup->timestamp) (*matched)++;
2579         else WARN("Found %s, but wrong signature: %08x %08x\n",
2580                   pdb_lookup->filename, root->TimeDateStamp, pdb_lookup->timestamp);
2581         if (root->Age == pdb_lookup->age) (*matched)++;
2582         else WARN("Found %s, but wrong age: %08x %08x\n",
2583                   pdb_lookup->filename, root->Age, pdb_lookup->age);
2584         TRACE("found JG for %s: age=%x timestamp=%x\n",
2585               pdb_lookup->filename, root->Age, root->TimeDateStamp);
2586         pdb_load_stream_name_table(pdb_file, &root->names[0], root->cbNames);
2587 
2588         pdb_free(root);
2589     }
2590     else if (!memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
2591     {
2592         const struct PDB_DS_HEADER* pdb = (const struct PDB_DS_HEADER*)image;
2593         struct PDB_DS_ROOT*         root;
2594 
2595         pdb_file->u.ds.toc =
2596             pdb_ds_read(pdb,
2597                         (const DWORD*)((const char*)pdb + pdb->toc_page * pdb->block_size),
2598                         pdb->toc_size);
2599         root = pdb_read_ds_file(pdb, pdb_file->u.ds.toc, 1);
2600         if (!root)
2601         {
2602             ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
2603             return FALSE;
2604         }
2605         switch (root->Version)
2606         {
2607         case 20000404:
2608             break;
2609         default:
2610             ERR("-Unknown root block version %d\n", root->Version);
2611         }
2612         pdb_file->kind = PDB_DS;
2613         pdb_file->u.ds.guid = root->guid;
2614         pdb_file->age = root->Age;
2615         if (!memcmp(&root->guid, &pdb_lookup->guid, sizeof(GUID))) (*matched)++;
2616         else WARN("Found %s, but wrong GUID: %s %s\n",
2617                   pdb_lookup->filename, debugstr_guid(&root->guid),
2618                      debugstr_guid(&pdb_lookup->guid));
2619         if (root->Age == pdb_lookup->age) (*matched)++;
2620         else WARN("Found %s, but wrong age: %08x %08x\n",
2621                   pdb_lookup->filename, root->Age, pdb_lookup->age);
2622         TRACE("found DS for %s: age=%x guid=%s\n",
2623               pdb_lookup->filename, root->Age, debugstr_guid(&root->guid));
2624         pdb_load_stream_name_table(pdb_file, &root->names[0], root->cbNames);
2625 
2626         pdb_free(root);
2627     }
2628 
2629     if (0) /* some tool to dump the internal files from a PDB file */
2630     {
2631         int     i, num_files;
2632 
2633         switch (pdb_file->kind)
2634         {
2635         case PDB_JG: num_files = pdb_file->u.jg.toc->num_files; break;
2636         case PDB_DS: num_files = pdb_file->u.ds.toc->num_files; break;
2637         }
2638 
2639         for (i = 1; i < num_files; i++)
2640         {
2641             unsigned char* x = pdb_read_file(pdb_file, i);
2642             FIXME("********************** [%u]: size=%08x\n",
2643                   i, pdb_get_file_size(pdb_file, i));
2644             dump(x, pdb_get_file_size(pdb_file, i));
2645             pdb_free(x);
2646         }
2647     }
2648     return ret;
2649 }
2650 
2651 static BOOL pdb_process_internal(const struct process* pcs,
2652                                  const struct msc_debug_info* msc_dbg,
2653                                  const struct pdb_lookup* pdb_lookup,
2654                                  struct pdb_module_info* pdb_module_info,
2655                                  unsigned module_index);
2656 
2657 static void pdb_process_symbol_imports(const struct process* pcs,
2658                                        const struct msc_debug_info* msc_dbg,
2659                                        const PDB_SYMBOLS* symbols,
2660                                        const void* symbols_image,
2661                                        const char* image,
2662                                        const struct pdb_lookup* pdb_lookup,
2663                                        struct pdb_module_info* pdb_module_info,
2664                                        unsigned module_index)
2665 {
2666     if (module_index == -1 && symbols && symbols->pdbimport_size)
2667     {
2668         const PDB_SYMBOL_IMPORT*imp;
2669         const void*             first;
2670         const void*             last;
2671         const char*             ptr;
2672         int                     i = 0;
2673         struct pdb_file_info    sf0 = pdb_module_info->pdb_files[0];
2674 
2675         imp = (const PDB_SYMBOL_IMPORT*)((const char*)symbols_image + sizeof(PDB_SYMBOLS) +
2676                                          symbols->module_size + symbols->offset_size +
2677                                          symbols->hash_size + symbols->srcmodule_size);
2678         first = imp;
2679         last = (const char*)imp + symbols->pdbimport_size;
2680         while (imp < (const PDB_SYMBOL_IMPORT*)last)
2681         {
2682             ptr = (const char*)imp + sizeof(*imp) + strlen(imp->filename);
2683             if (i >= CV_MAX_MODULES) FIXME("Out of bounds!!!\n");
2684             if (!strcasecmp(pdb_lookup->filename, imp->filename))
2685             {
2686                 if (module_index != -1) FIXME("Twice the entry\n");
2687                 else module_index = i;
2688                 pdb_module_info->pdb_files[i] = sf0;
2689             }
2690             else
2691             {
2692                 struct pdb_lookup       imp_pdb_lookup;
2693 
2694                 /* FIXME: this is an import of a JG PDB file
2695                  * how's a DS PDB handled ?
2696                  */
2697                 imp_pdb_lookup.filename = imp->filename;
2698                 imp_pdb_lookup.kind = PDB_JG;
2699                 imp_pdb_lookup.timestamp = imp->TimeDateStamp;
2700                 imp_pdb_lookup.age = imp->Age;
2701                 TRACE("got for %s: age=%u ts=%x\n",
2702                       imp->filename, imp->Age, imp->TimeDateStamp);
2703                 pdb_process_internal(pcs, msc_dbg, &imp_pdb_lookup, pdb_module_info, i);
2704             }
2705             i++;
2706             imp = (const PDB_SYMBOL_IMPORT*)((const char*)first + ((ptr - (const char*)first + strlen(ptr) + 1 + 3) & ~3));
2707         }
2708         pdb_module_info->used_subfiles = i;
2709     }
2710     if (module_index == -1)
2711     {
2712         module_index = 0;
2713         pdb_module_info->used_subfiles = 1;
2714     }
2715     cv_current_module = &cv_zmodules[module_index];
2716     if (cv_current_module->allowed) FIXME("Already allowed??\n");
2717     cv_current_module->allowed = TRUE;
2718 }
2719 
2720 static BOOL pdb_process_internal(const struct process* pcs,
2721                                  const struct msc_debug_info* msc_dbg,
2722                                  const struct pdb_lookup* pdb_lookup,
2723                                  struct pdb_module_info* pdb_module_info,
2724                                  unsigned module_index)
2725 {
2726     HANDLE      hMap = NULL;
2727     char*       image = NULL;
2728     BYTE*       symbols_image = NULL;
2729     char*       files_image = NULL;
2730     DWORD       files_size = 0;
2731     unsigned    matched;
2732     struct pdb_file_info* pdb_file;
2733 
2734     TRACE("Processing PDB file %s\n", pdb_lookup->filename);
2735 
2736     pdb_file = &pdb_module_info->pdb_files[module_index == -1 ? 0 : module_index];
2737     /* Open and map() .PDB file */
2738     if ((hMap = map_pdb_file(pcs, pdb_lookup, msc_dbg->module)) == NULL ||
2739         ((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
2740     {
2741         WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
2742         CloseHandle(hMap);
2743         return FALSE;
2744     }
2745     if (!pdb_init(pdb_lookup, pdb_file, image, &matched) || matched != 2)
2746     {
2747         CloseHandle(hMap);
2748         UnmapViewOfFile(image);
2749         return FALSE;
2750     }
2751 
2752     pdb_file->hMap = hMap;
2753     pdb_file->image = image;
2754     symbols_image = pdb_read_file(pdb_file, 3);
2755     if (symbols_image)
2756     {
2757         PDB_SYMBOLS symbols;
2758         BYTE*       globalimage;
2759         BYTE*       modimage;
2760         BYTE*       file;
2761         int         header_size = 0;
2762         PDB_STREAM_INDEXES* psi;
2763 
2764         pdb_convert_symbols_header(&symbols, &header_size, symbols_image);
2765         switch (symbols.version)
2766         {
2767         case 0:            /* VC 4.0 */
2768         case 19960307:     /* VC 5.0 */
2769         case 19970606:     /* VC 6.0 */
2770         case 19990903:
2771             break;
2772         default:
2773             ERR("-Unknown symbol info version %d %08x\n",
2774                 symbols.version, symbols.version);
2775         }
2776 
2777         switch (symbols.stream_index_size)
2778         {
2779         case 0:
2780         case sizeof(PDB_STREAM_INDEXES_OLD):
2781             /* no fpo ext stream in this case */
2782             break;
2783         case sizeof(PDB_STREAM_INDEXES):
2784             psi = (PDB_STREAM_INDEXES*)((const char*)symbols_image + sizeof(PDB_SYMBOLS) +
2785                                         symbols.module_size + symbols.offset_size +
2786                                         symbols.hash_size + symbols.srcmodule_size +
2787                                         symbols.pdbimport_size + symbols.unknown2_size);
2788             pdb_file->fpoext_stream = psi->FPO_EXT;
2789             break;
2790         default:
2791             FIXME("Unknown PDB_STREAM_INDEXES size (%d)\n", symbols.stream_index_size);
2792             break;
2793         }
2794         files_image = pdb_read_strings(pdb_file);
2795         if (files_image) files_size = *(const DWORD*)(files_image + 8);
2796 
2797         pdb_process_symbol_imports(pcs, msc_dbg, &symbols, symbols_image, image,
2798                                    pdb_lookup, pdb_module_info, module_index);
2799         pdb_process_types(msc_dbg, pdb_file);
2800 
2801         /* Read global symbol table */
2802         globalimage = pdb_read_file(pdb_file, symbols.gsym_file);
2803         if (globalimage)
2804         {
2805             codeview_snarf(msc_dbg, globalimage, 0,
2806                            pdb_get_file_size(pdb_file, symbols.gsym_file), FALSE);
2807         }
2808 
2809         /* Read per-module symbols' tables */
2810         file = symbols_image + header_size;
2811         while (file - symbols_image < header_size + symbols.module_size)
2812         {
2813             PDB_SYMBOL_FILE_EX          sfile;
2814             const char*                 file_name;
2815             unsigned                    size;
2816 
2817             HeapValidate(GetProcessHeap(), 0, NULL);
2818             pdb_convert_symbol_file(&symbols, &sfile, &size, file);
2819 
2820             modimage = pdb_read_file(pdb_file, sfile.file);
2821             if (modimage)
2822             {
2823                 if (sfile.symbol_size)
2824                     codeview_snarf(msc_dbg, modimage, sizeof(DWORD),
2825                                    sfile.symbol_size, TRUE);
2826 
2827                 if (sfile.lineno_size)
2828                     codeview_snarf_linetab(msc_dbg,
2829                                            modimage + sfile.symbol_size,
2830                                            sfile.lineno_size,
2831                                            pdb_file->kind == PDB_JG);
2832                 if (files_image)
2833                     codeview_snarf_linetab2(msc_dbg, modimage + sfile.symbol_size + sfile.lineno_size,
2834                                    pdb_get_file_size(pdb_file, sfile.file) - sfile.symbol_size - sfile.lineno_size,
2835                                    files_image + 12, files_size);
2836 
2837                 pdb_free(modimage);
2838             }
2839             file_name = (const char*)file + size;
2840             file_name += strlen(file_name) + 1;
2841             file = (BYTE*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3);
2842         }
2843         /* finish the remaining public and global information */
2844         if (globalimage)
2845         {
2846             codeview_snarf_public(msc_dbg, globalimage, 0,
2847                                   pdb_get_file_size(pdb_file, symbols.gsym_file));
2848             pdb_free(globalimage);
2849         }
2850     }
2851     else
2852         pdb_process_symbol_imports(pcs, msc_dbg, NULL, NULL, image,
2853                                    pdb_lookup, pdb_module_info, module_index);
2854 
2855     pdb_free(symbols_image);
2856     pdb_free(files_image);
2857 
2858     return TRUE;
2859 }
2860 
2861 static BOOL pdb_process_file(const struct process* pcs,
2862                              const struct msc_debug_info* msc_dbg,
2863                              struct pdb_lookup* pdb_lookup)
2864 {
2865     BOOL                        ret;
2866     struct module_format*       modfmt;
2867     struct pdb_module_info*     pdb_module_info;
2868 
2869     modfmt = HeapAlloc(GetProcessHeap(), 0,
2870                        sizeof(struct module_format) + sizeof(struct pdb_module_info));
2871     if (!modfmt) return FALSE;
2872 
2873     pdb_module_info = (void*)(modfmt + 1);
2874     msc_dbg->module->format_info[DFI_PDB] = modfmt;
2875     modfmt->module      = msc_dbg->module;
2876     modfmt->remove      = pdb_module_remove;
2877     modfmt->loc_compute = NULL;
2878     modfmt->u.pdb_info  = pdb_module_info;
2879 
2880     memset(cv_zmodules, 0, sizeof(cv_zmodules));
2881     codeview_init_basic_types(msc_dbg->module);
2882     ret = pdb_process_internal(pcs, msc_dbg, pdb_lookup,
2883                                msc_dbg->module->format_info[DFI_PDB]->u.pdb_info, -1);
2884     codeview_clear_type_table();
2885     if (ret)
2886     {
2887         struct pdb_module_info*     pdb_info = msc_dbg->module->format_info[DFI_PDB]->u.pdb_info;
2888         msc_dbg->module->module.SymType = SymCv;
2889         if (pdb_info->pdb_files[0].kind == PDB_JG)
2890             msc_dbg->module->module.PdbSig = pdb_info->pdb_files[0].u.jg.timestamp;
2891         else
2892             msc_dbg->module->module.PdbSig70 = pdb_info->pdb_files[0].u.ds.guid;
2893         msc_dbg->module->module.PdbAge = pdb_info->pdb_files[0].age;
2894         MultiByteToWideChar(CP_ACP, 0, pdb_lookup->filename, -1,
2895                             msc_dbg->module->module.LoadedPdbName,
2896                             sizeof(msc_dbg->module->module.LoadedPdbName) / sizeof(WCHAR));
2897         /* FIXME: we could have a finer grain here */
2898         msc_dbg->module->module.LineNumbers = TRUE;
2899         msc_dbg->module->module.GlobalSymbols = TRUE;
2900         msc_dbg->module->module.TypeInfo = TRUE;
2901         msc_dbg->module->module.SourceIndexed = TRUE;
2902         msc_dbg->module->module.Publics = TRUE;
2903     }
2904     else
2905     {
2906         msc_dbg->module->format_info[DFI_PDB] = NULL;
2907         HeapFree(GetProcessHeap(), 0, modfmt);
2908     }
2909     return ret;
2910 }
2911 
2912 BOOL pdb_fetch_file_info(const struct pdb_lookup* pdb_lookup, unsigned* matched)
2913 {
2914     HANDLE              hFile, hMap = NULL;
2915     char*               image = NULL;
2916     BOOL                ret;
2917     struct pdb_file_info pdb_file;
2918 
2919     if ((hFile = CreateFileA(pdb_lookup->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
2920                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ||
2921         ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) ||
2922         ((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
2923     {
2924         WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
2925         ret = FALSE;
2926     }
2927     else
2928     {
2929         ret = pdb_init(pdb_lookup, &pdb_file, image, matched);
2930         pdb_free_file(&pdb_file);
2931     }
2932 
2933     if (image) UnmapViewOfFile(image);
2934     if (hMap) CloseHandle(hMap);
2935     if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
2936 
2937     return ret;
2938 }
2939 
2940 /*========================================================================
2941  * FPO unwinding code
2942  */
2943 
2944 /* Stack unwinding is based on postfixed operations.
2945  * Let's define our Postfix EValuator
2946  */
2947 #define PEV_MAX_LEN      32
2948 struct pevaluator
2949 {
2950     struct cpu_stack_walk*  csw;
2951     struct pool             pool;
2952     struct vector           stack;
2953     unsigned                stk_index;
2954     struct hash_table       values;
2955     char                    error[64];
2956 };
2957 
2958 struct zvalue
2959 {
2960     DWORD_PTR                   value;
2961     struct hash_table_elt       elt;
2962 };
2963 
2964 #define PEV_ERROR(pev, msg)       snprintf((pev)->error, sizeof((pev)->error), "%s", (msg))
2965 #define PEV_ERROR1(pev, msg, pmt) snprintf((pev)->error, sizeof((pev)->error), (msg), (pmt))
2966 
2967 #if 0
2968 static void pev_dump_stack(struct pevaluator* pev)
2969 {
2970     unsigned i;
2971     FIXME("stack #%d\n", pev->stk_index);
2972     for (i = 0; i < pev->stk_index; i++)
2973     {
2974         FIXME("\t%d) %s\n", i, *(char**)vector_at(&pev->stack, i));
2975     }
2976 }
2977 #endif
2978 
2979 /* get the value out of an operand (variable or literal) */
2980 static BOOL  pev_get_val(struct pevaluator* pev, const char* str, DWORD_PTR* val)
2981 {
2982     char*                       n;
2983     struct hash_table_iter      hti;
2984     void*                       ptr;
2985 
2986     switch (str[0])
2987     {
2988     case '$':
2989     case '.':
2990         hash_table_iter_init(&pev->values, &hti, str);
2991         while ((ptr = hash_table_iter_up(&hti)))
2992         {
2993             if (!strcmp(CONTAINING_RECORD(ptr, struct zvalue, elt)->elt.name, str))
2994             {
2995                 *val = CONTAINING_RECORD(ptr, struct zvalue, elt)->value;
2996                 return TRUE;
2997             }
2998         }
2999         return PEV_ERROR1(pev, "get_zvalue: no value found (%s)", str);
3000     default:
3001         *val = strtol(str, &n, 10);
3002         if (n == str || *n != '\0')
3003             return PEV_ERROR1(pev, "get_val: not a literal (%s)", str);
3004         return TRUE;
3005     }
3006 }
3007 
3008 /* push an operand onto the stack */
3009 static BOOL  pev_push(struct pevaluator* pev, const char* elt)
3010 {
3011     char**      at;
3012     if (pev->stk_index < vector_length(&pev->stack))
3013         at = vector_at(&pev->stack, pev->stk_index);
3014     else
3015         at = vector_add(&pev->stack, &pev->pool);
3016     if (!at) return PEV_ERROR(pev, "push: out of memory");
3017     *at = pool_strdup(&pev->pool, elt);
3018     pev->stk_index++;
3019     return TRUE;
3020 }
3021 
3022 /* pop an operand from the stack */
3023 static BOOL  pev_pop(struct pevaluator* pev, char* elt)
3024 {
3025     char**      at = vector_at(&pev->stack, --pev->stk_index);
3026     if (!at) return PEV_ERROR(pev, "pop: stack empty");
3027     strcpy(elt, *at);
3028     return TRUE;
3029 }
3030 
3031 /* pop an operand from the stack, and gets its value */
3032 static BOOL  pev_pop_val(struct pevaluator* pev, DWORD_PTR* val)
3033 {
3034     char        p[PEV_MAX_LEN];
3035 
3036     return pev_pop(pev, p) && pev_get_val(pev, p, val);
3037 }
3038 
3039 /* set var 'name' a new value (creates the var if it doesn't exist) */
3040 static BOOL  pev_set_value(struct pevaluator* pev, const char* name, DWORD_PTR val)
3041 {
3042     struct hash_table_iter      hti;
3043     void*                       ptr;
3044 
3045     hash_table_iter_init(&pev->values, &hti, name);
3046     while ((ptr = hash_table_iter_up(&hti)))
3047     {
3048         if (!strcmp(CONTAINING_RECORD(ptr, struct zvalue, elt)->elt.name, name))
3049         {
3050             CONTAINING_RECORD(ptr, struct zvalue, elt)->value = val;
3051             break;
3052         }
3053     }
3054     if (!ptr)
3055     {
3056         struct zvalue* zv = pool_alloc(&pev->pool, sizeof(*zv));
3057         if (!zv) return PEV_ERROR(pev, "set_value: out of memory");
3058         zv->value = val;
3059 
3060         zv->elt.name = pool_strdup(&pev->pool, name);
3061         hash_table_add(&pev->values, &zv->elt);
3062     }
3063     return TRUE;
3064 }
3065 
3066 /* execute a binary operand from the two top most values on the stack.
3067  * puts result on top of the stack */
3068 static BOOL  pev_binop(struct pevaluator* pev, char op)
3069 {
3070     char        res[PEV_MAX_LEN];
3071     DWORD_PTR   v1, v2, c;
3072 
3073     if (!pev_pop_val(pev, &v1) || !pev_pop_val(pev, &v2)) return FALSE;
3074     switch (op)
3075     {
3076     case '+': c = v1 + v2; break;
3077     case '-': c = v1 - v2; break;
3078     case '*': c = v1 * v2; break;
3079     case '/': c = v1 / v2; break;
3080     case '%': c = v1 % v2; break;
3081     default: return PEV_ERROR1(pev, "binop: unknown op (%c)", op);
3082     }
3083     snprintf(res, sizeof(res), "%ld", c);
3084     pev_push(pev, res);
3085     return TRUE;
3086 }
3087 
3088 /* pops top most operand, dereference it, on pushes the result on top of the stack */
3089 static BOOL  pev_deref(struct pevaluator* pev)
3090 {
3091     char        res[PEV_MAX_LEN];
3092     DWORD_PTR   v1, v2;
3093 
3094     if (!pev_pop_val(pev, &v1)) return FALSE;
3095     if (!sw_read_mem(pev->csw, v1, &v2, sizeof(v2)))
3096         return PEV_ERROR1(pev, "deref: cannot read mem at %lx\n", v1);
3097     snprintf(res, sizeof(res), "%ld", v2);
3098     pev_push(pev, res);
3099     return TRUE;
3100 }
3101 
3102 /* assign value to variable (from two top most operands) */
3103 static BOOL  pev_assign(struct pevaluator* pev)
3104 {
3105     char                p2[PEV_MAX_LEN];
3106     DWORD_PTR           v1;
3107 
3108     if (!pev_pop_val(pev, &v1) || !pev_pop(pev, p2)) return FALSE;
3109     if (p2[0] != '$') return PEV_ERROR1(pev, "assign: %s isn't a variable", p2);
3110     pev_set_value(pev, p2, v1);
3111 
3112     return TRUE;
3113 }
3114 
3115 /* initializes the postfix evaluator */
3116 static void  pev_init(struct pevaluator* pev, struct cpu_stack_walk* csw,
3117                       PDB_FPO_DATA* fpoext, struct pdb_cmd_pair* cpair)
3118 {
3119     pev->csw = csw;
3120     pool_init(&pev->pool, 512);
3121     vector_init(&pev->stack, sizeof(char*), 8);
3122     pev->stk_index = 0;
3123     hash_table_init(&pev->pool, &pev->values, 8);
3124     pev->error[0] = '\0';
3125     for (; cpair->name; cpair++)
3126         pev_set_value(pev, cpair->name, *cpair->pvalue);
3127     pev_set_value(pev, ".raSearchStart", fpoext->start);
3128     pev_set_value(pev, ".cbLocals",      fpoext->locals_size);
3129     pev_set_value(pev, ".cbParams",      fpoext->params_size);
3130     pev_set_value(pev, ".cbSavedRegs",   fpoext->savedregs_size);
3131 }
3132 
3133 static BOOL  pev_free(struct pevaluator* pev, struct pdb_cmd_pair* cpair)
3134 {
3135     DWORD_PTR   val;
3136 
3137     if (cpair) for (; cpair->name; cpair++)
3138     {
3139         if (pev_get_val(pev, cpair->name, &val))
3140             *cpair->pvalue = val;
3141     }
3142     pool_destroy(&pev->pool);
3143     return TRUE;
3144 }
3145 
3146 static BOOL  pdb_parse_cmd_string(struct cpu_stack_walk* csw, PDB_FPO_DATA* fpoext,
3147                                   const char* cmd, struct pdb_cmd_pair* cpair)
3148 {
3149     char                token[PEV_MAX_LEN];
3150     char*               ptok = token;
3151     const char*         ptr;
3152     BOOL                over = FALSE;
3153     struct pevaluator   pev;
3154 
3155     pev_init(&pev, csw, fpoext, cpair);
3156     for (ptr = cmd; !over; ptr++)
3157     {
3158         if (*ptr == ' ' || (over = *ptr == '\0'))
3159         {
3160             *ptok = '\0';
3161 
3162             if (!strcmp(token, "+") || !strcmp(token, "-") || !strcmp(token, "*") ||
3163                 !strcmp(token, "/") || !strcmp(token, "%"))
3164             {
3165                 if (!pev_binop(&pev, token[0])) goto done;
3166             }
3167             else if (!strcmp(token, "^"))
3168             {
3169                 if (!pev_deref(&pev)) goto done;
3170             }
3171             else if (!strcmp(token, "="))
3172             {
3173                 if (!pev_assign(&pev)) goto done;
3174             }
3175             else
3176             {
3177                 if (!pev_push(&pev, token)) goto done;
3178             }
3179             ptok = token;
3180         }
3181         else
3182         {
3183             if (ptok - token >= PEV_MAX_LEN - 1)
3184             {
3185                 PEV_ERROR1(&pev, "parse: token too long (%s)", ptr - (ptok - token));
3186                 goto done;
3187             }
3188             *ptok++ = *ptr;
3189         }
3190     }
3191     pev_free(&pev, cpair);
3192     return TRUE;
3193 done:
3194     FIXME("Couldn't evaluate %s => %s\n", wine_dbgstr_a(cmd), pev.error);
3195     pev_free(&pev, NULL);
3196     return FALSE;
3197 }
3198 
3199 BOOL         pdb_virtual_unwind(struct cpu_stack_walk* csw, DWORD_PTR ip,
3200                                 CONTEXT* context, struct pdb_cmd_pair* cpair)
3201 {
3202     struct module_pair          pair;
3203     struct pdb_module_info*     pdb_info;
3204     PDB_FPO_DATA*               fpoext;
3205     unsigned                    i, size, strsize;
3206     char*                       strbase;
3207     BOOL                        ret = TRUE;
3208 
3209     if (!(pair.pcs = process_find_by_handle(csw->hProcess)) ||
3210         !(pair.requested = module_find_by_addr(pair.pcs, ip, DMT_UNKNOWN)) ||
3211         !module_get_debug(&pair))
3212         return FALSE;
3213     if (!pair.effective->format_info[DFI_PDB]) return FALSE;
3214     pdb_info = pair.effective->format_info[DFI_PDB]->u.pdb_info;
3215     TRACE("searching %lx => %lx\n", ip, ip - (DWORD_PTR)pair.effective->module.BaseOfImage);
3216     ip -= (DWORD_PTR)pair.effective->module.BaseOfImage;
3217 
3218     strbase = pdb_read_strings(&pdb_info->pdb_files[0]);
3219     if (!strbase) return FALSE;
3220     strsize = *(const DWORD*)(strbase + 8);
3221     fpoext = pdb_read_file(&pdb_info->pdb_files[0], pdb_info->pdb_files[0].fpoext_stream);
3222     size = pdb_get_file_size(&pdb_info->pdb_files[0], pdb_info->pdb_files[0].fpoext_stream);
3223     if (fpoext && (size % sizeof(*fpoext)) == 0)
3224     {
3225         size /= sizeof(*fpoext);
3226         for (i = 0; i < size; i++)
3227         {
3228             if (fpoext[i].start <= ip && ip < fpoext[i].start + fpoext[i].func_size)
3229             {
3230                 TRACE("\t%08x %08x %8x %8x %4x %4x %4x %08x %s\n",
3231                       fpoext[i].start, fpoext[i].func_size, fpoext[i].locals_size,
3232                       fpoext[i].params_size, fpoext[i].maxstack_size, fpoext[i].prolog_size,
3233                       fpoext[i].savedregs_size, fpoext[i].flags,
3234                       fpoext[i].str_offset < strsize ?
3235                           wine_dbgstr_a(strbase + 12 + fpoext[i].str_offset) : "<out of bounds>");
3236                 if (fpoext[i].str_offset < strsize)
3237                     ret = pdb_parse_cmd_string(csw, &fpoext[i], strbase + 12 + fpoext[i].str_offset, cpair);
3238                 else
3239                     ret = FALSE;
3240                 break;
3241             }
3242         }
3243     }
3244     else ret = FALSE;
3245     pdb_free(fpoext);
3246     pdb_free(strbase);
3247 
3248     return ret;
3249 }
3250 
3251 /*========================================================================
3252  * Process CodeView debug information.
3253  */
3254 
3255 #define MAKESIG(a,b,c,d)        ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
3256 #define CODEVIEW_NB09_SIG       MAKESIG('N','B','0','9')
3257 #define CODEVIEW_NB10_SIG       MAKESIG('N','B','1','0')
3258 #define CODEVIEW_NB11_SIG       MAKESIG('N','B','1','1')
3259 #define CODEVIEW_RSDS_SIG       MAKESIG('R','S','D','S')
3260 
3261 static BOOL codeview_process_info(const struct process* pcs,
3262                                   const struct msc_debug_info* msc_dbg)
3263 {
3264     const DWORD*                signature = (const DWORD*)msc_dbg->root;
3265     BOOL                        ret = FALSE;
3266     struct pdb_lookup           pdb_lookup;
3267 
3268     TRACE("Processing signature %.4s\n", (const char*)signature);
3269 
3270     switch (*signature)
3271     {
3272     case CODEVIEW_NB09_SIG:
3273     case CODEVIEW_NB11_SIG:
3274     {
3275         const OMFSignature*     cv = (const OMFSignature*)msc_dbg->root;
3276         const OMFDirHeader*     hdr = (const OMFDirHeader*)(msc_dbg->root + cv->filepos);
3277         const OMFDirEntry*      ent;
3278         const OMFDirEntry*      prev;
3279         const OMFDirEntry*      next;
3280         unsigned int                    i;
3281 
3282         codeview_init_basic_types(msc_dbg->module);
3283 
3284         for (i = 0; i < hdr->cDir; i++)
3285         {
3286             ent = (const OMFDirEntry*)((const BYTE*)hdr + hdr->cbDirHeader + i * hdr->cbDirEntry);
3287             if (ent->SubSection == sstGlobalTypes)
3288             {
3289                 const OMFGlobalTypes*           types;
3290                 struct codeview_type_parse      ctp;
3291 
3292                 types = (const OMFGlobalTypes*)(msc_dbg->root + ent->lfo);
3293                 ctp.module = msc_dbg->module;
3294                 ctp.offset = (const DWORD*)(types + 1);
3295                 ctp.num    = types->cTypes;
3296                 ctp.table  = (const BYTE*)(ctp.offset + types->cTypes);
3297 
3298                 cv_current_module = &cv_zmodules[0];
3299                 if (cv_current_module->allowed) FIXME("Already allowed??\n");
3300                 cv_current_module->allowed = TRUE;
3301 
3302                 codeview_parse_type_table(&ctp);
3303                 break;
3304             }
3305         }
3306 
3307         ent = (const OMFDirEntry*)((const BYTE*)hdr + hdr->cbDirHeader);
3308         for (i = 0; i < hdr->cDir; i++, ent = next)
3309         {
3310             next = (i == hdr->cDir-1) ? NULL :
3311                    (const OMFDirEntry*)((const BYTE*)ent + hdr->cbDirEntry);
3312             prev = (i == 0) ? NULL :
3313                    (const OMFDirEntry*)((const BYTE*)ent - hdr->cbDirEntry);
3314 
3315             if (ent->SubSection == sstAlignSym)
3316             {
3317                 codeview_snarf(msc_dbg, msc_dbg->root + ent->lfo, sizeof(DWORD),
3318                                ent->cb, TRUE);
3319 
3320                 /*
3321                  * Check the next and previous entry.  If either is a
3322                  * sstSrcModule, it contains the line number info for
3323                  * this file.
3324                  *
3325                  * FIXME: This is not a general solution!
3326                  */
3327                 if (next && next->iMod == ent->iMod && next->SubSection == sstSrcModule)
3328                     codeview_snarf_linetab(msc_dbg, msc_dbg->root + next->lfo,
3329                                            next->cb, TRUE);
3330 
3331                 if (prev && prev->iMod == ent->iMod && prev->SubSection == sstSrcModule)
3332                     codeview_snarf_linetab(msc_dbg, msc_dbg->root + prev->lfo,
3333                                            prev->cb, TRUE);
3334 
3335             }
3336         }
3337 
3338         msc_dbg->module->module.SymType = SymCv;
3339         /* FIXME: we could have a finer grain here */
3340         msc_dbg->module->module.LineNumbers = TRUE;
3341         msc_dbg->module->module.GlobalSymbols = TRUE;
3342         msc_dbg->module->module.TypeInfo = TRUE;
3343         msc_dbg->module->module.SourceIndexed = TRUE;
3344         msc_dbg->module->module.Publics = TRUE;
3345         codeview_clear_type_table();
3346         ret = TRUE;
3347         break;
3348     }
3349 
3350     case CODEVIEW_NB10_SIG:
3351     {
3352         const CODEVIEW_PDB_DATA* pdb = (const CODEVIEW_PDB_DATA*)msc_dbg->root;
3353         pdb_lookup.filename = pdb->name;
3354         pdb_lookup.kind = PDB_JG;
3355         pdb_lookup.timestamp = pdb->timestamp;
3356         pdb_lookup.age = pdb->age;
3357         ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
3358         break;
3359     }
3360     case CODEVIEW_RSDS_SIG:
3361     {
3362         const OMFSignatureRSDS* rsds = (const OMFSignatureRSDS*)msc_dbg->root;
3363 
3364         TRACE("Got RSDS type of PDB file: guid=%s age=%08x name=%s\n",
3365               wine_dbgstr_guid(&rsds->guid), rsds->age, rsds->name);
3366         pdb_lookup.filename = rsds->name;
3367         pdb_lookup.kind = PDB_DS;
3368         pdb_lookup.guid = rsds->guid;
3369         pdb_lookup.age = rsds->age;
3370         ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
3371         break;
3372     }
3373     default:
3374         ERR("Unknown CODEVIEW signature %08x in module %s\n",
3375             *signature, debugstr_w(msc_dbg->module->module.ModuleName));
3376         break;
3377     }
3378     if (ret)
3379     {
3380         msc_dbg->module->module.CVSig = *signature;
3381         memcpy(msc_dbg->module->module.CVData, msc_dbg->root,
3382                sizeof(msc_dbg->module->module.CVData));
3383     }
3384     return ret;
3385 }
3386 
3387 /*========================================================================
3388  * Process debug directory.
3389  */
3390 BOOL pe_load_debug_directory(const struct process* pcs, struct module* module,
3391                              const BYTE* mapping,
3392                              const IMAGE_SECTION_HEADER* sectp, DWORD nsect,
3393                              const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg)
3394 {
3395     BOOL                        ret;
3396     int                         i;
3397     struct msc_debug_info       msc_dbg;
3398 
3399     msc_dbg.module = module;
3400     msc_dbg.nsect  = nsect;
3401     msc_dbg.sectp  = sectp;
3402     msc_dbg.nomap  = 0;
3403     msc_dbg.omapp  = NULL;
3404 
3405     __TRY
3406     {
3407         ret = FALSE;
3408 
3409         /* First, watch out for OMAP data */
3410         for (i = 0; i < nDbg; i++)
3411         {
3412             if (dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC)
3413             {
3414                 msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
3415                 msc_dbg.omapp = (const OMAP_DATA*)(mapping + dbg[i].PointerToRawData);
3416                 break;
3417             }
3418         }
3419 
3420         /* Now, try to parse CodeView debug info */
3421         for (i = 0; i < nDbg; i++)
3422         {
3423             if (dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW)
3424             {
3425                 msc_dbg.root = mapping + dbg[i].PointerToRawData;
3426                 if ((ret = codeview_process_info(pcs, &msc_dbg))) goto done;
3427             }
3428         }
3429 
3430         /* If not found, try to parse COFF debug info */
3431         for (i = 0; i < nDbg; i++)
3432         {
3433             if (dbg[i].Type == IMAGE_DEBUG_TYPE_COFF)
3434             {
3435                 msc_dbg.root = mapping + dbg[i].PointerToRawData;
3436                 if ((ret = coff_process_info(&msc_dbg))) goto done;
3437             }
3438         }
3439     done:
3440 	 /* FIXME: this should be supported... this is the debug information for
3441 	  * functions compiled without a frame pointer (FPO = frame pointer omission)
3442 	  * the associated data helps finding out the relevant information
3443 	  */
3444         for (i = 0; i < nDbg; i++)
3445             if (dbg[i].Type == IMAGE_DEBUG_TYPE_FPO)
3446                 FIXME("This guy has FPO information\n");
3447 #if 0
3448 
3449 #define FRAME_FPO   0
3450 #define FRAME_TRAP  1
3451 #define FRAME_TSS   2
3452 
3453 typedef struct _FPO_DATA
3454 {
3455 	DWORD       ulOffStart;            /* offset 1st byte of function code */
3456 	DWORD       cbProcSize;            /* # bytes in function */
3457 	DWORD       cdwLocals;             /* # bytes in locals/4 */
3458 	WORD        cdwParams;             /* # bytes in params/4 */
3459 
3460 	WORD        cbProlog : 8;          /* # bytes in prolog */
3461 	WORD        cbRegs   : 3;          /* # regs saved */
3462 	WORD        fHasSEH  : 1;          /* TRUE if SEH in func */
3463 	WORD        fUseBP   : 1;          /* TRUE if EBP has been allocated */
3464 	WORD        reserved : 1;          /* reserved for future use */
3465 	WORD        cbFrame  : 2;          /* frame type */
3466 } FPO_DATA;
3467 #endif
3468 
3469     }
3470     __EXCEPT_PAGE_FAULT
3471     {
3472         ERR("Got a page fault while loading symbols\n");
3473         ret = FALSE;
3474     }
3475     __ENDTRY
3476     return ret;
3477 }
3478