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