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