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.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Note - this handles reading debug information for 32 bit applications
23 * that run under Windows-NT for example. I doubt that this would work well
24 * for 16 bit applications, but I don't think it really matters since the
25 * file format is different, and we should never get in here in such cases.
28 * Get 16 bit CV stuff working.
29 * Add symbol size to internal symbol table.
33 #include "wine/port.h"
42 #define PATH_MAX MAX_PATH
44 #include "wine/exception.h"
45 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(winedbg
);
50 WINE_DECLARE_DEBUG_CHANNEL(winedbg_msc
);
52 #define MAX_PATHNAME_LEN 1024
61 typedef struct tagMSC_DBG_INFO
64 PIMAGE_SECTION_HEADER sectp
;
71 /*========================================================================
72 * Debug file access helper routines
75 static WINE_EXCEPTION_FILTER(page_fault
)
77 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
78 return EXCEPTION_EXECUTE_HANDLER
;
79 return EXCEPTION_CONTINUE_SEARCH
;
82 /*========================================================================
83 * Process COFF debug information.
88 unsigned int startaddr
;
93 struct name_hash
**entries
;
100 struct CoffFile
*files
;
105 static const char* DEBUG_GetCoffName( PIMAGE_SYMBOL coff_sym
, const char* coff_strtab
)
107 static char namebuff
[9];
110 if( coff_sym
->N
.Name
.Short
)
112 memcpy(namebuff
, coff_sym
->N
.ShortName
, 8);
114 nampnt
= &namebuff
[0];
118 nampnt
= coff_strtab
+ coff_sym
->N
.Name
.Long
;
121 if( nampnt
[0] == '_' )
126 static int DEBUG_AddCoffFile( struct CoffFileSet
* coff_files
, const char* filename
)
128 struct CoffFile
* file
;
130 if( coff_files
->nfiles
+ 1 >= coff_files
->nfiles_alloc
)
132 coff_files
->nfiles_alloc
+= 10;
133 coff_files
->files
= (struct CoffFile
*) DBG_realloc(coff_files
->files
,
134 coff_files
->nfiles_alloc
* sizeof(struct CoffFile
));
136 file
= coff_files
->files
+ coff_files
->nfiles
;
137 file
->startaddr
= 0xffffffff;
139 file
->filename
= filename
;
140 file
->linetab_offset
= -1;
142 file
->entries
= NULL
;
143 file
->neps
= file
->neps_alloc
= 0;
145 return coff_files
->nfiles
++;
148 static void DEBUG_AddCoffSymbol( struct CoffFile
* coff_file
, struct name_hash
* sym
)
150 if( coff_file
->neps
+ 1 >= coff_file
->neps_alloc
)
152 coff_file
->neps_alloc
+= 10;
153 coff_file
->entries
= (struct name_hash
**)
154 DBG_realloc(coff_file
->entries
,
155 coff_file
->neps_alloc
* sizeof(struct name_hash
*));
157 coff_file
->entries
[coff_file
->neps
++] = sym
;
160 static enum DbgInfoLoad
DEBUG_ProcessCoff( DBG_MODULE
*module
, const BYTE
* root
)
162 PIMAGE_AUX_SYMBOL aux
;
163 PIMAGE_COFF_SYMBOLS_HEADER coff
;
164 PIMAGE_LINENUMBER coff_linetab
;
165 PIMAGE_LINENUMBER linepnt
;
167 PIMAGE_SYMBOL coff_sym
;
168 PIMAGE_SYMBOL coff_symbols
;
169 struct CoffFileSet coff_files
;
170 int curr_file_idx
= -1;
179 enum DbgInfoLoad dil
= DIL_ERROR
;
181 WINE_TRACE("Processing COFF symbols...\n");
183 assert(sizeof(IMAGE_SYMBOL
) == IMAGE_SIZEOF_SYMBOL
);
184 assert(sizeof(IMAGE_LINENUMBER
) == IMAGE_SIZEOF_LINENUMBER
);
186 coff_files
.files
= NULL
;
187 coff_files
.nfiles
= coff_files
.nfiles_alloc
= 0;
189 coff
= (PIMAGE_COFF_SYMBOLS_HEADER
) root
;
191 coff_symbols
= (PIMAGE_SYMBOL
) ((unsigned int) coff
+ coff
->LvaToFirstSymbol
);
192 coff_linetab
= (PIMAGE_LINENUMBER
) ((unsigned int) coff
+ coff
->LvaToFirstLinenumber
);
193 coff_strtab
= (char *) (coff_symbols
+ coff
->NumberOfSymbols
);
197 new_value
.cookie
= DV_TARGET
;
198 new_value
.type
= NULL
;
200 for(i
=0; i
< coff
->NumberOfSymbols
; i
++ )
202 coff_sym
= coff_symbols
+ i
;
203 naux
= coff_sym
->NumberOfAuxSymbols
;
205 if( coff_sym
->StorageClass
== IMAGE_SYM_CLASS_FILE
)
207 curr_file_idx
= DEBUG_AddCoffFile( &coff_files
, (char *) (coff_sym
+ 1) );
208 WINE_TRACE("New file %s\n", coff_files
.files
[curr_file_idx
].filename
);
213 if (curr_file_idx
< 0) {
214 assert(coff_files
.nfiles
== 0 && coff_files
.nfiles_alloc
== 0);
215 curr_file_idx
= DEBUG_AddCoffFile( &coff_files
, "<none>" );
216 WINE_TRACE("New file %s\n", coff_files
.files
[curr_file_idx
].filename
);
220 * This guy marks the size and location of the text section
221 * for the current file. We need to keep track of this so
222 * we can figure out what file the different global functions
225 if( (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_STATIC
)
227 && (coff_sym
->Type
== 0)
228 && (coff_sym
->SectionNumber
== 1) )
230 aux
= (PIMAGE_AUX_SYMBOL
) (coff_sym
+ 1);
232 if( coff_files
.files
[curr_file_idx
].linetab_offset
!= -1 )
235 * Save this so we can still get the old name.
237 const char* fn
= coff_files
.files
[curr_file_idx
].filename
;
239 WINE_TRACE_(winedbg_msc
)(
240 "Duplicating sect from %s: %lx %x %x %d %d\n",
241 coff_files
.files
[curr_file_idx
].filename
,
243 aux
->Section
.NumberOfRelocations
,
244 aux
->Section
.NumberOfLinenumbers
,
246 aux
->Section
.Selection
);
247 WINE_TRACE_(winedbg_msc
)(
248 "More sect %d %s %08lx %d %d %d\n",
249 coff_sym
->SectionNumber
,
250 DEBUG_GetCoffName( coff_sym
, coff_strtab
),
253 coff_sym
->StorageClass
,
254 coff_sym
->NumberOfAuxSymbols
);
257 * Duplicate the file entry. We have no way to describe
258 * multiple text sections in our current way of handling things.
260 DEBUG_AddCoffFile( &coff_files
, fn
);
264 WINE_TRACE_(winedbg_msc
)(
265 "New text sect from %s: %lx %x %x %d %d\n",
266 coff_files
.files
[curr_file_idx
].filename
,
268 aux
->Section
.NumberOfRelocations
,
269 aux
->Section
.NumberOfLinenumbers
,
271 aux
->Section
.Selection
);
274 if( coff_files
.files
[curr_file_idx
].startaddr
> coff_sym
->Value
)
276 coff_files
.files
[curr_file_idx
].startaddr
= coff_sym
->Value
;
279 if( coff_files
.files
[curr_file_idx
].endaddr
< coff_sym
->Value
+ aux
->Section
.Length
)
281 coff_files
.files
[curr_file_idx
].endaddr
= coff_sym
->Value
+ aux
->Section
.Length
;
284 coff_files
.files
[curr_file_idx
].linetab_offset
= linetab_indx
;
285 coff_files
.files
[curr_file_idx
].linecnt
= aux
->Section
.NumberOfLinenumbers
;
286 linetab_indx
+= aux
->Section
.NumberOfLinenumbers
;
291 if( (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_STATIC
)
293 && (coff_sym
->SectionNumber
== 1) )
295 DWORD base
= module
->msc_dbg_info
->sectp
[coff_sym
->SectionNumber
- 1].VirtualAddress
;
297 * This is a normal static function when naux == 0.
298 * Just register it. The current file is the correct
299 * one in this instance.
301 nampnt
= DEBUG_GetCoffName( coff_sym
, coff_strtab
);
303 new_value
.addr
.seg
= 0;
304 new_value
.addr
.off
= (int) ((char *)module
->load_addr
+ base
+ coff_sym
->Value
);
306 WINE_TRACE_(winedbg_msc
)("\tAdding static symbol %s\n", nampnt
);
308 /* FIXME: was adding symbol to this_file ??? */
309 DEBUG_AddCoffSymbol( &coff_files
.files
[curr_file_idx
],
310 DEBUG_AddSymbol( nampnt
, &new_value
,
311 coff_files
.files
[curr_file_idx
].filename
,
312 SYM_WIN32
| SYM_FUNC
) );
317 if( (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_EXTERNAL
)
318 && ISFCN(coff_sym
->Type
)
319 && (coff_sym
->SectionNumber
> 0) )
321 const char* this_file
= NULL
;
322 DWORD base
= module
->msc_dbg_info
->sectp
[coff_sym
->SectionNumber
- 1].VirtualAddress
;
323 nampnt
= DEBUG_GetCoffName( coff_sym
, coff_strtab
);
325 new_value
.addr
.seg
= 0;
326 new_value
.addr
.off
= (int) ((char *)module
->load_addr
+ base
+ coff_sym
->Value
);
328 WINE_TRACE_(winedbg_msc
)("%d: %lx %s\n", i
, new_value
.addr
.off
, nampnt
);
329 WINE_TRACE_(winedbg_msc
)(
330 "\tAdding global symbol %s (sect=%s)\n",
331 nampnt
, module
->msc_dbg_info
->sectp
[coff_sym
->SectionNumber
- 1].Name
);
334 * Now we need to figure out which file this guy belongs to.
336 for(j
=0; j
< coff_files
.nfiles
; j
++)
338 if( coff_files
.files
[j
].startaddr
<= base
+ coff_sym
->Value
339 && coff_files
.files
[j
].endaddr
> base
+ coff_sym
->Value
)
341 this_file
= coff_files
.files
[j
].filename
;
345 if (j
< coff_files
.nfiles
) {
346 DEBUG_AddCoffSymbol( &coff_files
.files
[j
],
347 DEBUG_AddSymbol( nampnt
, &new_value
, this_file
, SYM_WIN32
| SYM_FUNC
) );
349 DEBUG_AddSymbol( nampnt
, &new_value
, NULL
, SYM_WIN32
| SYM_FUNC
);
355 if( (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_EXTERNAL
)
356 && (coff_sym
->SectionNumber
> 0) )
358 DWORD base
= module
->msc_dbg_info
->sectp
[coff_sym
->SectionNumber
- 1].VirtualAddress
;
360 * Similar to above, but for the case of data symbols.
361 * These aren't treated as entrypoints.
363 nampnt
= DEBUG_GetCoffName( coff_sym
, coff_strtab
);
365 new_value
.addr
.seg
= 0;
366 new_value
.addr
.off
= (int) ((char *)module
->load_addr
+ base
+ coff_sym
->Value
);
368 WINE_TRACE_(winedbg_msc
)("%d: %lx %s\n", i
, new_value
.addr
.off
, nampnt
);
369 WINE_TRACE_(winedbg_msc
)("\tAdding global data symbol %s\n", nampnt
);
372 * Now we need to figure out which file this guy belongs to.
374 DEBUG_AddSymbol( nampnt
, &new_value
, NULL
, SYM_WIN32
| SYM_DATA
);
379 if( (coff_sym
->StorageClass
== IMAGE_SYM_CLASS_STATIC
)
383 * Ignore these. They don't have anything to do with
390 WINE_TRACE_(winedbg_msc
)(
391 "Skipping unknown entry '%s' %d %d %d\n",
392 DEBUG_GetCoffName( coff_sym
, coff_strtab
),
393 coff_sym
->StorageClass
, coff_sym
->SectionNumber
, naux
);
396 * For now, skip past the aux entries.
403 * OK, we now should have a list of files, and we should have a list
404 * of entrypoints. We need to sort the entrypoints so that we are
405 * able to tie the line numbers with the given functions within the
408 if( coff_files
.files
!= NULL
)
410 for(j
=0; j
< coff_files
.nfiles
; j
++)
412 if( coff_files
.files
[j
].entries
!= NULL
)
414 qsort(coff_files
.files
[j
].entries
, coff_files
.files
[j
].neps
,
415 sizeof(struct name_hash
*), DEBUG_cmp_sym
);
420 * Now pick apart the line number tables, and attach the entries
421 * to the given functions.
423 for(j
=0; j
< coff_files
.nfiles
; j
++)
426 if( coff_files
.files
[j
].neps
!= 0 )
427 for(k
=0; k
< coff_files
.files
[j
].linecnt
; k
++)
429 linepnt
= coff_linetab
+ coff_files
.files
[j
].linetab_offset
+ k
;
431 * If we have spilled onto the next entrypoint, then
436 if (l
+1 >= coff_files
.files
[j
].neps
) break;
437 DEBUG_GetSymbolAddr(coff_files
.files
[j
].entries
[l
+1], &new_value
.addr
);
438 if( (((unsigned int)module
->load_addr
+
439 linepnt
->Type
.VirtualAddress
) >= new_value
.addr
.off
) )
446 * Add the line number. This is always relative to the
447 * start of the function, so we need to subtract that offset
450 DEBUG_GetSymbolAddr(coff_files
.files
[j
].entries
[l
], &new_value
.addr
);
451 DEBUG_AddLineNumber(coff_files
.files
[j
].entries
[l
],
453 (unsigned int) module
->load_addr
454 + linepnt
->Type
.VirtualAddress
455 - new_value
.addr
.off
);
462 if( coff_files
.files
!= NULL
)
464 for(j
=0; j
< coff_files
.nfiles
; j
++)
466 if( coff_files
.files
[j
].entries
!= NULL
)
468 DBG_free(coff_files
.files
[j
].entries
);
471 DBG_free(coff_files
.files
);
480 /*========================================================================
481 * Process CodeView type information.
488 unsigned short int len
;
494 unsigned short int len
;
498 unsigned char variant
[1];
503 unsigned short int len
;
505 unsigned int datatype
;
506 unsigned int attribute
;
507 unsigned char variant
[1];
512 unsigned short int len
;
515 unsigned char bitoff
;
521 unsigned short int len
;
525 unsigned char bitoff
;
530 unsigned short int len
;
534 unsigned short int arrlen
; /* numeric leaf */
536 unsigned char name
[1];
542 unsigned short int len
;
544 unsigned int elemtype
;
545 unsigned int idxtype
;
546 unsigned short int arrlen
; /* numeric leaf */
548 unsigned char name
[1];
554 unsigned short int len
;
561 unsigned short int structlen
; /* numeric leaf */
563 unsigned char name
[1];
569 unsigned short int len
;
573 unsigned int fieldlist
;
574 unsigned int derived
;
576 unsigned short int structlen
; /* numeric leaf */
578 unsigned char name
[1];
584 unsigned short int len
;
589 unsigned short int un_len
; /* numeric leaf */
591 unsigned char name
[1];
597 unsigned short int len
;
601 unsigned int fieldlist
;
602 unsigned short int un_len
; /* numeric leaf */
604 unsigned char name
[1];
610 unsigned short int len
;
616 unsigned char name
[1];
621 unsigned short int len
;
627 unsigned char name
[1];
632 unsigned short int len
;
634 unsigned char list
[1];
638 union codeview_fieldtype
650 unsigned short int offset
; /* numeric leaf */
658 unsigned short int offset
; /* numeric leaf */
667 unsigned short int vbpoff
; /* numeric leaf */
669 unsigned short int vboff
; /* numeric leaf */
679 unsigned short int vbpoff
; /* numeric leaf */
681 unsigned short int vboff
; /* numeric leaf */
689 unsigned short int value
; /* numeric leaf */
691 unsigned char name
[1];
699 unsigned char name
[1];
707 unsigned char name
[1];
715 unsigned short int offset
; /* numeric leaf */
717 unsigned char name
[1];
726 unsigned short int offset
; /* numeric leaf */
728 unsigned char name
[1];
737 unsigned char name
[1];
745 unsigned char name
[1];
753 unsigned char name
[1];
761 unsigned char name
[1];
768 unsigned char name
[1];
776 unsigned char name
[1];
811 unsigned char name
[1];
818 unsigned int vtab_offset
;
819 unsigned char name
[1];
827 unsigned char name
[1];
834 unsigned int vtab_offset
;
835 unsigned char name
[1];
858 unsigned char name
[1];
866 unsigned char name
[1];
874 unsigned char name
[1];
880 * This covers the basic datatypes that VC++ seems to be using these days.
881 * 32 bit mode only. There are additional numbers for the pointers in 16
882 * bit mode. There are many other types listed in the documents, but these
883 * are apparently not used by the compiler, or represent pointer types
886 #define T_NOTYPE 0x0000 /* Notype */
887 #define T_ABS 0x0001 /* Abs */
888 #define T_VOID 0x0003 /* Void */
889 #define T_CHAR 0x0010 /* signed char */
890 #define T_SHORT 0x0011 /* short */
891 #define T_LONG 0x0012 /* long */
892 #define T_QUAD 0x0013 /* long long */
893 #define T_UCHAR 0x0020 /* unsigned char */
894 #define T_USHORT 0x0021 /* unsigned short */
895 #define T_ULONG 0x0022 /* unsigned long */
896 #define T_UQUAD 0x0023 /* unsigned long long */
897 #define T_REAL32 0x0040 /* float */
898 #define T_REAL64 0x0041 /* double */
899 #define T_RCHAR 0x0070 /* real char */
900 #define T_WCHAR 0x0071 /* wide char */
901 #define T_INT4 0x0074 /* int */
902 #define T_UINT4 0x0075 /* unsigned int */
904 #define T_32PVOID 0x0403 /* 32 bit near pointer to void */
905 #define T_32PCHAR 0x0410 /* 16:32 near pointer to signed char */
906 #define T_32PSHORT 0x0411 /* 16:32 near pointer to short */
907 #define T_32PLONG 0x0412 /* 16:32 near pointer to int */
908 #define T_32PQUAD 0x0413 /* 16:32 near pointer to long long */
909 #define T_32PUCHAR 0x0420 /* 16:32 near pointer to unsigned char */
910 #define T_32PUSHORT 0x0421 /* 16:32 near pointer to unsigned short */
911 #define T_32PULONG 0x0422 /* 16:32 near pointer to unsigned int */
912 #define T_32PUQUAD 0x0423 /* 16:32 near pointer to long long */
913 #define T_32PREAL32 0x0440 /* 16:32 near pointer to float */
914 #define T_32PREAL64 0x0441 /* 16:32 near pointer to float */
915 #define T_32PRCHAR 0x0470 /* 16:32 near pointer to real char */
916 #define T_32PWCHAR 0x0471 /* 16:32 near pointer to real char */
917 #define T_32PINT4 0x0474 /* 16:32 near pointer to int */
918 #define T_32PUINT4 0x0475 /* 16:32 near pointer to unsigned int */
921 #define LF_MODIFIER 0x0001
922 #define LF_POINTER 0x0002
923 #define LF_ARRAY 0x0003
924 #define LF_CLASS 0x0004
925 #define LF_STRUCTURE 0x0005
926 #define LF_UNION 0x0006
927 #define LF_ENUM 0x0007
928 #define LF_PROCEDURE 0x0008
929 #define LF_MFUNCTION 0x0009
930 #define LF_VTSHAPE 0x000a
931 #define LF_COBOL0 0x000b
932 #define LF_COBOL1 0x000c
933 #define LF_BARRAY 0x000d
934 #define LF_LABEL 0x000e
935 #define LF_NULL 0x000f
936 #define LF_NOTTRAN 0x0010
937 #define LF_DIMARRAY 0x0011
938 #define LF_VFTPATH 0x0012
939 #define LF_PRECOMP 0x0013
940 #define LF_ENDPRECOMP 0x0014
941 #define LF_OEM 0x0015
942 #define LF_TYPESERVER 0x0016
944 #define LF_MODIFIER_32 0x1001 /* variants with new 32-bit type indices */
945 #define LF_POINTER_32 0x1002
946 #define LF_ARRAY_32 0x1003
947 #define LF_CLASS_32 0x1004
948 #define LF_STRUCTURE_32 0x1005
949 #define LF_UNION_32 0x1006
950 #define LF_ENUM_32 0x1007
951 #define LF_PROCEDURE_32 0x1008
952 #define LF_MFUNCTION_32 0x1009
953 #define LF_COBOL0_32 0x100a
954 #define LF_BARRAY_32 0x100b
955 #define LF_DIMARRAY_32 0x100c
956 #define LF_VFTPATH_32 0x100d
957 #define LF_PRECOMP_32 0x100e
958 #define LF_OEM_32 0x100f
960 #define LF_SKIP 0x0200
961 #define LF_ARGLIST 0x0201
962 #define LF_DEFARG 0x0202
963 #define LF_LIST 0x0203
964 #define LF_FIELDLIST 0x0204
965 #define LF_DERIVED 0x0205
966 #define LF_BITFIELD 0x0206
967 #define LF_METHODLIST 0x0207
968 #define LF_DIMCONU 0x0208
969 #define LF_DIMCONLU 0x0209
970 #define LF_DIMVARU 0x020a
971 #define LF_DIMVARLU 0x020b
972 #define LF_REFSYM 0x020c
974 #define LF_SKIP_32 0x1200 /* variants with new 32-bit type indices */
975 #define LF_ARGLIST_32 0x1201
976 #define LF_DEFARG_32 0x1202
977 #define LF_FIELDLIST_32 0x1203
978 #define LF_DERIVED_32 0x1204
979 #define LF_BITFIELD_32 0x1205
980 #define LF_METHODLIST_32 0x1206
981 #define LF_DIMCONU_32 0x1207
982 #define LF_DIMCONLU_32 0x1208
983 #define LF_DIMVARU_32 0x1209
984 #define LF_DIMVARLU_32 0x120a
986 #define LF_BCLASS 0x0400
987 #define LF_VBCLASS 0x0401
988 #define LF_IVBCLASS 0x0402
989 #define LF_ENUMERATE 0x0403
990 #define LF_FRIENDFCN 0x0404
991 #define LF_INDEX 0x0405
992 #define LF_MEMBER 0x0406
993 #define LF_STMEMBER 0x0407
994 #define LF_METHOD 0x0408
995 #define LF_NESTTYPE 0x0409
996 #define LF_VFUNCTAB 0x040a
997 #define LF_FRIENDCLS 0x040b
998 #define LF_ONEMETHOD 0x040c
999 #define LF_VFUNCOFF 0x040d
1000 #define LF_NESTTYPEEX 0x040e
1001 #define LF_MEMBERMODIFY 0x040f
1003 #define LF_BCLASS_32 0x1400 /* variants with new 32-bit type indices */
1004 #define LF_VBCLASS_32 0x1401
1005 #define LF_IVBCLASS_32 0x1402
1006 #define LF_FRIENDFCN_32 0x1403
1007 #define LF_INDEX_32 0x1404
1008 #define LF_MEMBER_32 0x1405
1009 #define LF_STMEMBER_32 0x1406
1010 #define LF_METHOD_32 0x1407
1011 #define LF_NESTTYPE_32 0x1408
1012 #define LF_VFUNCTAB_32 0x1409
1013 #define LF_FRIENDCLS_32 0x140a
1014 #define LF_ONEMETHOD_32 0x140b
1015 #define LF_VFUNCOFF_32 0x140c
1016 #define LF_NESTTYPEEX_32 0x140d
1018 #define LF_NUMERIC 0x8000 /* numeric leaf types */
1019 #define LF_CHAR 0x8000
1020 #define LF_SHORT 0x8001
1021 #define LF_USHORT 0x8002
1022 #define LF_LONG 0x8003
1023 #define LF_ULONG 0x8004
1024 #define LF_REAL32 0x8005
1025 #define LF_REAL64 0x8006
1026 #define LF_REAL80 0x8007
1027 #define LF_REAL128 0x8008
1028 #define LF_QUADWORD 0x8009
1029 #define LF_UQUADWORD 0x800a
1030 #define LF_REAL48 0x800b
1031 #define LF_COMPLEX32 0x800c
1032 #define LF_COMPLEX64 0x800d
1033 #define LF_COMPLEX80 0x800e
1034 #define LF_COMPLEX128 0x800f
1035 #define LF_VARSTRING 0x8010
1039 #define MAX_BUILTIN_TYPES 0x480
1040 static struct datatype
* cv_basic_types
[MAX_BUILTIN_TYPES
];
1041 static unsigned int num_cv_defined_types
= 0;
1042 static struct datatype
**cv_defined_types
= NULL
;
1045 DEBUG_InitCVDataTypes(void)
1048 * These are the common builtin types that are used by VC++.
1050 cv_basic_types
[T_NOTYPE
] = NULL
;
1051 cv_basic_types
[T_ABS
] = NULL
;
1052 cv_basic_types
[T_VOID
] = DEBUG_GetBasicType(DT_BASIC_VOID
);
1053 cv_basic_types
[T_CHAR
] = DEBUG_GetBasicType(DT_BASIC_CHAR
);
1054 cv_basic_types
[T_SHORT
] = DEBUG_GetBasicType(DT_BASIC_SHORTINT
);
1055 cv_basic_types
[T_LONG
] = DEBUG_GetBasicType(DT_BASIC_LONGINT
);
1056 cv_basic_types
[T_QUAD
] = DEBUG_GetBasicType(DT_BASIC_LONGLONGINT
);
1057 cv_basic_types
[T_UCHAR
] = DEBUG_GetBasicType(DT_BASIC_UCHAR
);
1058 cv_basic_types
[T_USHORT
] = DEBUG_GetBasicType(DT_BASIC_USHORTINT
);
1059 cv_basic_types
[T_ULONG
] = DEBUG_GetBasicType(DT_BASIC_ULONGINT
);
1060 cv_basic_types
[T_UQUAD
] = DEBUG_GetBasicType(DT_BASIC_ULONGLONGINT
);
1061 cv_basic_types
[T_REAL32
] = DEBUG_GetBasicType(DT_BASIC_FLOAT
);
1062 cv_basic_types
[T_REAL64
] = DEBUG_GetBasicType(DT_BASIC_DOUBLE
);
1063 cv_basic_types
[T_RCHAR
] = DEBUG_GetBasicType(DT_BASIC_CHAR
);
1064 cv_basic_types
[T_WCHAR
] = DEBUG_GetBasicType(DT_BASIC_SHORTINT
);
1065 cv_basic_types
[T_INT4
] = DEBUG_GetBasicType(DT_BASIC_INT
);
1066 cv_basic_types
[T_UINT4
] = DEBUG_GetBasicType(DT_BASIC_UINT
);
1068 cv_basic_types
[T_32PVOID
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_VOID
]);
1069 cv_basic_types
[T_32PCHAR
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_CHAR
]);
1070 cv_basic_types
[T_32PSHORT
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_SHORT
]);
1071 cv_basic_types
[T_32PLONG
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_LONG
]);
1072 cv_basic_types
[T_32PQUAD
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_QUAD
]);
1073 cv_basic_types
[T_32PUCHAR
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_UCHAR
]);
1074 cv_basic_types
[T_32PUSHORT
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_USHORT
]);
1075 cv_basic_types
[T_32PULONG
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_ULONG
]);
1076 cv_basic_types
[T_32PUQUAD
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_UQUAD
]);
1077 cv_basic_types
[T_32PREAL32
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_REAL32
]);
1078 cv_basic_types
[T_32PREAL64
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_REAL64
]);
1079 cv_basic_types
[T_32PRCHAR
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_RCHAR
]);
1080 cv_basic_types
[T_32PWCHAR
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_WCHAR
]);
1081 cv_basic_types
[T_32PINT4
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_INT4
]);
1082 cv_basic_types
[T_32PUINT4
] = DEBUG_FindOrMakePointerType(cv_basic_types
[T_UINT4
]);
1087 numeric_leaf( int *value
, unsigned short int *leaf
)
1089 unsigned short int type
= *leaf
++;
1092 if ( type
< LF_NUMERIC
)
1102 *value
= *(char *)leaf
;
1107 *value
= *(short *)leaf
;
1112 *value
= *(unsigned short *)leaf
;
1117 *value
= *(int *)leaf
;
1122 *value
= *(unsigned int *)leaf
;
1128 *value
= 0; /* FIXME */
1133 *value
= 0; /* FIXME */
1138 *value
= 0; /* FIXME */
1143 *value
= 0; /* FIXME */
1148 *value
= 0; /* FIXME */
1153 *value
= 0; /* FIXME */
1158 *value
= 0; /* FIXME */
1163 *value
= 0; /* FIXME */
1168 *value
= 0; /* FIXME */
1173 *value
= 0; /* FIXME */
1177 length
+= 2 + *leaf
;
1178 *value
= 0; /* FIXME */
1182 DEBUG_Printf("Unknown numeric leaf type %04x\n", type
);
1192 terminate_string( unsigned char *name
)
1194 static char symname
[256];
1196 int namelen
= name
[0];
1197 assert( namelen
>= 0 && namelen
< 256 );
1199 memcpy( symname
, name
+1, namelen
);
1200 symname
[namelen
] = '\0';
1202 if ( !*symname
|| strcmp( symname
, "__unnamed" ) == 0 )
1209 struct datatype
* DEBUG_GetCVType(unsigned int typeno
)
1211 struct datatype
* dt
= NULL
;
1214 * Convert Codeview type numbers into something we can grok internally.
1215 * Numbers < 0x1000 are all fixed builtin types. Numbers from 0x1000 and
1216 * up are all user defined (structs, etc).
1218 if ( typeno
< 0x1000 )
1220 if ( typeno
< MAX_BUILTIN_TYPES
)
1221 dt
= cv_basic_types
[typeno
];
1225 if ( typeno
- 0x1000 < num_cv_defined_types
)
1226 dt
= cv_defined_types
[typeno
- 0x1000];
1233 DEBUG_AddCVType( unsigned int typeno
, struct datatype
*dt
)
1235 while ( typeno
- 0x1000 >= num_cv_defined_types
)
1237 num_cv_defined_types
+= 0x100;
1238 cv_defined_types
= (struct datatype
**)
1239 DBG_realloc( cv_defined_types
,
1240 num_cv_defined_types
* sizeof(struct datatype
*) );
1242 memset( cv_defined_types
+ num_cv_defined_types
- 0x100,
1244 0x100 * sizeof(struct datatype
*) );
1246 if ( cv_defined_types
== NULL
)
1250 cv_defined_types
[ typeno
- 0x1000 ] = dt
;
1255 DEBUG_ClearTypeTable( void )
1257 if ( cv_defined_types
)
1258 DBG_free( cv_defined_types
);
1260 cv_defined_types
= NULL
;
1261 num_cv_defined_types
= 0;
1265 DEBUG_AddCVType_Pointer( unsigned int typeno
, unsigned int datatype
)
1267 struct datatype
*dt
=
1268 DEBUG_FindOrMakePointerType( DEBUG_GetCVType( datatype
) );
1270 return DEBUG_AddCVType( typeno
, dt
);
1274 DEBUG_AddCVType_Array( unsigned int typeno
, char *name
,
1275 unsigned int elemtype
, unsigned int arr_len
)
1277 struct datatype
*dt
= DEBUG_NewDataType( DT_ARRAY
, name
);
1278 struct datatype
*elem
= DEBUG_GetCVType( elemtype
);
1279 unsigned int elem_size
= elem
? DEBUG_GetObjectSize( elem
) : 0;
1280 unsigned int arr_max
= elem_size
? arr_len
/ elem_size
: 0;
1282 DEBUG_SetArrayParams( dt
, 0, arr_max
, elem
);
1283 return DEBUG_AddCVType( typeno
, dt
);
1287 DEBUG_AddCVType_Bitfield( unsigned int typeno
,
1288 unsigned int bitoff
, unsigned int nbits
,
1289 unsigned int basetype
)
1291 struct datatype
*dt
= DEBUG_NewDataType( DT_BITFIELD
, NULL
);
1292 struct datatype
*base
= DEBUG_GetCVType( basetype
);
1294 DEBUG_SetBitfieldParams( dt
, bitoff
, nbits
, base
);
1295 return DEBUG_AddCVType( typeno
, dt
);
1299 DEBUG_AddCVType_EnumFieldList( unsigned int typeno
, unsigned char *list
, int len
)
1301 struct datatype
*dt
= DEBUG_NewDataType( DT_ENUM
, NULL
);
1302 unsigned char *ptr
= list
;
1304 while ( ptr
- list
< len
)
1306 union codeview_fieldtype
*type
= (union codeview_fieldtype
*)ptr
;
1308 if ( *ptr
>= 0xf0 ) /* LF_PAD... */
1314 switch ( type
->generic
.id
)
1318 int value
, vlen
= numeric_leaf( &value
, &type
->enumerate
.value
);
1319 unsigned char *name
= (unsigned char *)&type
->enumerate
.value
+ vlen
;
1321 DEBUG_AddStructElement( dt
, terminate_string( name
),
1324 ptr
+= 2 + 2 + vlen
+ (1 + name
[0]);
1329 DEBUG_Printf("Unhandled type %04x in ENUM field list\n",
1335 return DEBUG_AddCVType( typeno
, dt
);
1339 DEBUG_AddCVType_StructFieldList( unsigned int typeno
, unsigned char *list
, int len
)
1341 struct datatype
*dt
= DEBUG_NewDataType( DT_STRUCT
, NULL
);
1342 unsigned char *ptr
= list
;
1344 while ( ptr
- list
< len
)
1346 union codeview_fieldtype
*type
= (union codeview_fieldtype
*)ptr
;
1348 if ( *ptr
>= 0xf0 ) /* LF_PAD... */
1354 switch ( type
->generic
.id
)
1358 int offset
, olen
= numeric_leaf( &offset
, &type
->bclass
.offset
);
1360 /* FIXME: ignored for now */
1362 ptr
+= 2 + 2 + 2 + olen
;
1368 int offset
, olen
= numeric_leaf( &offset
, &type
->bclass32
.offset
);
1370 /* FIXME: ignored for now */
1372 ptr
+= 2 + 2 + 4 + olen
;
1379 int vbpoff
, vbplen
= numeric_leaf( &vbpoff
, &type
->vbclass
.vbpoff
);
1380 unsigned short int *p_vboff
= (unsigned short int *)((char *)&type
->vbclass
.vbpoff
+ vbpoff
);
1381 int vpoff
, vplen
= numeric_leaf( &vpoff
, p_vboff
);
1383 /* FIXME: ignored for now */
1385 ptr
+= 2 + 2 + 2 + 2 + vbplen
+ vplen
;
1390 case LF_IVBCLASS_32
:
1392 int vbpoff
, vbplen
= numeric_leaf( &vbpoff
, &type
->vbclass32
.vbpoff
);
1393 unsigned short int *p_vboff
= (unsigned short int *)((char *)&type
->vbclass32
.vbpoff
+ vbpoff
);
1394 int vpoff
, vplen
= numeric_leaf( &vpoff
, p_vboff
);
1396 /* FIXME: ignored for now */
1398 ptr
+= 2 + 2 + 4 + 4 + vbplen
+ vplen
;
1404 int offset
, olen
= numeric_leaf( &offset
, &type
->member
.offset
);
1405 unsigned char *name
= (unsigned char *)&type
->member
.offset
+ olen
;
1407 struct datatype
*subtype
= DEBUG_GetCVType( type
->member
.type
);
1408 int elem_size
= subtype
? DEBUG_GetObjectSize( subtype
) : 0;
1410 DEBUG_AddStructElement( dt
, terminate_string( name
),
1411 subtype
, offset
<< 3, elem_size
<< 3 );
1413 ptr
+= 2 + 2 + 2 + olen
+ (1 + name
[0]);
1419 int offset
, olen
= numeric_leaf( &offset
, &type
->member32
.offset
);
1420 unsigned char *name
= (unsigned char *)&type
->member32
.offset
+ olen
;
1422 struct datatype
*subtype
= DEBUG_GetCVType( type
->member32
.type
);
1423 int elem_size
= subtype
? DEBUG_GetObjectSize( subtype
) : 0;
1425 DEBUG_AddStructElement( dt
, terminate_string( name
),
1426 subtype
, offset
<< 3, elem_size
<< 3 );
1428 ptr
+= 2 + 2 + 4 + olen
+ (1 + name
[0]);
1433 /* FIXME: ignored for now */
1434 ptr
+= 2 + 2 + 2 + (1 + type
->stmember
.name
[0]);
1437 case LF_STMEMBER_32
:
1438 /* FIXME: ignored for now */
1439 ptr
+= 2 + 4 + 2 + (1 + type
->stmember32
.name
[0]);
1443 /* FIXME: ignored for now */
1444 ptr
+= 2 + 2 + 2 + (1 + type
->method
.name
[0]);
1448 /* FIXME: ignored for now */
1449 ptr
+= 2 + 2 + 4 + (1 + type
->method32
.name
[0]);
1453 /* FIXME: ignored for now */
1454 ptr
+= 2 + 2 + (1 + type
->nesttype
.name
[0]);
1457 case LF_NESTTYPE_32
:
1458 /* FIXME: ignored for now */
1459 ptr
+= 2 + 2 + 4 + (1 + type
->nesttype32
.name
[0]);
1463 /* FIXME: ignored for now */
1467 case LF_VFUNCTAB_32
:
1468 /* FIXME: ignored for now */
1473 /* FIXME: ignored for now */
1474 switch ( (type
->onemethod
.attribute
>> 2) & 7 )
1476 case 4: case 6: /* (pure) introducing virtual method */
1477 ptr
+= 2 + 2 + 2 + 4 + (1 + type
->onemethod_virt
.name
[0]);
1481 ptr
+= 2 + 2 + 2 + (1 + type
->onemethod
.name
[0]);
1486 case LF_ONEMETHOD_32
:
1487 /* FIXME: ignored for now */
1488 switch ( (type
->onemethod32
.attribute
>> 2) & 7 )
1490 case 4: case 6: /* (pure) introducing virtual method */
1491 ptr
+= 2 + 2 + 4 + 4 + (1 + type
->onemethod32_virt
.name
[0]);
1495 ptr
+= 2 + 2 + 4 + (1 + type
->onemethod32
.name
[0]);
1501 DEBUG_Printf("Unhandled type %04x in STRUCT field list\n",
1507 return DEBUG_AddCVType( typeno
, dt
);
1511 DEBUG_AddCVType_Enum( unsigned int typeno
, char *name
, unsigned int fieldlist
)
1513 struct datatype
*dt
= DEBUG_NewDataType( DT_ENUM
, name
);
1514 struct datatype
*list
= DEBUG_GetCVType( fieldlist
);
1517 if(DEBUG_CopyFieldlist( dt
, list
) == FALSE
)
1520 return DEBUG_AddCVType( typeno
, dt
);
1524 DEBUG_AddCVType_Struct( unsigned int typeno
, char *name
, int structlen
, unsigned int fieldlist
)
1526 struct datatype
*dt
= DEBUG_NewDataType( DT_STRUCT
, name
);
1527 struct datatype
*list
= DEBUG_GetCVType( fieldlist
);
1531 DEBUG_SetStructSize( dt
, structlen
);
1532 if(DEBUG_CopyFieldlist( dt
, list
) == FALSE
)
1536 return DEBUG_AddCVType( typeno
, dt
);
1540 DEBUG_ParseTypeTable( char *table
, int len
)
1542 unsigned int curr_type
= 0x1000;
1545 while ( ptr
- table
< len
)
1547 union codeview_type
*type
= (union codeview_type
*) ptr
;
1550 switch ( type
->generic
.id
)
1553 retv
= DEBUG_AddCVType_Pointer( curr_type
, type
->pointer
.datatype
);
1556 retv
= DEBUG_AddCVType_Pointer( curr_type
, type
->pointer32
.datatype
);
1561 int arrlen
, alen
= numeric_leaf( &arrlen
, &type
->array
.arrlen
);
1562 unsigned char *name
= (unsigned char *)&type
->array
.arrlen
+ alen
;
1564 retv
= DEBUG_AddCVType_Array( curr_type
, terminate_string( name
),
1565 type
->array
.elemtype
, arrlen
);
1570 int arrlen
, alen
= numeric_leaf( &arrlen
, &type
->array32
.arrlen
);
1571 unsigned char *name
= (unsigned char *)&type
->array32
.arrlen
+ alen
;
1573 retv
= DEBUG_AddCVType_Array( curr_type
, terminate_string( name
),
1574 type
->array32
.elemtype
, type
->array32
.arrlen
);
1579 retv
= DEBUG_AddCVType_Bitfield( curr_type
, type
->bitfield
.bitoff
,
1580 type
->bitfield
.nbits
,
1581 type
->bitfield
.type
);
1583 case LF_BITFIELD_32
:
1584 retv
= DEBUG_AddCVType_Bitfield( curr_type
, type
->bitfield32
.bitoff
,
1585 type
->bitfield32
.nbits
,
1586 type
->bitfield32
.type
);
1590 case LF_FIELDLIST_32
:
1593 * A 'field list' is a CodeView-specific data type which doesn't
1594 * directly correspond to any high-level data type. It is used
1595 * to hold the collection of members of a struct, class, union
1596 * or enum type. The actual definition of that type will follow
1597 * later, and refer to the field list definition record.
1599 * As we don't have a field list type ourselves, we look ahead
1600 * in the field list to try to find out whether this field list
1601 * will be used for an enum or struct type, and create a dummy
1602 * type of the corresponding sort. Later on, the definition of
1603 * the 'real' type will copy the member / enumeration data.
1606 char *list
= type
->fieldlist
.list
;
1607 int len
= (ptr
+ type
->generic
.len
+ 2) - list
;
1609 if ( ((union codeview_fieldtype
*)list
)->generic
.id
== LF_ENUMERATE
)
1610 retv
= DEBUG_AddCVType_EnumFieldList( curr_type
, list
, len
);
1612 retv
= DEBUG_AddCVType_StructFieldList( curr_type
, list
, len
);
1619 int structlen
, slen
= numeric_leaf( &structlen
, &type
->structure
.structlen
);
1620 unsigned char *name
= (unsigned char *)&type
->structure
.structlen
+ slen
;
1622 retv
= DEBUG_AddCVType_Struct( curr_type
, terminate_string( name
),
1623 structlen
, type
->structure
.fieldlist
);
1626 case LF_STRUCTURE_32
:
1629 int structlen
, slen
= numeric_leaf( &structlen
, &type
->structure32
.structlen
);
1630 unsigned char *name
= (unsigned char *)&type
->structure32
.structlen
+ slen
;
1632 retv
= DEBUG_AddCVType_Struct( curr_type
, terminate_string( name
),
1633 structlen
, type
->structure32
.fieldlist
);
1639 int un_len
, ulen
= numeric_leaf( &un_len
, &type
->t_union
.un_len
);
1640 unsigned char *name
= (unsigned char *)&type
->t_union
.un_len
+ ulen
;
1642 retv
= DEBUG_AddCVType_Struct( curr_type
, terminate_string( name
),
1643 un_len
, type
->t_union
.fieldlist
);
1648 int un_len
, ulen
= numeric_leaf( &un_len
, &type
->t_union32
.un_len
);
1649 unsigned char *name
= (unsigned char *)&type
->t_union32
.un_len
+ ulen
;
1651 retv
= DEBUG_AddCVType_Struct( curr_type
, terminate_string( name
),
1652 un_len
, type
->t_union32
.fieldlist
);
1657 retv
= DEBUG_AddCVType_Enum( curr_type
, terminate_string( type
->enumeration
.name
),
1658 type
->enumeration
.field
);
1661 retv
= DEBUG_AddCVType_Enum( curr_type
, terminate_string( type
->enumeration32
.name
),
1662 type
->enumeration32
.field
);
1673 ptr
+= type
->generic
.len
+ 2;
1680 /*========================================================================
1681 * Process CodeView line number information.
1689 const unsigned int* ui
;
1698 struct codeview_linetab_hdr
1704 const char * sourcefile
;
1705 const unsigned short * linetab
;
1706 const unsigned int * offtab
;
1709 static struct codeview_linetab_hdr
*
1710 DEBUG_SnarfLinetab(const char * linetab
,
1714 char filename
[PATH_MAX
];
1715 const unsigned int * filetab
;
1719 struct codeview_linetab_hdr
* lt_hdr
;
1720 unsigned int * lt_ptr
;
1724 union any_size pnt2
;
1725 struct startend
* start
;
1729 * Now get the important bits.
1735 filetab
= (const unsigned int *) pnt
.c
;
1738 * Now count up the number of segments in the file.
1741 for(i
=0; i
<nfile
; i
++)
1743 pnt2
.c
= linetab
+ filetab
[i
];
1748 * Next allocate the header we will be returning.
1749 * There is one header for each segment, so that we can reach in
1750 * and pull bits as required.
1752 lt_hdr
= (struct codeview_linetab_hdr
*)
1753 DBG_alloc((nseg
+ 1) * sizeof(*lt_hdr
));
1754 if( lt_hdr
== NULL
)
1759 memset(lt_hdr
, 0, sizeof(*lt_hdr
) * (nseg
+1));
1762 * Now fill the header we will be returning, one for each segment.
1763 * Note that this will basically just contain pointers into the existing
1764 * line table, and we do not actually copy any additional information
1765 * or allocate any additional memory.
1769 for(i
=0; i
<nfile
; i
++)
1772 * Get the pointer into the segment information.
1774 pnt2
.c
= linetab
+ filetab
[i
];
1775 file_segcount
= *pnt2
.s
;
1778 lt_ptr
= (unsigned int *) pnt2
.c
;
1779 start
= (struct startend
*) (lt_ptr
+ file_segcount
);
1782 * Now snarf the filename for all of the segments for this file.
1784 fn
= (unsigned char *) (start
+ file_segcount
);
1785 memset(filename
, 0, sizeof(filename
));
1786 memcpy(filename
, fn
+ 1, *fn
);
1787 fn
= DBG_strdup(filename
);
1789 for(k
= 0; k
< file_segcount
; k
++, this_seg
++)
1791 pnt2
.c
= linetab
+ lt_ptr
[k
];
1792 lt_hdr
[this_seg
].start
= start
[k
].start
;
1793 lt_hdr
[this_seg
].end
= start
[k
].end
;
1794 lt_hdr
[this_seg
].sourcefile
= fn
;
1795 lt_hdr
[this_seg
].segno
= *pnt2
.s
++;
1796 lt_hdr
[this_seg
].nline
= *pnt2
.s
++;
1797 lt_hdr
[this_seg
].offtab
= pnt2
.ui
;
1798 lt_hdr
[this_seg
].linetab
= (unsigned short *)
1799 (pnt2
.ui
+ lt_hdr
[this_seg
].nline
);
1810 /*========================================================================
1811 * Process CodeView symbol information.
1814 union codeview_symbol
1826 unsigned int offset
;
1828 unsigned short symtype
;
1829 unsigned char namelen
;
1830 unsigned char name
[1];
1837 unsigned int symtype
;
1838 unsigned int offset
;
1840 unsigned char namelen
;
1841 unsigned char name
[1];
1848 unsigned int pparent
;
1851 unsigned int offset
;
1852 unsigned short segment
;
1853 unsigned short thunk_len
;
1854 unsigned char thtype
;
1855 unsigned char namelen
;
1856 unsigned char name
[1];
1863 unsigned int pparent
;
1866 unsigned int proc_len
;
1867 unsigned int debug_start
;
1868 unsigned int debug_end
;
1869 unsigned int offset
;
1870 unsigned short segment
;
1871 unsigned short proctype
;
1872 unsigned char flags
;
1873 unsigned char namelen
;
1874 unsigned char name
[1];
1881 unsigned int pparent
;
1884 unsigned int proc_len
;
1885 unsigned int debug_start
;
1886 unsigned int debug_end
;
1887 unsigned int proctype
;
1888 unsigned int offset
;
1889 unsigned short segment
;
1890 unsigned char flags
;
1891 unsigned char namelen
;
1892 unsigned char name
[1];
1897 short int len
; /* Total length of this entry */
1898 short int id
; /* Always S_BPREL32 */
1899 unsigned int offset
; /* Stack offset relative to BP */
1900 unsigned short symtype
;
1901 unsigned char namelen
;
1902 unsigned char name
[1];
1907 short int len
; /* Total length of this entry */
1908 short int id
; /* Always S_BPREL32 */
1909 unsigned int offset
; /* Stack offset relative to BP */
1910 unsigned int symtype
;
1911 unsigned char namelen
;
1912 unsigned char name
[1];
1917 #define S_COMPILE 0x0001
1918 #define S_REGISTER 0x0002
1919 #define S_CONSTANT 0x0003
1920 #define S_UDT 0x0004
1921 #define S_SSEARCH 0x0005
1922 #define S_END 0x0006
1923 #define S_SKIP 0x0007
1924 #define S_CVRESERVE 0x0008
1925 #define S_OBJNAME 0x0009
1926 #define S_ENDARG 0x000a
1927 #define S_COBOLUDT 0x000b
1928 #define S_MANYREG 0x000c
1929 #define S_RETURN 0x000d
1930 #define S_ENTRYTHIS 0x000e
1932 #define S_BPREL 0x0200
1933 #define S_LDATA 0x0201
1934 #define S_GDATA 0x0202
1935 #define S_PUB 0x0203
1936 #define S_LPROC 0x0204
1937 #define S_GPROC 0x0205
1938 #define S_THUNK 0x0206
1939 #define S_BLOCK 0x0207
1940 #define S_WITH 0x0208
1941 #define S_LABEL 0x0209
1942 #define S_CEXMODEL 0x020a
1943 #define S_VFTPATH 0x020b
1944 #define S_REGREL 0x020c
1945 #define S_LTHREAD 0x020d
1946 #define S_GTHREAD 0x020e
1948 #define S_PROCREF 0x0400
1949 #define S_DATAREF 0x0401
1950 #define S_ALIGN 0x0402
1951 #define S_LPROCREF 0x0403
1953 #define S_REGISTER_32 0x1001 /* Variants with new 32-bit type indices */
1954 #define S_CONSTANT_32 0x1002
1955 #define S_UDT_32 0x1003
1956 #define S_COBOLUDT_32 0x1004
1957 #define S_MANYREG_32 0x1005
1959 #define S_BPREL_32 0x1006
1960 #define S_LDATA_32 0x1007
1961 #define S_GDATA_32 0x1008
1962 #define S_PUB_32 0x1009
1963 #define S_LPROC_32 0x100a
1964 #define S_GPROC_32 0x100b
1965 #define S_VFTTABLE_32 0x100c
1966 #define S_REGREL_32 0x100d
1967 #define S_LTHREAD_32 0x100e
1968 #define S_GTHREAD_32 0x100f
1973 DEBUG_MapCVOffset( DBG_MODULE
*module
, unsigned int offset
)
1975 int nomap
= module
->msc_dbg_info
->nomap
;
1976 OMAP_DATA
*omapp
= module
->msc_dbg_info
->omapp
;
1979 if ( !nomap
|| !omapp
)
1982 /* FIXME: use binary search */
1983 for ( i
= 0; i
< nomap
-1; i
++ )
1984 if ( omapp
[i
].from
<= offset
&& omapp
[i
+1].from
> offset
)
1985 return !omapp
[i
].to
? 0 : omapp
[i
].to
+ (offset
- omapp
[i
].from
);
1990 static struct name_hash
*
1991 DEBUG_AddCVSymbol( DBG_MODULE
*module
, char *name
, int namelen
,
1992 int type
, unsigned int seg
, unsigned int offset
,
1993 int size
, int cookie
, int flags
,
1994 struct codeview_linetab_hdr
*linetab
)
1996 int nsect
= module
->msc_dbg_info
->nsect
;
1997 PIMAGE_SECTION_HEADER sectp
= module
->msc_dbg_info
->sectp
;
1999 struct name_hash
*symbol
;
2000 char symname
[PATH_MAX
];
2004 * Some sanity checks
2007 if ( !name
|| !namelen
)
2010 if ( !seg
|| seg
> nsect
)
2014 * Convert type, address, and symbol name
2016 value
.type
= type
? DEBUG_GetCVType( type
) : NULL
;
2017 value
.cookie
= cookie
;
2020 value
.addr
.off
= (unsigned int) module
->load_addr
+
2021 DEBUG_MapCVOffset( module
, sectp
[seg
-1].VirtualAddress
+ offset
);
2023 memcpy( symname
, name
, namelen
);
2024 symname
[namelen
] = '\0';
2028 * Check whether we have line number information
2032 for ( ; linetab
->linetab
; linetab
++ )
2033 if ( linetab
->segno
== seg
2034 && linetab
->start
<= offset
2035 && linetab
->end
> offset
)
2038 if ( !linetab
->linetab
)
2044 * Create Wine symbol record
2046 symbol
= DEBUG_AddSymbol( symname
, &value
,
2047 linetab
? linetab
->sourcefile
: NULL
, flags
);
2050 DEBUG_SetSymbolSize( symbol
, size
);
2054 * Add line numbers if found
2059 for ( i
= 0; i
< linetab
->nline
; i
++ )
2060 if ( linetab
->offtab
[i
] >= offset
2061 && linetab
->offtab
[i
] < offset
+ size
)
2063 DEBUG_AddLineNumber( symbol
, linetab
->linetab
[i
],
2064 linetab
->offtab
[i
] - offset
);
2071 static struct wine_locals
*
2072 DEBUG_AddCVLocal( struct name_hash
*func
, char *name
, int namelen
,
2073 int type
, int offset
)
2075 struct wine_locals
*local
;
2076 char symname
[PATH_MAX
];
2078 memcpy( symname
, name
, namelen
);
2079 symname
[namelen
] = '\0';
2081 local
= DEBUG_AddLocal( func
, 0, offset
, 0, 0, symname
);
2082 DEBUG_SetLocalSymbolType( local
, DEBUG_GetCVType( type
) );
2088 DEBUG_SnarfCodeView( DBG_MODULE
*module
, const BYTE
* root
, int offset
, int size
,
2089 struct codeview_linetab_hdr
*linetab
)
2091 struct name_hash
*curr_func
= NULL
;
2096 * Loop over the different types of records and whenever we
2097 * find something we are interested in, record it and move on.
2099 for ( i
= offset
; i
< size
; i
+= length
)
2101 union codeview_symbol
*sym
= (union codeview_symbol
*)(root
+ i
);
2102 length
= sym
->generic
.len
+ 2;
2104 switch ( sym
->generic
.id
)
2107 * Global and local data symbols. We don't associate these
2108 * with any given source file.
2113 DEBUG_AddCVSymbol( module
, sym
->data
.name
, sym
->data
.namelen
,
2114 sym
->data
.symtype
, sym
->data
.seg
,
2115 sym
->data
.offset
, 0,
2116 DV_TARGET
, SYM_WIN32
| SYM_DATA
, NULL
);
2121 DEBUG_AddCVSymbol( module
, sym
->data32
.name
, sym
->data32
.namelen
,
2122 sym
->data32
.symtype
, sym
->data32
.seg
,
2123 sym
->data32
.offset
, 0,
2124 DV_TARGET
, SYM_WIN32
| SYM_DATA
, NULL
);
2128 * Sort of like a global function, but it just points
2129 * to a thunk, which is a stupid name for what amounts to
2130 * a PLT slot in the normal jargon that everyone else uses.
2133 DEBUG_AddCVSymbol( module
, sym
->thunk
.name
, sym
->thunk
.namelen
,
2134 0, sym
->thunk
.segment
,
2135 sym
->thunk
.offset
, sym
->thunk
.thunk_len
,
2136 DV_TARGET
, SYM_WIN32
| SYM_FUNC
, NULL
);
2140 * Global and static functions.
2144 DEBUG_Normalize( curr_func
);
2146 curr_func
= DEBUG_AddCVSymbol( module
, sym
->proc
.name
, sym
->proc
.namelen
,
2147 sym
->proc
.proctype
, sym
->proc
.segment
,
2148 sym
->proc
.offset
, sym
->proc
.proc_len
,
2149 DV_TARGET
, SYM_WIN32
| SYM_FUNC
, linetab
);
2151 DEBUG_SetSymbolBPOff( curr_func
, sym
->proc
.debug_start
);
2155 DEBUG_Normalize( curr_func
);
2157 curr_func
= DEBUG_AddCVSymbol( module
, sym
->proc32
.name
, sym
->proc32
.namelen
,
2158 sym
->proc32
.proctype
, sym
->proc32
.segment
,
2159 sym
->proc32
.offset
, sym
->proc32
.proc_len
,
2160 DV_TARGET
, SYM_WIN32
| SYM_FUNC
, linetab
);
2162 DEBUG_SetSymbolBPOff( curr_func
, sym
->proc32
.debug_start
);
2167 * Function parameters and stack variables.
2170 DEBUG_AddCVLocal( curr_func
, sym
->stack
.name
, sym
->stack
.namelen
,
2171 sym
->stack
.symtype
, sym
->stack
.offset
);
2174 DEBUG_AddCVLocal( curr_func
, sym
->stack32
.name
, sym
->stack32
.namelen
,
2175 sym
->stack32
.symtype
, sym
->stack32
.offset
);
2180 * These are special, in that they are always followed by an
2181 * additional length-prefixed string which is *not* included
2182 * into the symbol length count. We need to skip it.
2188 LPBYTE name
= (LPBYTE
)sym
+ length
;
2189 length
+= (*name
+ 1 + 3) & ~3;
2195 DEBUG_Normalize( curr_func
);
2197 if ( linetab
) DBG_free(linetab
);
2203 /*========================================================================
2208 typedef struct _PDB_FILE
2213 } PDB_FILE
, *PPDB_FILE
;
2215 typedef struct _PDB_HEADER
2223 WORD toc_block
[ 1 ];
2225 } PDB_HEADER
, *PPDB_HEADER
;
2227 typedef struct _PDB_TOC
2232 } PDB_TOC
, *PPDB_TOC
;
2234 typedef struct _PDB_ROOT
2237 DWORD TimeDateStamp
;
2242 } PDB_ROOT
, *PPDB_ROOT
;
2244 typedef struct _PDB_TYPES_OLD
2253 } PDB_TYPES_OLD
, *PPDB_TYPES_OLD
;
2255 typedef struct _PDB_TYPES
2268 DWORD search_offset
;
2270 DWORD unknown_offset
;
2273 } PDB_TYPES
, *PPDB_TYPES
;
2275 typedef struct _PDB_SYMBOL_RANGE
2281 DWORD characteristics
;
2285 } PDB_SYMBOL_RANGE
, *PPDB_SYMBOL_RANGE
;
2287 typedef struct _PDB_SYMBOL_RANGE_EX
2293 DWORD characteristics
;
2299 } PDB_SYMBOL_RANGE_EX
, *PPDB_SYMBOL_RANGE_EX
;
2301 typedef struct _PDB_SYMBOL_FILE
2304 PDB_SYMBOL_RANGE range
;
2314 } PDB_SYMBOL_FILE
, *PPDB_SYMBOL_FILE
;
2316 typedef struct _PDB_SYMBOL_FILE_EX
2319 PDB_SYMBOL_RANGE_EX range
;
2327 DWORD reserved
[ 2 ];
2330 } PDB_SYMBOL_FILE_EX
, *PPDB_SYMBOL_FILE_EX
;
2332 typedef struct _PDB_SYMBOL_SOURCE
2338 } PDB_SYMBOL_SOURCE
, *PPDB_SYMBOL_SOURCE
;
2340 typedef struct _PDB_SYMBOL_IMPORT
2344 DWORD TimeDateStamp
;
2348 } PDB_SYMBOL_IMPORT
, *PPDB_SYMBOL_IMPORT
;
2350 typedef struct _PDB_SYMBOLS_OLD
2359 DWORD srcmodule_size
;
2361 } PDB_SYMBOLS_OLD
, *PPDB_SYMBOLS_OLD
;
2363 typedef struct _PDB_SYMBOLS
2374 DWORD srcmodule_size
;
2375 DWORD pdbimport_size
;
2378 } PDB_SYMBOLS
, *PPDB_SYMBOLS
;
2382 static void *pdb_read( LPBYTE image
, WORD
*block_list
, int size
)
2384 PPDB_HEADER pdb
= (PPDB_HEADER
)image
;
2388 if ( !size
) return NULL
;
2390 nBlocks
= (size
+ pdb
->blocksize
-1) / pdb
->blocksize
;
2391 buffer
= DBG_alloc( nBlocks
* pdb
->blocksize
);
2393 for ( i
= 0; i
< nBlocks
; i
++ )
2394 memcpy( buffer
+ i
*pdb
->blocksize
,
2395 image
+ block_list
[i
]*pdb
->blocksize
, pdb
->blocksize
);
2400 static void *pdb_read_file( LPBYTE image
, PPDB_TOC toc
, DWORD fileNr
)
2402 PPDB_HEADER pdb
= (PPDB_HEADER
)image
;
2406 if ( !toc
|| fileNr
>= toc
->nFiles
)
2409 block_list
= (WORD
*) &toc
->file
[ toc
->nFiles
];
2410 for ( i
= 0; i
< fileNr
; i
++ )
2411 block_list
+= (toc
->file
[i
].size
+ pdb
->blocksize
-1) / pdb
->blocksize
;
2413 return pdb_read( image
, block_list
, toc
->file
[fileNr
].size
);
2416 static void pdb_free( void *buffer
)
2421 static void pdb_convert_types_header( PDB_TYPES
*types
, char *image
)
2423 memset( types
, 0, sizeof(PDB_TYPES
) );
2424 if ( !image
) return;
2426 if ( *(DWORD
*)image
< 19960000 ) /* FIXME: correct version? */
2428 /* Old version of the types record header */
2429 PDB_TYPES_OLD
*old
= (PDB_TYPES_OLD
*)image
;
2430 types
->version
= old
->version
;
2431 types
->type_offset
= sizeof(PDB_TYPES_OLD
);
2432 types
->type_size
= old
->type_size
;
2433 types
->first_index
= old
->first_index
;
2434 types
->last_index
= old
->last_index
;
2435 types
->file
= old
->file
;
2439 /* New version of the types record header */
2440 *types
= *(PDB_TYPES
*)image
;
2444 static void pdb_convert_symbols_header( PDB_SYMBOLS
*symbols
,
2445 int *header_size
, char *image
)
2447 memset( symbols
, 0, sizeof(PDB_SYMBOLS
) );
2448 if ( !image
) return;
2450 if ( *(DWORD
*)image
!= 0xffffffff )
2452 /* Old version of the symbols record header */
2453 PDB_SYMBOLS_OLD
*old
= (PDB_SYMBOLS_OLD
*)image
;
2454 symbols
->version
= 0;
2455 symbols
->module_size
= old
->module_size
;
2456 symbols
->offset_size
= old
->offset_size
;
2457 symbols
->hash_size
= old
->hash_size
;
2458 symbols
->srcmodule_size
= old
->srcmodule_size
;
2459 symbols
->pdbimport_size
= 0;
2460 symbols
->hash1_file
= old
->hash1_file
;
2461 symbols
->hash2_file
= old
->hash2_file
;
2462 symbols
->gsym_file
= old
->gsym_file
;
2464 *header_size
= sizeof(PDB_SYMBOLS_OLD
);
2468 /* New version of the symbols record header */
2469 *symbols
= *(PDB_SYMBOLS
*)image
;
2471 *header_size
= sizeof(PDB_SYMBOLS
);
2475 static enum DbgInfoLoad
DEBUG_ProcessPDBFile( DBG_MODULE
*module
,
2476 const char *filename
, DWORD timestamp
)
2478 enum DbgInfoLoad dil
= DIL_ERROR
;
2481 PDB_HEADER
*pdb
= NULL
;
2482 PDB_TOC
*toc
= NULL
;
2483 PDB_ROOT
*root
= NULL
;
2484 char *types_image
= NULL
;
2485 char *symbols_image
= NULL
;
2487 PDB_SYMBOLS symbols
;
2488 int header_size
= 0;
2489 char *modimage
, *file
;
2491 WINE_TRACE("Processing PDB file %s\n", filename
);
2494 * Open and map() .PDB file
2496 image
= DEBUG_MapDebugInfoFile( filename
, 0, 0, &hFile
, &hMap
);
2499 WINE_ERR("-Unable to peruse .PDB file %s\n", filename
);
2504 * Read in TOC and well-known files
2507 pdb
= (PPDB_HEADER
)image
;
2508 toc
= pdb_read( image
, pdb
->toc_block
, pdb
->toc
.size
);
2509 root
= pdb_read_file( image
, toc
, 1 );
2510 types_image
= pdb_read_file( image
, toc
, 2 );
2511 symbols_image
= pdb_read_file( image
, toc
, 3 );
2513 pdb_convert_types_header( &types
, types_image
);
2514 pdb_convert_symbols_header( &symbols
, &header_size
, symbols_image
);
2518 WINE_ERR("-Unable to get root from .PDB file %s\n", filename
);
2523 * Check for unknown versions
2526 switch ( root
->version
)
2528 case 19950623: /* VC 4.0 */
2530 case 19960307: /* VC 5.0 */
2531 case 19970604: /* VC 6.0 */
2534 WINE_ERR("-Unknown root block version %ld\n", root
->version
);
2537 switch ( types
.version
)
2539 case 19950410: /* VC 4.0 */
2541 case 19961031: /* VC 5.0 / 6.0 */
2544 WINE_ERR("-Unknown type info version %ld\n", types
.version
);
2547 switch ( symbols
.version
)
2549 case 0: /* VC 4.0 */
2550 case 19960307: /* VC 5.0 */
2551 case 19970606: /* VC 6.0 */
2554 WINE_ERR("-Unknown symbol info version %ld\n", symbols
.version
);
2559 * Check .PDB time stamp
2562 if ( root
->TimeDateStamp
!= timestamp
)
2564 WINE_ERR("-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2565 filename
, root
->TimeDateStamp
, timestamp
);
2572 DEBUG_ParseTypeTable( types_image
+ types
.type_offset
, types
.type_size
);
2575 * Read type-server .PDB imports
2578 if ( symbols
.pdbimport_size
)
2581 WINE_ERR("-Type server .PDB imports ignored!\n");
2585 * Read global symbol table
2588 modimage
= pdb_read_file( image
, toc
, symbols
.gsym_file
);
2591 DEBUG_SnarfCodeView( module
, modimage
, 0,
2592 toc
->file
[symbols
.gsym_file
].size
, NULL
);
2593 pdb_free( modimage
);
2597 * Read per-module symbol / linenumber tables
2600 file
= symbols_image
+ header_size
;
2601 while ( file
- symbols_image
< header_size
+ symbols
.module_size
)
2603 int file_nr
, file_index
, symbol_size
, lineno_size
;
2606 if ( symbols
.version
< 19970000 )
2608 PDB_SYMBOL_FILE
*sym_file
= (PDB_SYMBOL_FILE
*) file
;
2609 file_nr
= sym_file
->file
;
2610 file_name
= sym_file
->filename
;
2611 file_index
= sym_file
->range
.index
;
2612 symbol_size
= sym_file
->symbol_size
;
2613 lineno_size
= sym_file
->lineno_size
;
2617 PDB_SYMBOL_FILE_EX
*sym_file
= (PDB_SYMBOL_FILE_EX
*) file
;
2618 file_nr
= sym_file
->file
;
2619 file_name
= sym_file
->filename
;
2620 file_index
= sym_file
->range
.index
;
2621 symbol_size
= sym_file
->symbol_size
;
2622 lineno_size
= sym_file
->lineno_size
;
2625 modimage
= pdb_read_file( image
, toc
, file_nr
);
2628 struct codeview_linetab_hdr
*linetab
= NULL
;
2631 linetab
= DEBUG_SnarfLinetab( modimage
+ symbol_size
, lineno_size
);
2634 DEBUG_SnarfCodeView( module
, modimage
, sizeof(DWORD
),
2635 symbol_size
, linetab
);
2637 pdb_free( modimage
);
2640 file_name
+= strlen(file_name
) + 1;
2641 file
= (char *)( (DWORD
)(file_name
+ strlen(file_name
) + 1 + 3) & ~3 );
2652 DEBUG_ClearTypeTable();
2654 if ( symbols_image
) pdb_free( symbols_image
);
2655 if ( types_image
) pdb_free( types_image
);
2656 if ( root
) pdb_free( root
);
2657 if ( toc
) pdb_free( toc
);
2659 DEBUG_UnmapDebugInfoFile(hFile
, hMap
, image
);
2667 /*========================================================================
2668 * Process CodeView debug information.
2671 #define CODEVIEW_NB09_SIG ( 'N' | ('B' << 8) | ('0' << 16) | ('9' << 24) )
2672 #define CODEVIEW_NB10_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('0' << 24) )
2673 #define CODEVIEW_NB11_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('1' << 24) )
2675 typedef struct _CODEVIEW_HEADER
2680 } CODEVIEW_HEADER
, *PCODEVIEW_HEADER
;
2682 typedef struct _CODEVIEW_PDB_DATA
2688 } CODEVIEW_PDB_DATA
, *PCODEVIEW_PDB_DATA
;
2690 typedef struct _CV_DIRECTORY_HEADER
2698 } CV_DIRECTORY_HEADER
, *PCV_DIRECTORY_HEADER
;
2700 typedef struct _CV_DIRECTORY_ENTRY
2707 } CV_DIRECTORY_ENTRY
, *PCV_DIRECTORY_ENTRY
;
2710 #define sstAlignSym 0x125
2711 #define sstSrcModule 0x127
2714 static enum DbgInfoLoad
DEBUG_ProcessCodeView( DBG_MODULE
*module
, const BYTE
* root
)
2716 PCODEVIEW_HEADER cv
= (PCODEVIEW_HEADER
)root
;
2717 enum DbgInfoLoad dil
= DIL_ERROR
;
2719 switch ( cv
->dwSignature
)
2721 case CODEVIEW_NB09_SIG
:
2722 case CODEVIEW_NB11_SIG
:
2724 PCV_DIRECTORY_HEADER hdr
= (PCV_DIRECTORY_HEADER
)(root
+ cv
->lfoDirectory
);
2725 PCV_DIRECTORY_ENTRY ent
, prev
, next
;
2728 ent
= (PCV_DIRECTORY_ENTRY
)((LPBYTE
)hdr
+ hdr
->cbDirHeader
);
2729 for ( i
= 0; i
< hdr
->cDir
; i
++, ent
= next
)
2731 next
= (i
== hdr
->cDir
-1)? NULL
:
2732 (PCV_DIRECTORY_ENTRY
)((LPBYTE
)ent
+ hdr
->cbDirEntry
);
2733 prev
= (i
== 0)? NULL
:
2734 (PCV_DIRECTORY_ENTRY
)((LPBYTE
)ent
- hdr
->cbDirEntry
);
2736 if ( ent
->subsection
== sstAlignSym
)
2739 * Check the next and previous entry. If either is a
2740 * sstSrcModule, it contains the line number info for
2743 * FIXME: This is not a general solution!
2745 struct codeview_linetab_hdr
*linetab
= NULL
;
2747 if ( next
&& next
->iMod
== ent
->iMod
2748 && next
->subsection
== sstSrcModule
)
2749 linetab
= DEBUG_SnarfLinetab( root
+ next
->lfo
, next
->cb
);
2751 if ( prev
&& prev
->iMod
== ent
->iMod
2752 && prev
->subsection
== sstSrcModule
)
2753 linetab
= DEBUG_SnarfLinetab( root
+ prev
->lfo
, prev
->cb
);
2756 DEBUG_SnarfCodeView( module
, root
+ ent
->lfo
, sizeof(DWORD
),
2765 case CODEVIEW_NB10_SIG
:
2767 PCODEVIEW_PDB_DATA pdb
= (PCODEVIEW_PDB_DATA
)(cv
+ 1);
2769 dil
= DEBUG_ProcessPDBFile( module
, pdb
->name
, pdb
->timestamp
);
2774 WINE_ERR("Unknown CODEVIEW signature %08lX in module %s\n",
2775 cv
->dwSignature
, module
->module_name
);
2783 /*========================================================================
2784 * Process debug directory.
2786 enum DbgInfoLoad
DEBUG_ProcessDebugDirectory( DBG_MODULE
*module
, const BYTE
* file_map
,
2787 PIMAGE_DEBUG_DIRECTORY dbg
, int nDbg
)
2789 enum DbgInfoLoad dil
;
2793 /* First, watch out for OMAP data */
2794 for ( i
= 0; i
< nDbg
; i
++ )
2796 if ( dbg
[i
].Type
== IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
)
2798 module
->msc_dbg_info
->nomap
= dbg
[i
].SizeOfData
/ sizeof(OMAP_DATA
);
2799 module
->msc_dbg_info
->omapp
= (OMAP_DATA
*)(file_map
+ dbg
[i
].PointerToRawData
);
2804 /* Now, try to parse CodeView debug info */
2805 for ( i
= 0; dil
!= DIL_LOADED
&& i
< nDbg
; i
++ )
2807 if ( dbg
[i
].Type
== IMAGE_DEBUG_TYPE_CODEVIEW
)
2809 dil
= DEBUG_ProcessCodeView( module
, file_map
+ dbg
[i
].PointerToRawData
);
2813 /* If not found, try to parse COFF debug info */
2814 for ( i
= 0; dil
!= DIL_LOADED
&& i
< nDbg
; i
++ )
2816 if ( dbg
[i
].Type
== IMAGE_DEBUG_TYPE_COFF
)
2817 dil
= DEBUG_ProcessCoff( module
, file_map
+ dbg
[i
].PointerToRawData
);
2820 /* FIXME: this should be supported... this is the debug information for
2821 * functions compiled without a frame pointer (FPO = frame pointer omission)
2822 * the associated data helps finding out the relevant information
2824 for ( i
= 0; i
< nDbg
; i
++ )
2825 if ( dbg
[i
].Type
== IMAGE_DEBUG_TYPE_FPO
)
2826 DEBUG_Printf("This guy has FPO information\n");
2829 #define FRAME_TRAP 1
2832 typedef struct _FPO_DATA
{
2833 DWORD ulOffStart
; /* offset 1st byte of function code */
2834 DWORD cbProcSize
; /* # bytes in function */
2835 DWORD cdwLocals
; /* # bytes in locals/4 */
2836 WORD cdwParams
; /* # bytes in params/4 */
2838 WORD cbProlog
: 8; /* # bytes in prolog */
2839 WORD cbRegs
: 3; /* # regs saved */
2840 WORD fHasSEH
: 1; /* TRUE if SEH in func */
2841 WORD fUseBP
: 1; /* TRUE if EBP has been allocated */
2842 WORD reserved
: 1; /* reserved for future use */
2843 WORD cbFrame
: 2; /* frame type */
2847 __EXCEPT(page_fault
)