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