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