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