dinput: COM cleanup - use helper function instead of direct typecast in base joystick...
[wine.git] / dlls / dbghelp / msc.c
blob90e832cfe6436b0b4cb1694e9882a3abbbc19c3b
1 /*
2 * File msc.c - read VC++ debug information from COFF and eventually
3 * from PDB files.
5 * Copyright (C) 1996, Eric Youngdale.
6 * Copyright (C) 1999-2000, Ulrich Weigand.
7 * Copyright (C) 2004-2009, Eric Pouech.
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.
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.
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
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.
30 * TODO:
31 * Get 16 bit CV stuff working.
32 * Add symbol size to internal symbol table.
35 #define NONAMELESSUNION
37 #include "config.h"
38 #include "wine/port.h"
40 #include <assert.h>
41 #include <stdio.h>
42 #include <stdlib.h>
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"
56 #include "wine/exception.h"
57 #include "wine/debug.h"
58 #include "dbghelp_private.h"
59 #include "wine/mscvpdb.h"
61 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
63 #define MAX_PATHNAME_LEN 1024
65 /*========================================================================
66 * Debug file access helper routines
69 static void dump(const void* ptr, unsigned len)
71 unsigned int i, j;
72 char msg[128];
73 const char* hexof = "0123456789abcdef";
74 const BYTE* x = ptr;
76 for (i = 0; i < len; i += 16)
78 sprintf(msg, "%08x: ", i);
79 memset(msg + 10, ' ', 3 * 16 + 1 + 16);
80 for (j = 0; j < min(16, len - i); j++)
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] : '.';
88 msg[10 + 3 * 16] = ' ';
89 msg[10 + 3 * 16 + 1 + 16] = '\0';
90 FIXME("%s\n", msg);
94 /*========================================================================
95 * Process CodeView type information.
98 #define MAX_BUILTIN_TYPES 0x06FF
99 #define FIRST_DEFINABLE_TYPE 0x1000
101 static struct symt* cv_basic_types[MAX_BUILTIN_TYPES];
103 struct cv_defined_module
105 BOOL allowed;
106 unsigned int num_defined_types;
107 struct symt** defined_types;
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;
114 static void codeview_init_basic_types(struct module* module)
116 struct symt_udt* udt;
118 * These are the common builtin types that are used by VC++.
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;
148 if (sizeof(void*) == 4)
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;
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;
182 else
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;
212 static int leaf_as_variant(VARIANT* v, const unsigned short int* leaf)
214 unsigned short int type = *leaf++;
215 int length = 2;
217 if (type < LF_NUMERIC)
219 v->n1.n2.vt = VT_UINT;
220 v->n1.n2.n3.uintVal = type;
222 else
224 switch (type)
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;
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;
238 case LF_USHORT:
239 length += 2;
240 v->n1.n2.vt = VT_UI2;
241 v->n1.n2.n3.uiVal = *leaf;
242 break;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
328 default:
329 FIXME("Unknown numeric leaf type %04x\n", type);
330 v->n1.n2.vt = VT_EMPTY; /* FIXME */
331 break;
335 return length;
338 static int numeric_leaf(int* value, const unsigned short int* leaf)
340 unsigned short int type = *leaf++;
341 int length = 2;
343 if (type < LF_NUMERIC)
345 *value = type;
347 else
349 switch (type)
351 case LF_CHAR:
352 length += 1;
353 *value = *(const char*)leaf;
354 break;
356 case LF_SHORT:
357 length += 2;
358 *value = *(const short*)leaf;
359 break;
361 case LF_USHORT:
362 length += 2;
363 *value = *leaf;
364 break;
366 case LF_LONG:
367 length += 4;
368 *value = *(const int*)leaf;
369 break;
371 case LF_ULONG:
372 length += 4;
373 *value = *(const unsigned int*)leaf;
374 break;
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;
383 case LF_REAL32:
384 FIXME("Unsupported numeric leaf type %04x\n", type);
385 length += 4;
386 *value = 0; /* FIXME */
387 break;
389 case LF_REAL48:
390 FIXME("Unsupported numeric leaf type %04x\n", type);
391 length += 6;
392 *value = 0; /* FIXME */
393 break;
395 case LF_REAL64:
396 FIXME("Unsupported numeric leaf type %04x\n", type);
397 length += 8;
398 *value = 0; /* FIXME */
399 break;
401 case LF_REAL80:
402 FIXME("Unsupported numeric leaf type %04x\n", type);
403 length += 10;
404 *value = 0; /* FIXME */
405 break;
407 case LF_REAL128:
408 FIXME("Unsupported numeric leaf type %04x\n", type);
409 length += 16;
410 *value = 0; /* FIXME */
411 break;
413 case LF_COMPLEX32:
414 FIXME("Unsupported numeric leaf type %04x\n", type);
415 length += 4;
416 *value = 0; /* FIXME */
417 break;
419 case LF_COMPLEX64:
420 FIXME("Unsupported numeric leaf type %04x\n", type);
421 length += 8;
422 *value = 0; /* FIXME */
423 break;
425 case LF_COMPLEX80:
426 FIXME("Unsupported numeric leaf type %04x\n", type);
427 length += 10;
428 *value = 0; /* FIXME */
429 break;
431 case LF_COMPLEX128:
432 FIXME("Unsupported numeric leaf type %04x\n", type);
433 length += 16;
434 *value = 0; /* FIXME */
435 break;
437 case LF_VARSTRING:
438 FIXME("Unsupported numeric leaf type %04x\n", type);
439 length += 2 + *leaf;
440 *value = 0; /* FIXME */
441 break;
443 default:
444 FIXME("Unknown numeric leaf type %04x\n", type);
445 *value = 0;
446 break;
450 return length;
453 /* convert a pascal string (as stored in debug information) into
454 * a C string (null terminated).
456 static const char* terminate_string(const struct p_string* p_name)
458 static char symname[256];
460 memcpy(symname, p_name->name, p_name->namelen);
461 symname[p_name->namelen] = '\0';
463 return (!*symname || strcmp(symname, "__unnamed") == 0) ? NULL : symname;
466 static struct symt* codeview_get_type(unsigned int typeno, BOOL quiet)
468 struct symt* symt = NULL;
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).
475 if (typeno < FIRST_DEFINABLE_TYPE)
477 if (typeno < MAX_BUILTIN_TYPES)
478 symt = cv_basic_types[typeno];
480 else
482 unsigned mod_index = typeno >> 24;
483 unsigned mod_typeno = typeno & 0x00FFFFFF;
484 struct cv_defined_module* mod;
486 mod = (mod_index == 0) ? cv_current_module : &cv_zmodules[mod_index];
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
492 if (mod_typeno - FIRST_DEFINABLE_TYPE < mod->num_defined_types)
493 symt = mod->defined_types[mod_typeno - FIRST_DEFINABLE_TYPE];
496 if (!quiet && !symt && typeno) FIXME("Returning NULL symt for type-id %x\n", typeno);
497 return symt;
500 struct codeview_type_parse
502 struct module* module;
503 const BYTE* table;
504 const DWORD* offset;
505 DWORD num;
508 static inline const void* codeview_jump_to_type(const struct codeview_type_parse* ctp, DWORD idx)
510 if (idx < FIRST_DEFINABLE_TYPE) return NULL;
511 idx -= FIRST_DEFINABLE_TYPE;
512 return (idx >= ctp->num) ? NULL : (ctp->table + ctp->offset[idx]);
515 static int codeview_add_type(unsigned int typeno, struct symt* dt)
517 if (typeno < FIRST_DEFINABLE_TYPE)
518 FIXME("What the heck\n");
519 if (!cv_current_module)
521 FIXME("Adding %x to non allowed module\n", typeno);
522 return FALSE;
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)
529 if (cv_current_module->defined_types)
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*));
537 else
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*));
544 if (cv_current_module->defined_types == NULL) return FALSE;
546 if (cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE])
548 if (cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE] != dt)
549 FIXME("Overwriting at %x\n", typeno);
551 cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE] = dt;
552 return TRUE;
555 static void codeview_clear_type_table(void)
557 int i;
559 for (i = 0; i < CV_MAX_MODULES; i++)
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;
567 cv_current_module = NULL;
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);
574 static void* codeview_cast_symt(struct symt* symt, enum SymTagEnum tag)
576 if (symt->tag != tag)
578 FIXME("Bad tag. Expected %d, but got %d\n", tag, symt->tag);
579 return NULL;
581 return symt;
584 static struct symt* codeview_fetch_type(struct codeview_type_parse* ctp,
585 unsigned typeno, BOOL details)
587 struct symt* symt;
588 const union codeview_type* p;
590 if (!typeno) return NULL;
591 if ((symt = codeview_get_type(typeno, TRUE))) return symt;
593 /* forward declaration */
594 if (!(p = codeview_jump_to_type(ctp, typeno)))
596 FIXME("Cannot locate type %x\n", typeno);
597 return NULL;
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;
604 static struct symt* codeview_add_type_pointer(struct codeview_type_parse* ctp,
605 struct symt* existing,
606 unsigned int pointee_type)
608 struct symt* pointee;
610 if (existing)
612 existing = codeview_cast_symt(existing, SymTagPointerType);
613 return existing;
615 pointee = codeview_fetch_type(ctp, pointee_type, FALSE);
616 return &symt_new_pointer(ctp->module, pointee)->symt;
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)
625 struct symt* elem = codeview_fetch_type(ctp, elemtype, FALSE);
626 struct symt* index = codeview_fetch_type(ctp, indextype, FALSE);
628 return &symt_new_array(ctp->module, 0, -arr_len, elem, index)->symt;
631 static int codeview_add_type_enum_field_list(struct module* module,
632 struct symt_enum* symt,
633 const union codeview_reftype* ref_type)
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;
639 while (ptr < last)
641 if (*ptr >= 0xf0) /* LF_PAD... */
643 ptr += *ptr & 0x0f;
644 continue;
647 type = (const union codeview_fieldtype*)ptr;
649 switch (type->generic.id)
651 case LF_ENUMERATE_V1:
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);
656 symt_add_enum_element(module, symt, terminate_string(p_name), value);
657 ptr += 2 + 2 + vlen + (1 + p_name->namelen);
658 break;
660 case LF_ENUMERATE_V3:
662 int value, vlen = numeric_leaf(&value, &type->enumerate_v3.value);
663 const char* name = (const char*)&type->enumerate_v3.value + vlen;
665 symt_add_enum_element(module, symt, name, value);
666 ptr += 2 + 2 + vlen + (1 + strlen(name));
667 break;
670 default:
671 FIXME("Unsupported type %04x in ENUM field list\n", type->generic.id);
672 return FALSE;
675 return TRUE;
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)
682 struct symt* subtype;
683 const union codeview_reftype*cv_type;
685 if ((cv_type = codeview_jump_to_type(ctp, type)))
687 switch (cv_type->generic.id)
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;
703 subtype = codeview_fetch_type(ctp, type, FALSE);
705 if (subtype)
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);
714 static int codeview_add_type_struct_field_list(struct codeview_type_parse* ctp,
715 struct symt_udt* symt,
716 unsigned fieldlistno)
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;
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;
731 while (ptr < last)
733 if (*ptr >= 0xf0) /* LF_PAD... */
735 ptr += *ptr & 0x0f;
736 continue;
739 type = (const union codeview_fieldtype*)ptr;
741 switch (type->generic.id)
743 case LF_BCLASS_V1:
744 leaf_len = numeric_leaf(&value, &type->bclass_v1.offset);
746 /* FIXME: ignored for now */
748 ptr += 2 + 2 + 2 + leaf_len;
749 break;
751 case LF_BCLASS_V2:
752 leaf_len = numeric_leaf(&value, &type->bclass_v2.offset);
754 /* FIXME: ignored for now */
756 ptr += 2 + 2 + 4 + leaf_len;
757 break;
759 case LF_VBCLASS_V1:
760 case LF_IVBCLASS_V1:
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);
768 /* FIXME: ignored for now */
770 ptr += 2 + 2 + 2 + 2 + leaf_len + vplen;
772 break;
774 case LF_VBCLASS_V2:
775 case LF_IVBCLASS_V2:
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);
783 /* FIXME: ignored for now */
785 ptr += 2 + 2 + 4 + 4 + leaf_len + vplen;
787 break;
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);
793 codeview_add_udt_element(ctp, symt, terminate_string(p_name), value,
794 type->member_v1.type);
796 ptr += 2 + 2 + 2 + leaf_len + (1 + p_name->namelen);
797 break;
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);
803 codeview_add_udt_element(ctp, symt, terminate_string(p_name), value,
804 type->member_v2.type);
806 ptr += 2 + 2 + 4 + leaf_len + (1 + p_name->namelen);
807 break;
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;
813 codeview_add_udt_element(ctp, symt, c_name, value, type->member_v3.type);
815 ptr += 2 + 2 + 4 + leaf_len + (strlen(c_name) + 1);
816 break;
818 case LF_STMEMBER_V1:
819 /* FIXME: ignored for now */
820 ptr += 2 + 2 + 2 + (1 + type->stmember_v1.p_name.namelen);
821 break;
823 case LF_STMEMBER_V2:
824 /* FIXME: ignored for now */
825 ptr += 2 + 4 + 2 + (1 + type->stmember_v2.p_name.namelen);
826 break;
828 case LF_STMEMBER_V3:
829 /* FIXME: ignored for now */
830 ptr += 2 + 4 + 2 + (strlen(type->stmember_v3.name) + 1);
831 break;
833 case LF_METHOD_V1:
834 /* FIXME: ignored for now */
835 ptr += 2 + 2 + 2 + (1 + type->method_v1.p_name.namelen);
836 break;
838 case LF_METHOD_V2:
839 /* FIXME: ignored for now */
840 ptr += 2 + 2 + 4 + (1 + type->method_v2.p_name.namelen);
841 break;
843 case LF_METHOD_V3:
844 /* FIXME: ignored for now */
845 ptr += 2 + 2 + 4 + (strlen(type->method_v3.name) + 1);
846 break;
848 case LF_NESTTYPE_V1:
849 /* FIXME: ignored for now */
850 ptr += 2 + 2 + (1 + type->nesttype_v1.p_name.namelen);
851 break;
853 case LF_NESTTYPE_V2:
854 /* FIXME: ignored for now */
855 ptr += 2 + 2 + 4 + (1 + type->nesttype_v2.p_name.namelen);
856 break;
858 case LF_NESTTYPE_V3:
859 /* FIXME: ignored for now */
860 ptr += 2 + 2 + 4 + (strlen(type->nesttype_v3.name) + 1);
861 break;
863 case LF_VFUNCTAB_V1:
864 /* FIXME: ignored for now */
865 ptr += 2 + 2;
866 break;
868 case LF_VFUNCTAB_V2:
869 /* FIXME: ignored for now */
870 ptr += 2 + 2 + 4;
871 break;
873 case LF_ONEMETHOD_V1:
874 /* FIXME: ignored for now */
875 switch ((type->onemethod_v1.attribute >> 2) & 7)
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;
881 default:
882 ptr += 2 + 2 + 2 + (1 + type->onemethod_v1.p_name.namelen);
883 break;
885 break;
887 case LF_ONEMETHOD_V2:
888 /* FIXME: ignored for now */
889 switch ((type->onemethod_v2.attribute >> 2) & 7)
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;
895 default:
896 ptr += 2 + 2 + 4 + (1 + type->onemethod_v2.p_name.namelen);
897 break;
899 break;
901 case LF_ONEMETHOD_V3:
902 /* FIXME: ignored for now */
903 switch ((type->onemethod_v3.attribute >> 2) & 7)
905 case 4: case 6: /* (pure) introducing virtual method */
906 ptr += 2 + 2 + 4 + 4 + (strlen(type->onemethod_virt_v3.name) + 1);
907 break;
909 default:
910 ptr += 2 + 2 + 4 + (strlen(type->onemethod_v3.name) + 1);
911 break;
913 break;
915 default:
916 FIXME("Unsupported type %04x in STRUCT field list\n", type->generic.id);
917 return FALSE;
921 return TRUE;
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)
930 struct symt_enum* symt;
932 if (existing)
934 if (!(symt = codeview_cast_symt(existing, SymTagEnum))) return NULL;
935 /* should also check that all fields are the same */
937 else
939 symt = symt_new_enum(ctp->module, name,
940 codeview_fetch_type(ctp, basetype, FALSE));
941 if (fieldlistno)
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);
948 return &symt->symt;
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)
956 struct symt_udt* symt;
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 ?
961 if (!existing)
963 void* ptr;
964 struct symt_ht* type;
965 struct hash_table_iter hti;
967 hash_table_iter_init(&ctp->module->ht_types, &hti, name);
968 while ((ptr = hash_table_iter_up(&hti)))
970 type = GET_ENTRY(ptr, struct symt_ht, hash_elt);
972 if (type->symt.tag == SymTagUDT &&
973 type->hash_elt.name && !strcmp(type->hash_elt.name, name))
975 existing = &type->symt;
976 break;
980 if (existing)
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 */
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;
992 if (!existing) symt = symt_new_udt(ctp->module, name, structlen, kind);
994 return &symt->symt;
997 static struct symt* codeview_new_func_signature(struct codeview_type_parse* ctp,
998 struct symt* existing,
999 enum CV_call_e call_conv)
1001 struct symt_function_signature* sym;
1003 if (existing)
1005 sym = codeview_cast_symt(existing, SymTagFunctionType);
1006 if (!sym) return NULL;
1008 else
1010 sym = symt_new_function_signature(ctp->module, NULL, call_conv);
1012 return &sym->symt;
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)
1020 const union codeview_reftype* reftype;
1022 sym->rettype = codeview_fetch_type(ctp, ret_type, FALSE);
1023 if (args_list && (reftype = codeview_jump_to_type(ctp, args_list)))
1025 unsigned int i;
1026 switch (reftype->generic.id)
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);
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)
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;
1054 existing = codeview_get_type(curr_type, TRUE);
1056 switch (type->generic.id)
1058 case LF_MODIFIER_V1:
1059 /* FIXME: we don't handle modifiers,
1060 * but read previous type on the curr_type
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;
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;
1088 case LF_ARRAY_V1:
1089 if (existing) symt = codeview_cast_symt(existing, SymTagArrayType);
1090 else
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);
1098 break;
1099 case LF_ARRAY_V2:
1100 if (existing) symt = codeview_cast_symt(existing, SymTagArrayType);
1101 else
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);
1106 symt = codeview_add_type_array(ctp, terminate_string(p_name),
1107 type->array_v2.elemtype,
1108 type->array_v2.idxtype, value);
1110 break;
1111 case LF_ARRAY_V3:
1112 if (existing) symt = codeview_cast_symt(existing, SymTagArrayType);
1113 else
1115 leaf_len = numeric_leaf(&value, &type->array_v3.arrlen);
1116 c_name = (const char*)&type->array_v3.arrlen + leaf_len;
1118 symt = codeview_add_type_array(ctp, c_name,
1119 type->array_v3.elemtype,
1120 type->array_v3.idxtype, value);
1122 break;
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)
1133 codeview_add_type(curr_type, symt);
1134 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1135 type->struct_v1.fieldlist);
1137 break;
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)
1148 codeview_add_type(curr_type, symt);
1149 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1150 type->struct_v2.fieldlist);
1152 break;
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)
1163 codeview_add_type(curr_type, symt);
1164 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1165 type->struct_v3.fieldlist);
1167 break;
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)
1176 codeview_add_type(curr_type, symt);
1177 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1178 type->union_v1.fieldlist);
1180 break;
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)
1189 codeview_add_type(curr_type, symt);
1190 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1191 type->union_v2.fieldlist);
1193 break;
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)
1202 codeview_add_type(curr_type, symt);
1203 codeview_add_type_struct_field_list(ctp, (struct symt_udt*)symt,
1204 type->union_v3.fieldlist);
1206 break;
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;
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;
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;
1228 case LF_PROCEDURE_V1:
1229 symt = codeview_new_func_signature(ctp, existing, type->procedure_v1.call);
1230 if (details)
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);
1238 break;
1239 case LF_PROCEDURE_V2:
1240 symt = codeview_new_func_signature(ctp, existing,type->procedure_v2.call);
1241 if (details)
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);
1249 break;
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
1255 symt = codeview_new_func_signature(ctp, existing, type->mfunction_v1.call);
1256 if (details)
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);
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
1269 symt = codeview_new_func_signature(ctp, existing, type->mfunction_v2.call);
1270 if (details)
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);
1278 break;
1280 case LF_VTSHAPE_V1:
1281 /* this is an ugly hack... FIXME when we have C++ support */
1282 if (!(symt = existing))
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;
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;
1294 return codeview_add_type(curr_type, symt) ? symt : NULL;
1297 static int codeview_parse_type_table(struct codeview_type_parse* ctp)
1299 unsigned int curr_type = FIRST_DEFINABLE_TYPE;
1300 const union codeview_type* type;
1302 for (curr_type = FIRST_DEFINABLE_TYPE; curr_type < FIRST_DEFINABLE_TYPE + ctp->num; curr_type++)
1304 type = codeview_jump_to_type(ctp, curr_type);
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
1317 if (!(type->generic.id & 0x8600) || (type->generic.id & 0x0100))
1318 codeview_parse_one_type(ctp, curr_type, type, TRUE);
1321 return TRUE;
1324 /*========================================================================
1325 * Process CodeView line number information.
1327 static unsigned long codeview_get_address(const struct msc_debug_info* msc_dbg,
1328 unsigned seg, unsigned offset);
1330 static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const BYTE* linetab,
1331 int size, BOOL pascal_str)
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;
1345 nfile = *(const short*)linetab;
1346 filetab = (const unsigned int*)(linetab + 2 * sizeof(short));
1348 for (i = 0; i < nfile; i++)
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);
1356 * Now snarf the filename for all of the segments for this file.
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));
1363 for (j = 0; j < nseg; j++)
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++)
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
1376 if (!func || addr >= func->address + func->size)
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)
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;
1388 symt_add_func_line(msc_dbg->module, func, source,
1389 linenos[k], addr - func->address);
1395 static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const BYTE* linetab, DWORD size,
1396 const char* strimage, DWORD strsize)
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;
1407 /* locate LT2_FILES_BLOCK (if any) */
1408 lt2 = (const struct codeview_linetab2*)linetab;
1409 while ((const BYTE*)(lt2 + 1) < linetab + size)
1411 if (lt2->header == LT2_FILES_BLOCK)
1413 lt2_files = lt2;
1414 break;
1416 lt2 = codeview_linetab2_next_block(lt2);
1418 if (!lt2_files)
1420 TRACE("No LT2_FILES_BLOCK found\n");
1421 return;
1424 lt2 = (const struct codeview_linetab2*)linetab;
1425 while ((const BYTE*)(lt2 + 1) < linetab + size)
1427 /* FIXME: should also check that whole lines_blk fits in linetab + size */
1428 switch (lt2->header)
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)
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;
1447 for (i = 0; i < lines_blk->nlines; i++)
1449 symt_add_func_line(msc_dbg->module, func, source,
1450 lines_blk->l[i].lineno ^ 0x80000000,
1451 lines_blk->l[i].offset);
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;
1461 lt2 = codeview_linetab2_next_block(lt2);
1465 /*========================================================================
1466 * Process CodeView symbol information.
1469 static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
1470 unsigned int offset)
1472 int nomap = msc_dbg->nomap;
1473 const OMAP_DATA* omapp = msc_dbg->omapp;
1474 int i;
1476 if (!nomap || !omapp) return offset;
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);
1483 return 0;
1486 static unsigned long codeview_get_address(const struct msc_debug_info* msc_dbg,
1487 unsigned seg, unsigned offset)
1489 int nsect = msc_dbg->nsect;
1490 const IMAGE_SECTION_HEADER* sectp = msc_dbg->sectp;
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);
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)
1503 if (name && *name)
1505 unsigned long address = codeview_get_address(msc_dbg, segment, offset);
1507 if (force || !symt_find_nearest(msc_dbg->module, address))
1509 symt_new_global_variable(msc_dbg->module, compiland,
1510 name, is_local, address, 0,
1511 codeview_get_type(symtype, FALSE));
1516 static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root,
1517 int offset, int size, BOOL do_globals)
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;
1528 * Loop over the different types of records and whenever we
1529 * find something we are interested in, record it and move on.
1531 for (i = offset; i < size; i += length)
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);
1539 switch (sym->generic.id)
1542 * Global and local data symbols. We don't associate these
1543 * with any given source file.
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;
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;
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.
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;
1595 * Global and static functions.
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;
1640 * Function parameters and stack variables.
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;
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;
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;
1723 case S_END_V1:
1724 if (block)
1726 block = symt_close_func_block(msc_dbg->module, curr_func, block, 0);
1728 else if (curr_func)
1730 symt_normalize_function(msc_dbg->module, curr_func);
1731 curr_func = NULL;
1733 break;
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;
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))
1744 const char* ptr1 = sym->compiland_v2.p_name.name + sym->compiland_v2.p_name.namelen;
1745 const char* ptr2;
1746 while (*ptr1)
1748 ptr2 = ptr1 + strlen(ptr1) + 1;
1749 TRACE("\t%s => %s\n", ptr1, debugstr_a(ptr2));
1750 ptr1 = ptr2 + strlen(ptr2) + 1;
1753 break;
1754 case S_COMPILAND_V3:
1755 TRACE("S-Compiland-V3 %s\n", sym->compiland_v3.name);
1756 if (TRACE_ON(dbghelp_msc))
1758 const char* ptr1 = sym->compiland_v3.name + strlen(sym->compiland_v3.name);
1759 const char* ptr2;
1760 while (*ptr1)
1762 ptr2 = ptr1 + strlen(ptr1) + 1;
1763 TRACE("\t%s => %s\n", ptr1, debugstr_a(ptr2));
1764 ptr1 = ptr2 + strlen(ptr2) + 1;
1767 break;
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;
1776 case S_LABEL_V1:
1777 if (curr_func)
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));
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)
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);
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;
1800 case S_CONSTANT_V1:
1802 int vlen;
1803 const struct p_string* name;
1804 struct symt* se;
1805 VARIANT v;
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);
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);
1816 break;
1817 case S_CONSTANT_V2:
1819 int vlen;
1820 const struct p_string* name;
1821 struct symt* se;
1822 VARIANT v;
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);
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);
1833 break;
1834 case S_CONSTANT_V3:
1836 int vlen;
1837 const char* name;
1838 struct symt* se;
1839 VARIANT v;
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);
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);
1850 break;
1852 case S_UDT_V1:
1853 if (sym->udt_v1.type)
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);
1862 break;
1863 case S_UDT_V2:
1864 if (sym->udt_v2.type)
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);
1873 break;
1874 case S_UDT_V3:
1875 if (sym->udt_v3.type)
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);
1883 break;
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.
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;
1897 case S_MSTOOL_V3: /* just to silence a few warnings */
1898 case S_MSTOOLINFO_V3:
1899 case S_MSTOOLENV_V3:
1900 break;
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;
1907 case S_ALIGN_V1:
1908 TRACE("S-Align V1\n");
1909 break;
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;
1922 default:
1923 FIXME("Unsupported symbol id %x\n", sym->generic.id);
1924 dump(sym, 2 + sym->generic.len);
1925 break;
1929 if (curr_func) symt_normalize_function(msc_dbg->module, curr_func);
1931 return TRUE;
1934 static int codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYTE* root,
1935 int offset, int size)
1938 int i, length;
1939 struct symt_compiland* compiland = NULL;
1942 * Loop over the different types of records and whenever we
1943 * find something we are interested in, record it and move on.
1945 for (i = offset; i < size; i += length)
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);
1953 switch (sym->generic.id)
1955 case S_PUB_V1: /* FIXME is this really a 'data_v1' structure ?? */
1956 if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
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);
1962 break;
1963 case S_PUB_V2: /* FIXME is this really a 'data_v2' structure ?? */
1964 if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
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);
1970 break;
1972 case S_PUB_V3:
1973 if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
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);
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))
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);
1990 #endif
1991 break;
1993 * Global and local data symbols. We don't associate these
1994 * with any given source file.
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;
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.
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;
2025 msc_dbg->module->sortlist_valid = TRUE;
2027 msc_dbg->module->sortlist_valid = FALSE;
2028 return TRUE;
2031 /*========================================================================
2032 * Process PDB file.
2035 static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list,
2036 int size)
2038 int i, num_blocks;
2039 BYTE* buffer;
2041 if (!size) return NULL;
2043 num_blocks = (size + pdb->block_size - 1) / pdb->block_size;
2044 buffer = HeapAlloc(GetProcessHeap(), 0, num_blocks * pdb->block_size);
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);
2050 return buffer;
2053 static void* pdb_ds_read(const struct PDB_DS_HEADER* pdb, const DWORD* block_list,
2054 int size)
2056 int i, num_blocks;
2057 BYTE* buffer;
2059 if (!size) return NULL;
2061 num_blocks = (size + pdb->block_size - 1) / pdb->block_size;
2062 buffer = HeapAlloc(GetProcessHeap(), 0, num_blocks * pdb->block_size);
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);
2068 return buffer;
2071 static void* pdb_read_jg_file(const struct PDB_JG_HEADER* pdb,
2072 const struct PDB_JG_TOC* toc, DWORD file_nr)
2074 const WORD* block_list;
2075 DWORD i;
2077 if (!toc || file_nr >= toc->num_files) return NULL;
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;
2083 return pdb_jg_read(pdb, block_list, toc->file[file_nr].size);
2086 static void* pdb_read_ds_file(const struct PDB_DS_HEADER* pdb,
2087 const struct PDB_DS_TOC* toc, DWORD file_nr)
2089 const DWORD* block_list;
2090 DWORD i;
2092 if (!toc || file_nr >= toc->num_files) return NULL;
2094 if (toc->file_size[file_nr] == 0 || toc->file_size[file_nr] == 0xFFFFFFFF)
2096 FIXME(">>> requesting NULL stream (%u)\n", file_nr);
2097 return NULL;
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;
2103 return pdb_ds_read(pdb, block_list, toc->file_size[file_nr]);
2106 static void* pdb_read_file(const char* image, const struct pdb_lookup* pdb_lookup,
2107 DWORD file_nr)
2109 switch (pdb_lookup->kind)
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);
2118 return NULL;
2121 static unsigned pdb_get_file_size(const struct pdb_lookup* pdb_lookup, DWORD file_nr)
2123 switch (pdb_lookup->kind)
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];
2128 return 0;
2131 static void pdb_free(void* buffer)
2133 HeapFree(GetProcessHeap(), 0, buffer);
2136 static void pdb_free_lookup(const struct pdb_lookup* pdb_lookup)
2138 switch (pdb_lookup->kind)
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;
2149 static void pdb_convert_types_header(PDB_TYPES* types, const BYTE* image)
2151 memset(types, 0, sizeof(PDB_TYPES));
2152 if (!image) return;
2154 if (*(const DWORD*)image < 19960000) /* FIXME: correct version? */
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;
2165 else
2167 /* New version of the types record header */
2168 *types = *(const PDB_TYPES*)image;
2172 static void pdb_convert_symbols_header(PDB_SYMBOLS* symbols,
2173 int* header_size, const BYTE* image)
2175 memset(symbols, 0, sizeof(PDB_SYMBOLS));
2176 if (!image) return;
2178 if (*(const DWORD*)image != 0xffffffff)
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;
2192 *header_size = sizeof(PDB_SYMBOLS_OLD);
2194 else
2196 /* New version of the symbols record header */
2197 *symbols = *(const PDB_SYMBOLS*)image;
2198 *header_size = sizeof(PDB_SYMBOLS);
2202 static void pdb_convert_symbol_file(const PDB_SYMBOLS* symbols,
2203 PDB_SYMBOL_FILE_EX* sfile,
2204 unsigned* size, const void* image)
2207 if (symbols->version < 19970000)
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;
2217 else
2219 memcpy(sfile, image, sizeof(PDB_SYMBOL_FILE_EX));
2220 *size = sizeof(PDB_SYMBOL_FILE_EX) - 1;
2224 static HANDLE open_pdb_file(const struct process* pcs,
2225 const struct pdb_lookup* lookup,
2226 struct module* module)
2228 HANDLE h;
2229 char dbg_file_path[MAX_PATH];
2230 BOOL ret = FALSE;
2232 switch (lookup->kind)
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;
2243 if (!ret)
2245 WARN("\tCouldn't find %s\n", lookup->filename);
2246 return NULL;
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;
2254 static void pdb_process_types(const struct msc_debug_info* msc_dbg,
2255 const char* image, const struct pdb_lookup* pdb_lookup)
2257 BYTE* types_image = NULL;
2259 types_image = pdb_read_file(image, pdb_lookup, 2);
2260 if (types_image)
2262 PDB_TYPES types;
2263 struct codeview_type_parse ctp;
2264 DWORD total;
2265 const BYTE* ptr;
2266 DWORD* offset;
2268 pdb_convert_types_header(&types, types_image);
2270 /* Check for unknown versions */
2271 switch (types.version)
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);
2283 ctp.module = msc_dbg->module;
2284 /* reconstruct the types offset...
2285 * FIXME: maybe it's present in the newest PDB_TYPES structures
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)
2293 offset[ctp.num++] = ptr - ctp.table;
2294 ptr += ((const union codeview_type*)ptr)->generic.len + 2;
2296 ctp.offset = offset;
2298 /* Read type table */
2299 codeview_parse_type_table(&ctp);
2300 HeapFree(GetProcessHeap(), 0, offset);
2301 pdb_free(types_image);
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";
2308 /******************************************************************
2309 * pdb_init
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
2317 static BOOL pdb_init(struct pdb_lookup* pdb_lookup, const char* image, BOOL do_fill)
2319 BOOL ret = TRUE;
2321 /* check the file header, and if ok, load the TOC */
2322 TRACE("PDB(%s): %.40s\n", pdb_lookup->filename, debugstr_an(image, 40));
2324 if (!memcmp(image, PDB_JG_IDENT, sizeof(PDB_JG_IDENT)))
2326 const struct PDB_JG_HEADER* pdb = (const struct PDB_JG_HEADER*)image;
2327 struct PDB_JG_ROOT* root;
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)
2333 ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
2334 return FALSE;
2336 switch (root->Version)
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);
2346 if (do_fill)
2348 pdb_lookup->kind = PDB_JG;
2349 pdb_lookup->u.jg.timestamp = root->TimeDateStamp;
2350 pdb_lookup->age = root->Age;
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);
2361 else if (!memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
2363 const struct PDB_DS_HEADER* pdb = (const struct PDB_DS_HEADER*)image;
2364 struct PDB_DS_ROOT* root;
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)
2373 ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
2374 return FALSE;
2376 switch (root->Version)
2378 case 20000404:
2379 break;
2380 default:
2381 ERR("-Unknown root block version %d\n", root->Version);
2383 if (do_fill)
2385 pdb_lookup->kind = PDB_DS;
2386 pdb_lookup->u.ds.guid = root->guid;
2387 pdb_lookup->age = root->Age;
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);
2399 if (0) /* some tool to dump the internal files from a PDB file */
2401 int i, num_files;
2403 switch (pdb_lookup->kind)
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;
2409 for (i = 1; i < num_files; i++)
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);
2418 return ret;
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);
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)
2434 if (module_index == -1 && symbols && symbols->pdbimport_size)
2436 const PDB_SYMBOL_IMPORT*imp;
2437 const void* first;
2438 const void* last;
2439 const char* ptr;
2440 int i = 0;
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)
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))
2453 if (module_index != -1) FIXME("Twice the entry\n");
2454 else module_index = i;
2456 else
2458 struct pdb_lookup imp_pdb_lookup;
2460 /* FIXME: this is an import of a JG PDB file
2461 * how's a DS PDB handled ?
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);
2471 i++;
2472 imp = (const PDB_SYMBOL_IMPORT*)((const char*)first + ((ptr - (const char*)first + strlen(ptr) + 1 + 3) & ~3));
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);
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)
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;
2493 TRACE("Processing PDB file %s\n", pdb_lookup->filename);
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))
2500 WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
2501 goto leave;
2503 pdb_init(pdb_lookup, image, FALSE);
2505 symbols_image = pdb_read_file(image, pdb_lookup, 3);
2506 if (symbols_image)
2508 PDB_SYMBOLS symbols;
2509 BYTE* globalimage;
2510 BYTE* modimage;
2511 BYTE* file;
2512 int header_size = 0;
2514 pdb_convert_symbols_header(&symbols, &header_size, symbols_image);
2515 switch (symbols.version)
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);
2527 files_image = pdb_read_file(image, pdb_lookup, 12); /* FIXME: really fixed ??? */
2528 if (files_image)
2530 if (*(const DWORD*)files_image == 0xeffeeffe)
2532 files_size = *(const DWORD*)(files_image + 8);
2534 else
2536 WARN("wrong header %x expecting 0xeffeeffe\n", *(const DWORD*)files_image);
2537 pdb_free(files_image);
2538 files_image = NULL;
2542 pdb_process_symbol_imports(pcs, msc_dbg, &symbols, symbols_image, image, pdb_lookup, module_index);
2544 /* Read global symbol table */
2545 globalimage = pdb_read_file(image, pdb_lookup, symbols.gsym_file);
2546 if (globalimage)
2548 codeview_snarf(msc_dbg, globalimage, 0,
2549 pdb_get_file_size(pdb_lookup, symbols.gsym_file), FALSE);
2552 /* Read per-module symbols' tables */
2553 file = symbols_image + header_size;
2554 while (file - symbols_image < header_size + symbols.module_size)
2556 PDB_SYMBOL_FILE_EX sfile;
2557 const char* file_name;
2558 unsigned size;
2560 HeapValidate(GetProcessHeap(), 0, NULL);
2561 pdb_convert_symbol_file(&symbols, &sfile, &size, file);
2563 modimage = pdb_read_file(image, pdb_lookup, sfile.file);
2564 if (modimage)
2566 if (sfile.symbol_size)
2567 codeview_snarf(msc_dbg, modimage, sizeof(DWORD),
2568 sfile.symbol_size, TRUE);
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);
2580 pdb_free(modimage);
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);
2586 /* finish the remaining public and global information */
2587 if (globalimage)
2589 codeview_snarf_public(msc_dbg, globalimage, 0,
2590 pdb_get_file_size(pdb_lookup, symbols.gsym_file));
2592 pdb_free(globalimage);
2595 else
2596 pdb_process_symbol_imports(pcs, msc_dbg, NULL, NULL, image, pdb_lookup,
2597 module_index);
2598 ret = TRUE;
2600 leave:
2601 /* Cleanup */
2602 pdb_free(symbols_image);
2603 pdb_free(files_image);
2604 pdb_free_lookup(pdb_lookup);
2606 if (image) UnmapViewOfFile(image);
2607 if (hMap) CloseHandle(hMap);
2608 if (hFile) CloseHandle(hFile);
2610 return ret;
2613 static BOOL pdb_process_file(const struct process* pcs,
2614 const struct msc_debug_info* msc_dbg,
2615 struct pdb_lookup* pdb_lookup)
2617 BOOL ret;
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)
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;
2641 return ret;
2644 BOOL pdb_fetch_file_info(struct pdb_lookup* pdb_lookup)
2646 HANDLE hFile, hMap = NULL;
2647 char* image = NULL;
2648 BOOL ret = TRUE;
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))
2655 WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
2656 ret = FALSE;
2658 else
2660 pdb_init(pdb_lookup, image, TRUE);
2661 pdb_free_lookup(pdb_lookup);
2664 if (image) UnmapViewOfFile(image);
2665 if (hMap) CloseHandle(hMap);
2666 if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
2668 return ret;
2671 /*========================================================================
2672 * Process CodeView debug information.
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')
2681 static BOOL codeview_process_info(const struct process* pcs,
2682 const struct msc_debug_info* msc_dbg)
2684 const DWORD* signature = (const DWORD*)msc_dbg->root;
2685 BOOL ret = FALSE;
2686 struct pdb_lookup pdb_lookup;
2688 TRACE("Processing signature %.4s\n", (const char*)signature);
2690 switch (*signature)
2692 case CODEVIEW_NB09_SIG:
2693 case CODEVIEW_NB11_SIG:
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;
2702 codeview_init_basic_types(msc_dbg->module);
2704 for (i = 0; i < hdr->cDir; i++)
2706 ent = (const OMFDirEntry*)((const BYTE*)hdr + hdr->cbDirHeader + i * hdr->cbDirEntry);
2707 if (ent->SubSection == sstGlobalTypes)
2709 const OMFGlobalTypes* types;
2710 struct codeview_type_parse ctp;
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);
2718 cv_current_module = &cv_zmodules[0];
2719 if (cv_current_module->allowed) FIXME("Already allowed ??\n");
2720 cv_current_module->allowed = TRUE;
2722 codeview_parse_type_table(&ctp);
2723 break;
2727 ent = (const OMFDirEntry*)((const BYTE*)hdr + hdr->cbDirHeader);
2728 for (i = 0; i < hdr->cDir; i++, ent = next)
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);
2735 if (ent->SubSection == sstAlignSym)
2737 codeview_snarf(msc_dbg, msc_dbg->root + ent->lfo, sizeof(DWORD),
2738 ent->cb, TRUE);
2741 * Check the next and previous entry. If either is a
2742 * sstSrcModule, it contains the line number info for
2743 * this file.
2745 * FIXME: This is not a general solution!
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);
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);
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;
2770 case CODEVIEW_NB10_SIG:
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;
2781 case CODEVIEW_RSDS_SIG:
2783 const OMFSignatureRSDS* rsds = (const OMFSignatureRSDS*)msc_dbg->root;
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;
2795 default:
2796 ERR("Unknown CODEVIEW signature %08x in module %s\n",
2797 *signature, debugstr_w(msc_dbg->module->module.ModuleName));
2798 break;
2800 if (ret)
2802 msc_dbg->module->module.CVSig = *signature;
2803 memcpy(msc_dbg->module->module.CVData, msc_dbg->root,
2804 sizeof(msc_dbg->module->module.CVData));
2806 return ret;
2809 /*========================================================================
2810 * Process debug directory.
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)
2817 BOOL ret;
2818 int i;
2819 struct msc_debug_info msc_dbg;
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;
2827 __TRY
2829 ret = FALSE;
2831 /* First, watch out for OMAP data */
2832 for (i = 0; i < nDbg; i++)
2834 if (dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC)
2836 msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
2837 msc_dbg.omapp = (const OMAP_DATA*)(mapping + dbg[i].PointerToRawData);
2838 break;
2842 /* Now, try to parse CodeView debug info */
2843 for (i = 0; i < nDbg; i++)
2845 if (dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW)
2847 msc_dbg.root = mapping + dbg[i].PointerToRawData;
2848 if ((ret = codeview_process_info(pcs, &msc_dbg))) goto done;
2852 /* If not found, try to parse COFF debug info */
2853 for (i = 0; i < nDbg; i++)
2855 if (dbg[i].Type == IMAGE_DEBUG_TYPE_COFF)
2857 msc_dbg.root = mapping + dbg[i].PointerToRawData;
2858 if ((ret = coff_process_info(&msc_dbg))) goto done;
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
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
2871 #define FRAME_FPO 0
2872 #define FRAME_TRAP 1
2873 #define FRAME_TSS 2
2875 typedef struct _FPO_DATA
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 */
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
2892 __EXCEPT_PAGE_FAULT
2894 ERR("Got a page fault while loading symbols\n");
2895 ret = FALSE;
2897 __ENDTRY
2898 return ret;