2 * File msc.c - read VC++ debug information from COFF and eventually
5 * Copyright (C) 1996, Eric Youngdale.
6 * Copyright (C) 1999-2000, Ulrich Weigand.
7 * Copyright (C) 2004, Eric Pouech.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * Note - this handles reading debug information for 32 bit applications
26 * that run under Windows-NT for example. I doubt that this would work well
27 * for 16 bit applications, but I don't think it really matters since the
28 * file format is different, and we should never get in here in such cases.
31 * Get 16 bit CV stuff working.
32 * Add symbol size to internal symbol table.
36 #include "wine/port.h"
46 #define PATH_MAX MAX_PATH
54 #include "wine/exception.h"
55 #include "wine/debug.h"
57 #include "dbghelp_private.h"
59 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc
);
61 #define MAX_PATHNAME_LEN 1024
71 struct module
* module
;
73 PIMAGE_SECTION_HEADER sectp
;
79 /*========================================================================
80 * Debug file access helper routines
83 static WINE_EXCEPTION_FILTER(page_fault
)
85 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
86 return EXCEPTION_EXECUTE_HANDLER
;
87 return EXCEPTION_CONTINUE_SEARCH
;
90 /*========================================================================
91 * Process COFF debug information.
96 unsigned int startaddr
;
98 struct symt_compiland
* compiland
;
101 struct symt
** entries
;
108 struct CoffFile
* files
;
113 static const char* coff_get_name(const IMAGE_SYMBOL
* coff_sym
,
114 const char* coff_strtab
)
116 static char namebuff
[9];
119 if (coff_sym
->N
.Name
.Short
)
121 memcpy(namebuff
, coff_sym
->N
.ShortName
, 8);
123 nampnt
= &namebuff
[0];
127 nampnt
= coff_strtab
+ coff_sym
->N
.Name
.Long
;
130 if (nampnt
[0] == '_') nampnt
++;
134 static int coff_add_file(struct CoffFileSet
* coff_files
, struct module
* module
,
135 const char* filename
)
137 struct CoffFile
* file
;
139 if (coff_files
->nfiles
+ 1 >= coff_files
->nfiles_alloc
)
141 coff_files
->nfiles_alloc
+= 10;
142 coff_files
->files
= (coff_files
->files
) ?
143 HeapReAlloc(GetProcessHeap(), 0, coff_files
->files
,
144 coff_files
->nfiles_alloc
* sizeof(struct CoffFile
)) :
145 HeapAlloc(GetProcessHeap(), 0,
146 coff_files
->nfiles_alloc
* sizeof(struct CoffFile
));
148 file
= coff_files
->files
+ coff_files
->nfiles
;
149 file
->startaddr
= 0xffffffff;
151 file
->compiland
= symt_new_compiland(module
, filename
);
152 file
->linetab_offset
= -1;
154 file
->entries
= NULL
;
155 file
->neps
= file
->neps_alloc
= 0;
157 return coff_files
->nfiles
++;
160 static void coff_add_symbol(struct CoffFile
* coff_file
, struct symt
* sym
)
162 if (coff_file
->neps
+ 1 >= coff_file
->neps_alloc
)
164 coff_file
->neps_alloc
+= 10;
165 coff_file
->entries
= (coff_file
->entries
) ?
166 HeapReAlloc(GetProcessHeap(), 0, coff_file
->entries
,
167 coff_file
->neps_alloc
* sizeof(struct symt
*)) :
168 HeapAlloc(GetProcessHeap(), 0,
169 coff_file
->neps_alloc
* sizeof(struct symt
*));
171 coff_file
->entries
[coff_file
->neps
++] = sym
;
174 static SYM_TYPE
coff_process_info(const struct msc_debug_info
* msc_dbg
)
176 const IMAGE_AUX_SYMBOL
* aux
;
177 const IMAGE_COFF_SYMBOLS_HEADER
* coff
;
178 const IMAGE_LINENUMBER
* coff_linetab
;
179 const IMAGE_LINENUMBER
* linepnt
;
180 const char* coff_strtab
;
181 const IMAGE_SYMBOL
* coff_sym
;
182 const IMAGE_SYMBOL
* coff_symbols
;
183 struct CoffFileSet coff_files
;
184 int curr_file_idx
= -1;
192 SYM_TYPE sym_type
= SymNone
;
195 TRACE("Processing COFF symbols...\n");
197 assert(sizeof(IMAGE_SYMBOL
) == IMAGE_SIZEOF_SYMBOL
);
198 assert(sizeof(IMAGE_LINENUMBER
) == IMAGE_SIZEOF_LINENUMBER
);
200 coff_files
.files
= NULL
;
201 coff_files
.nfiles
= coff_files
.nfiles_alloc
= 0;
203 coff
= (const IMAGE_COFF_SYMBOLS_HEADER
*)msc_dbg
->root
;
205 coff_symbols
= (const IMAGE_SYMBOL
*)((unsigned int)coff
+
206 coff
->LvaToFirstSymbol
);
207 coff_linetab
= (const IMAGE_LINENUMBER
*)((unsigned int)coff
+
208 coff
->LvaToFirstLinenumber
);
209 coff_strtab
= (const char*)(coff_symbols
+ coff
->NumberOfSymbols
);
213 for (i
= 0; i
< coff
->NumberOfSymbols
; i
++)
215 coff_sym
= coff_symbols
+ i
;
216 naux
= coff_sym
->NumberOfAuxSymbols
;
218 if (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_FILE
)
220 curr_file_idx
= coff_add_file(&coff_files
, msc_dbg
->module
,
221 (char*)(coff_sym
+ 1));
222 TRACE("New file %s\n", (char*)(coff_sym
+ 1));
227 if (curr_file_idx
< 0)
229 assert(coff_files
.nfiles
== 0 && coff_files
.nfiles_alloc
== 0);
230 curr_file_idx
= coff_add_file(&coff_files
, msc_dbg
->module
, "<none>");
231 TRACE("New file <none>\n");
235 * This guy marks the size and location of the text section
236 * for the current file. We need to keep track of this so
237 * we can figure out what file the different global functions
240 if (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_STATIC
&&
241 naux
!= 0 && coff_sym
->Type
== 0 && coff_sym
->SectionNumber
== 1)
243 aux
= (const IMAGE_AUX_SYMBOL
*) (coff_sym
+ 1);
245 if (coff_files
.files
[curr_file_idx
].linetab_offset
!= -1)
248 * Save this so we can still get the old name.
252 fn
= source_get(msc_dbg
->module
,
253 coff_files
.files
[curr_file_idx
].compiland
->source
);
255 TRACE("Duplicating sect from %s: %lx %x %x %d %d\n",
256 fn
, aux
->Section
.Length
,
257 aux
->Section
.NumberOfRelocations
,
258 aux
->Section
.NumberOfLinenumbers
,
259 aux
->Section
.Number
, aux
->Section
.Selection
);
260 TRACE("More sect %d %s %08lx %d %d %d\n",
261 coff_sym
->SectionNumber
,
262 coff_get_name(coff_sym
, coff_strtab
),
263 coff_sym
->Value
, coff_sym
->Type
,
264 coff_sym
->StorageClass
, coff_sym
->NumberOfAuxSymbols
);
267 * Duplicate the file entry. We have no way to describe
268 * multiple text sections in our current way of handling things.
270 coff_add_file(&coff_files
, msc_dbg
->module
, fn
);
274 TRACE("New text sect from %s: %lx %x %x %d %d\n",
275 source_get(msc_dbg
->module
, coff_files
.files
[curr_file_idx
].compiland
->source
),
277 aux
->Section
.NumberOfRelocations
,
278 aux
->Section
.NumberOfLinenumbers
,
279 aux
->Section
.Number
, aux
->Section
.Selection
);
282 if (coff_files
.files
[curr_file_idx
].startaddr
> coff_sym
->Value
)
284 coff_files
.files
[curr_file_idx
].startaddr
= coff_sym
->Value
;
287 if (coff_files
.files
[curr_file_idx
].endaddr
< coff_sym
->Value
+ aux
->Section
.Length
)
289 coff_files
.files
[curr_file_idx
].endaddr
= coff_sym
->Value
+ aux
->Section
.Length
;
292 coff_files
.files
[curr_file_idx
].linetab_offset
= linetab_indx
;
293 coff_files
.files
[curr_file_idx
].linecnt
= aux
->Section
.NumberOfLinenumbers
;
294 linetab_indx
+= aux
->Section
.NumberOfLinenumbers
;
299 if (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_STATIC
&& naux
== 0 &&
300 coff_sym
->SectionNumber
== 1)
302 DWORD base
= msc_dbg
->sectp
[coff_sym
->SectionNumber
- 1].VirtualAddress
;
304 * This is a normal static function when naux == 0.
305 * Just register it. The current file is the correct
306 * one in this instance.
308 nampnt
= coff_get_name(coff_sym
, coff_strtab
);
310 TRACE("\tAdding static symbol %s\n", nampnt
);
312 /* FIXME: was adding symbol to this_file ??? */
313 coff_add_symbol(&coff_files
.files
[curr_file_idx
],
314 &symt_new_function(msc_dbg
->module
,
315 coff_files
.files
[curr_file_idx
].compiland
,
317 msc_dbg
->module
->module
.BaseOfImage
+ base
+ coff_sym
->Value
,
319 NULL
/* FIXME */)->symt
);
324 if (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_EXTERNAL
&&
325 ISFCN(coff_sym
->Type
) && coff_sym
->SectionNumber
> 0)
327 struct symt_compiland
* compiland
= NULL
;
328 DWORD base
= msc_dbg
->sectp
[coff_sym
->SectionNumber
- 1].VirtualAddress
;
329 nampnt
= coff_get_name(coff_sym
, coff_strtab
);
331 TRACE("%d: %lx %s\n",
332 i
, msc_dbg
->module
->module
.BaseOfImage
+ base
+ coff_sym
->Value
,
334 TRACE("\tAdding global symbol %s (sect=%s)\n",
335 nampnt
, msc_dbg
->sectp
[coff_sym
->SectionNumber
- 1].Name
);
338 * Now we need to figure out which file this guy belongs to.
340 for (j
= 0; j
< coff_files
.nfiles
; j
++)
342 if (coff_files
.files
[j
].startaddr
<= base
+ coff_sym
->Value
343 && coff_files
.files
[j
].endaddr
> base
+ coff_sym
->Value
)
345 compiland
= coff_files
.files
[j
].compiland
;
349 if (j
< coff_files
.nfiles
)
351 coff_add_symbol(&coff_files
.files
[j
],
352 &symt_new_function(msc_dbg
->module
, compiland
, nampnt
,
353 msc_dbg
->module
->module
.BaseOfImage
+ base
+ coff_sym
->Value
,
354 0 /* FIXME */, NULL
/* FIXME */)->symt
);
358 symt_new_function(msc_dbg
->module
, NULL
, nampnt
,
359 msc_dbg
->module
->module
.BaseOfImage
+ base
+ coff_sym
->Value
,
360 0 /* FIXME */, NULL
/* FIXME */);
366 if (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_EXTERNAL
&&
367 coff_sym
->SectionNumber
> 0)
369 DWORD base
= msc_dbg
->sectp
[coff_sym
->SectionNumber
- 1].VirtualAddress
;
371 * Similar to above, but for the case of data symbols.
372 * These aren't treated as entrypoints.
374 nampnt
= coff_get_name(coff_sym
, coff_strtab
);
376 TRACE("%d: %lx %s\n",
377 i
, msc_dbg
->module
->module
.BaseOfImage
+ base
+ coff_sym
->Value
,
379 TRACE("\tAdding global data symbol %s\n", nampnt
);
382 * Now we need to figure out which file this guy belongs to.
384 symt_new_global_variable(msc_dbg
->module
, NULL
, nampnt
, TRUE
/* FIXME */,
385 msc_dbg
->module
->module
.BaseOfImage
+ base
+ coff_sym
->Value
,
386 0 /* FIXME */, NULL
/* FIXME */);
391 if (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_STATIC
&& naux
== 0)
394 * Ignore these. They don't have anything to do with
401 TRACE("Skipping unknown entry '%s' %d %d %d\n",
402 coff_get_name(coff_sym
, coff_strtab
),
403 coff_sym
->StorageClass
, coff_sym
->SectionNumber
, naux
);
406 * For now, skip past the aux entries.
411 if (coff_files
.files
!= NULL
)
414 * OK, we now should have a list of files, and we should have a list
415 * of entrypoints. We need to sort the entrypoints so that we are
416 * able to tie the line numbers with the given functions within the
419 for (j
= 0; j
< coff_files
.nfiles
; j
++)
421 if (coff_files
.files
[j
].entries
!= NULL
)
423 qsort(coff_files
.files
[j
].entries
, coff_files
.files
[j
].neps
,
424 sizeof(struct symt
*), symt_cmp_addr
);
429 * Now pick apart the line number tables, and attach the entries
430 * to the given functions.
432 for (j
= 0; j
< coff_files
.nfiles
; j
++)
435 if (coff_files
.files
[j
].neps
!= 0)
437 for (k
= 0; k
< coff_files
.files
[j
].linecnt
; k
++)
439 linepnt
= coff_linetab
+ coff_files
.files
[j
].linetab_offset
+ k
;
441 * If we have spilled onto the next entrypoint, then
446 if (l
+1 >= coff_files
.files
[j
].neps
) break;
447 symt_get_info(coff_files
.files
[j
].entries
[l
+1], TI_GET_ADDRESS
, &addr
);
448 if (((msc_dbg
->module
->module
.BaseOfImage
+ linepnt
->Type
.VirtualAddress
) < addr
))
453 if (coff_files
.files
[j
].entries
[l
+1]->tag
== SymTagFunction
)
456 * Add the line number. This is always relative to the
457 * start of the function, so we need to subtract that offset
460 symt_get_info(coff_files
.files
[j
].entries
[l
+1], TI_GET_ADDRESS
, &addr
);
461 symt_add_func_line(msc_dbg
->module
, (struct symt_function
*)coff_files
.files
[j
].entries
[l
+1],
462 coff_files
.files
[j
].compiland
->source
, linepnt
->Linenumber
,
463 msc_dbg
->module
->module
.BaseOfImage
+ linepnt
->Type
.VirtualAddress
- addr
);
471 for (j
= 0; j
< coff_files
.nfiles
; j
++)
473 if (coff_files
.files
[j
].entries
!= NULL
)
475 HeapFree(GetProcessHeap(), 0, coff_files
.files
[j
].entries
);
478 HeapFree(GetProcessHeap(), 0, coff_files
.files
);
485 /*========================================================================
486 * Process CodeView type information.
493 unsigned short int len
;
499 unsigned short int len
;
503 unsigned char variant
[1];
508 unsigned short int len
;
510 unsigned int datatype
;
511 unsigned int attribute
;
512 unsigned char variant
[1];
517 unsigned short int len
;
520 unsigned char bitoff
;
526 unsigned short int len
;
530 unsigned char bitoff
;
535 unsigned short int len
;
539 unsigned short int arrlen
; /* numeric leaf */
541 unsigned char name
[1];
547 unsigned short int len
;
549 unsigned int elemtype
;
550 unsigned int idxtype
;
551 unsigned short int arrlen
; /* numeric leaf */
553 unsigned char name
[1];
559 unsigned short int len
;
566 unsigned short int structlen
; /* numeric leaf */
568 unsigned char name
[1];
574 unsigned short int len
;
578 unsigned int fieldlist
;
579 unsigned int derived
;
581 unsigned short int structlen
; /* numeric leaf */
583 unsigned char name
[1];
589 unsigned short int len
;
594 unsigned short int un_len
; /* numeric leaf */
596 unsigned char name
[1];
602 unsigned short int len
;
606 unsigned int fieldlist
;
607 unsigned short int un_len
; /* numeric leaf */
609 unsigned char name
[1];
615 unsigned short int len
;
621 unsigned char name
[1];
626 unsigned short int len
;
632 unsigned char name
[1];
637 unsigned short int len
;
639 unsigned char list
[1];
643 union codeview_fieldtype
655 unsigned short int offset
; /* numeric leaf */
663 unsigned short int offset
; /* numeric leaf */
672 unsigned short int vbpoff
; /* numeric leaf */
674 unsigned short int vboff
; /* numeric leaf */
684 unsigned short int vbpoff
; /* numeric leaf */
686 unsigned short int vboff
; /* numeric leaf */
694 unsigned short int value
; /* numeric leaf */
696 unsigned char name
[1];
704 unsigned char name
[1];
712 unsigned char name
[1];
720 unsigned short int offset
; /* numeric leaf */
722 unsigned char name
[1];
731 unsigned short int offset
; /* numeric leaf */
733 unsigned char name
[1];
742 unsigned char name
[1];
750 unsigned char name
[1];
758 unsigned char name
[1];
766 unsigned char name
[1];
773 unsigned char name
[1];
781 unsigned char name
[1];
815 unsigned char name
[1];
823 unsigned int vtab_offset
;
824 unsigned char name
[1];
832 unsigned char name
[1];
840 unsigned int vtab_offset
;
841 unsigned char name
[1];
864 unsigned char name
[1];
872 unsigned char name
[1];
880 unsigned char name
[1];
886 * This covers the basic datatypes that VC++ seems to be using these days.
887 * 32 bit mode only. There are additional numbers for the pointers in 16
888 * bit mode. There are many other types listed in the documents, but these
889 * are apparently not used by the compiler, or represent pointer types
892 #define T_NOTYPE 0x0000 /* Notype */
893 #define T_ABS 0x0001 /* Abs */
894 #define T_VOID 0x0003 /* Void */
895 #define T_CHAR 0x0010 /* signed char */
896 #define T_SHORT 0x0011 /* short */
897 #define T_LONG 0x0012 /* long */
898 #define T_QUAD 0x0013 /* long long */
899 #define T_UCHAR 0x0020 /* unsigned char */
900 #define T_USHORT 0x0021 /* unsigned short */
901 #define T_ULONG 0x0022 /* unsigned long */
902 #define T_UQUAD 0x0023 /* unsigned long long */
903 #define T_REAL32 0x0040 /* float */
904 #define T_REAL64 0x0041 /* double */
905 #define T_RCHAR 0x0070 /* real char */
906 #define T_WCHAR 0x0071 /* wide char */
907 #define T_INT4 0x0074 /* int */
908 #define T_UINT4 0x0075 /* unsigned int */
910 #define T_32PVOID 0x0403 /* 32 bit near pointer to void */
911 #define T_32PCHAR 0x0410 /* 16:32 near pointer to signed char */
912 #define T_32PSHORT 0x0411 /* 16:32 near pointer to short */
913 #define T_32PLONG 0x0412 /* 16:32 near pointer to int */
914 #define T_32PQUAD 0x0413 /* 16:32 near pointer to long long */
915 #define T_32PUCHAR 0x0420 /* 16:32 near pointer to unsigned char */
916 #define T_32PUSHORT 0x0421 /* 16:32 near pointer to unsigned short */
917 #define T_32PULONG 0x0422 /* 16:32 near pointer to unsigned int */
918 #define T_32PUQUAD 0x0423 /* 16:32 near pointer to long long */
919 #define T_32PREAL32 0x0440 /* 16:32 near pointer to float */
920 #define T_32PREAL64 0x0441 /* 16:32 near pointer to float */
921 #define T_32PRCHAR 0x0470 /* 16:32 near pointer to real char */
922 #define T_32PWCHAR 0x0471 /* 16:32 near pointer to real char */
923 #define T_32PINT4 0x0474 /* 16:32 near pointer to int */
924 #define T_32PUINT4 0x0475 /* 16:32 near pointer to unsigned int */
927 #define LF_MODIFIER 0x0001
928 #define LF_POINTER 0x0002
929 #define LF_ARRAY 0x0003
930 #define LF_CLASS 0x0004
931 #define LF_STRUCTURE 0x0005
932 #define LF_UNION 0x0006
933 #define LF_ENUM 0x0007
934 #define LF_PROCEDURE 0x0008
935 #define LF_MFUNCTION 0x0009
936 #define LF_VTSHAPE 0x000a
937 #define LF_COBOL0 0x000b
938 #define LF_COBOL1 0x000c
939 #define LF_BARRAY 0x000d
940 #define LF_LABEL 0x000e
941 #define LF_NULL 0x000f
942 #define LF_NOTTRAN 0x0010
943 #define LF_DIMARRAY 0x0011
944 #define LF_VFTPATH 0x0012
945 #define LF_PRECOMP 0x0013
946 #define LF_ENDPRECOMP 0x0014
947 #define LF_OEM 0x0015
948 #define LF_TYPESERVER 0x0016
950 #define LF_MODIFIER_32 0x1001 /* variants with new 32-bit type indices */
951 #define LF_POINTER_32 0x1002
952 #define LF_ARRAY_32 0x1003
953 #define LF_CLASS_32 0x1004
954 #define LF_STRUCTURE_32 0x1005
955 #define LF_UNION_32 0x1006
956 #define LF_ENUM_32 0x1007
957 #define LF_PROCEDURE_32 0x1008
958 #define LF_MFUNCTION_32 0x1009
959 #define LF_COBOL0_32 0x100a
960 #define LF_BARRAY_32 0x100b
961 #define LF_DIMARRAY_32 0x100c
962 #define LF_VFTPATH_32 0x100d
963 #define LF_PRECOMP_32 0x100e
964 #define LF_OEM_32 0x100f
966 #define LF_SKIP 0x0200
967 #define LF_ARGLIST 0x0201
968 #define LF_DEFARG 0x0202
969 #define LF_LIST 0x0203
970 #define LF_FIELDLIST 0x0204
971 #define LF_DERIVED 0x0205
972 #define LF_BITFIELD 0x0206
973 #define LF_METHODLIST 0x0207
974 #define LF_DIMCONU 0x0208
975 #define LF_DIMCONLU 0x0209
976 #define LF_DIMVARU 0x020a
977 #define LF_DIMVARLU 0x020b
978 #define LF_REFSYM 0x020c
980 #define LF_SKIP_32 0x1200 /* variants with new 32-bit type indices */
981 #define LF_ARGLIST_32 0x1201
982 #define LF_DEFARG_32 0x1202
983 #define LF_FIELDLIST_32 0x1203
984 #define LF_DERIVED_32 0x1204
985 #define LF_BITFIELD_32 0x1205
986 #define LF_METHODLIST_32 0x1206
987 #define LF_DIMCONU_32 0x1207
988 #define LF_DIMCONLU_32 0x1208
989 #define LF_DIMVARU_32 0x1209
990 #define LF_DIMVARLU_32 0x120a
992 #define LF_BCLASS 0x0400
993 #define LF_VBCLASS 0x0401
994 #define LF_IVBCLASS 0x0402
995 #define LF_ENUMERATE 0x0403
996 #define LF_FRIENDFCN 0x0404
997 #define LF_INDEX 0x0405
998 #define LF_MEMBER 0x0406
999 #define LF_STMEMBER 0x0407
1000 #define LF_METHOD 0x0408
1001 #define LF_NESTTYPE 0x0409
1002 #define LF_VFUNCTAB 0x040a
1003 #define LF_FRIENDCLS 0x040b
1004 #define LF_ONEMETHOD 0x040c
1005 #define LF_VFUNCOFF 0x040d
1006 #define LF_NESTTYPEEX 0x040e
1007 #define LF_MEMBERMODIFY 0x040f
1009 #define LF_BCLASS_32 0x1400 /* variants with new 32-bit type indices */
1010 #define LF_VBCLASS_32 0x1401
1011 #define LF_IVBCLASS_32 0x1402
1012 #define LF_FRIENDFCN_32 0x1403
1013 #define LF_INDEX_32 0x1404
1014 #define LF_MEMBER_32 0x1405
1015 #define LF_STMEMBER_32 0x1406
1016 #define LF_METHOD_32 0x1407
1017 #define LF_NESTTYPE_32 0x1408
1018 #define LF_VFUNCTAB_32 0x1409
1019 #define LF_FRIENDCLS_32 0x140a
1020 #define LF_ONEMETHOD_32 0x140b
1021 #define LF_VFUNCOFF_32 0x140c
1022 #define LF_NESTTYPEEX_32 0x140d
1024 #define LF_NUMERIC 0x8000 /* numeric leaf types */
1025 #define LF_CHAR 0x8000
1026 #define LF_SHORT 0x8001
1027 #define LF_USHORT 0x8002
1028 #define LF_LONG 0x8003
1029 #define LF_ULONG 0x8004
1030 #define LF_REAL32 0x8005
1031 #define LF_REAL64 0x8006
1032 #define LF_REAL80 0x8007
1033 #define LF_REAL128 0x8008
1034 #define LF_QUADWORD 0x8009
1035 #define LF_UQUADWORD 0x800a
1036 #define LF_REAL48 0x800b
1037 #define LF_COMPLEX32 0x800c
1038 #define LF_COMPLEX64 0x800d
1039 #define LF_COMPLEX80 0x800e
1040 #define LF_COMPLEX128 0x800f
1041 #define LF_VARSTRING 0x8010
1043 #define MAX_BUILTIN_TYPES 0x480
1044 static struct symt
* cv_basic_types
[MAX_BUILTIN_TYPES
];
1045 static unsigned int num_cv_defined_types
= 0;
1046 static struct symt
** cv_defined_types
= NULL
;
1047 #define SymTagCVBitField (SymTagMax + 0x100)
1048 struct codeview_bitfield
1052 unsigned bitposition
;
1055 static struct codeview_bitfield
* cv_bitfields
;
1056 static unsigned num_cv_bitfields
;
1057 static unsigned used_cv_bitfields
;
1059 static void codeview_init_basic_types(struct module
* module
)
1062 * These are the common builtin types that are used by VC++.
1064 cv_basic_types
[T_NOTYPE
] = NULL
;
1065 cv_basic_types
[T_ABS
] = NULL
;
1066 cv_basic_types
[T_VOID
] = &symt_new_basic(module
, btVoid
, "void", 0)->symt
;
1067 cv_basic_types
[T_CHAR
] = &symt_new_basic(module
, btChar
, "char", 1)->symt
;
1068 cv_basic_types
[T_SHORT
] = &symt_new_basic(module
, btInt
, "short int", 2)->symt
;
1069 cv_basic_types
[T_LONG
] = &symt_new_basic(module
, btInt
, "long int", 4)->symt
;
1070 cv_basic_types
[T_QUAD
] = &symt_new_basic(module
, btInt
, "long long int", 8)->symt
;
1071 cv_basic_types
[T_UCHAR
] = &symt_new_basic(module
, btUInt
, "unsignd char", 1)->symt
;
1072 cv_basic_types
[T_USHORT
] = &symt_new_basic(module
, btUInt
, "unsigned short", 2)->symt
;
1073 cv_basic_types
[T_ULONG
] = &symt_new_basic(module
, btUInt
, "unsigned long", 4)->symt
;
1074 cv_basic_types
[T_UQUAD
] = &symt_new_basic(module
, btUInt
, "unsigned long long", 8)->symt
;
1075 cv_basic_types
[T_REAL32
] = &symt_new_basic(module
, btFloat
, "float", 4)->symt
;
1076 cv_basic_types
[T_REAL64
] = &symt_new_basic(module
, btFloat
, "double", 8)->symt
;
1077 cv_basic_types
[T_RCHAR
] = &symt_new_basic(module
, btInt
, "signed char", 1)->symt
;
1078 cv_basic_types
[T_WCHAR
] = &symt_new_basic(module
, btWChar
, "wchar_t", 2)->symt
;
1079 cv_basic_types
[T_INT4
] = &symt_new_basic(module
, btInt
, "INT4", 4)->symt
;
1080 cv_basic_types
[T_UINT4
] = &symt_new_basic(module
, btUInt
, "UINT4", 4)->symt
;
1082 cv_basic_types
[T_32PVOID
] = &symt_new_pointer(module
, cv_basic_types
[T_VOID
])->symt
;
1083 cv_basic_types
[T_32PCHAR
] = &symt_new_pointer(module
, cv_basic_types
[T_CHAR
])->symt
;
1084 cv_basic_types
[T_32PSHORT
] = &symt_new_pointer(module
, cv_basic_types
[T_SHORT
])->symt
;
1085 cv_basic_types
[T_32PLONG
] = &symt_new_pointer(module
, cv_basic_types
[T_LONG
])->symt
;
1086 cv_basic_types
[T_32PQUAD
] = &symt_new_pointer(module
, cv_basic_types
[T_QUAD
])->symt
;
1087 cv_basic_types
[T_32PUCHAR
] = &symt_new_pointer(module
, cv_basic_types
[T_UCHAR
])->symt
;
1088 cv_basic_types
[T_32PUSHORT
] = &symt_new_pointer(module
, cv_basic_types
[T_USHORT
])->symt
;
1089 cv_basic_types
[T_32PULONG
] = &symt_new_pointer(module
, cv_basic_types
[T_ULONG
])->symt
;
1090 cv_basic_types
[T_32PUQUAD
] = &symt_new_pointer(module
, cv_basic_types
[T_UQUAD
])->symt
;
1091 cv_basic_types
[T_32PREAL32
] = &symt_new_pointer(module
, cv_basic_types
[T_REAL32
])->symt
;
1092 cv_basic_types
[T_32PREAL64
] = &symt_new_pointer(module
, cv_basic_types
[T_REAL64
])->symt
;
1093 cv_basic_types
[T_32PRCHAR
] = &symt_new_pointer(module
, cv_basic_types
[T_RCHAR
])->symt
;
1094 cv_basic_types
[T_32PWCHAR
] = &symt_new_pointer(module
, cv_basic_types
[T_WCHAR
])->symt
;
1095 cv_basic_types
[T_32PINT4
] = &symt_new_pointer(module
, cv_basic_types
[T_INT4
])->symt
;
1096 cv_basic_types
[T_32PUINT4
] = &symt_new_pointer(module
, cv_basic_types
[T_UINT4
])->symt
;
1099 static int numeric_leaf(int* value
, const unsigned short int* leaf
)
1101 unsigned short int type
= *leaf
++;
1104 if (type
< LF_NUMERIC
)
1114 *value
= *(char*)leaf
;
1119 *value
= *(short*)leaf
;
1124 *value
= *(unsigned short*)leaf
;
1129 *value
= *(int*)leaf
;
1134 *value
= *(unsigned int*)leaf
;
1140 *value
= 0; /* FIXME */
1145 *value
= 0; /* FIXME */
1150 *value
= 0; /* FIXME */
1155 *value
= 0; /* FIXME */
1160 *value
= 0; /* FIXME */
1165 *value
= 0; /* FIXME */
1170 *value
= 0; /* FIXME */
1175 *value
= 0; /* FIXME */
1180 *value
= 0; /* FIXME */
1185 *value
= 0; /* FIXME */
1189 length
+= 2 + *leaf
;
1190 *value
= 0; /* FIXME */
1194 FIXME("Unknown numeric leaf type %04x\n", type
);
1203 static const char* terminate_string(const unsigned char* name
)
1205 static char symname
[256];
1207 int namelen
= name
[0];
1208 assert(namelen
>= 0 && namelen
< 256);
1210 memcpy(symname
, name
+ 1, namelen
);
1211 symname
[namelen
] = '\0';
1213 return (!*symname
|| strcmp(symname
, "__unnamed") == 0) ? NULL
: symname
;
1216 static struct symt
* codeview_get_type(unsigned int typeno
, BOOL allow_special
)
1218 struct symt
* symt
= NULL
;
1221 * Convert Codeview type numbers into something we can grok internally.
1222 * Numbers < 0x1000 are all fixed builtin types. Numbers from 0x1000 and
1223 * up are all user defined (structs, etc).
1225 if (typeno
< 0x1000)
1227 if (typeno
< MAX_BUILTIN_TYPES
)
1228 symt
= cv_basic_types
[typeno
];
1232 if (typeno
- 0x1000 < num_cv_defined_types
)
1233 symt
= cv_defined_types
[typeno
- 0x1000];
1235 if (!allow_special
&& symt
&& symt
->tag
== SymTagCVBitField
)
1236 FIXME("bitfields are only handled for UDTs\n");
1240 static int codeview_add_type(unsigned int typeno
, struct symt
* dt
)
1242 while (typeno
- 0x1000 >= num_cv_defined_types
)
1244 num_cv_defined_types
+= 0x100;
1245 if (cv_defined_types
)
1246 cv_defined_types
= (struct symt
**)
1247 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cv_defined_types
,
1248 num_cv_defined_types
* sizeof(struct symt
*));
1250 cv_defined_types
= (struct symt
**)
1251 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1252 num_cv_defined_types
* sizeof(struct symt
*));
1254 if (cv_defined_types
== NULL
) return FALSE
;
1257 cv_defined_types
[typeno
- 0x1000] = dt
;
1261 static void codeview_clear_type_table(void)
1263 if (cv_defined_types
) HeapFree(GetProcessHeap(), 0, cv_defined_types
);
1264 cv_defined_types
= NULL
;
1265 num_cv_defined_types
= 0;
1267 if (cv_bitfields
) HeapFree(GetProcessHeap(), 0, cv_bitfields
);
1268 cv_bitfields
= NULL
;
1269 num_cv_bitfields
= used_cv_bitfields
= 0;
1272 static int codeview_add_type_pointer(struct module
* module
, unsigned int typeno
,
1273 unsigned int datatype
)
1275 struct symt
* symt
= &symt_new_pointer(module
, codeview_get_type(datatype
, FALSE
))->symt
;
1276 return codeview_add_type(typeno
, symt
);
1279 static int codeview_add_type_array(struct module
* module
,
1280 unsigned int typeno
, const char* name
,
1281 unsigned int elemtype
, unsigned int arr_len
)
1284 struct symt
* elem
= codeview_get_type(elemtype
, FALSE
);
1290 symt_get_info(elem
, TI_GET_LENGTH
, &elem_size
);
1291 if (elem_size
) arr_max
= arr_len
/ elem_size
;
1293 symt
= &symt_new_array(module
, 0, arr_max
, elem
)->symt
;
1294 return codeview_add_type(typeno
, symt
);
1297 static int codeview_add_type_bitfield(unsigned int typeno
, unsigned int bitoff
,
1298 unsigned int nbits
, unsigned int basetype
)
1300 if (used_cv_bitfields
>= num_cv_bitfields
)
1302 num_cv_bitfields
*= 2;
1304 cv_bitfields
= HeapReAlloc(GetProcessHeap(), 0, cv_bitfields
,
1305 num_cv_bitfields
* sizeof(struct codeview_bitfield
));
1307 cv_bitfields
= HeapAlloc(GetProcessHeap(), 0,
1308 num_cv_bitfields
* sizeof(struct codeview_bitfield
));
1309 if (!cv_bitfields
) return 0;
1312 cv_bitfields
[used_cv_bitfields
].symt
.tag
= SymTagCVBitField
;
1313 cv_bitfields
[used_cv_bitfields
].subtype
= basetype
;
1314 cv_bitfields
[used_cv_bitfields
].bitposition
= bitoff
;
1315 cv_bitfields
[used_cv_bitfields
].bitlength
= nbits
;
1317 return codeview_add_type(typeno
, &cv_bitfields
[used_cv_bitfields
++].symt
);
1320 static int codeview_add_type_enum_field_list(struct module
* module
,
1321 unsigned int typeno
,
1322 const unsigned char* list
, int len
)
1324 struct symt_enum
* symt
;
1325 const unsigned char* ptr
= list
;
1327 symt
= symt_new_enum(module
, NULL
);
1328 while (ptr
- list
< len
)
1330 union codeview_fieldtype
* type
= (union codeview_fieldtype
*)ptr
;
1332 if (*ptr
>= 0xf0) /* LF_PAD... */
1338 switch (type
->generic
.id
)
1342 int value
, vlen
= numeric_leaf(&value
, &type
->enumerate
.value
);
1343 unsigned char* name
= (unsigned char*)&type
->enumerate
.value
+ vlen
;
1345 symt_add_enum_element(module
, symt
, terminate_string(name
), value
);
1346 ptr
+= 2 + 2 + vlen
+ (1 + name
[0]);
1351 FIXME("Unhandled type %04x in ENUM field list\n", type
->generic
.id
);
1356 return codeview_add_type(typeno
, &symt
->symt
);
1359 static int codeview_add_type_struct_field_list(struct module
* module
,
1360 unsigned int typeno
,
1361 const unsigned char* list
, int len
)
1363 struct symt_udt
* symt
;
1364 const unsigned char* ptr
= list
;
1366 symt
= symt_new_udt(module
, NULL
, 0, UdtStruct
/* don't care */);
1367 while (ptr
- list
< len
)
1369 const union codeview_fieldtype
* type
= (const union codeview_fieldtype
*)ptr
;
1371 if (*ptr
>= 0xf0) /* LF_PAD... */
1377 switch (type
->generic
.id
)
1381 int offset
, olen
= numeric_leaf(&offset
, &type
->bclass
.offset
);
1383 /* FIXME: ignored for now */
1385 ptr
+= 2 + 2 + 2 + olen
;
1391 int offset
, olen
= numeric_leaf(&offset
, &type
->bclass32
.offset
);
1393 /* FIXME: ignored for now */
1395 ptr
+= 2 + 2 + 4 + olen
;
1402 int vbpoff
, vbplen
= numeric_leaf(&vbpoff
, &type
->vbclass
.vbpoff
);
1403 const unsigned short int* p_vboff
= (const unsigned short int*)((char*)&type
->vbclass
.vbpoff
+ vbpoff
);
1404 int vpoff
, vplen
= numeric_leaf(&vpoff
, p_vboff
);
1406 /* FIXME: ignored for now */
1408 ptr
+= 2 + 2 + 2 + 2 + vbplen
+ vplen
;
1413 case LF_IVBCLASS_32
:
1415 int vbpoff
, vbplen
= numeric_leaf(&vbpoff
, &type
->vbclass32
.vbpoff
);
1416 const unsigned short int* p_vboff
= (const unsigned short int*)((char*)&type
->vbclass32
.vbpoff
+ vbpoff
);
1417 int vpoff
, vplen
= numeric_leaf(&vpoff
, p_vboff
);
1419 /* FIXME: ignored for now */
1421 ptr
+= 2 + 2 + 4 + 4 + vbplen
+ vplen
;
1427 int offset
, olen
= numeric_leaf(&offset
, &type
->member
.offset
);
1428 const unsigned char* name
= (const unsigned char*)&type
->member
.offset
+ olen
;
1429 struct symt
* subtype
= codeview_get_type(type
->member
.type
, TRUE
);
1431 if (!subtype
|| subtype
->tag
!= SymTagCVBitField
)
1433 DWORD elem_size
= 0;
1434 if (subtype
) symt_get_info(subtype
, TI_GET_LENGTH
, &elem_size
);
1435 symt_add_udt_element(module
, symt
, terminate_string(name
),
1436 subtype
, offset
<< 3, elem_size
<< 3);
1440 struct codeview_bitfield
* cvbf
= (struct codeview_bitfield
*)subtype
;
1441 symt_add_udt_element(module
, symt
, terminate_string(name
),
1442 codeview_get_type(cvbf
->subtype
, FALSE
),
1443 cvbf
->bitposition
, cvbf
->bitlength
);
1446 ptr
+= 2 + 2 + 2 + olen
+ (1 + name
[0]);
1452 int offset
, olen
= numeric_leaf(&offset
, &type
->member32
.offset
);
1453 const unsigned char* name
= (const unsigned char*)&type
->member32
.offset
+ olen
;
1454 struct symt
* subtype
= codeview_get_type(type
->member32
.type
, TRUE
);
1456 if (!subtype
|| subtype
->tag
!= SymTagCVBitField
)
1458 DWORD elem_size
= 0;
1459 if (subtype
) symt_get_info(subtype
, TI_GET_LENGTH
, &elem_size
);
1460 symt_add_udt_element(module
, symt
, terminate_string(name
),
1461 subtype
, offset
<< 3, elem_size
<< 3);
1465 struct codeview_bitfield
* cvbf
= (struct codeview_bitfield
*)subtype
;
1466 symt_add_udt_element(module
, symt
, terminate_string(name
),
1467 codeview_get_type(cvbf
->subtype
, FALSE
),
1468 cvbf
->bitposition
, cvbf
->bitlength
);
1471 ptr
+= 2 + 2 + 4 + olen
+ (1 + name
[0]);
1476 /* FIXME: ignored for now */
1477 ptr
+= 2 + 2 + 2 + (1 + type
->stmember
.name
[0]);
1480 case LF_STMEMBER_32
:
1481 /* FIXME: ignored for now */
1482 ptr
+= 2 + 4 + 2 + (1 + type
->stmember32
.name
[0]);
1486 /* FIXME: ignored for now */
1487 ptr
+= 2 + 2 + 2 + (1 + type
->method
.name
[0]);
1491 /* FIXME: ignored for now */
1492 ptr
+= 2 + 2 + 4 + (1 + type
->method32
.name
[0]);
1496 /* FIXME: ignored for now */
1497 ptr
+= 2 + 2 + (1 + type
->nesttype
.name
[0]);
1500 case LF_NESTTYPE_32
:
1501 /* FIXME: ignored for now */
1502 ptr
+= 2 + 2 + 4 + (1 + type
->nesttype32
.name
[0]);
1506 /* FIXME: ignored for now */
1510 case LF_VFUNCTAB_32
:
1511 /* FIXME: ignored for now */
1516 /* FIXME: ignored for now */
1517 switch ((type
->onemethod
.attribute
>> 2) & 7)
1519 case 4: case 6: /* (pure) introducing virtual method */
1520 ptr
+= 2 + 2 + 2 + 4 + (1 + type
->onemethod_virt
.name
[0]);
1524 ptr
+= 2 + 2 + 2 + (1 + type
->onemethod
.name
[0]);
1529 case LF_ONEMETHOD_32
:
1530 /* FIXME: ignored for now */
1531 switch ((type
->onemethod32
.attribute
>> 2) & 7)
1533 case 4: case 6: /* (pure) introducing virtual method */
1534 ptr
+= 2 + 2 + 4 + 4 + (1 + type
->onemethod32_virt
.name
[0]);
1538 ptr
+= 2 + 2 + 4 + (1 + type
->onemethod32
.name
[0]);
1544 FIXME("Unhandled type %04x in STRUCT field list\n", type
->generic
.id
);
1549 return codeview_add_type(typeno
, &symt
->symt
);
1552 static int codeview_add_type_enum(struct module
* module
, unsigned int typeno
,
1553 const char* name
, unsigned int fieldlist
)
1555 struct symt_enum
* symt
= symt_new_enum(module
, name
);
1556 struct symt
* list
= codeview_get_type(fieldlist
, FALSE
);
1558 /* FIXME: this is rather ugly !!! */
1559 if (list
) symt
->vchildren
= ((struct symt_enum
*)list
)->vchildren
;
1561 return codeview_add_type(typeno
, &symt
->symt
);
1564 static int codeview_add_type_struct(struct module
* module
, unsigned int typeno
,
1565 const char* name
, int structlen
,
1566 unsigned int fieldlist
, enum UdtKind kind
)
1568 struct symt_udt
* symt
= symt_new_udt(module
, name
, structlen
, kind
);
1569 struct symt
* list
= codeview_get_type(fieldlist
, FALSE
);
1571 /* FIXME: this is rather ugly !!! */
1572 if (list
) symt
->vchildren
= ((struct symt_udt
*)list
)->vchildren
;
1574 return codeview_add_type(typeno
, &symt
->symt
);
1577 static int codeview_parse_type_table(struct module
* module
, const char* table
, int len
)
1579 unsigned int curr_type
= 0x1000;
1580 const char* ptr
= table
;
1582 while (ptr
- table
< len
)
1584 const union codeview_type
* type
= (const union codeview_type
*)ptr
;
1587 switch (type
->generic
.id
)
1590 retv
= codeview_add_type_pointer(module
, curr_type
,
1591 type
->pointer
.datatype
);
1594 retv
= codeview_add_type_pointer(module
, curr_type
,
1595 type
->pointer32
.datatype
);
1600 int arrlen
, alen
= numeric_leaf(&arrlen
, &type
->array
.arrlen
);
1601 const unsigned char* name
= (const unsigned char*)&type
->array
.arrlen
+ alen
;
1603 retv
= codeview_add_type_array(module
, curr_type
, terminate_string(name
),
1604 type
->array
.elemtype
, arrlen
);
1609 int arrlen
, alen
= numeric_leaf(&arrlen
, &type
->array32
.arrlen
);
1610 const unsigned char* name
= (const unsigned char*)&type
->array32
.arrlen
+ alen
;
1612 retv
= codeview_add_type_array(module
, curr_type
, terminate_string(name
),
1613 type
->array32
.elemtype
,
1614 type
->array32
.arrlen
);
1618 /* a bitfields is a CodeView specific data type which represent a bitfield
1619 * in a structure or a class. For now, we store it in a SymTag-like type
1620 * (so that the rest of the process is seamless), but check at udt inclusion
1621 * type for its presence
1624 retv
= codeview_add_type_bitfield(curr_type
, type
->bitfield
.bitoff
,
1625 type
->bitfield
.nbits
,
1626 type
->bitfield
.type
);
1628 case LF_BITFIELD_32
:
1629 retv
= codeview_add_type_bitfield(curr_type
, type
->bitfield32
.bitoff
,
1630 type
->bitfield32
.nbits
,
1631 type
->bitfield32
.type
);
1635 case LF_FIELDLIST_32
:
1638 * A 'field list' is a CodeView-specific data type which doesn't
1639 * directly correspond to any high-level data type. It is used
1640 * to hold the collection of members of a struct, class, union
1641 * or enum type. The actual definition of that type will follow
1642 * later, and refer to the field list definition record.
1644 * As we don't have a field list type ourselves, we look ahead
1645 * in the field list to try to find out whether this field list
1646 * will be used for an enum or struct type, and create a dummy
1647 * type of the corresponding sort. Later on, the definition of
1648 * the 'real' type will copy the member / enumeration data.
1651 const char* list
= type
->fieldlist
.list
;
1652 int len
= (ptr
+ type
->generic
.len
+ 2) - list
;
1654 if (((union codeview_fieldtype
*)list
)->generic
.id
== LF_ENUMERATE
)
1655 retv
= codeview_add_type_enum_field_list(module
, curr_type
, list
, len
);
1657 retv
= codeview_add_type_struct_field_list(module
, curr_type
, list
, len
);
1664 int structlen
, slen
= numeric_leaf(&structlen
, &type
->structure
.structlen
);
1665 const unsigned char* name
= (const unsigned char*)&type
->structure
.structlen
+ slen
;
1667 retv
= codeview_add_type_struct(module
, curr_type
, terminate_string(name
),
1668 structlen
, type
->structure
.fieldlist
,
1669 type
->generic
.id
== LF_CLASS
? UdtClass
: UdtStruct
);
1672 case LF_STRUCTURE_32
:
1675 int structlen
, slen
= numeric_leaf(&structlen
, &type
->structure32
.structlen
);
1676 const unsigned char* name
= (const unsigned char*)&type
->structure32
.structlen
+ slen
;
1678 retv
= codeview_add_type_struct(module
, curr_type
, terminate_string(name
),
1679 structlen
, type
->structure32
.fieldlist
,
1680 type
->generic
.id
== LF_CLASS
? UdtClass
: UdtStruct
);
1686 int un_len
, ulen
= numeric_leaf(&un_len
, &type
->t_union
.un_len
);
1687 const unsigned char* name
= (const unsigned char*)&type
->t_union
.un_len
+ ulen
;
1689 retv
= codeview_add_type_struct(module
, curr_type
, terminate_string(name
),
1690 un_len
, type
->t_union
.fieldlist
, UdtUnion
);
1695 int un_len
, ulen
= numeric_leaf(&un_len
, &type
->t_union32
.un_len
);
1696 const unsigned char* name
= (const unsigned char*)&type
->t_union32
.un_len
+ ulen
;
1698 retv
= codeview_add_type_struct(module
, curr_type
, terminate_string(name
),
1699 un_len
, type
->t_union32
.fieldlist
, UdtUnion
);
1704 retv
= codeview_add_type_enum(module
, curr_type
, terminate_string(type
->enumeration
.name
),
1705 type
->enumeration
.field
);
1708 retv
= codeview_add_type_enum(module
, curr_type
, terminate_string(type
->enumeration32
.name
),
1709 type
->enumeration32
.field
);
1713 FIXME("Unhandled leaf %x\n", type
->generic
.id
);
1721 ptr
+= type
->generic
.len
+ 2;
1727 /*========================================================================
1728 * Process CodeView line number information.
1736 const unsigned int* ui
;
1745 struct codeview_linetab
1751 struct symt_compiland
* compiland
;
1752 const unsigned short* linetab
;
1753 const unsigned int* offtab
;
1756 static struct codeview_linetab
* codeview_snarf_linetab(struct module
* module
,
1757 const char* linetab
, int size
)
1760 char filename
[PATH_MAX
];
1761 const unsigned int* filetab
;
1765 struct codeview_linetab
* lt_hdr
;
1766 unsigned int* lt_ptr
;
1770 union any_size pnt2
;
1771 struct startend
* start
;
1773 struct symt_compiland
* compiland
;
1776 * Now get the important bits.
1782 filetab
= (const unsigned int*) pnt
.c
;
1785 * Now count up the number of segments in the file.
1788 for (i
= 0; i
< nfile
; i
++)
1790 pnt2
.c
= linetab
+ filetab
[i
];
1795 * Next allocate the header we will be returning.
1796 * There is one header for each segment, so that we can reach in
1797 * and pull bits as required.
1799 lt_hdr
= (struct codeview_linetab
*)
1800 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (nseg
+ 1) * sizeof(*lt_hdr
));
1807 * Now fill the header we will be returning, one for each segment.
1808 * Note that this will basically just contain pointers into the existing
1809 * line table, and we do not actually copy any additional information
1810 * or allocate any additional memory.
1814 for (i
= 0; i
< nfile
; i
++)
1817 * Get the pointer into the segment information.
1819 pnt2
.c
= linetab
+ filetab
[i
];
1820 file_segcount
= *pnt2
.s
;
1823 lt_ptr
= (unsigned int*) pnt2
.c
;
1824 start
= (struct startend
*)(lt_ptr
+ file_segcount
);
1827 * Now snarf the filename for all of the segments for this file.
1829 fn
= (unsigned char*)(start
+ file_segcount
);
1830 memset(filename
, 0, sizeof(filename
));
1831 memcpy(filename
, fn
+ 1, *fn
);
1832 compiland
= symt_new_compiland(module
, filename
);
1834 for (k
= 0; k
< file_segcount
; k
++, this_seg
++)
1836 pnt2
.c
= linetab
+ lt_ptr
[k
];
1837 lt_hdr
[this_seg
].start
= start
[k
].start
;
1838 lt_hdr
[this_seg
].end
= start
[k
].end
;
1839 lt_hdr
[this_seg
].compiland
= compiland
;
1840 lt_hdr
[this_seg
].segno
= *pnt2
.s
++;
1841 lt_hdr
[this_seg
].nline
= *pnt2
.s
++;
1842 lt_hdr
[this_seg
].offtab
= pnt2
.ui
;
1843 lt_hdr
[this_seg
].linetab
= (unsigned short*)(pnt2
.ui
+ lt_hdr
[this_seg
].nline
);
1853 /*========================================================================
1854 * Process CodeView symbol information.
1857 union codeview_symbol
1869 unsigned int offset
;
1871 unsigned short symtype
;
1872 unsigned char namelen
;
1873 unsigned char name
[1];
1880 unsigned int symtype
;
1881 unsigned int offset
;
1883 unsigned char namelen
;
1884 unsigned char name
[1];
1891 unsigned int pparent
;
1894 unsigned int offset
;
1895 unsigned short segment
;
1896 unsigned short thunk_len
;
1897 unsigned char thtype
;
1898 unsigned char namelen
;
1899 unsigned char name
[1];
1906 unsigned int pparent
;
1909 unsigned int proc_len
;
1910 unsigned int debug_start
;
1911 unsigned int debug_end
;
1912 unsigned int offset
;
1913 unsigned short segment
;
1914 unsigned short proctype
;
1915 unsigned char flags
;
1916 unsigned char namelen
;
1917 unsigned char name
[1];
1924 unsigned int pparent
;
1927 unsigned int proc_len
;
1928 unsigned int debug_start
;
1929 unsigned int debug_end
;
1930 unsigned int proctype
;
1931 unsigned int offset
;
1932 unsigned short segment
;
1933 unsigned char flags
;
1934 unsigned char namelen
;
1935 unsigned char name
[1];
1940 short int len
; /* Total length of this entry */
1941 short int id
; /* Always S_BPREL32 */
1942 unsigned int offset
; /* Stack offset relative to BP */
1943 unsigned short symtype
;
1944 unsigned char namelen
;
1945 unsigned char name
[1];
1950 short int len
; /* Total length of this entry */
1951 short int id
; /* Always S_BPREL32 */
1952 unsigned int offset
; /* Stack offset relative to BP */
1953 unsigned int symtype
;
1954 unsigned char namelen
;
1955 unsigned char name
[1];
1959 #define S_COMPILE 0x0001
1960 #define S_REGISTER 0x0002
1961 #define S_CONSTANT 0x0003
1962 #define S_UDT 0x0004
1963 #define S_SSEARCH 0x0005
1964 #define S_END 0x0006
1965 #define S_SKIP 0x0007
1966 #define S_CVRESERVE 0x0008
1967 #define S_OBJNAME 0x0009
1968 #define S_ENDARG 0x000a
1969 #define S_COBOLUDT 0x000b
1970 #define S_MANYREG 0x000c
1971 #define S_RETURN 0x000d
1972 #define S_ENTRYTHIS 0x000e
1974 #define S_BPREL 0x0200
1975 #define S_LDATA 0x0201
1976 #define S_GDATA 0x0202
1977 #define S_PUB 0x0203
1978 #define S_LPROC 0x0204
1979 #define S_GPROC 0x0205
1980 #define S_THUNK 0x0206
1981 #define S_BLOCK 0x0207
1982 #define S_WITH 0x0208
1983 #define S_LABEL 0x0209
1984 #define S_CEXMODEL 0x020a
1985 #define S_VFTPATH 0x020b
1986 #define S_REGREL 0x020c
1987 #define S_LTHREAD 0x020d
1988 #define S_GTHREAD 0x020e
1990 #define S_PROCREF 0x0400
1991 #define S_DATAREF 0x0401
1992 #define S_ALIGN 0x0402
1993 #define S_LPROCREF 0x0403
1995 #define S_REGISTER_32 0x1001 /* Variants with new 32-bit type indices */
1996 #define S_CONSTANT_32 0x1002
1997 #define S_UDT_32 0x1003
1998 #define S_COBOLUDT_32 0x1004
1999 #define S_MANYREG_32 0x1005
2001 #define S_BPREL_32 0x1006
2002 #define S_LDATA_32 0x1007
2003 #define S_GDATA_32 0x1008
2004 #define S_PUB_32 0x1009
2005 #define S_LPROC_32 0x100a
2006 #define S_GPROC_32 0x100b
2007 #define S_VFTTABLE_32 0x100c
2008 #define S_REGREL_32 0x100d
2009 #define S_LTHREAD_32 0x100e
2010 #define S_GTHREAD_32 0x100f
2012 static unsigned int codeview_map_offset(const struct msc_debug_info
* msc_dbg
,
2013 unsigned int offset
)
2015 int nomap
= msc_dbg
->nomap
;
2016 const OMAP_DATA
* omapp
= msc_dbg
->omapp
;
2019 if (!nomap
|| !omapp
) return offset
;
2021 /* FIXME: use binary search */
2022 for (i
= 0; i
< nomap
- 1; i
++)
2023 if (omapp
[i
].from
<= offset
&& omapp
[i
+1].from
> offset
)
2024 return !omapp
[i
].to
? 0 : omapp
[i
].to
+ (offset
- omapp
[i
].from
);
2029 static const struct codeview_linetab
*
2030 codeview_get_linetab(const struct codeview_linetab
* linetab
,
2031 unsigned seg
, unsigned offset
)
2034 * Check whether we have line number information
2038 for (; linetab
->linetab
; linetab
++)
2039 if (linetab
->segno
== seg
&&
2040 linetab
->start
<= offset
&& linetab
->end
> offset
)
2042 if (!linetab
->linetab
) linetab
= NULL
;
2047 static unsigned codeview_get_address(const struct msc_debug_info
* msc_dbg
,
2048 unsigned seg
, unsigned offset
)
2050 int nsect
= msc_dbg
->nsect
;
2051 const IMAGE_SECTION_HEADER
* sectp
= msc_dbg
->sectp
;
2053 if (!seg
|| seg
> nsect
) return 0;
2054 return msc_dbg
->module
->module
.BaseOfImage
+
2055 codeview_map_offset(msc_dbg
, sectp
[seg
-1].VirtualAddress
+ offset
);
2058 static void codeview_add_func_linenum(struct module
* module
,
2059 struct symt_function
* func
,
2060 const struct codeview_linetab
* linetab
,
2061 unsigned offset
, unsigned size
)
2065 if (!linetab
) return;
2066 for (i
= 0; i
< linetab
->nline
; i
++)
2068 if (linetab
->offtab
[i
] >= offset
&& linetab
->offtab
[i
] < offset
+ size
)
2070 symt_add_func_line(module
, func
, linetab
->compiland
->source
,
2071 linetab
->linetab
[i
], linetab
->offtab
[i
] - offset
);
2076 static int codeview_snarf(const struct msc_debug_info
* msc_dbg
, const BYTE
* root
,
2077 int offset
, int size
,
2078 struct codeview_linetab
* linetab
)
2080 struct symt_function
* curr_func
= NULL
;
2082 char symname
[PATH_MAX
];
2083 const struct codeview_linetab
* flt
;
2086 * Loop over the different types of records and whenever we
2087 * find something we are interested in, record it and move on.
2089 for (i
= offset
; i
< size
; i
+= length
)
2091 const union codeview_symbol
* sym
= (const union codeview_symbol
*)(root
+ i
);
2092 length
= sym
->generic
.len
+ 2;
2094 switch (sym
->generic
.id
)
2097 * Global and local data symbols. We don't associate these
2098 * with any given source file.
2102 memcpy(symname
, sym
->data
.name
, sym
->data
.namelen
);
2103 symname
[sym
->data
.namelen
] = '\0';
2104 flt
= codeview_get_linetab(linetab
, sym
->data
.seg
, sym
->data
.offset
);
2105 /* global data should be the only one of type global var...
2106 * the other ones sound different
2109 symt_new_global_variable(msc_dbg
->module
,
2110 flt
? flt
->compiland
: NULL
,
2111 symname
, sym
->generic
.id
== S_GDATA
,
2112 codeview_get_address(msc_dbg
, sym
->data
.seg
, sym
->data
.offset
),
2114 codeview_get_type(sym
->data
.symtype
, FALSE
));
2119 memcpy(symname
, sym
->data32
.name
, sym
->data32
.namelen
);
2120 symname
[sym
->data32
.namelen
] = '\0';
2121 flt
= codeview_get_linetab(linetab
, sym
->data32
.seg
, sym
->data32
.offset
);
2122 /* global data should be the only one of type global var...
2123 * the other ones sound different
2126 symt_new_global_variable(msc_dbg
->module
, flt
? flt
->compiland
: NULL
,
2127 symname
, sym
->generic
.id
== S_GDATA_32
,
2128 codeview_get_address(msc_dbg
, sym
->data32
.seg
, sym
->data32
.offset
),
2130 codeview_get_type(sym
->data32
.symtype
, FALSE
));
2133 case S_PUB
: /* FIXME is this really a 'data' structure ?? */
2134 memcpy(symname
, sym
->data
.name
, sym
->data
.namelen
);
2135 symname
[sym
->data
.namelen
] = '\0';
2136 flt
= codeview_get_linetab(linetab
, sym
->data
.seg
, sym
->data
.offset
);
2137 symt_new_public(msc_dbg
->module
, flt
? flt
->compiland
: NULL
,
2139 codeview_get_address(msc_dbg
, sym
->data
.seg
, sym
->data
.offset
),
2140 0, TRUE
/* FIXME */, TRUE
/* FIXME */);
2143 case S_PUB_32
: /* FIXME is this really a 'data32' structure ?? */
2144 memcpy(symname
, sym
->data32
.name
, sym
->data32
.namelen
);
2145 symname
[sym
->data32
.namelen
] = '\0';
2146 flt
= codeview_get_linetab(linetab
, sym
->data32
.seg
, sym
->data32
.offset
);
2147 symt_new_public(msc_dbg
->module
, flt
? flt
->compiland
: NULL
,
2149 codeview_get_address(msc_dbg
, sym
->data32
.seg
, sym
->data32
.offset
),
2150 0, TRUE
/* FIXME */, TRUE
/* FIXME */);
2154 * Sort of like a global function, but it just points
2155 * to a thunk, which is a stupid name for what amounts to
2156 * a PLT slot in the normal jargon that everyone else uses.
2159 memcpy(symname
, sym
->thunk
.name
, sym
->thunk
.namelen
);
2160 symname
[sym
->thunk
.namelen
] = '\0';
2161 flt
= codeview_get_linetab(linetab
, sym
->thunk
.segment
, sym
->thunk
.offset
);
2162 symt_new_function(msc_dbg
->module
, flt
? flt
->compiland
: NULL
,
2164 codeview_get_address(msc_dbg
, sym
->thunk
.segment
, sym
->thunk
.offset
),
2165 sym
->thunk
.thunk_len
,
2166 codeview_get_type(sym
->thunk
.thtype
, FALSE
));
2170 * Global and static functions.
2174 if (curr_func
) symt_normalize_function(msc_dbg
->module
, curr_func
);
2176 memcpy(symname
, sym
->proc
.name
, sym
->proc
.namelen
);
2177 symname
[sym
->proc
.namelen
] = '\0';
2178 flt
= codeview_get_linetab(linetab
, sym
->proc
.segment
, sym
->proc
.offset
);
2179 curr_func
= symt_new_function(msc_dbg
->module
,
2180 flt
? flt
->compiland
: NULL
, symname
,
2181 codeview_get_address(msc_dbg
, sym
->proc
.segment
, sym
->proc
.offset
),
2183 codeview_get_type(sym
->proc
.proctype
, FALSE
));
2185 codeview_add_func_linenum(msc_dbg
->module
, curr_func
, flt
,
2186 sym
->proc
.offset
, sym
->proc
.proc_len
);
2187 /* DEBUG_SetSymbolBPOff(curr_func, sym->proc.debug_start); */
2191 if (curr_func
) symt_normalize_function(msc_dbg
->module
, curr_func
);
2193 memcpy(symname
, sym
->proc32
.name
, sym
->proc32
.namelen
);
2194 symname
[sym
->proc32
.namelen
] = '\0';
2195 flt
= codeview_get_linetab(linetab
, sym
->proc32
.segment
, sym
->proc32
.offset
);
2196 curr_func
= symt_new_function(msc_dbg
->module
,
2197 flt
? flt
->compiland
: NULL
, symname
,
2198 codeview_get_address(msc_dbg
, sym
->proc32
.segment
, sym
->proc32
.offset
),
2199 sym
->proc32
.proc_len
,
2200 codeview_get_type(sym
->proc32
.proctype
, FALSE
));
2202 codeview_add_func_linenum(msc_dbg
->module
, curr_func
, flt
,
2203 sym
->proc32
.offset
, sym
->proc32
.proc_len
);
2204 /* DEBUG_SetSymbolBPOff(curr_func, sym->proc32.debug_start); */
2208 * Function parameters and stack variables.
2211 memcpy(symname
, sym
->stack
.name
, sym
->stack
.namelen
);
2212 symname
[sym
->stack
.namelen
] = '\0';
2213 symt_add_func_local(msc_dbg
->module
, curr_func
, 0, sym
->stack
.offset
,
2214 NULL
, codeview_get_type(sym
->stack
.symtype
, FALSE
),
2218 memcpy(symname
, sym
->stack32
.name
, sym
->stack32
.namelen
);
2219 symname
[sym
->stack32
.namelen
] = '\0';
2220 symt_add_func_local(msc_dbg
->module
, curr_func
, 0, sym
->stack32
.offset
,
2221 NULL
, codeview_get_type(sym
->stack32
.symtype
, FALSE
),
2226 * These are special, in that they are always followed by an
2227 * additional length-prefixed string which is *not* included
2228 * into the symbol length count. We need to skip it.
2234 LPBYTE name
= (LPBYTE
)sym
+ length
;
2235 length
+= (*name
+ 1 + 3) & ~3;
2239 FIXME("Unsupported id %x\n", sym
->generic
.id
);
2243 if (curr_func
) symt_normalize_function(msc_dbg
->module
, curr_func
);
2245 if (linetab
) HeapFree(GetProcessHeap(), 0, linetab
);
2249 /*========================================================================
2254 typedef struct _PDB_FILE
2258 } PDB_FILE
,* PPDB_FILE
;
2260 typedef struct _PDB_HEADER
2269 } PDB_HEADER
, *PPDB_HEADER
;
2271 typedef struct _PDB_TOC
2275 } PDB_TOC
, *PPDB_TOC
;
2277 typedef struct _PDB_ROOT
2280 DWORD TimeDateStamp
;
2284 } PDB_ROOT
, *PPDB_ROOT
;
2286 typedef struct _PDB_TYPES_OLD
2294 } PDB_TYPES_OLD
, *PPDB_TYPES_OLD
;
2296 typedef struct _PDB_TYPES
2309 DWORD search_offset
;
2311 DWORD unknown_offset
;
2313 } PDB_TYPES
, *PPDB_TYPES
;
2315 typedef struct _PDB_SYMBOL_RANGE
2321 DWORD characteristics
;
2324 } PDB_SYMBOL_RANGE
, *PPDB_SYMBOL_RANGE
;
2326 typedef struct _PDB_SYMBOL_RANGE_EX
2332 DWORD characteristics
;
2337 } PDB_SYMBOL_RANGE_EX
, *PPDB_SYMBOL_RANGE_EX
;
2339 typedef struct _PDB_SYMBOL_FILE
2342 PDB_SYMBOL_RANGE range
;
2351 } PDB_SYMBOL_FILE
, *PPDB_SYMBOL_FILE
;
2353 typedef struct _PDB_SYMBOL_FILE_EX
2356 PDB_SYMBOL_RANGE_EX range
;
2366 } PDB_SYMBOL_FILE_EX
, *PPDB_SYMBOL_FILE_EX
;
2368 typedef struct _PDB_SYMBOL_SOURCE
2373 } PDB_SYMBOL_SOURCE
, *PPDB_SYMBOL_SOURCE
;
2375 typedef struct _PDB_SYMBOL_IMPORT
2379 DWORD TimeDateStamp
;
2382 } PDB_SYMBOL_IMPORT
, *PPDB_SYMBOL_IMPORT
;
2384 typedef struct _PDB_SYMBOLS_OLD
2393 DWORD srcmodule_size
;
2394 } PDB_SYMBOLS_OLD
, *PPDB_SYMBOLS_OLD
;
2396 typedef struct _PDB_SYMBOLS
2407 DWORD srcmodule_size
;
2408 DWORD pdbimport_size
;
2410 } PDB_SYMBOLS
, *PPDB_SYMBOLS
;
2413 static void* pdb_read(const BYTE
* image
, const WORD
* block_list
, int size
)
2415 const PDB_HEADER
* pdb
= (const PDB_HEADER
*)image
;
2419 if (!size
) return NULL
;
2421 nBlocks
= (size
+ pdb
->blocksize
- 1) / pdb
->blocksize
;
2422 buffer
= HeapAlloc(GetProcessHeap(), 0, nBlocks
* pdb
->blocksize
);
2424 for (i
= 0; i
< nBlocks
; i
++)
2425 memcpy(buffer
+ i
* pdb
->blocksize
,
2426 image
+ block_list
[i
] * pdb
->blocksize
, pdb
->blocksize
);
2431 static void* pdb_read_file(const BYTE
* image
, const PDB_TOC
* toc
, DWORD fileNr
)
2433 const PDB_HEADER
* pdb
= (const PDB_HEADER
*)image
;
2434 const WORD
* block_list
;
2437 if (!toc
|| fileNr
>= toc
->nFiles
) return NULL
;
2439 block_list
= (const WORD
*) &toc
->file
[toc
->nFiles
];
2440 for (i
= 0; i
< fileNr
; i
++)
2441 block_list
+= (toc
->file
[i
].size
+ pdb
->blocksize
- 1) / pdb
->blocksize
;
2443 return pdb_read(image
, block_list
, toc
->file
[fileNr
].size
);
2446 static void pdb_free(void* buffer
)
2448 HeapFree(GetProcessHeap(), 0, buffer
);
2451 static void pdb_convert_types_header(PDB_TYPES
* types
, const BYTE
* image
)
2453 memset(types
, 0, sizeof(PDB_TYPES
));
2456 if (*(DWORD
*)image
< 19960000) /* FIXME: correct version? */
2458 /* Old version of the types record header */
2459 const PDB_TYPES_OLD
* old
= (const PDB_TYPES_OLD
*)image
;
2460 types
->version
= old
->version
;
2461 types
->type_offset
= sizeof(PDB_TYPES_OLD
);
2462 types
->type_size
= old
->type_size
;
2463 types
->first_index
= old
->first_index
;
2464 types
->last_index
= old
->last_index
;
2465 types
->file
= old
->file
;
2469 /* New version of the types record header */
2470 *types
= *(const PDB_TYPES
*)image
;
2474 static void pdb_convert_symbols_header(PDB_SYMBOLS
* symbols
,
2475 int* header_size
, const BYTE
* image
)
2477 memset(symbols
, 0, sizeof(PDB_SYMBOLS
));
2480 if (*(DWORD
*)image
!= 0xffffffff)
2482 /* Old version of the symbols record header */
2483 const PDB_SYMBOLS_OLD
* old
= (const PDB_SYMBOLS_OLD
*)image
;
2484 symbols
->version
= 0;
2485 symbols
->module_size
= old
->module_size
;
2486 symbols
->offset_size
= old
->offset_size
;
2487 symbols
->hash_size
= old
->hash_size
;
2488 symbols
->srcmodule_size
= old
->srcmodule_size
;
2489 symbols
->pdbimport_size
= 0;
2490 symbols
->hash1_file
= old
->hash1_file
;
2491 symbols
->hash2_file
= old
->hash2_file
;
2492 symbols
->gsym_file
= old
->gsym_file
;
2494 *header_size
= sizeof(PDB_SYMBOLS_OLD
);
2498 /* New version of the symbols record header */
2499 *symbols
= *(const PDB_SYMBOLS
*)image
;
2500 *header_size
= sizeof(PDB_SYMBOLS
);
2504 static const char* get_last_sep(const char* str
)
2508 if ((a
= strrchr(str
, '/'))) str
= a
;
2509 return (a
= strrchr(str
, '\\')) ? a
: str
;
2512 static HANDLE
open_pdb_file(const struct process
* pcs
, struct module
* module
,
2516 char dbg_file_path
[MAX_PATH
];
2518 h
= CreateFileA(filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
2519 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2520 if (h
== INVALID_HANDLE_VALUE
)
2522 h
= FindDebugInfoFile(filename
, pcs
->search_path
, dbg_file_path
);
2528 strcpy(dbg_file_path
, module
->module
.LoadedImageName
);
2529 if ((p
= get_last_sep(dbg_file_path
)))
2531 if ((q
= get_last_sep(filename
))) q
++; else q
= filename
;
2532 strcpy((char*)p
+ 1, q
);
2533 h
= CreateFileA(dbg_file_path
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
2534 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2538 return (h
== INVALID_HANDLE_VALUE
) ? NULL
: h
;
2541 static SYM_TYPE
pdb_process_file(const struct process
* pcs
,
2542 const struct msc_debug_info
* msc_dbg
,
2543 char* filename
, DWORD timestamp
)
2545 SYM_TYPE sym_type
= -1;
2546 HANDLE hFile
, hMap
= NULL
;
2548 PDB_HEADER
* pdb
= NULL
;
2549 PDB_TOC
* toc
= NULL
;
2550 PDB_ROOT
* root
= NULL
;
2551 char* types_image
= NULL
;
2552 char* symbols_image
= NULL
;
2554 PDB_SYMBOLS symbols
;
2555 int header_size
= 0;
2559 TRACE("Processing PDB file %s\n", filename
);
2562 * Open and map() .PDB file
2564 if ((hFile
= open_pdb_file(pcs
, msc_dbg
->module
, filename
)) == NULL
||
2565 ((hMap
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
)) == NULL
) ||
2566 ((image
= MapViewOfFile(hMap
, FILE_MAP_READ
, 0, 0, 0)) == NULL
))
2568 ERR("-Unable to peruse .PDB file %s\n", filename
);
2573 * Read in TOC and well-known files
2575 pdb
= (PPDB_HEADER
)image
;
2576 toc
= pdb_read(image
, pdb
->toc_block
, pdb
->toc
.size
);
2577 root
= pdb_read_file(image
, toc
, 1);
2578 types_image
= pdb_read_file(image
, toc
, 2);
2579 symbols_image
= pdb_read_file(image
, toc
, 3);
2581 pdb_convert_types_header(&types
, types_image
);
2582 pdb_convert_symbols_header(&symbols
, &header_size
, symbols_image
);
2586 ERR("-Unable to get root from .PDB file %s\n", filename
);
2591 * Check for unknown versions
2594 switch (root
->version
)
2596 case 19950623: /* VC 4.0 */
2598 case 19960307: /* VC 5.0 */
2599 case 19970604: /* VC 6.0 */
2602 ERR("-Unknown root block version %ld\n", root
->version
);
2605 switch (types
.version
)
2607 case 19950410: /* VC 4.0 */
2609 case 19961031: /* VC 5.0 / 6.0 */
2612 ERR("-Unknown type info version %ld\n", types
.version
);
2615 switch (symbols
.version
)
2617 case 0: /* VC 4.0 */
2618 case 19960307: /* VC 5.0 */
2619 case 19970606: /* VC 6.0 */
2622 ERR("-Unknown symbol info version %ld\n", symbols
.version
);
2626 /* Check .PDB time stamp */
2627 if (root
->TimeDateStamp
!= timestamp
)
2629 ERR("-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2630 filename
, root
->TimeDateStamp
, timestamp
);
2633 /* Read type table */
2634 codeview_parse_type_table(msc_dbg
->module
, types_image
+ types
.type_offset
, types
.type_size
);
2636 /* Read type-server .PDB imports */
2637 if (symbols
.pdbimport_size
)
2640 ERR("-Type server .PDB imports ignored!\n");
2643 /* Read global symbol table */
2644 modimage
= pdb_read_file(image
, toc
, symbols
.gsym_file
);
2647 codeview_snarf(msc_dbg
, modimage
, 0, toc
->file
[symbols
.gsym_file
].size
, NULL
);
2651 /* Read per-module symbol / linenumber tables */
2652 file
= symbols_image
+ header_size
;
2653 while (file
- symbols_image
< header_size
+ symbols
.module_size
)
2655 int file_nr
, file_index
, symbol_size
, lineno_size
;
2658 if (symbols
.version
< 19970000)
2660 PDB_SYMBOL_FILE
*sym_file
= (PDB_SYMBOL_FILE
*) file
;
2661 file_nr
= sym_file
->file
;
2662 file_name
= sym_file
->filename
;
2663 file_index
= sym_file
->range
.index
;
2664 symbol_size
= sym_file
->symbol_size
;
2665 lineno_size
= sym_file
->lineno_size
;
2669 PDB_SYMBOL_FILE_EX
*sym_file
= (PDB_SYMBOL_FILE_EX
*) file
;
2670 file_nr
= sym_file
->file
;
2671 file_name
= sym_file
->filename
;
2672 file_index
= sym_file
->range
.index
;
2673 symbol_size
= sym_file
->symbol_size
;
2674 lineno_size
= sym_file
->lineno_size
;
2677 modimage
= pdb_read_file(image
, toc
, file_nr
);
2680 struct codeview_linetab
* linetab
= NULL
;
2683 linetab
= codeview_snarf_linetab(msc_dbg
->module
, modimage
+ symbol_size
, lineno_size
);
2686 codeview_snarf(msc_dbg
, modimage
, sizeof(DWORD
), symbol_size
, linetab
);
2691 file_name
+= strlen(file_name
) + 1;
2692 file
= (char*)((DWORD
)(file_name
+ strlen(file_name
) + 1 + 3) & ~3);
2700 codeview_clear_type_table();
2702 if (symbols_image
) pdb_free(symbols_image
);
2703 if (types_image
) pdb_free(types_image
);
2704 if (root
) pdb_free(root
);
2705 if (toc
) pdb_free(toc
);
2707 if (image
) UnmapViewOfFile(image
);
2708 if (hMap
) CloseHandle(hMap
);
2709 if (hFile
) CloseHandle(hFile
);
2714 /*========================================================================
2715 * Process CodeView debug information.
2718 #define CODEVIEW_NB09_SIG ('N' | ('B' << 8) | ('0' << 16) | ('9' << 24))
2719 #define CODEVIEW_NB10_SIG ('N' | ('B' << 8) | ('1' << 16) | ('0' << 24))
2720 #define CODEVIEW_NB11_SIG ('N' | ('B' << 8) | ('1' << 16) | ('1' << 24))
2722 typedef struct _CODEVIEW_HEADER
2726 } CODEVIEW_HEADER
,* PCODEVIEW_HEADER
;
2728 typedef struct _CODEVIEW_PDB_DATA
2733 } CODEVIEW_PDB_DATA
, *PCODEVIEW_PDB_DATA
;
2735 typedef struct _CV_DIRECTORY_HEADER
2742 } CV_DIRECTORY_HEADER
, *PCV_DIRECTORY_HEADER
;
2744 typedef struct _CV_DIRECTORY_ENTRY
2750 } CV_DIRECTORY_ENTRY
, *PCV_DIRECTORY_ENTRY
;
2752 #define sstAlignSym 0x125
2753 #define sstSrcModule 0x127
2755 static SYM_TYPE
codeview_process_info(const struct process
* pcs
,
2756 const struct msc_debug_info
* msc_dbg
)
2758 const CODEVIEW_HEADER
* cv
= (const CODEVIEW_HEADER
*)msc_dbg
->root
;
2759 SYM_TYPE sym_type
= -1;
2761 switch (cv
->dwSignature
)
2763 case CODEVIEW_NB09_SIG
:
2764 case CODEVIEW_NB11_SIG
:
2766 const CV_DIRECTORY_HEADER
* hdr
= (const CV_DIRECTORY_HEADER
*)(msc_dbg
->root
+ cv
->lfoDirectory
);
2767 const CV_DIRECTORY_ENTRY
* ent
;
2768 const CV_DIRECTORY_ENTRY
* prev
;
2769 const CV_DIRECTORY_ENTRY
* next
;
2772 codeview_init_basic_types(msc_dbg
->module
);
2773 ent
= (const CV_DIRECTORY_ENTRY
*)((const BYTE
*)hdr
+ hdr
->cbDirHeader
);
2774 for (i
= 0; i
< hdr
->cDir
; i
++, ent
= next
)
2776 next
= (i
== hdr
->cDir
-1)? NULL
:
2777 (const CV_DIRECTORY_ENTRY
*)((const BYTE
*)ent
+ hdr
->cbDirEntry
);
2778 prev
= (i
== 0)? NULL
:
2779 (const CV_DIRECTORY_ENTRY
*)((const BYTE
*)ent
- hdr
->cbDirEntry
);
2781 if (ent
->subsection
== sstAlignSym
)
2784 * Check the next and previous entry. If either is a
2785 * sstSrcModule, it contains the line number info for
2788 * FIXME: This is not a general solution!
2790 struct codeview_linetab
* linetab
= NULL
;
2792 if (next
&& next
->iMod
== ent
->iMod
&& next
->subsection
== sstSrcModule
)
2793 linetab
= codeview_snarf_linetab(msc_dbg
->module
, msc_dbg
->root
+ next
->lfo
, next
->cb
);
2795 if (prev
&& prev
->iMod
== ent
->iMod
&& prev
->subsection
== sstSrcModule
)
2796 linetab
= codeview_snarf_linetab(msc_dbg
->module
, msc_dbg
->root
+ prev
->lfo
, prev
->cb
);
2798 codeview_snarf(msc_dbg
, msc_dbg
->root
+ ent
->lfo
, sizeof(DWORD
),
2807 case CODEVIEW_NB10_SIG
:
2809 PCODEVIEW_PDB_DATA pdb
= (PCODEVIEW_PDB_DATA
)(cv
+ 1);
2811 codeview_init_basic_types(msc_dbg
->module
);
2812 sym_type
= pdb_process_file(pcs
, msc_dbg
, pdb
->name
, pdb
->timestamp
);
2816 ERR("Unknown CODEVIEW signature %08lX in module %s\n",
2817 cv
->dwSignature
, msc_dbg
->module
->module
.ModuleName
);
2824 /*========================================================================
2825 * Process debug directory.
2827 SYM_TYPE
pe_load_debug_directory(const struct process
* pcs
, struct module
* module
,
2828 const BYTE
* mapping
, PIMAGE_DEBUG_DIRECTORY dbg
,
2833 struct msc_debug_info msc_dbg
;
2834 IMAGE_NT_HEADERS
* nth
= RtlImageNtHeader((void*)mapping
);
2836 msc_dbg
.module
= module
;
2837 msc_dbg
.nsect
= nth
->FileHeader
.NumberOfSections
;
2838 msc_dbg
.sectp
= (PIMAGE_SECTION_HEADER
)((char*)&nth
->OptionalHeader
+ nth
->FileHeader
.SizeOfOptionalHeader
);
2840 msc_dbg
.omapp
= NULL
;
2846 /* First, watch out for OMAP data */
2847 for (i
= 0; i
< nDbg
; i
++)
2849 if (dbg
[i
].Type
== IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
)
2851 msc_dbg
.nomap
= dbg
[i
].SizeOfData
/ sizeof(OMAP_DATA
);
2852 msc_dbg
.omapp
= (OMAP_DATA
*)(mapping
+ dbg
[i
].PointerToRawData
);
2857 /* Now, try to parse CodeView debug info */
2858 for (i
= 0; i
< nDbg
; i
++)
2860 if (dbg
[i
].Type
== IMAGE_DEBUG_TYPE_CODEVIEW
)
2862 msc_dbg
.root
= mapping
+ dbg
[i
].PointerToRawData
;
2863 sym_type
= codeview_process_info(pcs
, &msc_dbg
);
2864 if (sym_type
== SymCv
) goto done
;
2868 /* If not found, try to parse COFF debug info */
2869 for (i
= 0; i
< nDbg
; i
++)
2871 if (dbg
[i
].Type
== IMAGE_DEBUG_TYPE_COFF
)
2873 msc_dbg
.root
= mapping
+ dbg
[i
].PointerToRawData
;
2874 sym_type
= coff_process_info(&msc_dbg
);
2875 if (sym_type
== SymCoff
) goto done
;
2880 /* FIXME: this should be supported... this is the debug information for
2881 * functions compiled without a frame pointer (FPO = frame pointer omission)
2882 * the associated data helps finding out the relevant information
2884 for (i
= 0; i
< nDbg
; i
++)
2885 if (dbg
[i
].Type
== IMAGE_DEBUG_TYPE_FPO
)
2886 DEBUG_Printf("This guy has FPO information\n");
2889 #define FRAME_TRAP 1
2892 typedef struct _FPO_DATA
2894 DWORD ulOffStart
; /* offset 1st byte of function code */
2895 DWORD cbProcSize
; /* # bytes in function */
2896 DWORD cdwLocals
; /* # bytes in locals/4 */
2897 WORD cdwParams
; /* # bytes in params/4 */
2899 WORD cbProlog
: 8; /* # bytes in prolog */
2900 WORD cbRegs
: 3; /* # regs saved */
2901 WORD fHasSEH
: 1; /* TRUE if SEH in func */
2902 WORD fUseBP
: 1; /* TRUE if EBP has been allocated */
2903 WORD reserved
: 1; /* reserved for future use */
2904 WORD cbFrame
: 2; /* frame type */
2910 __EXCEPT(page_fault
)
2912 ERR("Got a page fault while loading symbols\n");