Minor fixes.
[wine/gsoc_dplay.git] / programs / winedbg / msc.c
blobed7781ae3bbb9135769afae0df8a128a0d65290b
1 /*
2 * File msc.c - read VC++ debug information from COFF and eventually
3 * from PDB files.
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.
27 * TODO:
28 * Get 16 bit CV stuff working.
29 * Add symbol size to internal symbol table.
32 #include "config.h"
33 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 #ifndef PATH_MAX
38 #define PATH_MAX MAX_PATH
39 #endif
40 #include "wine/exception.h"
41 #include "excpt.h"
42 #include "debugger.h"
44 #define MAX_PATHNAME_LEN 1024
46 typedef struct
48 DWORD from;
49 DWORD to;
51 } OMAP_DATA;
53 typedef struct tagMSC_DBG_INFO
55 int nsect;
56 PIMAGE_SECTION_HEADER sectp;
58 int nomap;
59 OMAP_DATA * omapp;
61 } MSC_DBG_INFO;
63 /*========================================================================
64 * Debug file access helper routines
67 static WINE_EXCEPTION_FILTER(page_fault)
69 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
70 return EXCEPTION_EXECUTE_HANDLER;
71 return EXCEPTION_CONTINUE_SEARCH;
74 /***********************************************************************
75 * DEBUG_LocateDebugInfoFile
77 * NOTE: dbg_filename must be at least MAX_PATHNAME_LEN bytes in size
79 static void DEBUG_LocateDebugInfoFile(const char *filename, char *dbg_filename)
81 char *str1 = DBG_alloc(MAX_PATHNAME_LEN);
82 char *str2 = DBG_alloc(MAX_PATHNAME_LEN*10);
83 const char *file;
84 char *name_part;
86 file = strrchr(filename, '\\');
87 if( file == NULL ) file = filename; else file++;
89 if ((GetEnvironmentVariable("_NT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
90 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
91 (GetEnvironmentVariable("_NT_ALT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
92 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
93 (SearchPath(NULL, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part)))
94 lstrcpyn(dbg_filename, str2, MAX_PATHNAME_LEN);
95 else
96 lstrcpyn(dbg_filename, filename, MAX_PATHNAME_LEN);
97 DBG_free(str1);
98 DBG_free(str2);
101 /***********************************************************************
102 * DEBUG_MapDebugInfoFile
104 static void* DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
105 HANDLE* hFile, HANDLE* hMap)
107 DWORD g_offset; /* offset aligned on map granuality */
108 DWORD g_size; /* size to map, with offset aligned */
109 char* ret;
111 *hMap = 0;
113 if (name != NULL) {
114 char filename[MAX_PATHNAME_LEN];
116 DEBUG_LocateDebugInfoFile(name, filename);
117 if ((*hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
118 return NULL;
121 if (!size) {
122 DWORD file_size = GetFileSize(*hFile, NULL);
123 if (file_size == (DWORD)-1) return NULL;
124 size = file_size - offset;
127 g_offset = offset & ~0xFFFF; /* FIXME: is granularity portable ? */
128 g_size = offset + size - g_offset;
130 if ((*hMap = CreateFileMapping(*hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == 0)
131 return NULL;
133 if ((ret = MapViewOfFile(*hMap, FILE_MAP_READ, 0, g_offset, g_size)) != NULL)
134 ret += offset - g_offset;
136 return ret;
139 /***********************************************************************
140 * DEBUG_UnmapDebugInfoFile
142 static void DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, void* addr)
144 if (addr) UnmapViewOfFile(addr);
145 if (hMap) CloseHandle(hMap);
146 if (hFile!=INVALID_HANDLE_VALUE) CloseHandle(hFile);
151 /*========================================================================
152 * Process COFF debug information.
155 struct CoffFile
157 unsigned int startaddr;
158 unsigned int endaddr;
159 const char *filename;
160 int linetab_offset;
161 int linecnt;
162 struct name_hash **entries;
163 int neps;
164 int neps_alloc;
167 struct CoffFileSet
169 struct CoffFile *files;
170 int nfiles;
171 int nfiles_alloc;
174 static const char* DEBUG_GetCoffName( PIMAGE_SYMBOL coff_sym, const char* coff_strtab )
176 static char namebuff[9];
177 const char* nampnt;
179 if( coff_sym->N.Name.Short )
181 memcpy(namebuff, coff_sym->N.ShortName, 8);
182 namebuff[8] = '\0';
183 nampnt = &namebuff[0];
185 else
187 nampnt = coff_strtab + coff_sym->N.Name.Long;
190 if( nampnt[0] == '_' )
191 nampnt++;
192 return nampnt;
195 static int DEBUG_AddCoffFile( struct CoffFileSet* coff_files, const char* filename )
197 struct CoffFile* file;
199 if( coff_files->nfiles + 1 >= coff_files->nfiles_alloc )
201 coff_files->nfiles_alloc += 10;
202 coff_files->files = (struct CoffFile *) DBG_realloc(coff_files->files,
203 coff_files->nfiles_alloc * sizeof(struct CoffFile));
205 file = coff_files->files + coff_files->nfiles;
206 file->startaddr = 0xffffffff;
207 file->endaddr = 0;
208 file->filename = filename;
209 file->linetab_offset = -1;
210 file->linecnt = 0;
211 file->entries = NULL;
212 file->neps = file->neps_alloc = 0;
214 return coff_files->nfiles++;
217 static void DEBUG_AddCoffSymbol( struct CoffFile* coff_file, struct name_hash* sym )
219 if( coff_file->neps + 1 >= coff_file->neps_alloc )
221 coff_file->neps_alloc += 10;
222 coff_file->entries = (struct name_hash **)
223 DBG_realloc(coff_file->entries,
224 coff_file->neps_alloc * sizeof(struct name_hash *));
226 coff_file->entries[coff_file->neps++] = sym;
229 static enum DbgInfoLoad DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
231 PIMAGE_AUX_SYMBOL aux;
232 PIMAGE_COFF_SYMBOLS_HEADER coff;
233 PIMAGE_LINENUMBER coff_linetab;
234 PIMAGE_LINENUMBER linepnt;
235 char * coff_strtab;
236 PIMAGE_SYMBOL coff_sym;
237 PIMAGE_SYMBOL coff_symbols;
238 struct CoffFileSet coff_files;
239 int curr_file_idx = -1;
240 unsigned int i;
241 int j;
242 int k;
243 int l;
244 int linetab_indx;
245 const char * nampnt;
246 int naux;
247 DBG_VALUE new_value;
248 enum DbgInfoLoad dil = DIL_ERROR;
250 DEBUG_Printf(DBG_CHN_TRACE, "Processing COFF symbols...\n");
252 assert(sizeof(IMAGE_SYMBOL) == IMAGE_SIZEOF_SYMBOL);
253 assert(sizeof(IMAGE_LINENUMBER) == IMAGE_SIZEOF_LINENUMBER);
255 coff_files.files = NULL;
256 coff_files.nfiles = coff_files.nfiles_alloc = 0;
258 coff = (PIMAGE_COFF_SYMBOLS_HEADER) root;
260 coff_symbols = (PIMAGE_SYMBOL) ((unsigned int) coff + coff->LvaToFirstSymbol);
261 coff_linetab = (PIMAGE_LINENUMBER) ((unsigned int) coff + coff->LvaToFirstLinenumber);
262 coff_strtab = (char *) (coff_symbols + coff->NumberOfSymbols);
264 linetab_indx = 0;
266 new_value.cookie = DV_TARGET;
267 new_value.type = NULL;
269 for(i=0; i < coff->NumberOfSymbols; i++ )
271 coff_sym = coff_symbols + i;
272 naux = coff_sym->NumberOfAuxSymbols;
274 if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE )
276 curr_file_idx = DEBUG_AddCoffFile( &coff_files, (char *) (coff_sym + 1) );
277 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
278 i += naux;
279 continue;
282 if (curr_file_idx < 0) {
283 assert(coff_files.nfiles == 0 && coff_files.nfiles_alloc == 0);
284 curr_file_idx = DEBUG_AddCoffFile( &coff_files, "<none>" );
285 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
289 * This guy marks the size and location of the text section
290 * for the current file. We need to keep track of this so
291 * we can figure out what file the different global functions
292 * go with.
294 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
295 && (naux != 0)
296 && (coff_sym->Type == 0)
297 && (coff_sym->SectionNumber == 1) )
299 aux = (PIMAGE_AUX_SYMBOL) (coff_sym + 1);
301 if( coff_files.files[curr_file_idx].linetab_offset != -1 )
304 * Save this so we can still get the old name.
306 const char* fn = coff_files.files[curr_file_idx].filename;
308 #ifdef MORE_DBG
309 DEBUG_Printf(DBG_CHN_TRACE, "Duplicating sect from %s: %lx %x %x %d %d\n",
310 coff_files.files[curr_file_idx].filename,
311 aux->Section.Length,
312 aux->Section.NumberOfRelocations,
313 aux->Section.NumberOfLinenumbers,
314 aux->Section.Number,
315 aux->Section.Selection);
316 DEBUG_Printf(DBG_CHN_TRACE, "More sect %d %s %08lx %d %d %d\n",
317 coff_sym->SectionNumber,
318 DEBUG_GetCoffName( coff_sym, coff_strtab ),
319 coff_sym->Value,
320 coff_sym->Type,
321 coff_sym->StorageClass,
322 coff_sym->NumberOfAuxSymbols);
323 #endif
326 * Duplicate the file entry. We have no way to describe
327 * multiple text sections in our current way of handling things.
329 DEBUG_AddCoffFile( &coff_files, fn );
331 #ifdef MORE_DBG
332 else
334 DEBUG_Printf(DBG_CHN_TRACE, "New text sect from %s: %lx %x %x %d %d\n",
335 coff_files.files[curr_file_idx].filename,
336 aux->Section.Length,
337 aux->Section.NumberOfRelocations,
338 aux->Section.NumberOfLinenumbers,
339 aux->Section.Number,
340 aux->Section.Selection);
342 #endif
344 if( coff_files.files[curr_file_idx].startaddr > coff_sym->Value )
346 coff_files.files[curr_file_idx].startaddr = coff_sym->Value;
349 if( coff_files.files[curr_file_idx].endaddr < coff_sym->Value + aux->Section.Length )
351 coff_files.files[curr_file_idx].endaddr = coff_sym->Value + aux->Section.Length;
354 coff_files.files[curr_file_idx].linetab_offset = linetab_indx;
355 coff_files.files[curr_file_idx].linecnt = aux->Section.NumberOfLinenumbers;
356 linetab_indx += aux->Section.NumberOfLinenumbers;
357 i += naux;
358 continue;
361 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
362 && (naux == 0)
363 && (coff_sym->SectionNumber == 1) )
365 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
367 * This is a normal static function when naux == 0.
368 * Just register it. The current file is the correct
369 * one in this instance.
371 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
373 new_value.addr.seg = 0;
374 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
376 #ifdef MORE_DBG
377 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding static symbol %s\n", nampnt);
378 #endif
380 /* FIXME: was adding symbol to this_file ??? */
381 DEBUG_AddCoffSymbol( &coff_files.files[curr_file_idx],
382 DEBUG_AddSymbol( nampnt, &new_value,
383 coff_files.files[curr_file_idx].filename,
384 SYM_WIN32 | SYM_FUNC ) );
385 i += naux;
386 continue;
389 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
390 && ISFCN(coff_sym->Type)
391 && (coff_sym->SectionNumber > 0) )
393 const char* this_file = NULL;
394 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
395 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
397 new_value.addr.seg = 0;
398 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
400 #ifdef MORE_DBG
401 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
403 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global symbol %s (sect=%s)\n",
404 nampnt, MSC_INFO(module)->sectp[coff_sym->SectionNumber - 1].Name);
405 #endif
408 * Now we need to figure out which file this guy belongs to.
410 for(j=0; j < coff_files.nfiles; j++)
412 if( coff_files.files[j].startaddr <= base + coff_sym->Value
413 && coff_files.files[j].endaddr > base + coff_sym->Value )
415 this_file = coff_files.files[j].filename;
416 break;
419 if (j < coff_files.nfiles) {
420 DEBUG_AddCoffSymbol( &coff_files.files[j],
421 DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 | SYM_FUNC ) );
422 } else {
423 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_FUNC );
425 i += naux;
426 continue;
429 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
430 && (coff_sym->SectionNumber > 0) )
432 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
434 * Similar to above, but for the case of data symbols.
435 * These aren't treated as entrypoints.
437 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
439 new_value.addr.seg = 0;
440 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
442 #ifdef MORE_DBG
443 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
445 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global data symbol %s\n", nampnt);
446 #endif
449 * Now we need to figure out which file this guy belongs to.
451 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_DATA );
452 i += naux;
453 continue;
456 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
457 && (naux == 0) )
460 * Ignore these. They don't have anything to do with
461 * reality.
463 i += naux;
464 continue;
467 #ifdef MORE_DBG
468 DEBUG_Printf(DBG_CHN_TRACE,"Skipping unknown entry '%s' %d %d %d\n",
469 DEBUG_GetCoffName( coff_sym, coff_strtab ),
470 coff_sym->StorageClass, coff_sym->SectionNumber, naux);
471 #endif
474 * For now, skip past the aux entries.
476 i += naux;
481 * OK, we now should have a list of files, and we should have a list
482 * of entrypoints. We need to sort the entrypoints so that we are
483 * able to tie the line numbers with the given functions within the
484 * file.
486 if( coff_files.files != NULL )
488 for(j=0; j < coff_files.nfiles; j++)
490 if( coff_files.files[j].entries != NULL )
492 qsort(coff_files.files[j].entries, coff_files.files[j].neps,
493 sizeof(struct name_hash *), DEBUG_cmp_sym);
498 * Now pick apart the line number tables, and attach the entries
499 * to the given functions.
501 for(j=0; j < coff_files.nfiles; j++)
503 l = 0;
504 if( coff_files.files[j].neps != 0 )
505 for(k=0; k < coff_files.files[j].linecnt; k++)
507 linepnt = coff_linetab + coff_files.files[j].linetab_offset + k;
509 * If we have spilled onto the next entrypoint, then
510 * bump the counter..
512 while(TRUE)
514 if (l+1 >= coff_files.files[j].neps) break;
515 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l+1], &new_value.addr);
516 if( (((unsigned int)module->load_addr +
517 linepnt->Type.VirtualAddress) >= new_value.addr.off) )
519 l++;
520 } else break;
524 * Add the line number. This is always relative to the
525 * start of the function, so we need to subtract that offset
526 * first.
528 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l], &new_value.addr);
529 DEBUG_AddLineNumber(coff_files.files[j].entries[l],
530 linepnt->Linenumber,
531 (unsigned int) module->load_addr
532 + linepnt->Type.VirtualAddress
533 - new_value.addr.off);
538 dil = DIL_LOADED;
540 if( coff_files.files != NULL )
542 for(j=0; j < coff_files.nfiles; j++)
544 if( coff_files.files[j].entries != NULL )
546 DBG_free(coff_files.files[j].entries);
549 DBG_free(coff_files.files);
552 return dil;
558 /*========================================================================
559 * Process CodeView type information.
562 union codeview_type
564 struct
566 unsigned short int len;
567 short int id;
568 } generic;
570 struct
572 unsigned short int len;
573 short int id;
574 short int attribute;
575 short int datatype;
576 unsigned char variant[1];
577 } pointer;
579 struct
581 unsigned short int len;
582 short int id;
583 unsigned int datatype;
584 unsigned int attribute;
585 unsigned char variant[1];
586 } pointer32;
588 struct
590 unsigned short int len;
591 short int id;
592 unsigned char nbits;
593 unsigned char bitoff;
594 unsigned short type;
595 } bitfield;
597 struct
599 unsigned short int len;
600 short int id;
601 unsigned int type;
602 unsigned char nbits;
603 unsigned char bitoff;
604 } bitfield32;
606 struct
608 unsigned short int len;
609 short int id;
610 short int elemtype;
611 short int idxtype;
612 unsigned short int arrlen; /* numeric leaf */
613 #if 0
614 unsigned char name[1];
615 #endif
616 } array;
618 struct
620 unsigned short int len;
621 short int id;
622 unsigned int elemtype;
623 unsigned int idxtype;
624 unsigned short int arrlen; /* numeric leaf */
625 #if 0
626 unsigned char name[1];
627 #endif
628 } array32;
630 struct
632 unsigned short int len;
633 short int id;
634 short int n_element;
635 short int fieldlist;
636 short int property;
637 short int derived;
638 short int vshape;
639 unsigned short int structlen; /* numeric leaf */
640 #if 0
641 unsigned char name[1];
642 #endif
643 } structure;
645 struct
647 unsigned short int len;
648 short int id;
649 short int n_element;
650 short int property;
651 unsigned int fieldlist;
652 unsigned int derived;
653 unsigned int vshape;
654 unsigned short int structlen; /* numeric leaf */
655 #if 0
656 unsigned char name[1];
657 #endif
658 } structure32;
660 struct
662 unsigned short int len;
663 short int id;
664 short int count;
665 short int fieldlist;
666 short int property;
667 unsigned short int un_len; /* numeric leaf */
668 #if 0
669 unsigned char name[1];
670 #endif
671 } t_union;
673 struct
675 unsigned short int len;
676 short int id;
677 short int count;
678 short int property;
679 unsigned int fieldlist;
680 unsigned short int un_len; /* numeric leaf */
681 #if 0
682 unsigned char name[1];
683 #endif
684 } t_union32;
686 struct
688 unsigned short int len;
689 short int id;
690 short int count;
691 short int type;
692 short int field;
693 short int property;
694 unsigned char name[1];
695 } enumeration;
697 struct
699 unsigned short int len;
700 short int id;
701 short int count;
702 short int property;
703 unsigned int type;
704 unsigned int field;
705 unsigned char name[1];
706 } enumeration32;
708 struct
710 unsigned short int len;
711 short int id;
712 unsigned char list[1];
713 } fieldlist;
716 union codeview_fieldtype
718 struct
720 short int id;
721 } generic;
723 struct
725 short int id;
726 short int type;
727 short int attribute;
728 unsigned short int offset; /* numeric leaf */
729 } bclass;
731 struct
733 short int id;
734 short int attribute;
735 unsigned int type;
736 unsigned short int offset; /* numeric leaf */
737 } bclass32;
739 struct
741 short int id;
742 short int btype;
743 short int vbtype;
744 short int attribute;
745 unsigned short int vbpoff; /* numeric leaf */
746 #if 0
747 unsigned short int vboff; /* numeric leaf */
748 #endif
749 } vbclass;
751 struct
753 short int id;
754 short int attribute;
755 unsigned int btype;
756 unsigned int vbtype;
757 unsigned short int vbpoff; /* numeric leaf */
758 #if 0
759 unsigned short int vboff; /* numeric leaf */
760 #endif
761 } vbclass32;
763 struct
765 short int id;
766 short int attribute;
767 unsigned short int value; /* numeric leaf */
768 #if 0
769 unsigned char name[1];
770 #endif
771 } enumerate;
773 struct
775 short int id;
776 short int type;
777 unsigned char name[1];
778 } friendfcn;
780 struct
782 short int id;
783 short int _pad0;
784 unsigned int type;
785 unsigned char name[1];
786 } friendfcn32;
788 struct
790 short int id;
791 short int type;
792 short int attribute;
793 unsigned short int offset; /* numeric leaf */
794 #if 0
795 unsigned char name[1];
796 #endif
797 } member;
799 struct
801 short int id;
802 short int attribute;
803 unsigned int type;
804 unsigned short int offset; /* numeric leaf */
805 #if 0
806 unsigned char name[1];
807 #endif
808 } member32;
810 struct
812 short int id;
813 short int type;
814 short int attribute;
815 unsigned char name[1];
816 } stmember;
818 struct
820 short int id;
821 short int attribute;
822 unsigned int type;
823 unsigned char name[1];
824 } stmember32;
826 struct
828 short int id;
829 short int count;
830 short int mlist;
831 unsigned char name[1];
832 } method;
834 struct
836 short int id;
837 short int count;
838 unsigned int mlist;
839 unsigned char name[1];
840 } method32;
842 struct
844 short int id;
845 short int index;
846 unsigned char name[1];
847 } nesttype;
849 struct
851 short int id;
852 short int _pad0;
853 unsigned int index;
854 unsigned char name[1];
855 } nesttype32;
857 struct
859 short int id;
860 short int type;
861 } vfunctab;
863 struct
865 short int id;
866 short int _pad0;
867 unsigned int type;
868 } vfunctab32;
870 struct
872 short int id;
873 short int type;
874 } friendcls;
876 struct
878 short int id;
879 short int _pad0;
880 unsigned int type;
881 } friendcls32;
884 struct
886 short int id;
887 short int attribute;
888 short int type;
889 unsigned char name[1];
890 } onemethod;
891 struct
893 short int id;
894 short int attribute;
895 short int type;
896 unsigned int vtab_offset;
897 unsigned char name[1];
898 } onemethod_virt;
900 struct
902 short int id;
903 short int attribute;
904 unsigned int type;
905 unsigned char name[1];
906 } onemethod32;
907 struct
909 short int id;
910 short int attribute;
911 unsigned int type;
912 unsigned int vtab_offset;
913 unsigned char name[1];
914 } onemethod32_virt;
916 struct
918 short int id;
919 short int type;
920 unsigned int offset;
921 } vfuncoff;
923 struct
925 short int id;
926 short int _pad0;
927 unsigned int type;
928 unsigned int offset;
929 } vfuncoff32;
931 struct
933 short int id;
934 short int attribute;
935 short int index;
936 unsigned char name[1];
937 } nesttypeex;
939 struct
941 short int id;
942 short int attribute;
943 unsigned int index;
944 unsigned char name[1];
945 } nesttypeex32;
947 struct
949 short int id;
950 short int attribute;
951 unsigned int type;
952 unsigned char name[1];
953 } membermodify;
958 * This covers the basic datatypes that VC++ seems to be using these days.
959 * 32 bit mode only. There are additional numbers for the pointers in 16
960 * bit mode. There are many other types listed in the documents, but these
961 * are apparently not used by the compiler, or represent pointer types
962 * that are not used.
964 #define T_NOTYPE 0x0000 /* Notype */
965 #define T_ABS 0x0001 /* Abs */
966 #define T_VOID 0x0003 /* Void */
967 #define T_CHAR 0x0010 /* signed char */
968 #define T_SHORT 0x0011 /* short */
969 #define T_LONG 0x0012 /* long */
970 #define T_QUAD 0x0013 /* long long */
971 #define T_UCHAR 0x0020 /* unsigned char */
972 #define T_USHORT 0x0021 /* unsigned short */
973 #define T_ULONG 0x0022 /* unsigned long */
974 #define T_UQUAD 0x0023 /* unsigned long long */
975 #define T_REAL32 0x0040 /* float */
976 #define T_REAL64 0x0041 /* double */
977 #define T_RCHAR 0x0070 /* real char */
978 #define T_WCHAR 0x0071 /* wide char */
979 #define T_INT4 0x0074 /* int */
980 #define T_UINT4 0x0075 /* unsigned int */
982 #define T_32PVOID 0x0403 /* 32 bit near pointer to void */
983 #define T_32PCHAR 0x0410 /* 16:32 near pointer to signed char */
984 #define T_32PSHORT 0x0411 /* 16:32 near pointer to short */
985 #define T_32PLONG 0x0412 /* 16:32 near pointer to int */
986 #define T_32PQUAD 0x0413 /* 16:32 near pointer to long long */
987 #define T_32PUCHAR 0x0420 /* 16:32 near pointer to unsigned char */
988 #define T_32PUSHORT 0x0421 /* 16:32 near pointer to unsigned short */
989 #define T_32PULONG 0x0422 /* 16:32 near pointer to unsigned int */
990 #define T_32PUQUAD 0x0423 /* 16:32 near pointer to long long */
991 #define T_32PREAL32 0x0440 /* 16:32 near pointer to float */
992 #define T_32PREAL64 0x0441 /* 16:32 near pointer to float */
993 #define T_32PRCHAR 0x0470 /* 16:32 near pointer to real char */
994 #define T_32PWCHAR 0x0471 /* 16:32 near pointer to real char */
995 #define T_32PINT4 0x0474 /* 16:32 near pointer to int */
996 #define T_32PUINT4 0x0475 /* 16:32 near pointer to unsigned int */
999 #define LF_MODIFIER 0x0001
1000 #define LF_POINTER 0x0002
1001 #define LF_ARRAY 0x0003
1002 #define LF_CLASS 0x0004
1003 #define LF_STRUCTURE 0x0005
1004 #define LF_UNION 0x0006
1005 #define LF_ENUM 0x0007
1006 #define LF_PROCEDURE 0x0008
1007 #define LF_MFUNCTION 0x0009
1008 #define LF_VTSHAPE 0x000a
1009 #define LF_COBOL0 0x000b
1010 #define LF_COBOL1 0x000c
1011 #define LF_BARRAY 0x000d
1012 #define LF_LABEL 0x000e
1013 #define LF_NULL 0x000f
1014 #define LF_NOTTRAN 0x0010
1015 #define LF_DIMARRAY 0x0011
1016 #define LF_VFTPATH 0x0012
1017 #define LF_PRECOMP 0x0013
1018 #define LF_ENDPRECOMP 0x0014
1019 #define LF_OEM 0x0015
1020 #define LF_TYPESERVER 0x0016
1022 #define LF_MODIFIER_32 0x1001 /* variants with new 32-bit type indices */
1023 #define LF_POINTER_32 0x1002
1024 #define LF_ARRAY_32 0x1003
1025 #define LF_CLASS_32 0x1004
1026 #define LF_STRUCTURE_32 0x1005
1027 #define LF_UNION_32 0x1006
1028 #define LF_ENUM_32 0x1007
1029 #define LF_PROCEDURE_32 0x1008
1030 #define LF_MFUNCTION_32 0x1009
1031 #define LF_COBOL0_32 0x100a
1032 #define LF_BARRAY_32 0x100b
1033 #define LF_DIMARRAY_32 0x100c
1034 #define LF_VFTPATH_32 0x100d
1035 #define LF_PRECOMP_32 0x100e
1036 #define LF_OEM_32 0x100f
1038 #define LF_SKIP 0x0200
1039 #define LF_ARGLIST 0x0201
1040 #define LF_DEFARG 0x0202
1041 #define LF_LIST 0x0203
1042 #define LF_FIELDLIST 0x0204
1043 #define LF_DERIVED 0x0205
1044 #define LF_BITFIELD 0x0206
1045 #define LF_METHODLIST 0x0207
1046 #define LF_DIMCONU 0x0208
1047 #define LF_DIMCONLU 0x0209
1048 #define LF_DIMVARU 0x020a
1049 #define LF_DIMVARLU 0x020b
1050 #define LF_REFSYM 0x020c
1052 #define LF_SKIP_32 0x1200 /* variants with new 32-bit type indices */
1053 #define LF_ARGLIST_32 0x1201
1054 #define LF_DEFARG_32 0x1202
1055 #define LF_FIELDLIST_32 0x1203
1056 #define LF_DERIVED_32 0x1204
1057 #define LF_BITFIELD_32 0x1205
1058 #define LF_METHODLIST_32 0x1206
1059 #define LF_DIMCONU_32 0x1207
1060 #define LF_DIMCONLU_32 0x1208
1061 #define LF_DIMVARU_32 0x1209
1062 #define LF_DIMVARLU_32 0x120a
1064 #define LF_BCLASS 0x0400
1065 #define LF_VBCLASS 0x0401
1066 #define LF_IVBCLASS 0x0402
1067 #define LF_ENUMERATE 0x0403
1068 #define LF_FRIENDFCN 0x0404
1069 #define LF_INDEX 0x0405
1070 #define LF_MEMBER 0x0406
1071 #define LF_STMEMBER 0x0407
1072 #define LF_METHOD 0x0408
1073 #define LF_NESTTYPE 0x0409
1074 #define LF_VFUNCTAB 0x040a
1075 #define LF_FRIENDCLS 0x040b
1076 #define LF_ONEMETHOD 0x040c
1077 #define LF_VFUNCOFF 0x040d
1078 #define LF_NESTTYPEEX 0x040e
1079 #define LF_MEMBERMODIFY 0x040f
1081 #define LF_BCLASS_32 0x1400 /* variants with new 32-bit type indices */
1082 #define LF_VBCLASS_32 0x1401
1083 #define LF_IVBCLASS_32 0x1402
1084 #define LF_FRIENDFCN_32 0x1403
1085 #define LF_INDEX_32 0x1404
1086 #define LF_MEMBER_32 0x1405
1087 #define LF_STMEMBER_32 0x1406
1088 #define LF_METHOD_32 0x1407
1089 #define LF_NESTTYPE_32 0x1408
1090 #define LF_VFUNCTAB_32 0x1409
1091 #define LF_FRIENDCLS_32 0x140a
1092 #define LF_ONEMETHOD_32 0x140b
1093 #define LF_VFUNCOFF_32 0x140c
1094 #define LF_NESTTYPEEX_32 0x140d
1096 #define LF_NUMERIC 0x8000 /* numeric leaf types */
1097 #define LF_CHAR 0x8000
1098 #define LF_SHORT 0x8001
1099 #define LF_USHORT 0x8002
1100 #define LF_LONG 0x8003
1101 #define LF_ULONG 0x8004
1102 #define LF_REAL32 0x8005
1103 #define LF_REAL64 0x8006
1104 #define LF_REAL80 0x8007
1105 #define LF_REAL128 0x8008
1106 #define LF_QUADWORD 0x8009
1107 #define LF_UQUADWORD 0x800a
1108 #define LF_REAL48 0x800b
1109 #define LF_COMPLEX32 0x800c
1110 #define LF_COMPLEX64 0x800d
1111 #define LF_COMPLEX80 0x800e
1112 #define LF_COMPLEX128 0x800f
1113 #define LF_VARSTRING 0x8010
1117 #define MAX_BUILTIN_TYPES 0x480
1118 static struct datatype * cv_basic_types[MAX_BUILTIN_TYPES];
1119 static unsigned int num_cv_defined_types = 0;
1120 static struct datatype **cv_defined_types = NULL;
1122 void
1123 DEBUG_InitCVDataTypes(void)
1126 * These are the common builtin types that are used by VC++.
1128 cv_basic_types[T_NOTYPE] = NULL;
1129 cv_basic_types[T_ABS] = NULL;
1130 cv_basic_types[T_VOID] = DEBUG_GetBasicType(DT_BASIC_VOID);
1131 cv_basic_types[T_CHAR] = DEBUG_GetBasicType(DT_BASIC_CHAR);
1132 cv_basic_types[T_SHORT] = DEBUG_GetBasicType(DT_BASIC_SHORTINT);
1133 cv_basic_types[T_LONG] = DEBUG_GetBasicType(DT_BASIC_LONGINT);
1134 cv_basic_types[T_QUAD] = DEBUG_GetBasicType(DT_BASIC_LONGLONGINT);
1135 cv_basic_types[T_UCHAR] = DEBUG_GetBasicType(DT_BASIC_UCHAR);
1136 cv_basic_types[T_USHORT] = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
1137 cv_basic_types[T_ULONG] = DEBUG_GetBasicType(DT_BASIC_ULONGINT);
1138 cv_basic_types[T_UQUAD] = DEBUG_GetBasicType(DT_BASIC_ULONGLONGINT);
1139 cv_basic_types[T_REAL32] = DEBUG_GetBasicType(DT_BASIC_FLOAT);
1140 cv_basic_types[T_REAL64] = DEBUG_GetBasicType(DT_BASIC_DOUBLE);
1141 cv_basic_types[T_RCHAR] = DEBUG_GetBasicType(DT_BASIC_CHAR);
1142 cv_basic_types[T_WCHAR] = DEBUG_GetBasicType(DT_BASIC_SHORTINT);
1143 cv_basic_types[T_INT4] = DEBUG_GetBasicType(DT_BASIC_INT);
1144 cv_basic_types[T_UINT4] = DEBUG_GetBasicType(DT_BASIC_UINT);
1146 cv_basic_types[T_32PVOID] = DEBUG_FindOrMakePointerType(cv_basic_types[T_VOID]);
1147 cv_basic_types[T_32PCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_CHAR]);
1148 cv_basic_types[T_32PSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_SHORT]);
1149 cv_basic_types[T_32PLONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_LONG]);
1150 cv_basic_types[T_32PQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_QUAD]);
1151 cv_basic_types[T_32PUCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UCHAR]);
1152 cv_basic_types[T_32PUSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_USHORT]);
1153 cv_basic_types[T_32PULONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_ULONG]);
1154 cv_basic_types[T_32PUQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UQUAD]);
1155 cv_basic_types[T_32PREAL32] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL32]);
1156 cv_basic_types[T_32PREAL64] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL64]);
1157 cv_basic_types[T_32PRCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_RCHAR]);
1158 cv_basic_types[T_32PWCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_WCHAR]);
1159 cv_basic_types[T_32PINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_INT4]);
1160 cv_basic_types[T_32PUINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UINT4]);
1164 static int
1165 numeric_leaf( int *value, unsigned short int *leaf )
1167 unsigned short int type = *leaf++;
1168 int length = 2;
1170 if ( type < LF_NUMERIC )
1172 *value = type;
1174 else
1176 switch ( type )
1178 case LF_CHAR:
1179 length += 1;
1180 *value = *(char *)leaf;
1181 break;
1183 case LF_SHORT:
1184 length += 2;
1185 *value = *(short *)leaf;
1186 break;
1188 case LF_USHORT:
1189 length += 2;
1190 *value = *(unsigned short *)leaf;
1191 break;
1193 case LF_LONG:
1194 length += 4;
1195 *value = *(int *)leaf;
1196 break;
1198 case LF_ULONG:
1199 length += 4;
1200 *value = *(unsigned int *)leaf;
1201 break;
1203 case LF_QUADWORD:
1204 case LF_UQUADWORD:
1205 length += 8;
1206 *value = 0; /* FIXME */
1207 break;
1209 case LF_REAL32:
1210 length += 4;
1211 *value = 0; /* FIXME */
1212 break;
1214 case LF_REAL48:
1215 length += 6;
1216 *value = 0; /* FIXME */
1217 break;
1219 case LF_REAL64:
1220 length += 8;
1221 *value = 0; /* FIXME */
1222 break;
1224 case LF_REAL80:
1225 length += 10;
1226 *value = 0; /* FIXME */
1227 break;
1229 case LF_REAL128:
1230 length += 16;
1231 *value = 0; /* FIXME */
1232 break;
1234 case LF_COMPLEX32:
1235 length += 4;
1236 *value = 0; /* FIXME */
1237 break;
1239 case LF_COMPLEX64:
1240 length += 8;
1241 *value = 0; /* FIXME */
1242 break;
1244 case LF_COMPLEX80:
1245 length += 10;
1246 *value = 0; /* FIXME */
1247 break;
1249 case LF_COMPLEX128:
1250 length += 16;
1251 *value = 0; /* FIXME */
1252 break;
1254 case LF_VARSTRING:
1255 length += 2 + *leaf;
1256 *value = 0; /* FIXME */
1257 break;
1259 default:
1260 DEBUG_Printf( DBG_CHN_MESG, "Unknown numeric leaf type %04x\n", type );
1261 *value = 0;
1262 break;
1266 return length;
1269 static char *
1270 terminate_string( unsigned char *name )
1272 static char symname[256];
1274 int namelen = name[0];
1275 assert( namelen >= 0 && namelen < 256 );
1277 memcpy( symname, name+1, namelen );
1278 symname[namelen] = '\0';
1280 if ( !*symname || strcmp( symname, "__unnamed" ) == 0 )
1281 return NULL;
1282 else
1283 return symname;
1286 static
1287 struct datatype * DEBUG_GetCVType(unsigned int typeno)
1289 struct datatype * dt = NULL;
1292 * Convert Codeview type numbers into something we can grok internally.
1293 * Numbers < 0x1000 are all fixed builtin types. Numbers from 0x1000 and
1294 * up are all user defined (structs, etc).
1296 if ( typeno < 0x1000 )
1298 if ( typeno < MAX_BUILTIN_TYPES )
1299 dt = cv_basic_types[typeno];
1301 else
1303 if ( typeno - 0x1000 < num_cv_defined_types )
1304 dt = cv_defined_types[typeno - 0x1000];
1307 return dt;
1310 static int
1311 DEBUG_AddCVType( unsigned int typeno, struct datatype *dt )
1313 while ( typeno - 0x1000 >= num_cv_defined_types )
1315 num_cv_defined_types += 0x100;
1316 cv_defined_types = (struct datatype **)
1317 DBG_realloc( cv_defined_types,
1318 num_cv_defined_types * sizeof(struct datatype *) );
1320 memset( cv_defined_types + num_cv_defined_types - 0x100,
1322 0x100 * sizeof(struct datatype *) );
1324 if ( cv_defined_types == NULL )
1325 return FALSE;
1328 cv_defined_types[ typeno - 0x1000 ] = dt;
1329 return TRUE;
1332 static void
1333 DEBUG_ClearTypeTable( void )
1335 if ( cv_defined_types )
1336 DBG_free( cv_defined_types );
1338 cv_defined_types = NULL;
1339 num_cv_defined_types = 0;
1342 static int
1343 DEBUG_AddCVType_Pointer( unsigned int typeno, unsigned int datatype )
1345 struct datatype *dt =
1346 DEBUG_FindOrMakePointerType( DEBUG_GetCVType( datatype ) );
1348 return DEBUG_AddCVType( typeno, dt );
1351 static int
1352 DEBUG_AddCVType_Array( unsigned int typeno, char *name,
1353 unsigned int elemtype, unsigned int arr_len )
1355 struct datatype *dt = DEBUG_NewDataType( DT_ARRAY, name );
1356 struct datatype *elem = DEBUG_GetCVType( elemtype );
1357 unsigned int elem_size = elem? DEBUG_GetObjectSize( elem ) : 0;
1358 unsigned int arr_max = elem_size? arr_len / elem_size : 0;
1360 DEBUG_SetArrayParams( dt, 0, arr_max, elem );
1361 return DEBUG_AddCVType( typeno, dt );
1364 static int
1365 DEBUG_AddCVType_Bitfield( unsigned int typeno,
1366 unsigned int bitoff, unsigned int nbits,
1367 unsigned int basetype )
1369 struct datatype *dt = DEBUG_NewDataType( DT_BITFIELD, NULL );
1370 struct datatype *base = DEBUG_GetCVType( basetype );
1372 DEBUG_SetBitfieldParams( dt, bitoff, nbits, base );
1373 return DEBUG_AddCVType( typeno, dt );
1376 static int
1377 DEBUG_AddCVType_EnumFieldList( unsigned int typeno, unsigned char *list, int len )
1379 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, NULL );
1380 unsigned char *ptr = list;
1382 while ( ptr - list < len )
1384 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1386 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1388 ptr += *ptr & 0x0f;
1389 continue;
1392 switch ( type->generic.id )
1394 case LF_ENUMERATE:
1396 int value, vlen = numeric_leaf( &value, &type->enumerate.value );
1397 unsigned char *name = (unsigned char *)&type->enumerate.value + vlen;
1399 DEBUG_AddStructElement( dt, terminate_string( name ),
1400 NULL, value, 0 );
1402 ptr += 2 + 2 + vlen + (1 + name[0]);
1403 break;
1406 default:
1407 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in ENUM field list\n",
1408 type->generic.id );
1409 return FALSE;
1413 return DEBUG_AddCVType( typeno, dt );
1416 static int
1417 DEBUG_AddCVType_StructFieldList( unsigned int typeno, unsigned char *list, int len )
1419 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, NULL );
1420 unsigned char *ptr = list;
1422 while ( ptr - list < len )
1424 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1426 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1428 ptr += *ptr & 0x0f;
1429 continue;
1432 switch ( type->generic.id )
1434 case LF_BCLASS:
1436 int offset, olen = numeric_leaf( &offset, &type->bclass.offset );
1438 /* FIXME: ignored for now */
1440 ptr += 2 + 2 + 2 + olen;
1441 break;
1444 case LF_BCLASS_32:
1446 int offset, olen = numeric_leaf( &offset, &type->bclass32.offset );
1448 /* FIXME: ignored for now */
1450 ptr += 2 + 2 + 4 + olen;
1451 break;
1454 case LF_VBCLASS:
1455 case LF_IVBCLASS:
1457 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass.vbpoff );
1458 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass.vbpoff + vbpoff);
1459 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1461 /* FIXME: ignored for now */
1463 ptr += 2 + 2 + 2 + 2 + vbplen + vplen;
1464 break;
1467 case LF_VBCLASS_32:
1468 case LF_IVBCLASS_32:
1470 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass32.vbpoff );
1471 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass32.vbpoff + vbpoff);
1472 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1474 /* FIXME: ignored for now */
1476 ptr += 2 + 2 + 4 + 4 + vbplen + vplen;
1477 break;
1480 case LF_MEMBER:
1482 int offset, olen = numeric_leaf( &offset, &type->member.offset );
1483 unsigned char *name = (unsigned char *)&type->member.offset + olen;
1485 struct datatype *subtype = DEBUG_GetCVType( type->member.type );
1486 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1488 DEBUG_AddStructElement( dt, terminate_string( name ),
1489 subtype, offset << 3, elem_size << 3 );
1491 ptr += 2 + 2 + 2 + olen + (1 + name[0]);
1492 break;
1495 case LF_MEMBER_32:
1497 int offset, olen = numeric_leaf( &offset, &type->member32.offset );
1498 unsigned char *name = (unsigned char *)&type->member32.offset + olen;
1500 struct datatype *subtype = DEBUG_GetCVType( type->member32.type );
1501 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1503 DEBUG_AddStructElement( dt, terminate_string( name ),
1504 subtype, offset << 3, elem_size << 3 );
1506 ptr += 2 + 2 + 4 + olen + (1 + name[0]);
1507 break;
1510 case LF_STMEMBER:
1511 /* FIXME: ignored for now */
1512 ptr += 2 + 2 + 2 + (1 + type->stmember.name[0]);
1513 break;
1515 case LF_STMEMBER_32:
1516 /* FIXME: ignored for now */
1517 ptr += 2 + 4 + 2 + (1 + type->stmember32.name[0]);
1518 break;
1520 case LF_METHOD:
1521 /* FIXME: ignored for now */
1522 ptr += 2 + 2 + 2 + (1 + type->method.name[0]);
1523 break;
1525 case LF_METHOD_32:
1526 /* FIXME: ignored for now */
1527 ptr += 2 + 2 + 4 + (1 + type->method32.name[0]);
1528 break;
1530 case LF_NESTTYPE:
1531 /* FIXME: ignored for now */
1532 ptr += 2 + 2 + (1 + type->nesttype.name[0]);
1533 break;
1535 case LF_NESTTYPE_32:
1536 /* FIXME: ignored for now */
1537 ptr += 2 + 2 + 4 + (1 + type->nesttype32.name[0]);
1538 break;
1540 case LF_VFUNCTAB:
1541 /* FIXME: ignored for now */
1542 ptr += 2 + 2;
1543 break;
1545 case LF_VFUNCTAB_32:
1546 /* FIXME: ignored for now */
1547 ptr += 2 + 2 + 4;
1548 break;
1550 case LF_ONEMETHOD:
1551 /* FIXME: ignored for now */
1552 switch ( (type->onemethod.attribute >> 2) & 7 )
1554 case 4: case 6: /* (pure) introducing virtual method */
1555 ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt.name[0]);
1556 break;
1558 default:
1559 ptr += 2 + 2 + 2 + (1 + type->onemethod.name[0]);
1560 break;
1562 break;
1564 case LF_ONEMETHOD_32:
1565 /* FIXME: ignored for now */
1566 switch ( (type->onemethod32.attribute >> 2) & 7 )
1568 case 4: case 6: /* (pure) introducing virtual method */
1569 ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod32_virt.name[0]);
1570 break;
1572 default:
1573 ptr += 2 + 2 + 4 + (1 + type->onemethod32.name[0]);
1574 break;
1576 break;
1578 default:
1579 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in STRUCT field list\n",
1580 type->generic.id );
1581 return FALSE;
1585 return DEBUG_AddCVType( typeno, dt );
1588 static int
1589 DEBUG_AddCVType_Enum( unsigned int typeno, char *name, unsigned int fieldlist )
1591 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, name );
1592 struct datatype *list = DEBUG_GetCVType( fieldlist );
1594 if ( list )
1595 if(DEBUG_CopyFieldlist( dt, list ) == FALSE)
1596 return FALSE;
1598 return DEBUG_AddCVType( typeno, dt );
1601 static int
1602 DEBUG_AddCVType_Struct( unsigned int typeno, char *name, int structlen, unsigned int fieldlist )
1604 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, name );
1605 struct datatype *list = DEBUG_GetCVType( fieldlist );
1607 if ( list )
1609 DEBUG_SetStructSize( dt, structlen );
1610 if(DEBUG_CopyFieldlist( dt, list ) == FALSE)
1611 return FALSE;
1614 return DEBUG_AddCVType( typeno, dt );
1617 static int
1618 DEBUG_ParseTypeTable( char *table, int len )
1620 unsigned int curr_type = 0x1000;
1621 char *ptr = table;
1623 while ( ptr - table < len )
1625 union codeview_type *type = (union codeview_type *) ptr;
1626 int retv = TRUE;
1628 switch ( type->generic.id )
1630 case LF_POINTER:
1631 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer.datatype );
1632 break;
1633 case LF_POINTER_32:
1634 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer32.datatype );
1635 break;
1637 case LF_ARRAY:
1639 int arrlen, alen = numeric_leaf( &arrlen, &type->array.arrlen );
1640 unsigned char *name = (unsigned char *)&type->array.arrlen + alen;
1642 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1643 type->array.elemtype, arrlen );
1644 break;
1646 case LF_ARRAY_32:
1648 int arrlen, alen = numeric_leaf( &arrlen, &type->array32.arrlen );
1649 unsigned char *name = (unsigned char *)&type->array32.arrlen + alen;
1651 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1652 type->array32.elemtype, type->array32.arrlen );
1653 break;
1656 case LF_BITFIELD:
1657 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield.bitoff,
1658 type->bitfield.nbits,
1659 type->bitfield.type );
1660 break;
1661 case LF_BITFIELD_32:
1662 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield32.bitoff,
1663 type->bitfield32.nbits,
1664 type->bitfield32.type );
1665 break;
1667 case LF_FIELDLIST:
1668 case LF_FIELDLIST_32:
1671 * A 'field list' is a CodeView-specific data type which doesn't
1672 * directly correspond to any high-level data type. It is used
1673 * to hold the collection of members of a struct, class, union
1674 * or enum type. The actual definition of that type will follow
1675 * later, and refer to the field list definition record.
1677 * As we don't have a field list type ourselves, we look ahead
1678 * in the field list to try to find out whether this field list
1679 * will be used for an enum or struct type, and create a dummy
1680 * type of the corresponding sort. Later on, the definition of
1681 * the 'real' type will copy the member / enumeration data.
1684 char *list = type->fieldlist.list;
1685 int len = (ptr + type->generic.len + 2) - list;
1687 if ( ((union codeview_fieldtype *)list)->generic.id == LF_ENUMERATE )
1688 retv = DEBUG_AddCVType_EnumFieldList( curr_type, list, len );
1689 else
1690 retv = DEBUG_AddCVType_StructFieldList( curr_type, list, len );
1691 break;
1694 case LF_STRUCTURE:
1695 case LF_CLASS:
1697 int structlen, slen = numeric_leaf( &structlen, &type->structure.structlen );
1698 unsigned char *name = (unsigned char *)&type->structure.structlen + slen;
1700 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1701 structlen, type->structure.fieldlist );
1702 break;
1704 case LF_STRUCTURE_32:
1705 case LF_CLASS_32:
1707 int structlen, slen = numeric_leaf( &structlen, &type->structure32.structlen );
1708 unsigned char *name = (unsigned char *)&type->structure32.structlen + slen;
1710 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1711 structlen, type->structure32.fieldlist );
1712 break;
1715 case LF_UNION:
1717 int un_len, ulen = numeric_leaf( &un_len, &type->t_union.un_len );
1718 unsigned char *name = (unsigned char *)&type->t_union.un_len + ulen;
1720 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1721 un_len, type->t_union.fieldlist );
1722 break;
1724 case LF_UNION_32:
1726 int un_len, ulen = numeric_leaf( &un_len, &type->t_union32.un_len );
1727 unsigned char *name = (unsigned char *)&type->t_union32.un_len + ulen;
1729 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1730 un_len, type->t_union32.fieldlist );
1731 break;
1734 case LF_ENUM:
1735 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration.name ),
1736 type->enumeration.field );
1737 break;
1738 case LF_ENUM_32:
1739 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration32.name ),
1740 type->enumeration32.field );
1741 break;
1743 default:
1744 break;
1747 if ( !retv )
1748 return FALSE;
1750 curr_type++;
1751 ptr += type->generic.len + 2;
1754 return TRUE;
1758 /*========================================================================
1759 * Process CodeView line number information.
1762 union any_size
1764 char * c;
1765 short * s;
1766 int * i;
1767 unsigned int * ui;
1770 struct startend
1772 unsigned int start;
1773 unsigned int end;
1776 struct codeview_linetab_hdr
1778 unsigned int nline;
1779 unsigned int segno;
1780 unsigned int start;
1781 unsigned int end;
1782 char * sourcefile;
1783 unsigned short * linetab;
1784 unsigned int * offtab;
1787 static struct codeview_linetab_hdr *
1788 DEBUG_SnarfLinetab(char * linetab,
1789 int size)
1791 int file_segcount;
1792 char filename[PATH_MAX];
1793 unsigned int * filetab;
1794 char * fn;
1795 int i;
1796 int k;
1797 struct codeview_linetab_hdr * lt_hdr;
1798 unsigned int * lt_ptr;
1799 int nfile;
1800 int nseg;
1801 union any_size pnt;
1802 union any_size pnt2;
1803 struct startend * start;
1804 int this_seg;
1807 * Now get the important bits.
1809 pnt.c = linetab;
1810 nfile = *pnt.s++;
1811 nseg = *pnt.s++;
1813 filetab = (unsigned int *) pnt.c;
1816 * Now count up the number of segments in the file.
1818 nseg = 0;
1819 for(i=0; i<nfile; i++)
1821 pnt2.c = linetab + filetab[i];
1822 nseg += *pnt2.s;
1826 * Next allocate the header we will be returning.
1827 * There is one header for each segment, so that we can reach in
1828 * and pull bits as required.
1830 lt_hdr = (struct codeview_linetab_hdr *)
1831 DBG_alloc((nseg + 1) * sizeof(*lt_hdr));
1832 if( lt_hdr == NULL )
1834 goto leave;
1837 memset(lt_hdr, 0, sizeof(*lt_hdr) * (nseg+1));
1840 * Now fill the header we will be returning, one for each segment.
1841 * Note that this will basically just contain pointers into the existing
1842 * line table, and we do not actually copy any additional information
1843 * or allocate any additional memory.
1846 this_seg = 0;
1847 for(i=0; i<nfile; i++)
1850 * Get the pointer into the segment information.
1852 pnt2.c = linetab + filetab[i];
1853 file_segcount = *pnt2.s;
1855 pnt2.ui++;
1856 lt_ptr = (unsigned int *) pnt2.c;
1857 start = (struct startend *) (lt_ptr + file_segcount);
1860 * Now snarf the filename for all of the segments for this file.
1862 fn = (unsigned char *) (start + file_segcount);
1863 memset(filename, 0, sizeof(filename));
1864 memcpy(filename, fn + 1, *fn);
1865 fn = DBG_strdup(filename);
1867 for(k = 0; k < file_segcount; k++, this_seg++)
1869 pnt2.c = linetab + lt_ptr[k];
1870 lt_hdr[this_seg].start = start[k].start;
1871 lt_hdr[this_seg].end = start[k].end;
1872 lt_hdr[this_seg].sourcefile = fn;
1873 lt_hdr[this_seg].segno = *pnt2.s++;
1874 lt_hdr[this_seg].nline = *pnt2.s++;
1875 lt_hdr[this_seg].offtab = pnt2.ui;
1876 lt_hdr[this_seg].linetab = (unsigned short *)
1877 (pnt2.ui + lt_hdr[this_seg].nline);
1881 leave:
1883 return lt_hdr;
1888 /*========================================================================
1889 * Process CodeView symbol information.
1892 union codeview_symbol
1894 struct
1896 short int len;
1897 short int id;
1898 } generic;
1900 struct
1902 short int len;
1903 short int id;
1904 unsigned int offset;
1905 unsigned short seg;
1906 unsigned short symtype;
1907 unsigned char namelen;
1908 unsigned char name[1];
1909 } data;
1911 struct
1913 short int len;
1914 short int id;
1915 unsigned int symtype;
1916 unsigned int offset;
1917 unsigned short seg;
1918 unsigned char namelen;
1919 unsigned char name[1];
1920 } data32;
1922 struct
1924 short int len;
1925 short int id;
1926 unsigned int pparent;
1927 unsigned int pend;
1928 unsigned int next;
1929 unsigned int offset;
1930 unsigned short segment;
1931 unsigned short thunk_len;
1932 unsigned char thtype;
1933 unsigned char namelen;
1934 unsigned char name[1];
1935 } thunk;
1937 struct
1939 short int len;
1940 short int id;
1941 unsigned int pparent;
1942 unsigned int pend;
1943 unsigned int next;
1944 unsigned int proc_len;
1945 unsigned int debug_start;
1946 unsigned int debug_end;
1947 unsigned int offset;
1948 unsigned short segment;
1949 unsigned short proctype;
1950 unsigned char flags;
1951 unsigned char namelen;
1952 unsigned char name[1];
1953 } proc;
1955 struct
1957 short int len;
1958 short int id;
1959 unsigned int pparent;
1960 unsigned int pend;
1961 unsigned int next;
1962 unsigned int proc_len;
1963 unsigned int debug_start;
1964 unsigned int debug_end;
1965 unsigned int proctype;
1966 unsigned int offset;
1967 unsigned short segment;
1968 unsigned char flags;
1969 unsigned char namelen;
1970 unsigned char name[1];
1971 } proc32;
1973 struct
1975 short int len; /* Total length of this entry */
1976 short int id; /* Always S_BPREL32 */
1977 unsigned int offset; /* Stack offset relative to BP */
1978 unsigned short symtype;
1979 unsigned char namelen;
1980 unsigned char name[1];
1981 } stack;
1983 struct
1985 short int len; /* Total length of this entry */
1986 short int id; /* Always S_BPREL32 */
1987 unsigned int offset; /* Stack offset relative to BP */
1988 unsigned int symtype;
1989 unsigned char namelen;
1990 unsigned char name[1];
1991 } stack32;
1995 #define S_COMPILE 0x0001
1996 #define S_REGISTER 0x0002
1997 #define S_CONSTANT 0x0003
1998 #define S_UDT 0x0004
1999 #define S_SSEARCH 0x0005
2000 #define S_END 0x0006
2001 #define S_SKIP 0x0007
2002 #define S_CVRESERVE 0x0008
2003 #define S_OBJNAME 0x0009
2004 #define S_ENDARG 0x000a
2005 #define S_COBOLUDT 0x000b
2006 #define S_MANYREG 0x000c
2007 #define S_RETURN 0x000d
2008 #define S_ENTRYTHIS 0x000e
2010 #define S_BPREL 0x0200
2011 #define S_LDATA 0x0201
2012 #define S_GDATA 0x0202
2013 #define S_PUB 0x0203
2014 #define S_LPROC 0x0204
2015 #define S_GPROC 0x0205
2016 #define S_THUNK 0x0206
2017 #define S_BLOCK 0x0207
2018 #define S_WITH 0x0208
2019 #define S_LABEL 0x0209
2020 #define S_CEXMODEL 0x020a
2021 #define S_VFTPATH 0x020b
2022 #define S_REGREL 0x020c
2023 #define S_LTHREAD 0x020d
2024 #define S_GTHREAD 0x020e
2026 #define S_PROCREF 0x0400
2027 #define S_DATAREF 0x0401
2028 #define S_ALIGN 0x0402
2029 #define S_LPROCREF 0x0403
2031 #define S_REGISTER_32 0x1001 /* Variants with new 32-bit type indices */
2032 #define S_CONSTANT_32 0x1002
2033 #define S_UDT_32 0x1003
2034 #define S_COBOLUDT_32 0x1004
2035 #define S_MANYREG_32 0x1005
2037 #define S_BPREL_32 0x1006
2038 #define S_LDATA_32 0x1007
2039 #define S_GDATA_32 0x1008
2040 #define S_PUB_32 0x1009
2041 #define S_LPROC_32 0x100a
2042 #define S_GPROC_32 0x100b
2043 #define S_VFTTABLE_32 0x100c
2044 #define S_REGREL_32 0x100d
2045 #define S_LTHREAD_32 0x100e
2046 #define S_GTHREAD_32 0x100f
2050 static unsigned int
2051 DEBUG_MapCVOffset( DBG_MODULE *module, unsigned int offset )
2053 int nomap = module->msc_info->nomap;
2054 OMAP_DATA *omapp = module->msc_info->omapp;
2055 int i;
2057 if ( !nomap || !omapp )
2058 return offset;
2060 /* FIXME: use binary search */
2061 for ( i = 0; i < nomap-1; i++ )
2062 if ( omapp[i].from <= offset && omapp[i+1].from > offset )
2063 return !omapp[i].to? 0 : omapp[i].to + (offset - omapp[i].from);
2065 return 0;
2068 static struct name_hash *
2069 DEBUG_AddCVSymbol( DBG_MODULE *module, char *name, int namelen,
2070 int type, unsigned int seg, unsigned int offset,
2071 int size, int cookie, int flags,
2072 struct codeview_linetab_hdr *linetab )
2074 int nsect = module->msc_info->nsect;
2075 PIMAGE_SECTION_HEADER sectp = module->msc_info->sectp;
2077 struct name_hash *symbol;
2078 char symname[PATH_MAX];
2079 DBG_VALUE value;
2082 * Some sanity checks
2085 if ( !name || !namelen )
2086 return NULL;
2088 if ( !seg || seg > nsect )
2089 return NULL;
2092 * Convert type, address, and symbol name
2094 value.type = type? DEBUG_GetCVType( type ) : NULL;
2095 value.cookie = cookie;
2097 value.addr.seg = 0;
2098 value.addr.off = (unsigned int) module->load_addr +
2099 DEBUG_MapCVOffset( module, sectp[seg-1].VirtualAddress + offset );
2101 memcpy( symname, name, namelen );
2102 symname[namelen] = '\0';
2106 * Check whether we have line number information
2108 if ( linetab )
2110 for ( ; linetab->linetab; linetab++ )
2111 if ( linetab->segno == seg
2112 && linetab->start <= offset
2113 && linetab->end > offset )
2114 break;
2116 if ( !linetab->linetab )
2117 linetab = NULL;
2122 * Create Wine symbol record
2124 symbol = DEBUG_AddSymbol( symname, &value,
2125 linetab? linetab->sourcefile : NULL, flags );
2127 if ( size )
2128 DEBUG_SetSymbolSize( symbol, size );
2132 * Add line numbers if found
2134 if ( linetab )
2136 unsigned int i;
2137 for ( i = 0; i < linetab->nline; i++ )
2138 if ( linetab->offtab[i] >= offset
2139 && linetab->offtab[i] < offset + size )
2141 DEBUG_AddLineNumber( symbol, linetab->linetab[i],
2142 linetab->offtab[i] - offset );
2146 return symbol;
2149 static struct wine_locals *
2150 DEBUG_AddCVLocal( struct name_hash *func, char *name, int namelen,
2151 int type, int offset )
2153 struct wine_locals *local;
2154 char symname[PATH_MAX];
2156 memcpy( symname, name, namelen );
2157 symname[namelen] = '\0';
2159 local = DEBUG_AddLocal( func, 0, offset, 0, 0, symname );
2160 DEBUG_SetLocalSymbolType( local, DEBUG_GetCVType( type ) );
2162 return local;
2165 static int
2166 DEBUG_SnarfCodeView( DBG_MODULE *module, LPBYTE root, int offset, int size,
2167 struct codeview_linetab_hdr *linetab )
2169 struct name_hash *curr_func = NULL;
2170 int i, length;
2174 * Loop over the different types of records and whenever we
2175 * find something we are interested in, record it and move on.
2177 for ( i = offset; i < size; i += length )
2179 union codeview_symbol *sym = (union codeview_symbol *)(root + i);
2180 length = sym->generic.len + 2;
2182 switch ( sym->generic.id )
2185 * Global and local data symbols. We don't associate these
2186 * with any given source file.
2188 case S_GDATA:
2189 case S_LDATA:
2190 case S_PUB:
2191 DEBUG_AddCVSymbol( module, sym->data.name, sym->data.namelen,
2192 sym->data.symtype, sym->data.seg,
2193 sym->data.offset, 0,
2194 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2195 break;
2196 case S_GDATA_32:
2197 case S_LDATA_32:
2198 case S_PUB_32:
2199 DEBUG_AddCVSymbol( module, sym->data32.name, sym->data32.namelen,
2200 sym->data32.symtype, sym->data32.seg,
2201 sym->data32.offset, 0,
2202 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2203 break;
2206 * Sort of like a global function, but it just points
2207 * to a thunk, which is a stupid name for what amounts to
2208 * a PLT slot in the normal jargon that everyone else uses.
2210 case S_THUNK:
2211 DEBUG_AddCVSymbol( module, sym->thunk.name, sym->thunk.namelen,
2212 0, sym->thunk.segment,
2213 sym->thunk.offset, sym->thunk.thunk_len,
2214 DV_TARGET, SYM_WIN32 | SYM_FUNC, NULL );
2215 break;
2218 * Global and static functions.
2220 case S_GPROC:
2221 case S_LPROC:
2222 DEBUG_Normalize( curr_func );
2224 curr_func = DEBUG_AddCVSymbol( module, sym->proc.name, sym->proc.namelen,
2225 sym->proc.proctype, sym->proc.segment,
2226 sym->proc.offset, sym->proc.proc_len,
2227 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
2229 DEBUG_SetSymbolBPOff( curr_func, sym->proc.debug_start );
2230 break;
2231 case S_GPROC_32:
2232 case S_LPROC_32:
2233 DEBUG_Normalize( curr_func );
2235 curr_func = DEBUG_AddCVSymbol( module, sym->proc32.name, sym->proc32.namelen,
2236 sym->proc32.proctype, sym->proc32.segment,
2237 sym->proc32.offset, sym->proc32.proc_len,
2238 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
2240 DEBUG_SetSymbolBPOff( curr_func, sym->proc32.debug_start );
2241 break;
2245 * Function parameters and stack variables.
2247 case S_BPREL:
2248 DEBUG_AddCVLocal( curr_func, sym->stack.name, sym->stack.namelen,
2249 sym->stack.symtype, sym->stack.offset );
2250 break;
2251 case S_BPREL_32:
2252 DEBUG_AddCVLocal( curr_func, sym->stack32.name, sym->stack32.namelen,
2253 sym->stack32.symtype, sym->stack32.offset );
2254 break;
2258 * These are special, in that they are always followed by an
2259 * additional length-prefixed string which is *not* included
2260 * into the symbol length count. We need to skip it.
2262 case S_PROCREF:
2263 case S_DATAREF:
2264 case S_LPROCREF:
2266 LPBYTE name = (LPBYTE)sym + length;
2267 length += (*name + 1 + 3) & ~3;
2268 break;
2273 DEBUG_Normalize( curr_func );
2275 if ( linetab ) DBG_free(linetab);
2276 return TRUE;
2281 /*========================================================================
2282 * Process PDB file.
2285 #pragma pack(1)
2286 typedef struct _PDB_FILE
2288 DWORD size;
2289 DWORD unknown;
2291 } PDB_FILE, *PPDB_FILE;
2293 typedef struct _PDB_HEADER
2295 CHAR ident[40];
2296 DWORD signature;
2297 DWORD blocksize;
2298 WORD freelist;
2299 WORD total_alloc;
2300 PDB_FILE toc;
2301 WORD toc_block[ 1 ];
2303 } PDB_HEADER, *PPDB_HEADER;
2305 typedef struct _PDB_TOC
2307 DWORD nFiles;
2308 PDB_FILE file[ 1 ];
2310 } PDB_TOC, *PPDB_TOC;
2312 typedef struct _PDB_ROOT
2314 DWORD version;
2315 DWORD TimeDateStamp;
2316 DWORD unknown;
2317 DWORD cbNames;
2318 CHAR names[ 1 ];
2320 } PDB_ROOT, *PPDB_ROOT;
2322 typedef struct _PDB_TYPES_OLD
2324 DWORD version;
2325 WORD first_index;
2326 WORD last_index;
2327 DWORD type_size;
2328 WORD file;
2329 WORD pad;
2331 } PDB_TYPES_OLD, *PPDB_TYPES_OLD;
2333 typedef struct _PDB_TYPES
2335 DWORD version;
2336 DWORD type_offset;
2337 DWORD first_index;
2338 DWORD last_index;
2339 DWORD type_size;
2340 WORD file;
2341 WORD pad;
2342 DWORD hash_size;
2343 DWORD hash_base;
2344 DWORD hash_offset;
2345 DWORD hash_len;
2346 DWORD search_offset;
2347 DWORD search_len;
2348 DWORD unknown_offset;
2349 DWORD unknown_len;
2351 } PDB_TYPES, *PPDB_TYPES;
2353 typedef struct _PDB_SYMBOL_RANGE
2355 WORD segment;
2356 WORD pad1;
2357 DWORD offset;
2358 DWORD size;
2359 DWORD characteristics;
2360 WORD index;
2361 WORD pad2;
2363 } PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
2365 typedef struct _PDB_SYMBOL_RANGE_EX
2367 WORD segment;
2368 WORD pad1;
2369 DWORD offset;
2370 DWORD size;
2371 DWORD characteristics;
2372 WORD index;
2373 WORD pad2;
2374 DWORD timestamp;
2375 DWORD unknown;
2377 } PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
2379 typedef struct _PDB_SYMBOL_FILE
2381 DWORD unknown1;
2382 PDB_SYMBOL_RANGE range;
2383 WORD flag;
2384 WORD file;
2385 DWORD symbol_size;
2386 DWORD lineno_size;
2387 DWORD unknown2;
2388 DWORD nSrcFiles;
2389 DWORD attribute;
2390 CHAR filename[ 1 ];
2392 } PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
2394 typedef struct _PDB_SYMBOL_FILE_EX
2396 DWORD unknown1;
2397 PDB_SYMBOL_RANGE_EX range;
2398 WORD flag;
2399 WORD file;
2400 DWORD symbol_size;
2401 DWORD lineno_size;
2402 DWORD unknown2;
2403 DWORD nSrcFiles;
2404 DWORD attribute;
2405 DWORD reserved[ 2 ];
2406 CHAR filename[ 1 ];
2408 } PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
2410 typedef struct _PDB_SYMBOL_SOURCE
2412 WORD nModules;
2413 WORD nSrcFiles;
2414 WORD table[ 1 ];
2416 } PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
2418 typedef struct _PDB_SYMBOL_IMPORT
2420 DWORD unknown1;
2421 DWORD unknown2;
2422 DWORD TimeDateStamp;
2423 DWORD nRequests;
2424 CHAR filename[ 1 ];
2426 } PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
2428 typedef struct _PDB_SYMBOLS_OLD
2430 WORD hash1_file;
2431 WORD hash2_file;
2432 WORD gsym_file;
2433 WORD pad;
2434 DWORD module_size;
2435 DWORD offset_size;
2436 DWORD hash_size;
2437 DWORD srcmodule_size;
2439 } PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
2441 typedef struct _PDB_SYMBOLS
2443 DWORD signature;
2444 DWORD version;
2445 DWORD unknown;
2446 DWORD hash1_file;
2447 DWORD hash2_file;
2448 DWORD gsym_file;
2449 DWORD module_size;
2450 DWORD offset_size;
2451 DWORD hash_size;
2452 DWORD srcmodule_size;
2453 DWORD pdbimport_size;
2454 DWORD resvd[ 5 ];
2456 } PDB_SYMBOLS, *PPDB_SYMBOLS;
2457 #pragma pack()
2460 static void *pdb_read( LPBYTE image, WORD *block_list, int size )
2462 PPDB_HEADER pdb = (PPDB_HEADER)image;
2463 int i, nBlocks;
2464 LPBYTE buffer;
2466 if ( !size ) return NULL;
2468 nBlocks = (size + pdb->blocksize-1) / pdb->blocksize;
2469 buffer = DBG_alloc( nBlocks * pdb->blocksize );
2471 for ( i = 0; i < nBlocks; i++ )
2472 memcpy( buffer + i*pdb->blocksize,
2473 image + block_list[i]*pdb->blocksize, pdb->blocksize );
2475 return buffer;
2478 static void *pdb_read_file( LPBYTE image, PPDB_TOC toc, DWORD fileNr )
2480 PPDB_HEADER pdb = (PPDB_HEADER)image;
2481 WORD *block_list;
2482 DWORD i;
2484 if ( !toc || fileNr >= toc->nFiles )
2485 return NULL;
2487 block_list = (WORD *) &toc->file[ toc->nFiles ];
2488 for ( i = 0; i < fileNr; i++ )
2489 block_list += (toc->file[i].size + pdb->blocksize-1) / pdb->blocksize;
2491 return pdb_read( image, block_list, toc->file[fileNr].size );
2494 static void pdb_free( void *buffer )
2496 DBG_free( buffer );
2499 static void pdb_convert_types_header( PDB_TYPES *types, char *image )
2501 memset( types, 0, sizeof(PDB_TYPES) );
2502 if ( !image ) return;
2504 if ( *(DWORD *)image < 19960000 ) /* FIXME: correct version? */
2506 /* Old version of the types record header */
2507 PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
2508 types->version = old->version;
2509 types->type_offset = sizeof(PDB_TYPES_OLD);
2510 types->type_size = old->type_size;
2511 types->first_index = old->first_index;
2512 types->last_index = old->last_index;
2513 types->file = old->file;
2515 else
2517 /* New version of the types record header */
2518 *types = *(PDB_TYPES *)image;
2522 static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
2523 int *header_size, char *image )
2525 memset( symbols, 0, sizeof(PDB_SYMBOLS) );
2526 if ( !image ) return;
2528 if ( *(DWORD *)image != 0xffffffff )
2530 /* Old version of the symbols record header */
2531 PDB_SYMBOLS_OLD *old = (PDB_SYMBOLS_OLD *)image;
2532 symbols->version = 0;
2533 symbols->module_size = old->module_size;
2534 symbols->offset_size = old->offset_size;
2535 symbols->hash_size = old->hash_size;
2536 symbols->srcmodule_size = old->srcmodule_size;
2537 symbols->pdbimport_size = 0;
2538 symbols->hash1_file = old->hash1_file;
2539 symbols->hash2_file = old->hash2_file;
2540 symbols->gsym_file = old->gsym_file;
2542 *header_size = sizeof(PDB_SYMBOLS_OLD);
2544 else
2546 /* New version of the symbols record header */
2547 *symbols = *(PDB_SYMBOLS *)image;
2549 *header_size = sizeof(PDB_SYMBOLS);
2553 static enum DbgInfoLoad DEBUG_ProcessPDBFile( DBG_MODULE *module,
2554 const char *filename, DWORD timestamp )
2556 enum DbgInfoLoad dil = DIL_ERROR;
2557 HANDLE hFile, hMap;
2558 char *image = NULL;
2559 PDB_HEADER *pdb = NULL;
2560 PDB_TOC *toc = NULL;
2561 PDB_ROOT *root = NULL;
2562 char *types_image = NULL;
2563 char *symbols_image = NULL;
2564 PDB_TYPES types;
2565 PDB_SYMBOLS symbols;
2566 int header_size = 0;
2567 char *modimage, *file;
2569 DEBUG_Printf( DBG_CHN_TRACE, "Processing PDB file %s\n", filename );
2572 * Open and map() .PDB file
2574 image = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2575 if ( !image )
2577 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .PDB file %s\n", filename );
2578 goto leave;
2582 * Read in TOC and well-known files
2585 pdb = (PPDB_HEADER)image;
2586 toc = pdb_read( image, pdb->toc_block, pdb->toc.size );
2587 root = pdb_read_file( image, toc, 1 );
2588 types_image = pdb_read_file( image, toc, 2 );
2589 symbols_image = pdb_read_file( image, toc, 3 );
2591 pdb_convert_types_header( &types, types_image );
2592 pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2594 if ( !root )
2596 DEBUG_Printf( DBG_CHN_ERR,
2597 "-Unable to get root from .PDB file %s\n",
2598 filename );
2599 goto leave;
2603 * Check for unknown versions
2606 switch ( root->version )
2608 case 19950623: /* VC 4.0 */
2609 case 19950814:
2610 case 19960307: /* VC 5.0 */
2611 case 19970604: /* VC 6.0 */
2612 break;
2613 default:
2614 DEBUG_Printf( DBG_CHN_ERR, "-Unknown root block version %ld\n", root->version );
2617 switch ( types.version )
2619 case 19950410: /* VC 4.0 */
2620 case 19951122:
2621 case 19961031: /* VC 5.0 / 6.0 */
2622 break;
2623 default:
2624 DEBUG_Printf( DBG_CHN_ERR, "-Unknown type info version %ld\n", types.version );
2627 switch ( symbols.version )
2629 case 0: /* VC 4.0 */
2630 case 19960307: /* VC 5.0 */
2631 case 19970606: /* VC 6.0 */
2632 break;
2633 default:
2634 DEBUG_Printf( DBG_CHN_ERR, "-Unknown symbol info version %ld\n", symbols.version );
2639 * Check .PDB time stamp
2642 if ( root->TimeDateStamp != timestamp )
2644 DEBUG_Printf( DBG_CHN_ERR, "-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2645 filename, root->TimeDateStamp, timestamp );
2649 * Read type table
2652 DEBUG_ParseTypeTable( types_image + types.type_offset, types.type_size );
2655 * Read type-server .PDB imports
2658 if ( symbols.pdbimport_size )
2660 /* FIXME */
2661 DEBUG_Printf(DBG_CHN_ERR, "-Type server .PDB imports ignored!\n" );
2665 * Read global symbol table
2668 modimage = pdb_read_file( image, toc, symbols.gsym_file );
2669 if ( modimage )
2671 DEBUG_SnarfCodeView( module, modimage, 0,
2672 toc->file[symbols.gsym_file].size, NULL );
2673 pdb_free( modimage );
2677 * Read per-module symbol / linenumber tables
2680 file = symbols_image + header_size;
2681 while ( file - symbols_image < header_size + symbols.module_size )
2683 int file_nr, file_index, symbol_size, lineno_size;
2684 char *file_name;
2686 if ( symbols.version < 19970000 )
2688 PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
2689 file_nr = sym_file->file;
2690 file_name = sym_file->filename;
2691 file_index = sym_file->range.index;
2692 symbol_size = sym_file->symbol_size;
2693 lineno_size = sym_file->lineno_size;
2695 else
2697 PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
2698 file_nr = sym_file->file;
2699 file_name = sym_file->filename;
2700 file_index = sym_file->range.index;
2701 symbol_size = sym_file->symbol_size;
2702 lineno_size = sym_file->lineno_size;
2705 modimage = pdb_read_file( image, toc, file_nr );
2706 if ( modimage )
2708 struct codeview_linetab_hdr *linetab = NULL;
2710 if ( lineno_size )
2711 linetab = DEBUG_SnarfLinetab( modimage + symbol_size, lineno_size );
2713 if ( symbol_size )
2714 DEBUG_SnarfCodeView( module, modimage, sizeof(DWORD),
2715 symbol_size, linetab );
2717 pdb_free( modimage );
2720 file_name += strlen(file_name) + 1;
2721 file = (char *)( (DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3 );
2724 dil = DIL_LOADED;
2726 leave:
2729 * Cleanup
2732 DEBUG_ClearTypeTable();
2734 if ( symbols_image ) pdb_free( symbols_image );
2735 if ( types_image ) pdb_free( types_image );
2736 if ( root ) pdb_free( root );
2737 if ( toc ) pdb_free( toc );
2739 DEBUG_UnmapDebugInfoFile(hFile, hMap, image);
2741 return dil;
2747 /*========================================================================
2748 * Process CodeView debug information.
2751 #define CODEVIEW_NB09_SIG ( 'N' | ('B' << 8) | ('0' << 16) | ('9' << 24) )
2752 #define CODEVIEW_NB10_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('0' << 24) )
2753 #define CODEVIEW_NB11_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('1' << 24) )
2755 typedef struct _CODEVIEW_HEADER
2757 DWORD dwSignature;
2758 DWORD lfoDirectory;
2760 } CODEVIEW_HEADER, *PCODEVIEW_HEADER;
2762 typedef struct _CODEVIEW_PDB_DATA
2764 DWORD timestamp;
2765 DWORD unknown;
2766 CHAR name[ 1 ];
2768 } CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA;
2770 typedef struct _CV_DIRECTORY_HEADER
2772 WORD cbDirHeader;
2773 WORD cbDirEntry;
2774 DWORD cDir;
2775 DWORD lfoNextDir;
2776 DWORD flags;
2778 } CV_DIRECTORY_HEADER, *PCV_DIRECTORY_HEADER;
2780 typedef struct _CV_DIRECTORY_ENTRY
2782 WORD subsection;
2783 WORD iMod;
2784 DWORD lfo;
2785 DWORD cb;
2787 } CV_DIRECTORY_ENTRY, *PCV_DIRECTORY_ENTRY;
2790 #define sstAlignSym 0x125
2791 #define sstSrcModule 0x127
2794 static enum DbgInfoLoad DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
2796 PCODEVIEW_HEADER cv = (PCODEVIEW_HEADER)root;
2797 enum DbgInfoLoad dil = DIL_ERROR;
2799 switch ( cv->dwSignature )
2801 case CODEVIEW_NB09_SIG:
2802 case CODEVIEW_NB11_SIG:
2804 PCV_DIRECTORY_HEADER hdr = (PCV_DIRECTORY_HEADER)(root + cv->lfoDirectory);
2805 PCV_DIRECTORY_ENTRY ent, prev, next;
2806 unsigned int i;
2808 ent = (PCV_DIRECTORY_ENTRY)((LPBYTE)hdr + hdr->cbDirHeader);
2809 for ( i = 0; i < hdr->cDir; i++, ent = next )
2811 next = (i == hdr->cDir-1)? NULL :
2812 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent + hdr->cbDirEntry);
2813 prev = (i == 0)? NULL :
2814 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent - hdr->cbDirEntry);
2816 if ( ent->subsection == sstAlignSym )
2819 * Check the next and previous entry. If either is a
2820 * sstSrcModule, it contains the line number info for
2821 * this file.
2823 * FIXME: This is not a general solution!
2825 struct codeview_linetab_hdr *linetab = NULL;
2827 if ( next && next->iMod == ent->iMod
2828 && next->subsection == sstSrcModule )
2829 linetab = DEBUG_SnarfLinetab( root + next->lfo, next->cb );
2831 if ( prev && prev->iMod == ent->iMod
2832 && prev->subsection == sstSrcModule )
2833 linetab = DEBUG_SnarfLinetab( root + prev->lfo, prev->cb );
2836 DEBUG_SnarfCodeView( module, root + ent->lfo, sizeof(DWORD),
2837 ent->cb, linetab );
2841 dil = DIL_LOADED;
2842 break;
2845 case CODEVIEW_NB10_SIG:
2847 PCODEVIEW_PDB_DATA pdb = (PCODEVIEW_PDB_DATA)(cv + 1);
2849 dil = DEBUG_ProcessPDBFile( module, pdb->name, pdb->timestamp );
2850 break;
2853 default:
2854 DEBUG_Printf( DBG_CHN_ERR, "Unknown CODEVIEW signature %08lX in module %s\n",
2855 cv->dwSignature, module->module_name );
2856 break;
2859 return dil;
2863 /*========================================================================
2864 * Process debug directory.
2866 static enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module,
2867 LPBYTE file_map,
2868 PIMAGE_DEBUG_DIRECTORY dbg,
2869 int nDbg )
2871 enum DbgInfoLoad dil;
2872 int i;
2873 __TRY {
2874 dil = DIL_ERROR;
2875 /* First, watch out for OMAP data */
2876 for ( i = 0; i < nDbg; i++ )
2878 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC )
2880 module->msc_info->nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
2881 module->msc_info->omapp = (OMAP_DATA *)(file_map + dbg[i].PointerToRawData);
2882 break;
2886 /* Now, try to parse CodeView debug info */
2887 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
2889 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW )
2891 dil = DEBUG_ProcessCodeView( module, file_map + dbg[i].PointerToRawData );
2895 /* If not found, try to parse COFF debug info */
2896 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
2898 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_COFF )
2899 dil = DEBUG_ProcessCoff( module, file_map + dbg[i].PointerToRawData );
2901 #if 0
2902 /* FIXME: this should be supported... this is the debug information for
2903 * functions compiled without a frame pointer (FPO = frame pointer omission)
2904 * the associated data helps finding out the relevant information
2906 for ( i = 0; i < nDbg; i++ )
2907 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_FPO )
2908 DEBUG_Printf(DBG_CHN_MESG, "This guy has FPO information\n");
2910 #define FRAME_FPO 0
2911 #define FRAME_TRAP 1
2912 #define FRAME_TSS 2
2914 typedef struct _FPO_DATA {
2915 DWORD ulOffStart; /* offset 1st byte of function code */
2916 DWORD cbProcSize; /* # bytes in function */
2917 DWORD cdwLocals; /* # bytes in locals/4 */
2918 WORD cdwParams; /* # bytes in params/4 */
2920 WORD cbProlog : 8; /* # bytes in prolog */
2921 WORD cbRegs : 3; /* # regs saved */
2922 WORD fHasSEH : 1; /* TRUE if SEH in func */
2923 WORD fUseBP : 1; /* TRUE if EBP has been allocated */
2924 WORD reserved : 1; /* reserved for future use */
2925 WORD cbFrame : 2; /* frame type */
2926 } FPO_DATA;
2927 #endif
2929 __EXCEPT(page_fault)
2931 return DIL_ERROR;
2933 __ENDTRY
2934 return dil;
2938 /*========================================================================
2939 * Process DBG file.
2941 static enum DbgInfoLoad DEBUG_ProcessDBGFile( DBG_MODULE *module,
2942 const char *filename, DWORD timestamp )
2944 enum DbgInfoLoad dil = DIL_ERROR;
2945 HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
2946 LPBYTE file_map = NULL;
2947 PIMAGE_SEPARATE_DEBUG_HEADER hdr;
2948 PIMAGE_DEBUG_DIRECTORY dbg;
2949 int nDbg;
2952 DEBUG_Printf( DBG_CHN_TRACE, "Processing DBG file %s\n", filename );
2954 file_map = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2955 if ( !file_map )
2957 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .DBG file %s\n", filename );
2958 goto leave;
2961 hdr = (PIMAGE_SEPARATE_DEBUG_HEADER) file_map;
2963 if ( hdr->TimeDateStamp != timestamp )
2965 DEBUG_Printf( DBG_CHN_ERR, "Warning - %s has incorrect internal timestamp\n",
2966 filename );
2968 * Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
2969 * files but nonetheless this check fails. Anyway, WINDBG (debugger for
2970 * Windows by Microsoft) loads debug symbols which have incorrect timestamps.
2975 dbg = (PIMAGE_DEBUG_DIRECTORY) ( file_map + sizeof(*hdr)
2976 + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
2977 + hdr->ExportedNamesSize );
2979 nDbg = hdr->DebugDirectorySize / sizeof(*dbg);
2981 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
2984 leave:
2985 DEBUG_UnmapDebugInfoFile( hFile, hMap, file_map );
2986 return dil;
2990 /*========================================================================
2991 * Process MSC debug information in PE file.
2993 enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
2994 void *_nth, unsigned long nth_ofs )
2996 enum DbgInfoLoad dil = DIL_ERROR;
2997 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
2998 PIMAGE_DATA_DIRECTORY dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
2999 PIMAGE_DEBUG_DIRECTORY dbg = NULL;
3000 int nDbg;
3001 MSC_DBG_INFO extra_info = { 0, NULL, 0, NULL };
3002 HANDLE hMap = 0;
3003 LPBYTE file_map = NULL;
3006 /* Read in section data */
3008 module->msc_info = &extra_info;
3009 extra_info.nsect = nth->FileHeader.NumberOfSections;
3010 extra_info.sectp = DBG_alloc( extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) );
3011 if ( !extra_info.sectp )
3012 goto leave;
3014 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr +
3015 nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
3016 nth->FileHeader.SizeOfOptionalHeader,
3017 extra_info.sectp,
3018 extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) ) )
3019 goto leave;
3021 /* Read in debug directory */
3023 nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
3024 if ( !nDbg )
3025 goto leave;
3027 dbg = (PIMAGE_DEBUG_DIRECTORY) DBG_alloc( nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) );
3028 if ( !dbg )
3029 goto leave;
3031 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr + dir->VirtualAddress,
3032 dbg, nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) ) )
3033 goto leave;
3036 /* Map in PE file */
3037 file_map = DEBUG_MapDebugInfoFile( NULL, 0, 0, &hFile, &hMap );
3038 if ( !file_map )
3039 goto leave;
3042 /* Parse debug directory */
3044 if ( nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED )
3046 /* Debug info is stripped to .DBG file */
3048 PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)(file_map + dbg->PointerToRawData);
3050 if ( nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC
3051 || misc->DataType != IMAGE_DEBUG_MISC_EXENAME )
3053 DEBUG_Printf( DBG_CHN_ERR, "-Debug info stripped, but no .DBG file in module %s\n",
3054 module->module_name );
3055 goto leave;
3058 dil = DEBUG_ProcessDBGFile( module, misc->Data, nth->FileHeader.TimeDateStamp );
3060 else
3062 /* Debug info is embedded into PE module */
3063 /* FIXME: the nDBG information we're manipulating comes from the debuggee
3064 * address space. However, the following code will be made against the
3065 * version mapped in the debugger address space. There are cases (for example
3066 * when the PE sections are compressed in the file and become decompressed
3067 * in the debuggee address space) where the two don't match.
3068 * Therefore, redo the DBG information lookup with the mapped data
3070 PIMAGE_NT_HEADERS mpd_nth = (PIMAGE_NT_HEADERS)(file_map + nth_ofs);
3071 PIMAGE_DATA_DIRECTORY mpd_dir;
3072 PIMAGE_DEBUG_DIRECTORY mpd_dbg = NULL;
3074 /* sanity checks */
3075 if ( mpd_nth->Signature != IMAGE_NT_SIGNATURE ||
3076 mpd_nth->FileHeader.NumberOfSections != nth->FileHeader.NumberOfSections ||
3077 (mpd_nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) != 0)
3078 goto leave;
3079 mpd_dir = mpd_nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
3081 if ((mpd_dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY)) != nDbg)
3082 goto leave;
3084 mpd_dbg = (PIMAGE_DEBUG_DIRECTORY)(file_map + mpd_dir->VirtualAddress);
3086 dil = DEBUG_ProcessDebugDirectory( module, file_map, mpd_dbg, nDbg );
3090 leave:
3091 module->msc_info = NULL;
3093 DEBUG_UnmapDebugInfoFile( 0, hMap, file_map );
3094 if ( extra_info.sectp ) DBG_free( extra_info.sectp );
3095 if ( dbg ) DBG_free( dbg );
3096 return dil;
3100 /*========================================================================
3101 * look for stabs information in PE header (it's how mingw compiler provides its
3102 * debugging information), and also wine PE <-> ELF linking through .wsolnk sections
3104 enum DbgInfoLoad DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile,
3105 void* _nth, unsigned long nth_ofs)
3107 IMAGE_SECTION_HEADER pe_seg;
3108 unsigned long pe_seg_ofs;
3109 int i, stabsize = 0, stabstrsize = 0;
3110 unsigned int stabs = 0, stabstr = 0;
3111 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
3112 enum DbgInfoLoad dil = DIL_ERROR;
3114 pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
3115 nth->FileHeader.SizeOfOptionalHeader;
3117 for (i = 0; i < nth->FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
3118 if (!DEBUG_READ_MEM_VERBOSE((void*)((char *)module->load_addr + pe_seg_ofs),
3119 &pe_seg, sizeof(pe_seg)))
3120 continue;
3122 if (!strcasecmp(pe_seg.Name, ".stab")) {
3123 stabs = pe_seg.VirtualAddress;
3124 stabsize = pe_seg.SizeOfRawData;
3125 } else if (!strncasecmp(pe_seg.Name, ".stabstr", 8)) {
3126 stabstr = pe_seg.VirtualAddress;
3127 stabstrsize = pe_seg.SizeOfRawData;
3131 if (stabstrsize && stabsize) {
3132 char* s1 = DBG_alloc(stabsize+stabstrsize);
3134 if (s1) {
3135 if (DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabs, s1, stabsize) &&
3136 DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabstr,
3137 s1 + stabsize, stabstrsize)) {
3138 dil = DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
3139 } else {
3140 DEBUG_Printf(DBG_CHN_MESG, "couldn't read data block\n");
3142 DBG_free(s1);
3143 } else {
3144 DEBUG_Printf(DBG_CHN_MESG, "couldn't alloc %d bytes\n",
3145 stabsize + stabstrsize);
3147 } else {
3148 dil = DIL_NOINFO;
3150 return dil;