Store print dlg structure in a property instead of DWL_USER.
[wine.git] / debugger / msc.c
blobf18933cbbf10ebbad7aea8cf9df72a4494eee51c
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 "debugger.h"
42 #define MAX_PATHNAME_LEN 1024
44 typedef struct
46 DWORD from;
47 DWORD to;
49 } OMAP_DATA;
51 typedef struct tagMSC_DBG_INFO
53 int nsect;
54 PIMAGE_SECTION_HEADER sectp;
56 int nomap;
57 OMAP_DATA * omapp;
59 } MSC_DBG_INFO;
61 /*========================================================================
62 * Debug file access helper routines
66 /***********************************************************************
67 * DEBUG_LocateDebugInfoFile
69 * NOTE: dbg_filename must be at least MAX_PATHNAME_LEN bytes in size
71 static void DEBUG_LocateDebugInfoFile(const char *filename, char *dbg_filename)
73 char *str1 = DBG_alloc(MAX_PATHNAME_LEN);
74 char *str2 = DBG_alloc(MAX_PATHNAME_LEN*10);
75 const char *file;
76 char *name_part;
78 file = strrchr(filename, '\\');
79 if( file == NULL ) file = filename; else file++;
81 if ((GetEnvironmentVariable("_NT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
82 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
83 (GetEnvironmentVariable("_NT_ALT_SYMBOL_PATH", str1, MAX_PATHNAME_LEN) &&
84 (SearchPath(str1, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part))) ||
85 (SearchPath(NULL, file, NULL, MAX_PATHNAME_LEN*10, str2, &name_part)))
86 lstrcpyn(dbg_filename, str2, MAX_PATHNAME_LEN);
87 else
88 lstrcpyn(dbg_filename, filename, MAX_PATHNAME_LEN);
89 DBG_free(str1);
90 DBG_free(str2);
93 /***********************************************************************
94 * DEBUG_MapDebugInfoFile
96 static void* DEBUG_MapDebugInfoFile(const char* name, DWORD offset, DWORD size,
97 HANDLE* hFile, HANDLE* hMap)
99 DWORD g_offset; /* offset aligned on map granuality */
100 DWORD g_size; /* size to map, with offset aligned */
101 char* ret;
103 *hMap = 0;
105 if (name != NULL) {
106 char filename[MAX_PATHNAME_LEN];
108 DEBUG_LocateDebugInfoFile(name, filename);
109 if ((*hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
110 return NULL;
113 if (!size) {
114 DWORD file_size = GetFileSize(*hFile, NULL);
115 if (file_size == (DWORD)-1) return NULL;
116 size = file_size - offset;
119 g_offset = offset & ~0xFFFF; /* FIXME: is granularity portable ? */
120 g_size = offset + size - g_offset;
122 if ((*hMap = CreateFileMapping(*hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == 0)
123 return NULL;
125 if ((ret = MapViewOfFile(*hMap, FILE_MAP_READ, 0, g_offset, g_size)) != NULL)
126 ret += offset - g_offset;
128 return ret;
131 /***********************************************************************
132 * DEBUG_UnmapDebugInfoFile
134 static void DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, void* addr)
136 if (addr) UnmapViewOfFile(addr);
137 if (hMap) CloseHandle(hMap);
138 if (hFile!=INVALID_HANDLE_VALUE) CloseHandle(hFile);
143 /*========================================================================
144 * Process COFF debug information.
147 struct CoffFile
149 unsigned int startaddr;
150 unsigned int endaddr;
151 const char *filename;
152 int linetab_offset;
153 int linecnt;
154 struct name_hash **entries;
155 int neps;
156 int neps_alloc;
159 struct CoffFileSet
161 struct CoffFile *files;
162 int nfiles;
163 int nfiles_alloc;
166 static const char* DEBUG_GetCoffName( PIMAGE_SYMBOL coff_sym, const char* coff_strtab )
168 static char namebuff[9];
169 const char* nampnt;
171 if( coff_sym->N.Name.Short )
173 memcpy(namebuff, coff_sym->N.ShortName, 8);
174 namebuff[8] = '\0';
175 nampnt = &namebuff[0];
177 else
179 nampnt = coff_strtab + coff_sym->N.Name.Long;
182 if( nampnt[0] == '_' )
183 nampnt++;
184 return nampnt;
187 static int DEBUG_AddCoffFile( struct CoffFileSet* coff_files, const char* filename )
189 struct CoffFile* file;
191 if( coff_files->nfiles + 1 >= coff_files->nfiles_alloc )
193 coff_files->nfiles_alloc += 10;
194 coff_files->files = (struct CoffFile *) DBG_realloc(coff_files->files,
195 coff_files->nfiles_alloc * sizeof(struct CoffFile));
197 file = coff_files->files + coff_files->nfiles;
198 file->startaddr = 0xffffffff;
199 file->endaddr = 0;
200 file->filename = filename;
201 file->linetab_offset = -1;
202 file->linecnt = 0;
203 file->entries = NULL;
204 file->neps = file->neps_alloc = 0;
206 return coff_files->nfiles++;
209 static void DEBUG_AddCoffSymbol( struct CoffFile* coff_file, struct name_hash* sym )
211 if( coff_file->neps + 1 >= coff_file->neps_alloc )
213 coff_file->neps_alloc += 10;
214 coff_file->entries = (struct name_hash **)
215 DBG_realloc(coff_file->entries,
216 coff_file->neps_alloc * sizeof(struct name_hash *));
218 coff_file->entries[coff_file->neps++] = sym;
221 static enum DbgInfoLoad DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
223 PIMAGE_AUX_SYMBOL aux;
224 PIMAGE_COFF_SYMBOLS_HEADER coff;
225 PIMAGE_LINENUMBER coff_linetab;
226 PIMAGE_LINENUMBER linepnt;
227 char * coff_strtab;
228 PIMAGE_SYMBOL coff_sym;
229 PIMAGE_SYMBOL coff_symbols;
230 struct CoffFileSet coff_files;
231 int curr_file_idx = -1;
232 unsigned int i;
233 int j;
234 int k;
235 int l;
236 int linetab_indx;
237 const char * nampnt;
238 int naux;
239 DBG_VALUE new_value;
240 enum DbgInfoLoad dil = DIL_ERROR;
242 DEBUG_Printf(DBG_CHN_TRACE, "Processing COFF symbols...\n");
244 assert(sizeof(IMAGE_SYMBOL) == IMAGE_SIZEOF_SYMBOL);
245 assert(sizeof(IMAGE_LINENUMBER) == IMAGE_SIZEOF_LINENUMBER);
247 coff_files.files = NULL;
248 coff_files.nfiles = coff_files.nfiles_alloc = 0;
250 coff = (PIMAGE_COFF_SYMBOLS_HEADER) root;
252 coff_symbols = (PIMAGE_SYMBOL) ((unsigned int) coff + coff->LvaToFirstSymbol);
253 coff_linetab = (PIMAGE_LINENUMBER) ((unsigned int) coff + coff->LvaToFirstLinenumber);
254 coff_strtab = (char *) (coff_symbols + coff->NumberOfSymbols);
256 linetab_indx = 0;
258 new_value.cookie = DV_TARGET;
259 new_value.type = NULL;
261 for(i=0; i < coff->NumberOfSymbols; i++ )
263 coff_sym = coff_symbols + i;
264 naux = coff_sym->NumberOfAuxSymbols;
266 if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE )
268 curr_file_idx = DEBUG_AddCoffFile( &coff_files, (char *) (coff_sym + 1) );
269 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
270 i += naux;
271 continue;
274 if (curr_file_idx < 0) {
275 assert(coff_files.nfiles == 0 && coff_files.nfiles_alloc == 0);
276 curr_file_idx = DEBUG_AddCoffFile( &coff_files, "<none>" );
277 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
281 * This guy marks the size and location of the text section
282 * for the current file. We need to keep track of this so
283 * we can figure out what file the different global functions
284 * go with.
286 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
287 && (naux != 0)
288 && (coff_sym->Type == 0)
289 && (coff_sym->SectionNumber == 1) )
291 aux = (PIMAGE_AUX_SYMBOL) (coff_sym + 1);
293 if( coff_files.files[curr_file_idx].linetab_offset != -1 )
296 * Save this so we can still get the old name.
298 const char* fn = coff_files.files[curr_file_idx].filename;
300 #ifdef MORE_DBG
301 DEBUG_Printf(DBG_CHN_TRACE, "Duplicating sect from %s: %lx %x %x %d %d\n",
302 coff_files.files[curr_file_idx].filename,
303 aux->Section.Length,
304 aux->Section.NumberOfRelocations,
305 aux->Section.NumberOfLinenumbers,
306 aux->Section.Number,
307 aux->Section.Selection);
308 DEBUG_Printf(DBG_CHN_TRACE, "More sect %d %s %08lx %d %d %d\n",
309 coff_sym->SectionNumber,
310 DEBUG_GetCoffName( coff_sym, coff_strtab ),
311 coff_sym->Value,
312 coff_sym->Type,
313 coff_sym->StorageClass,
314 coff_sym->NumberOfAuxSymbols);
315 #endif
318 * Duplicate the file entry. We have no way to describe
319 * multiple text sections in our current way of handling things.
321 DEBUG_AddCoffFile( &coff_files, fn );
323 #ifdef MORE_DBG
324 else
326 DEBUG_Printf(DBG_CHN_TRACE, "New text sect from %s: %lx %x %x %d %d\n",
327 coff_files.files[curr_file_idx].filename,
328 aux->Section.Length,
329 aux->Section.NumberOfRelocations,
330 aux->Section.NumberOfLinenumbers,
331 aux->Section.Number,
332 aux->Section.Selection);
334 #endif
336 if( coff_files.files[curr_file_idx].startaddr > coff_sym->Value )
338 coff_files.files[curr_file_idx].startaddr = coff_sym->Value;
341 if( coff_files.files[curr_file_idx].endaddr < coff_sym->Value + aux->Section.Length )
343 coff_files.files[curr_file_idx].endaddr = coff_sym->Value + aux->Section.Length;
346 coff_files.files[curr_file_idx].linetab_offset = linetab_indx;
347 coff_files.files[curr_file_idx].linecnt = aux->Section.NumberOfLinenumbers;
348 linetab_indx += aux->Section.NumberOfLinenumbers;
349 i += naux;
350 continue;
353 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
354 && (naux == 0)
355 && (coff_sym->SectionNumber == 1) )
357 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
359 * This is a normal static function when naux == 0.
360 * Just register it. The current file is the correct
361 * one in this instance.
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 #ifdef MORE_DBG
369 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding static symbol %s\n", nampnt);
370 #endif
372 /* FIXME: was adding symbol to this_file ??? */
373 DEBUG_AddCoffSymbol( &coff_files.files[curr_file_idx],
374 DEBUG_AddSymbol( nampnt, &new_value,
375 coff_files.files[curr_file_idx].filename,
376 SYM_WIN32 | SYM_FUNC ) );
377 i += naux;
378 continue;
381 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
382 && ISFCN(coff_sym->Type)
383 && (coff_sym->SectionNumber > 0) )
385 const char* this_file = NULL;
386 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
387 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
389 new_value.addr.seg = 0;
390 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
392 #ifdef MORE_DBG
393 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
395 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global symbol %s (sect=%s)\n",
396 nampnt, MSC_INFO(module)->sectp[coff_sym->SectionNumber - 1].Name);
397 #endif
400 * Now we need to figure out which file this guy belongs to.
402 for(j=0; j < coff_files.nfiles; j++)
404 if( coff_files.files[j].startaddr <= base + coff_sym->Value
405 && coff_files.files[j].endaddr > base + coff_sym->Value )
407 this_file = coff_files.files[j].filename;
408 break;
411 if (j < coff_files.nfiles) {
412 DEBUG_AddCoffSymbol( &coff_files.files[j],
413 DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 | SYM_FUNC ) );
414 } else {
415 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_FUNC );
417 i += naux;
418 continue;
421 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
422 && (coff_sym->SectionNumber > 0) )
424 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
426 * Similar to above, but for the case of data symbols.
427 * These aren't treated as entrypoints.
429 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
431 new_value.addr.seg = 0;
432 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
434 #ifdef MORE_DBG
435 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
437 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global data symbol %s\n", nampnt);
438 #endif
441 * Now we need to figure out which file this guy belongs to.
443 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_DATA );
444 i += naux;
445 continue;
448 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
449 && (naux == 0) )
452 * Ignore these. They don't have anything to do with
453 * reality.
455 i += naux;
456 continue;
459 #ifdef MORE_DBG
460 DEBUG_Printf(DBG_CHN_TRACE,"Skipping unknown entry '%s' %d %d %d\n",
461 DEBUG_GetCoffName( coff_sym, coff_strtab ),
462 coff_sym->StorageClass, coff_sym->SectionNumber, naux);
463 #endif
466 * For now, skip past the aux entries.
468 i += naux;
473 * OK, we now should have a list of files, and we should have a list
474 * of entrypoints. We need to sort the entrypoints so that we are
475 * able to tie the line numbers with the given functions within the
476 * file.
478 if( coff_files.files != NULL )
480 for(j=0; j < coff_files.nfiles; j++)
482 if( coff_files.files[j].entries != NULL )
484 qsort(coff_files.files[j].entries, coff_files.files[j].neps,
485 sizeof(struct name_hash *), DEBUG_cmp_sym);
490 * Now pick apart the line number tables, and attach the entries
491 * to the given functions.
493 for(j=0; j < coff_files.nfiles; j++)
495 l = 0;
496 if( coff_files.files[j].neps != 0 )
497 for(k=0; k < coff_files.files[j].linecnt; k++)
499 linepnt = coff_linetab + coff_files.files[j].linetab_offset + k;
501 * If we have spilled onto the next entrypoint, then
502 * bump the counter..
504 while(TRUE)
506 if (l+1 >= coff_files.files[j].neps) break;
507 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l+1], &new_value.addr);
508 if( (((unsigned int)module->load_addr +
509 linepnt->Type.VirtualAddress) >= new_value.addr.off) )
511 l++;
512 } else break;
516 * Add the line number. This is always relative to the
517 * start of the function, so we need to subtract that offset
518 * first.
520 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l], &new_value.addr);
521 DEBUG_AddLineNumber(coff_files.files[j].entries[l],
522 linepnt->Linenumber,
523 (unsigned int) module->load_addr
524 + linepnt->Type.VirtualAddress
525 - new_value.addr.off);
530 dil = DIL_LOADED;
532 if( coff_files.files != NULL )
534 for(j=0; j < coff_files.nfiles; j++)
536 if( coff_files.files[j].entries != NULL )
538 DBG_free(coff_files.files[j].entries);
541 DBG_free(coff_files.files);
544 return dil;
550 /*========================================================================
551 * Process CodeView type information.
554 union codeview_type
556 struct
558 unsigned short int len;
559 short int id;
560 } generic;
562 struct
564 unsigned short int len;
565 short int id;
566 short int attribute;
567 short int datatype;
568 unsigned char variant[1];
569 } pointer;
571 struct
573 unsigned short int len;
574 short int id;
575 unsigned int datatype;
576 unsigned int attribute;
577 unsigned char variant[1];
578 } pointer32;
580 struct
582 unsigned short int len;
583 short int id;
584 unsigned char nbits;
585 unsigned char bitoff;
586 unsigned short type;
587 } bitfield;
589 struct
591 unsigned short int len;
592 short int id;
593 unsigned int type;
594 unsigned char nbits;
595 unsigned char bitoff;
596 } bitfield32;
598 struct
600 unsigned short int len;
601 short int id;
602 short int elemtype;
603 short int idxtype;
604 unsigned short int arrlen; /* numeric leaf */
605 #if 0
606 unsigned char name[1];
607 #endif
608 } array;
610 struct
612 unsigned short int len;
613 short int id;
614 unsigned int elemtype;
615 unsigned int idxtype;
616 unsigned short int arrlen; /* numeric leaf */
617 #if 0
618 unsigned char name[1];
619 #endif
620 } array32;
622 struct
624 unsigned short int len;
625 short int id;
626 short int n_element;
627 short int fieldlist;
628 short int property;
629 short int derived;
630 short int vshape;
631 unsigned short int structlen; /* numeric leaf */
632 #if 0
633 unsigned char name[1];
634 #endif
635 } structure;
637 struct
639 unsigned short int len;
640 short int id;
641 short int n_element;
642 short int property;
643 unsigned int fieldlist;
644 unsigned int derived;
645 unsigned int vshape;
646 unsigned short int structlen; /* numeric leaf */
647 #if 0
648 unsigned char name[1];
649 #endif
650 } structure32;
652 struct
654 unsigned short int len;
655 short int id;
656 short int count;
657 short int fieldlist;
658 short int property;
659 unsigned short int un_len; /* numeric leaf */
660 #if 0
661 unsigned char name[1];
662 #endif
663 } t_union;
665 struct
667 unsigned short int len;
668 short int id;
669 short int count;
670 short int property;
671 unsigned int fieldlist;
672 unsigned short int un_len; /* numeric leaf */
673 #if 0
674 unsigned char name[1];
675 #endif
676 } t_union32;
678 struct
680 unsigned short int len;
681 short int id;
682 short int count;
683 short int type;
684 short int field;
685 short int property;
686 unsigned char name[1];
687 } enumeration;
689 struct
691 unsigned short int len;
692 short int id;
693 short int count;
694 short int property;
695 unsigned int type;
696 unsigned int field;
697 unsigned char name[1];
698 } enumeration32;
700 struct
702 unsigned short int len;
703 short int id;
704 unsigned char list[1];
705 } fieldlist;
708 union codeview_fieldtype
710 struct
712 short int id;
713 } generic;
715 struct
717 short int id;
718 short int type;
719 short int attribute;
720 unsigned short int offset; /* numeric leaf */
721 } bclass;
723 struct
725 short int id;
726 short int attribute;
727 unsigned int type;
728 unsigned short int offset; /* numeric leaf */
729 } bclass32;
731 struct
733 short int id;
734 short int btype;
735 short int vbtype;
736 short int attribute;
737 unsigned short int vbpoff; /* numeric leaf */
738 #if 0
739 unsigned short int vboff; /* numeric leaf */
740 #endif
741 } vbclass;
743 struct
745 short int id;
746 short int attribute;
747 unsigned int btype;
748 unsigned int vbtype;
749 unsigned short int vbpoff; /* numeric leaf */
750 #if 0
751 unsigned short int vboff; /* numeric leaf */
752 #endif
753 } vbclass32;
755 struct
757 short int id;
758 short int attribute;
759 unsigned short int value; /* numeric leaf */
760 #if 0
761 unsigned char name[1];
762 #endif
763 } enumerate;
765 struct
767 short int id;
768 short int type;
769 unsigned char name[1];
770 } friendfcn;
772 struct
774 short int id;
775 short int _pad0;
776 unsigned int type;
777 unsigned char name[1];
778 } friendfcn32;
780 struct
782 short int id;
783 short int type;
784 short int attribute;
785 unsigned short int offset; /* numeric leaf */
786 #if 0
787 unsigned char name[1];
788 #endif
789 } member;
791 struct
793 short int id;
794 short int attribute;
795 unsigned int type;
796 unsigned short int offset; /* numeric leaf */
797 #if 0
798 unsigned char name[1];
799 #endif
800 } member32;
802 struct
804 short int id;
805 short int type;
806 short int attribute;
807 unsigned char name[1];
808 } stmember;
810 struct
812 short int id;
813 short int attribute;
814 unsigned int type;
815 unsigned char name[1];
816 } stmember32;
818 struct
820 short int id;
821 short int count;
822 short int mlist;
823 unsigned char name[1];
824 } method;
826 struct
828 short int id;
829 short int count;
830 unsigned int mlist;
831 unsigned char name[1];
832 } method32;
834 struct
836 short int id;
837 short int index;
838 unsigned char name[1];
839 } nesttype;
841 struct
843 short int id;
844 short int _pad0;
845 unsigned int index;
846 unsigned char name[1];
847 } nesttype32;
849 struct
851 short int id;
852 short int type;
853 } vfunctab;
855 struct
857 short int id;
858 short int _pad0;
859 unsigned int type;
860 } vfunctab32;
862 struct
864 short int id;
865 short int type;
866 } friendcls;
868 struct
870 short int id;
871 short int _pad0;
872 unsigned int type;
873 } friendcls32;
876 struct
878 short int id;
879 short int attribute;
880 short int type;
881 unsigned char name[1];
882 } onemethod;
883 struct
885 short int id;
886 short int attribute;
887 short int type;
888 unsigned int vtab_offset;
889 unsigned char name[1];
890 } onemethod_virt;
892 struct
894 short int id;
895 short int attribute;
896 unsigned int type;
897 unsigned char name[1];
898 } onemethod32;
899 struct
901 short int id;
902 short int attribute;
903 unsigned int type;
904 unsigned int vtab_offset;
905 unsigned char name[1];
906 } onemethod32_virt;
908 struct
910 short int id;
911 short int type;
912 unsigned int offset;
913 } vfuncoff;
915 struct
917 short int id;
918 short int _pad0;
919 unsigned int type;
920 unsigned int offset;
921 } vfuncoff32;
923 struct
925 short int id;
926 short int attribute;
927 short int index;
928 unsigned char name[1];
929 } nesttypeex;
931 struct
933 short int id;
934 short int attribute;
935 unsigned int index;
936 unsigned char name[1];
937 } nesttypeex32;
939 struct
941 short int id;
942 short int attribute;
943 unsigned int type;
944 unsigned char name[1];
945 } membermodify;
950 * This covers the basic datatypes that VC++ seems to be using these days.
951 * 32 bit mode only. There are additional numbers for the pointers in 16
952 * bit mode. There are many other types listed in the documents, but these
953 * are apparently not used by the compiler, or represent pointer types
954 * that are not used.
956 #define T_NOTYPE 0x0000 /* Notype */
957 #define T_ABS 0x0001 /* Abs */
958 #define T_VOID 0x0003 /* Void */
959 #define T_CHAR 0x0010 /* signed char */
960 #define T_SHORT 0x0011 /* short */
961 #define T_LONG 0x0012 /* long */
962 #define T_QUAD 0x0013 /* long long */
963 #define T_UCHAR 0x0020 /* unsigned char */
964 #define T_USHORT 0x0021 /* unsigned short */
965 #define T_ULONG 0x0022 /* unsigned long */
966 #define T_UQUAD 0x0023 /* unsigned long long */
967 #define T_REAL32 0x0040 /* float */
968 #define T_REAL64 0x0041 /* double */
969 #define T_RCHAR 0x0070 /* real char */
970 #define T_WCHAR 0x0071 /* wide char */
971 #define T_INT4 0x0074 /* int */
972 #define T_UINT4 0x0075 /* unsigned int */
974 #define T_32PVOID 0x0403 /* 32 bit near pointer to void */
975 #define T_32PCHAR 0x0410 /* 16:32 near pointer to signed char */
976 #define T_32PSHORT 0x0411 /* 16:32 near pointer to short */
977 #define T_32PLONG 0x0412 /* 16:32 near pointer to int */
978 #define T_32PQUAD 0x0413 /* 16:32 near pointer to long long */
979 #define T_32PUCHAR 0x0420 /* 16:32 near pointer to unsigned char */
980 #define T_32PUSHORT 0x0421 /* 16:32 near pointer to unsigned short */
981 #define T_32PULONG 0x0422 /* 16:32 near pointer to unsigned int */
982 #define T_32PUQUAD 0x0423 /* 16:32 near pointer to long long */
983 #define T_32PREAL32 0x0440 /* 16:32 near pointer to float */
984 #define T_32PREAL64 0x0441 /* 16:32 near pointer to float */
985 #define T_32PRCHAR 0x0470 /* 16:32 near pointer to real char */
986 #define T_32PWCHAR 0x0471 /* 16:32 near pointer to real char */
987 #define T_32PINT4 0x0474 /* 16:32 near pointer to int */
988 #define T_32PUINT4 0x0475 /* 16:32 near pointer to unsigned int */
991 #define LF_MODIFIER 0x0001
992 #define LF_POINTER 0x0002
993 #define LF_ARRAY 0x0003
994 #define LF_CLASS 0x0004
995 #define LF_STRUCTURE 0x0005
996 #define LF_UNION 0x0006
997 #define LF_ENUM 0x0007
998 #define LF_PROCEDURE 0x0008
999 #define LF_MFUNCTION 0x0009
1000 #define LF_VTSHAPE 0x000a
1001 #define LF_COBOL0 0x000b
1002 #define LF_COBOL1 0x000c
1003 #define LF_BARRAY 0x000d
1004 #define LF_LABEL 0x000e
1005 #define LF_NULL 0x000f
1006 #define LF_NOTTRAN 0x0010
1007 #define LF_DIMARRAY 0x0011
1008 #define LF_VFTPATH 0x0012
1009 #define LF_PRECOMP 0x0013
1010 #define LF_ENDPRECOMP 0x0014
1011 #define LF_OEM 0x0015
1012 #define LF_TYPESERVER 0x0016
1014 #define LF_MODIFIER_32 0x1001 /* variants with new 32-bit type indices */
1015 #define LF_POINTER_32 0x1002
1016 #define LF_ARRAY_32 0x1003
1017 #define LF_CLASS_32 0x1004
1018 #define LF_STRUCTURE_32 0x1005
1019 #define LF_UNION_32 0x1006
1020 #define LF_ENUM_32 0x1007
1021 #define LF_PROCEDURE_32 0x1008
1022 #define LF_MFUNCTION_32 0x1009
1023 #define LF_COBOL0_32 0x100a
1024 #define LF_BARRAY_32 0x100b
1025 #define LF_DIMARRAY_32 0x100c
1026 #define LF_VFTPATH_32 0x100d
1027 #define LF_PRECOMP_32 0x100e
1028 #define LF_OEM_32 0x100f
1030 #define LF_SKIP 0x0200
1031 #define LF_ARGLIST 0x0201
1032 #define LF_DEFARG 0x0202
1033 #define LF_LIST 0x0203
1034 #define LF_FIELDLIST 0x0204
1035 #define LF_DERIVED 0x0205
1036 #define LF_BITFIELD 0x0206
1037 #define LF_METHODLIST 0x0207
1038 #define LF_DIMCONU 0x0208
1039 #define LF_DIMCONLU 0x0209
1040 #define LF_DIMVARU 0x020a
1041 #define LF_DIMVARLU 0x020b
1042 #define LF_REFSYM 0x020c
1044 #define LF_SKIP_32 0x1200 /* variants with new 32-bit type indices */
1045 #define LF_ARGLIST_32 0x1201
1046 #define LF_DEFARG_32 0x1202
1047 #define LF_FIELDLIST_32 0x1203
1048 #define LF_DERIVED_32 0x1204
1049 #define LF_BITFIELD_32 0x1205
1050 #define LF_METHODLIST_32 0x1206
1051 #define LF_DIMCONU_32 0x1207
1052 #define LF_DIMCONLU_32 0x1208
1053 #define LF_DIMVARU_32 0x1209
1054 #define LF_DIMVARLU_32 0x120a
1056 #define LF_BCLASS 0x0400
1057 #define LF_VBCLASS 0x0401
1058 #define LF_IVBCLASS 0x0402
1059 #define LF_ENUMERATE 0x0403
1060 #define LF_FRIENDFCN 0x0404
1061 #define LF_INDEX 0x0405
1062 #define LF_MEMBER 0x0406
1063 #define LF_STMEMBER 0x0407
1064 #define LF_METHOD 0x0408
1065 #define LF_NESTTYPE 0x0409
1066 #define LF_VFUNCTAB 0x040a
1067 #define LF_FRIENDCLS 0x040b
1068 #define LF_ONEMETHOD 0x040c
1069 #define LF_VFUNCOFF 0x040d
1070 #define LF_NESTTYPEEX 0x040e
1071 #define LF_MEMBERMODIFY 0x040f
1073 #define LF_BCLASS_32 0x1400 /* variants with new 32-bit type indices */
1074 #define LF_VBCLASS_32 0x1401
1075 #define LF_IVBCLASS_32 0x1402
1076 #define LF_FRIENDFCN_32 0x1403
1077 #define LF_INDEX_32 0x1404
1078 #define LF_MEMBER_32 0x1405
1079 #define LF_STMEMBER_32 0x1406
1080 #define LF_METHOD_32 0x1407
1081 #define LF_NESTTYPE_32 0x1408
1082 #define LF_VFUNCTAB_32 0x1409
1083 #define LF_FRIENDCLS_32 0x140a
1084 #define LF_ONEMETHOD_32 0x140b
1085 #define LF_VFUNCOFF_32 0x140c
1086 #define LF_NESTTYPEEX_32 0x140d
1088 #define LF_NUMERIC 0x8000 /* numeric leaf types */
1089 #define LF_CHAR 0x8000
1090 #define LF_SHORT 0x8001
1091 #define LF_USHORT 0x8002
1092 #define LF_LONG 0x8003
1093 #define LF_ULONG 0x8004
1094 #define LF_REAL32 0x8005
1095 #define LF_REAL64 0x8006
1096 #define LF_REAL80 0x8007
1097 #define LF_REAL128 0x8008
1098 #define LF_QUADWORD 0x8009
1099 #define LF_UQUADWORD 0x800a
1100 #define LF_REAL48 0x800b
1101 #define LF_COMPLEX32 0x800c
1102 #define LF_COMPLEX64 0x800d
1103 #define LF_COMPLEX80 0x800e
1104 #define LF_COMPLEX128 0x800f
1105 #define LF_VARSTRING 0x8010
1109 #define MAX_BUILTIN_TYPES 0x480
1110 static struct datatype * cv_basic_types[MAX_BUILTIN_TYPES];
1111 static unsigned int num_cv_defined_types = 0;
1112 static struct datatype **cv_defined_types = NULL;
1114 void
1115 DEBUG_InitCVDataTypes(void)
1118 * These are the common builtin types that are used by VC++.
1120 cv_basic_types[T_NOTYPE] = NULL;
1121 cv_basic_types[T_ABS] = NULL;
1122 cv_basic_types[T_VOID] = DEBUG_GetBasicType(DT_BASIC_VOID);
1123 cv_basic_types[T_CHAR] = DEBUG_GetBasicType(DT_BASIC_CHAR);
1124 cv_basic_types[T_SHORT] = DEBUG_GetBasicType(DT_BASIC_SHORTINT);
1125 cv_basic_types[T_LONG] = DEBUG_GetBasicType(DT_BASIC_LONGINT);
1126 cv_basic_types[T_QUAD] = DEBUG_GetBasicType(DT_BASIC_LONGLONGINT);
1127 cv_basic_types[T_UCHAR] = DEBUG_GetBasicType(DT_BASIC_UCHAR);
1128 cv_basic_types[T_USHORT] = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
1129 cv_basic_types[T_ULONG] = DEBUG_GetBasicType(DT_BASIC_ULONGINT);
1130 cv_basic_types[T_UQUAD] = DEBUG_GetBasicType(DT_BASIC_ULONGLONGINT);
1131 cv_basic_types[T_REAL32] = DEBUG_GetBasicType(DT_BASIC_FLOAT);
1132 cv_basic_types[T_REAL64] = DEBUG_GetBasicType(DT_BASIC_DOUBLE);
1133 cv_basic_types[T_RCHAR] = DEBUG_GetBasicType(DT_BASIC_CHAR);
1134 cv_basic_types[T_WCHAR] = DEBUG_GetBasicType(DT_BASIC_SHORTINT);
1135 cv_basic_types[T_INT4] = DEBUG_GetBasicType(DT_BASIC_INT);
1136 cv_basic_types[T_UINT4] = DEBUG_GetBasicType(DT_BASIC_UINT);
1138 cv_basic_types[T_32PVOID] = DEBUG_FindOrMakePointerType(cv_basic_types[T_VOID]);
1139 cv_basic_types[T_32PCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_CHAR]);
1140 cv_basic_types[T_32PSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_SHORT]);
1141 cv_basic_types[T_32PLONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_LONG]);
1142 cv_basic_types[T_32PQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_QUAD]);
1143 cv_basic_types[T_32PUCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UCHAR]);
1144 cv_basic_types[T_32PUSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_USHORT]);
1145 cv_basic_types[T_32PULONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_ULONG]);
1146 cv_basic_types[T_32PUQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UQUAD]);
1147 cv_basic_types[T_32PREAL32] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL32]);
1148 cv_basic_types[T_32PREAL64] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL64]);
1149 cv_basic_types[T_32PRCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_RCHAR]);
1150 cv_basic_types[T_32PWCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_WCHAR]);
1151 cv_basic_types[T_32PINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_INT4]);
1152 cv_basic_types[T_32PUINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UINT4]);
1156 static int
1157 numeric_leaf( int *value, unsigned short int *leaf )
1159 unsigned short int type = *leaf++;
1160 int length = 2;
1162 if ( type < LF_NUMERIC )
1164 *value = type;
1166 else
1168 switch ( type )
1170 case LF_CHAR:
1171 length += 1;
1172 *value = *(char *)leaf;
1173 break;
1175 case LF_SHORT:
1176 length += 2;
1177 *value = *(short *)leaf;
1178 break;
1180 case LF_USHORT:
1181 length += 2;
1182 *value = *(unsigned short *)leaf;
1183 break;
1185 case LF_LONG:
1186 length += 4;
1187 *value = *(int *)leaf;
1188 break;
1190 case LF_ULONG:
1191 length += 4;
1192 *value = *(unsigned int *)leaf;
1193 break;
1195 case LF_QUADWORD:
1196 case LF_UQUADWORD:
1197 length += 8;
1198 *value = 0; /* FIXME */
1199 break;
1201 case LF_REAL32:
1202 length += 4;
1203 *value = 0; /* FIXME */
1204 break;
1206 case LF_REAL48:
1207 length += 6;
1208 *value = 0; /* FIXME */
1209 break;
1211 case LF_REAL64:
1212 length += 8;
1213 *value = 0; /* FIXME */
1214 break;
1216 case LF_REAL80:
1217 length += 10;
1218 *value = 0; /* FIXME */
1219 break;
1221 case LF_REAL128:
1222 length += 16;
1223 *value = 0; /* FIXME */
1224 break;
1226 case LF_COMPLEX32:
1227 length += 4;
1228 *value = 0; /* FIXME */
1229 break;
1231 case LF_COMPLEX64:
1232 length += 8;
1233 *value = 0; /* FIXME */
1234 break;
1236 case LF_COMPLEX80:
1237 length += 10;
1238 *value = 0; /* FIXME */
1239 break;
1241 case LF_COMPLEX128:
1242 length += 16;
1243 *value = 0; /* FIXME */
1244 break;
1246 case LF_VARSTRING:
1247 length += 2 + *leaf;
1248 *value = 0; /* FIXME */
1249 break;
1251 default:
1252 DEBUG_Printf( DBG_CHN_MESG, "Unknown numeric leaf type %04x\n", type );
1253 *value = 0;
1254 break;
1258 return length;
1261 static char *
1262 terminate_string( unsigned char *name )
1264 static char symname[256];
1266 int namelen = name[0];
1267 assert( namelen >= 0 && namelen < 256 );
1269 memcpy( symname, name+1, namelen );
1270 symname[namelen] = '\0';
1272 if ( !*symname || strcmp( symname, "__unnamed" ) == 0 )
1273 return NULL;
1274 else
1275 return symname;
1278 static
1279 struct datatype * DEBUG_GetCVType(unsigned int typeno)
1281 struct datatype * dt = NULL;
1284 * Convert Codeview type numbers into something we can grok internally.
1285 * Numbers < 0x1000 are all fixed builtin types. Numbers from 0x1000 and
1286 * up are all user defined (structs, etc).
1288 if ( typeno < 0x1000 )
1290 if ( typeno < MAX_BUILTIN_TYPES )
1291 dt = cv_basic_types[typeno];
1293 else
1295 if ( typeno - 0x1000 < num_cv_defined_types )
1296 dt = cv_defined_types[typeno - 0x1000];
1299 return dt;
1302 static int
1303 DEBUG_AddCVType( unsigned int typeno, struct datatype *dt )
1305 while ( typeno - 0x1000 >= num_cv_defined_types )
1307 num_cv_defined_types += 0x100;
1308 cv_defined_types = (struct datatype **)
1309 DBG_realloc( cv_defined_types,
1310 num_cv_defined_types * sizeof(struct datatype *) );
1312 memset( cv_defined_types + num_cv_defined_types - 0x100,
1314 0x100 * sizeof(struct datatype *) );
1316 if ( cv_defined_types == NULL )
1317 return FALSE;
1320 cv_defined_types[ typeno - 0x1000 ] = dt;
1321 return TRUE;
1324 static void
1325 DEBUG_ClearTypeTable( void )
1327 if ( cv_defined_types )
1328 DBG_free( cv_defined_types );
1330 cv_defined_types = NULL;
1331 num_cv_defined_types = 0;
1334 static int
1335 DEBUG_AddCVType_Pointer( unsigned int typeno, unsigned int datatype )
1337 struct datatype *dt =
1338 DEBUG_FindOrMakePointerType( DEBUG_GetCVType( datatype ) );
1340 return DEBUG_AddCVType( typeno, dt );
1343 static int
1344 DEBUG_AddCVType_Array( unsigned int typeno, char *name,
1345 unsigned int elemtype, unsigned int arr_len )
1347 struct datatype *dt = DEBUG_NewDataType( DT_ARRAY, name );
1348 struct datatype *elem = DEBUG_GetCVType( elemtype );
1349 unsigned int elem_size = elem? DEBUG_GetObjectSize( elem ) : 0;
1350 unsigned int arr_max = elem_size? arr_len / elem_size : 0;
1352 DEBUG_SetArrayParams( dt, 0, arr_max, elem );
1353 return DEBUG_AddCVType( typeno, dt );
1356 static int
1357 DEBUG_AddCVType_Bitfield( unsigned int typeno,
1358 unsigned int bitoff, unsigned int nbits,
1359 unsigned int basetype )
1361 struct datatype *dt = DEBUG_NewDataType( DT_BITFIELD, NULL );
1362 struct datatype *base = DEBUG_GetCVType( basetype );
1364 DEBUG_SetBitfieldParams( dt, bitoff, nbits, base );
1365 return DEBUG_AddCVType( typeno, dt );
1368 static int
1369 DEBUG_AddCVType_EnumFieldList( unsigned int typeno, unsigned char *list, int len )
1371 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, NULL );
1372 unsigned char *ptr = list;
1374 while ( ptr - list < len )
1376 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1378 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1380 ptr += *ptr & 0x0f;
1381 continue;
1384 switch ( type->generic.id )
1386 case LF_ENUMERATE:
1388 int value, vlen = numeric_leaf( &value, &type->enumerate.value );
1389 unsigned char *name = (unsigned char *)&type->enumerate.value + vlen;
1391 DEBUG_AddStructElement( dt, terminate_string( name ),
1392 NULL, value, 0 );
1394 ptr += 2 + 2 + vlen + (1 + name[0]);
1395 break;
1398 default:
1399 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in ENUM field list\n",
1400 type->generic.id );
1401 return FALSE;
1405 return DEBUG_AddCVType( typeno, dt );
1408 static int
1409 DEBUG_AddCVType_StructFieldList( unsigned int typeno, unsigned char *list, int len )
1411 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, NULL );
1412 unsigned char *ptr = list;
1414 while ( ptr - list < len )
1416 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1418 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1420 ptr += *ptr & 0x0f;
1421 continue;
1424 switch ( type->generic.id )
1426 case LF_BCLASS:
1428 int offset, olen = numeric_leaf( &offset, &type->bclass.offset );
1430 /* FIXME: ignored for now */
1432 ptr += 2 + 2 + 2 + olen;
1433 break;
1436 case LF_BCLASS_32:
1438 int offset, olen = numeric_leaf( &offset, &type->bclass32.offset );
1440 /* FIXME: ignored for now */
1442 ptr += 2 + 2 + 4 + olen;
1443 break;
1446 case LF_VBCLASS:
1447 case LF_IVBCLASS:
1449 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass.vbpoff );
1450 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass.vbpoff + vbpoff);
1451 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1453 /* FIXME: ignored for now */
1455 ptr += 2 + 2 + 2 + 2 + vbplen + vplen;
1456 break;
1459 case LF_VBCLASS_32:
1460 case LF_IVBCLASS_32:
1462 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass32.vbpoff );
1463 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass32.vbpoff + vbpoff);
1464 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1466 /* FIXME: ignored for now */
1468 ptr += 2 + 2 + 4 + 4 + vbplen + vplen;
1469 break;
1472 case LF_MEMBER:
1474 int offset, olen = numeric_leaf( &offset, &type->member.offset );
1475 unsigned char *name = (unsigned char *)&type->member.offset + olen;
1477 struct datatype *subtype = DEBUG_GetCVType( type->member.type );
1478 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1480 DEBUG_AddStructElement( dt, terminate_string( name ),
1481 subtype, offset << 3, elem_size << 3 );
1483 ptr += 2 + 2 + 2 + olen + (1 + name[0]);
1484 break;
1487 case LF_MEMBER_32:
1489 int offset, olen = numeric_leaf( &offset, &type->member32.offset );
1490 unsigned char *name = (unsigned char *)&type->member32.offset + olen;
1492 struct datatype *subtype = DEBUG_GetCVType( type->member32.type );
1493 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1495 DEBUG_AddStructElement( dt, terminate_string( name ),
1496 subtype, offset << 3, elem_size << 3 );
1498 ptr += 2 + 2 + 4 + olen + (1 + name[0]);
1499 break;
1502 case LF_STMEMBER:
1503 /* FIXME: ignored for now */
1504 ptr += 2 + 2 + 2 + (1 + type->stmember.name[0]);
1505 break;
1507 case LF_STMEMBER_32:
1508 /* FIXME: ignored for now */
1509 ptr += 2 + 4 + 2 + (1 + type->stmember32.name[0]);
1510 break;
1512 case LF_METHOD:
1513 /* FIXME: ignored for now */
1514 ptr += 2 + 2 + 2 + (1 + type->method.name[0]);
1515 break;
1517 case LF_METHOD_32:
1518 /* FIXME: ignored for now */
1519 ptr += 2 + 2 + 4 + (1 + type->method32.name[0]);
1520 break;
1522 case LF_NESTTYPE:
1523 /* FIXME: ignored for now */
1524 ptr += 2 + 2 + (1 + type->nesttype.name[0]);
1525 break;
1527 case LF_NESTTYPE_32:
1528 /* FIXME: ignored for now */
1529 ptr += 2 + 2 + 4 + (1 + type->nesttype32.name[0]);
1530 break;
1532 case LF_VFUNCTAB:
1533 /* FIXME: ignored for now */
1534 ptr += 2 + 2;
1535 break;
1537 case LF_VFUNCTAB_32:
1538 /* FIXME: ignored for now */
1539 ptr += 2 + 2 + 4;
1540 break;
1542 case LF_ONEMETHOD:
1543 /* FIXME: ignored for now */
1544 switch ( (type->onemethod.attribute >> 2) & 7 )
1546 case 4: case 6: /* (pure) introducing virtual method */
1547 ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt.name[0]);
1548 break;
1550 default:
1551 ptr += 2 + 2 + 2 + (1 + type->onemethod.name[0]);
1552 break;
1554 break;
1556 case LF_ONEMETHOD_32:
1557 /* FIXME: ignored for now */
1558 switch ( (type->onemethod32.attribute >> 2) & 7 )
1560 case 4: case 6: /* (pure) introducing virtual method */
1561 ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod32_virt.name[0]);
1562 break;
1564 default:
1565 ptr += 2 + 2 + 4 + (1 + type->onemethod32.name[0]);
1566 break;
1568 break;
1570 default:
1571 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in STRUCT field list\n",
1572 type->generic.id );
1573 return FALSE;
1577 return DEBUG_AddCVType( typeno, dt );
1580 static int
1581 DEBUG_AddCVType_Enum( unsigned int typeno, char *name, unsigned int fieldlist )
1583 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, name );
1584 struct datatype *list = DEBUG_GetCVType( fieldlist );
1586 if ( list )
1587 if(DEBUG_CopyFieldlist( dt, list ) == FALSE)
1588 return FALSE;
1590 return DEBUG_AddCVType( typeno, dt );
1593 static int
1594 DEBUG_AddCVType_Struct( unsigned int typeno, char *name, int structlen, unsigned int fieldlist )
1596 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, name );
1597 struct datatype *list = DEBUG_GetCVType( fieldlist );
1599 if ( list )
1601 DEBUG_SetStructSize( dt, structlen );
1602 if(DEBUG_CopyFieldlist( dt, list ) == FALSE)
1603 return FALSE;
1606 return DEBUG_AddCVType( typeno, dt );
1609 static int
1610 DEBUG_ParseTypeTable( char *table, int len )
1612 unsigned int curr_type = 0x1000;
1613 char *ptr = table;
1615 while ( ptr - table < len )
1617 union codeview_type *type = (union codeview_type *) ptr;
1618 int retv = TRUE;
1620 switch ( type->generic.id )
1622 case LF_POINTER:
1623 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer.datatype );
1624 break;
1625 case LF_POINTER_32:
1626 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer32.datatype );
1627 break;
1629 case LF_ARRAY:
1631 int arrlen, alen = numeric_leaf( &arrlen, &type->array.arrlen );
1632 unsigned char *name = (unsigned char *)&type->array.arrlen + alen;
1634 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1635 type->array.elemtype, arrlen );
1636 break;
1638 case LF_ARRAY_32:
1640 int arrlen, alen = numeric_leaf( &arrlen, &type->array32.arrlen );
1641 unsigned char *name = (unsigned char *)&type->array32.arrlen + alen;
1643 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1644 type->array32.elemtype, type->array32.arrlen );
1645 break;
1648 case LF_BITFIELD:
1649 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield.bitoff,
1650 type->bitfield.nbits,
1651 type->bitfield.type );
1652 break;
1653 case LF_BITFIELD_32:
1654 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield32.bitoff,
1655 type->bitfield32.nbits,
1656 type->bitfield32.type );
1657 break;
1659 case LF_FIELDLIST:
1660 case LF_FIELDLIST_32:
1663 * A 'field list' is a CodeView-specific data type which doesn't
1664 * directly correspond to any high-level data type. It is used
1665 * to hold the collection of members of a struct, class, union
1666 * or enum type. The actual definition of that type will follow
1667 * later, and refer to the field list definition record.
1669 * As we don't have a field list type ourselves, we look ahead
1670 * in the field list to try to find out whether this field list
1671 * will be used for an enum or struct type, and create a dummy
1672 * type of the corresponding sort. Later on, the definition of
1673 * the 'real' type will copy the member / enumeration data.
1676 char *list = type->fieldlist.list;
1677 int len = (ptr + type->generic.len + 2) - list;
1679 if ( ((union codeview_fieldtype *)list)->generic.id == LF_ENUMERATE )
1680 retv = DEBUG_AddCVType_EnumFieldList( curr_type, list, len );
1681 else
1682 retv = DEBUG_AddCVType_StructFieldList( curr_type, list, len );
1683 break;
1686 case LF_STRUCTURE:
1687 case LF_CLASS:
1689 int structlen, slen = numeric_leaf( &structlen, &type->structure.structlen );
1690 unsigned char *name = (unsigned char *)&type->structure.structlen + slen;
1692 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1693 structlen, type->structure.fieldlist );
1694 break;
1696 case LF_STRUCTURE_32:
1697 case LF_CLASS_32:
1699 int structlen, slen = numeric_leaf( &structlen, &type->structure32.structlen );
1700 unsigned char *name = (unsigned char *)&type->structure32.structlen + slen;
1702 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1703 structlen, type->structure32.fieldlist );
1704 break;
1707 case LF_UNION:
1709 int un_len, ulen = numeric_leaf( &un_len, &type->t_union.un_len );
1710 unsigned char *name = (unsigned char *)&type->t_union.un_len + ulen;
1712 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1713 un_len, type->t_union.fieldlist );
1714 break;
1716 case LF_UNION_32:
1718 int un_len, ulen = numeric_leaf( &un_len, &type->t_union32.un_len );
1719 unsigned char *name = (unsigned char *)&type->t_union32.un_len + ulen;
1721 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1722 un_len, type->t_union32.fieldlist );
1723 break;
1726 case LF_ENUM:
1727 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration.name ),
1728 type->enumeration.field );
1729 break;
1730 case LF_ENUM_32:
1731 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration32.name ),
1732 type->enumeration32.field );
1733 break;
1735 default:
1736 break;
1739 if ( !retv )
1740 return FALSE;
1742 curr_type++;
1743 ptr += type->generic.len + 2;
1746 return TRUE;
1750 /*========================================================================
1751 * Process CodeView line number information.
1754 union any_size
1756 char * c;
1757 short * s;
1758 int * i;
1759 unsigned int * ui;
1762 struct startend
1764 unsigned int start;
1765 unsigned int end;
1768 struct codeview_linetab_hdr
1770 unsigned int nline;
1771 unsigned int segno;
1772 unsigned int start;
1773 unsigned int end;
1774 char * sourcefile;
1775 unsigned short * linetab;
1776 unsigned int * offtab;
1779 static struct codeview_linetab_hdr *
1780 DEBUG_SnarfLinetab(char * linetab,
1781 int size)
1783 int file_segcount;
1784 char filename[PATH_MAX];
1785 unsigned int * filetab;
1786 char * fn;
1787 int i;
1788 int k;
1789 struct codeview_linetab_hdr * lt_hdr;
1790 unsigned int * lt_ptr;
1791 int nfile;
1792 int nseg;
1793 union any_size pnt;
1794 union any_size pnt2;
1795 struct startend * start;
1796 int this_seg;
1799 * Now get the important bits.
1801 pnt.c = linetab;
1802 nfile = *pnt.s++;
1803 nseg = *pnt.s++;
1805 filetab = (unsigned int *) pnt.c;
1808 * Now count up the number of segments in the file.
1810 nseg = 0;
1811 for(i=0; i<nfile; i++)
1813 pnt2.c = linetab + filetab[i];
1814 nseg += *pnt2.s;
1818 * Next allocate the header we will be returning.
1819 * There is one header for each segment, so that we can reach in
1820 * and pull bits as required.
1822 lt_hdr = (struct codeview_linetab_hdr *)
1823 DBG_alloc((nseg + 1) * sizeof(*lt_hdr));
1824 if( lt_hdr == NULL )
1826 goto leave;
1829 memset(lt_hdr, 0, sizeof(*lt_hdr) * (nseg+1));
1832 * Now fill the header we will be returning, one for each segment.
1833 * Note that this will basically just contain pointers into the existing
1834 * line table, and we do not actually copy any additional information
1835 * or allocate any additional memory.
1838 this_seg = 0;
1839 for(i=0; i<nfile; i++)
1842 * Get the pointer into the segment information.
1844 pnt2.c = linetab + filetab[i];
1845 file_segcount = *pnt2.s;
1847 pnt2.ui++;
1848 lt_ptr = (unsigned int *) pnt2.c;
1849 start = (struct startend *) (lt_ptr + file_segcount);
1852 * Now snarf the filename for all of the segments for this file.
1854 fn = (unsigned char *) (start + file_segcount);
1855 memset(filename, 0, sizeof(filename));
1856 memcpy(filename, fn + 1, *fn);
1857 fn = DBG_strdup(filename);
1859 for(k = 0; k < file_segcount; k++, this_seg++)
1861 pnt2.c = linetab + lt_ptr[k];
1862 lt_hdr[this_seg].start = start[k].start;
1863 lt_hdr[this_seg].end = start[k].end;
1864 lt_hdr[this_seg].sourcefile = fn;
1865 lt_hdr[this_seg].segno = *pnt2.s++;
1866 lt_hdr[this_seg].nline = *pnt2.s++;
1867 lt_hdr[this_seg].offtab = pnt2.ui;
1868 lt_hdr[this_seg].linetab = (unsigned short *)
1869 (pnt2.ui + lt_hdr[this_seg].nline);
1873 leave:
1875 return lt_hdr;
1880 /*========================================================================
1881 * Process CodeView symbol information.
1884 union codeview_symbol
1886 struct
1888 short int len;
1889 short int id;
1890 } generic;
1892 struct
1894 short int len;
1895 short int id;
1896 unsigned int offset;
1897 unsigned short seg;
1898 unsigned short symtype;
1899 unsigned char namelen;
1900 unsigned char name[1];
1901 } data;
1903 struct
1905 short int len;
1906 short int id;
1907 unsigned int symtype;
1908 unsigned int offset;
1909 unsigned short seg;
1910 unsigned char namelen;
1911 unsigned char name[1];
1912 } data32;
1914 struct
1916 short int len;
1917 short int id;
1918 unsigned int pparent;
1919 unsigned int pend;
1920 unsigned int next;
1921 unsigned int offset;
1922 unsigned short segment;
1923 unsigned short thunk_len;
1924 unsigned char thtype;
1925 unsigned char namelen;
1926 unsigned char name[1];
1927 } thunk;
1929 struct
1931 short int len;
1932 short int id;
1933 unsigned int pparent;
1934 unsigned int pend;
1935 unsigned int next;
1936 unsigned int proc_len;
1937 unsigned int debug_start;
1938 unsigned int debug_end;
1939 unsigned int offset;
1940 unsigned short segment;
1941 unsigned short proctype;
1942 unsigned char flags;
1943 unsigned char namelen;
1944 unsigned char name[1];
1945 } proc;
1947 struct
1949 short int len;
1950 short int id;
1951 unsigned int pparent;
1952 unsigned int pend;
1953 unsigned int next;
1954 unsigned int proc_len;
1955 unsigned int debug_start;
1956 unsigned int debug_end;
1957 unsigned int proctype;
1958 unsigned int offset;
1959 unsigned short segment;
1960 unsigned char flags;
1961 unsigned char namelen;
1962 unsigned char name[1];
1963 } proc32;
1965 struct
1967 short int len; /* Total length of this entry */
1968 short int id; /* Always S_BPREL32 */
1969 unsigned int offset; /* Stack offset relative to BP */
1970 unsigned short symtype;
1971 unsigned char namelen;
1972 unsigned char name[1];
1973 } stack;
1975 struct
1977 short int len; /* Total length of this entry */
1978 short int id; /* Always S_BPREL32 */
1979 unsigned int offset; /* Stack offset relative to BP */
1980 unsigned int symtype;
1981 unsigned char namelen;
1982 unsigned char name[1];
1983 } stack32;
1987 #define S_COMPILE 0x0001
1988 #define S_REGISTER 0x0002
1989 #define S_CONSTANT 0x0003
1990 #define S_UDT 0x0004
1991 #define S_SSEARCH 0x0005
1992 #define S_END 0x0006
1993 #define S_SKIP 0x0007
1994 #define S_CVRESERVE 0x0008
1995 #define S_OBJNAME 0x0009
1996 #define S_ENDARG 0x000a
1997 #define S_COBOLUDT 0x000b
1998 #define S_MANYREG 0x000c
1999 #define S_RETURN 0x000d
2000 #define S_ENTRYTHIS 0x000e
2002 #define S_BPREL 0x0200
2003 #define S_LDATA 0x0201
2004 #define S_GDATA 0x0202
2005 #define S_PUB 0x0203
2006 #define S_LPROC 0x0204
2007 #define S_GPROC 0x0205
2008 #define S_THUNK 0x0206
2009 #define S_BLOCK 0x0207
2010 #define S_WITH 0x0208
2011 #define S_LABEL 0x0209
2012 #define S_CEXMODEL 0x020a
2013 #define S_VFTPATH 0x020b
2014 #define S_REGREL 0x020c
2015 #define S_LTHREAD 0x020d
2016 #define S_GTHREAD 0x020e
2018 #define S_PROCREF 0x0400
2019 #define S_DATAREF 0x0401
2020 #define S_ALIGN 0x0402
2021 #define S_LPROCREF 0x0403
2023 #define S_REGISTER_32 0x1001 /* Variants with new 32-bit type indices */
2024 #define S_CONSTANT_32 0x1002
2025 #define S_UDT_32 0x1003
2026 #define S_COBOLUDT_32 0x1004
2027 #define S_MANYREG_32 0x1005
2029 #define S_BPREL_32 0x1006
2030 #define S_LDATA_32 0x1007
2031 #define S_GDATA_32 0x1008
2032 #define S_PUB_32 0x1009
2033 #define S_LPROC_32 0x100a
2034 #define S_GPROC_32 0x100b
2035 #define S_VFTTABLE_32 0x100c
2036 #define S_REGREL_32 0x100d
2037 #define S_LTHREAD_32 0x100e
2038 #define S_GTHREAD_32 0x100f
2042 static unsigned int
2043 DEBUG_MapCVOffset( DBG_MODULE *module, unsigned int offset )
2045 int nomap = module->msc_info->nomap;
2046 OMAP_DATA *omapp = module->msc_info->omapp;
2047 int i;
2049 if ( !nomap || !omapp )
2050 return offset;
2052 /* FIXME: use binary search */
2053 for ( i = 0; i < nomap-1; i++ )
2054 if ( omapp[i].from <= offset && omapp[i+1].from > offset )
2055 return !omapp[i].to? 0 : omapp[i].to + (offset - omapp[i].from);
2057 return 0;
2060 static struct name_hash *
2061 DEBUG_AddCVSymbol( DBG_MODULE *module, char *name, int namelen,
2062 int type, unsigned int seg, unsigned int offset,
2063 int size, int cookie, int flags,
2064 struct codeview_linetab_hdr *linetab )
2066 int nsect = module->msc_info->nsect;
2067 PIMAGE_SECTION_HEADER sectp = module->msc_info->sectp;
2069 struct name_hash *symbol;
2070 char symname[PATH_MAX];
2071 DBG_VALUE value;
2074 * Some sanity checks
2077 if ( !name || !namelen )
2078 return NULL;
2080 if ( !seg || seg > nsect )
2081 return NULL;
2084 * Convert type, address, and symbol name
2086 value.type = type? DEBUG_GetCVType( type ) : NULL;
2087 value.cookie = cookie;
2089 value.addr.seg = 0;
2090 value.addr.off = (unsigned int) module->load_addr +
2091 DEBUG_MapCVOffset( module, sectp[seg-1].VirtualAddress + offset );
2093 memcpy( symname, name, namelen );
2094 symname[namelen] = '\0';
2098 * Check whether we have line number information
2100 if ( linetab )
2102 for ( ; linetab->linetab; linetab++ )
2103 if ( linetab->segno == seg
2104 && linetab->start <= offset
2105 && linetab->end > offset )
2106 break;
2108 if ( !linetab->linetab )
2109 linetab = NULL;
2114 * Create Wine symbol record
2116 symbol = DEBUG_AddSymbol( symname, &value,
2117 linetab? linetab->sourcefile : NULL, flags );
2119 if ( size )
2120 DEBUG_SetSymbolSize( symbol, size );
2124 * Add line numbers if found
2126 if ( linetab )
2128 unsigned int i;
2129 for ( i = 0; i < linetab->nline; i++ )
2130 if ( linetab->offtab[i] >= offset
2131 && linetab->offtab[i] < offset + size )
2133 DEBUG_AddLineNumber( symbol, linetab->linetab[i],
2134 linetab->offtab[i] - offset );
2138 return symbol;
2141 static struct wine_locals *
2142 DEBUG_AddCVLocal( struct name_hash *func, char *name, int namelen,
2143 int type, int offset )
2145 struct wine_locals *local;
2146 char symname[PATH_MAX];
2148 memcpy( symname, name, namelen );
2149 symname[namelen] = '\0';
2151 local = DEBUG_AddLocal( func, 0, offset, 0, 0, symname );
2152 DEBUG_SetLocalSymbolType( local, DEBUG_GetCVType( type ) );
2154 return local;
2157 static int
2158 DEBUG_SnarfCodeView( DBG_MODULE *module, LPBYTE root, int offset, int size,
2159 struct codeview_linetab_hdr *linetab )
2161 struct name_hash *curr_func = NULL;
2162 int i, length;
2166 * Loop over the different types of records and whenever we
2167 * find something we are interested in, record it and move on.
2169 for ( i = offset; i < size; i += length )
2171 union codeview_symbol *sym = (union codeview_symbol *)(root + i);
2172 length = sym->generic.len + 2;
2174 switch ( sym->generic.id )
2177 * Global and local data symbols. We don't associate these
2178 * with any given source file.
2180 case S_GDATA:
2181 case S_LDATA:
2182 case S_PUB:
2183 DEBUG_AddCVSymbol( module, sym->data.name, sym->data.namelen,
2184 sym->data.symtype, sym->data.seg,
2185 sym->data.offset, 0,
2186 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2187 break;
2188 case S_GDATA_32:
2189 case S_LDATA_32:
2190 case S_PUB_32:
2191 DEBUG_AddCVSymbol( module, sym->data32.name, sym->data32.namelen,
2192 sym->data32.symtype, sym->data32.seg,
2193 sym->data32.offset, 0,
2194 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2195 break;
2198 * Sort of like a global function, but it just points
2199 * to a thunk, which is a stupid name for what amounts to
2200 * a PLT slot in the normal jargon that everyone else uses.
2202 case S_THUNK:
2203 DEBUG_AddCVSymbol( module, sym->thunk.name, sym->thunk.namelen,
2204 0, sym->thunk.segment,
2205 sym->thunk.offset, sym->thunk.thunk_len,
2206 DV_TARGET, SYM_WIN32 | SYM_FUNC, NULL );
2207 break;
2210 * Global and static functions.
2212 case S_GPROC:
2213 case S_LPROC:
2214 DEBUG_Normalize( curr_func );
2216 curr_func = DEBUG_AddCVSymbol( module, sym->proc.name, sym->proc.namelen,
2217 sym->proc.proctype, sym->proc.segment,
2218 sym->proc.offset, sym->proc.proc_len,
2219 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
2221 DEBUG_SetSymbolBPOff( curr_func, sym->proc.debug_start );
2222 break;
2223 case S_GPROC_32:
2224 case S_LPROC_32:
2225 DEBUG_Normalize( curr_func );
2227 curr_func = DEBUG_AddCVSymbol( module, sym->proc32.name, sym->proc32.namelen,
2228 sym->proc32.proctype, sym->proc32.segment,
2229 sym->proc32.offset, sym->proc32.proc_len,
2230 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
2232 DEBUG_SetSymbolBPOff( curr_func, sym->proc32.debug_start );
2233 break;
2237 * Function parameters and stack variables.
2239 case S_BPREL:
2240 DEBUG_AddCVLocal( curr_func, sym->stack.name, sym->stack.namelen,
2241 sym->stack.symtype, sym->stack.offset );
2242 break;
2243 case S_BPREL_32:
2244 DEBUG_AddCVLocal( curr_func, sym->stack32.name, sym->stack32.namelen,
2245 sym->stack32.symtype, sym->stack32.offset );
2246 break;
2250 * These are special, in that they are always followed by an
2251 * additional length-prefixed string which is *not* included
2252 * into the symbol length count. We need to skip it.
2254 case S_PROCREF:
2255 case S_DATAREF:
2256 case S_LPROCREF:
2258 LPBYTE name = (LPBYTE)sym + length;
2259 length += (*name + 1 + 3) & ~3;
2260 break;
2265 DEBUG_Normalize( curr_func );
2267 if ( linetab ) DBG_free(linetab);
2268 return TRUE;
2273 /*========================================================================
2274 * Process PDB file.
2277 #pragma pack(1)
2278 typedef struct _PDB_FILE
2280 DWORD size;
2281 DWORD unknown;
2283 } PDB_FILE, *PPDB_FILE;
2285 typedef struct _PDB_HEADER
2287 CHAR ident[40];
2288 DWORD signature;
2289 DWORD blocksize;
2290 WORD freelist;
2291 WORD total_alloc;
2292 PDB_FILE toc;
2293 WORD toc_block[ 1 ];
2295 } PDB_HEADER, *PPDB_HEADER;
2297 typedef struct _PDB_TOC
2299 DWORD nFiles;
2300 PDB_FILE file[ 1 ];
2302 } PDB_TOC, *PPDB_TOC;
2304 typedef struct _PDB_ROOT
2306 DWORD version;
2307 DWORD TimeDateStamp;
2308 DWORD unknown;
2309 DWORD cbNames;
2310 CHAR names[ 1 ];
2312 } PDB_ROOT, *PPDB_ROOT;
2314 typedef struct _PDB_TYPES_OLD
2316 DWORD version;
2317 WORD first_index;
2318 WORD last_index;
2319 DWORD type_size;
2320 WORD file;
2321 WORD pad;
2323 } PDB_TYPES_OLD, *PPDB_TYPES_OLD;
2325 typedef struct _PDB_TYPES
2327 DWORD version;
2328 DWORD type_offset;
2329 DWORD first_index;
2330 DWORD last_index;
2331 DWORD type_size;
2332 WORD file;
2333 WORD pad;
2334 DWORD hash_size;
2335 DWORD hash_base;
2336 DWORD hash_offset;
2337 DWORD hash_len;
2338 DWORD search_offset;
2339 DWORD search_len;
2340 DWORD unknown_offset;
2341 DWORD unknown_len;
2343 } PDB_TYPES, *PPDB_TYPES;
2345 typedef struct _PDB_SYMBOL_RANGE
2347 WORD segment;
2348 WORD pad1;
2349 DWORD offset;
2350 DWORD size;
2351 DWORD characteristics;
2352 WORD index;
2353 WORD pad2;
2355 } PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
2357 typedef struct _PDB_SYMBOL_RANGE_EX
2359 WORD segment;
2360 WORD pad1;
2361 DWORD offset;
2362 DWORD size;
2363 DWORD characteristics;
2364 WORD index;
2365 WORD pad2;
2366 DWORD timestamp;
2367 DWORD unknown;
2369 } PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
2371 typedef struct _PDB_SYMBOL_FILE
2373 DWORD unknown1;
2374 PDB_SYMBOL_RANGE range;
2375 WORD flag;
2376 WORD file;
2377 DWORD symbol_size;
2378 DWORD lineno_size;
2379 DWORD unknown2;
2380 DWORD nSrcFiles;
2381 DWORD attribute;
2382 CHAR filename[ 1 ];
2384 } PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
2386 typedef struct _PDB_SYMBOL_FILE_EX
2388 DWORD unknown1;
2389 PDB_SYMBOL_RANGE_EX range;
2390 WORD flag;
2391 WORD file;
2392 DWORD symbol_size;
2393 DWORD lineno_size;
2394 DWORD unknown2;
2395 DWORD nSrcFiles;
2396 DWORD attribute;
2397 DWORD reserved[ 2 ];
2398 CHAR filename[ 1 ];
2400 } PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
2402 typedef struct _PDB_SYMBOL_SOURCE
2404 WORD nModules;
2405 WORD nSrcFiles;
2406 WORD table[ 1 ];
2408 } PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
2410 typedef struct _PDB_SYMBOL_IMPORT
2412 DWORD unknown1;
2413 DWORD unknown2;
2414 DWORD TimeDateStamp;
2415 DWORD nRequests;
2416 CHAR filename[ 1 ];
2418 } PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
2420 typedef struct _PDB_SYMBOLS_OLD
2422 WORD hash1_file;
2423 WORD hash2_file;
2424 WORD gsym_file;
2425 WORD pad;
2426 DWORD module_size;
2427 DWORD offset_size;
2428 DWORD hash_size;
2429 DWORD srcmodule_size;
2431 } PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
2433 typedef struct _PDB_SYMBOLS
2435 DWORD signature;
2436 DWORD version;
2437 DWORD unknown;
2438 DWORD hash1_file;
2439 DWORD hash2_file;
2440 DWORD gsym_file;
2441 DWORD module_size;
2442 DWORD offset_size;
2443 DWORD hash_size;
2444 DWORD srcmodule_size;
2445 DWORD pdbimport_size;
2446 DWORD resvd[ 5 ];
2448 } PDB_SYMBOLS, *PPDB_SYMBOLS;
2449 #pragma pack()
2452 static void *pdb_read( LPBYTE image, WORD *block_list, int size )
2454 PPDB_HEADER pdb = (PPDB_HEADER)image;
2455 int i, nBlocks;
2456 LPBYTE buffer;
2458 if ( !size ) return NULL;
2460 nBlocks = (size + pdb->blocksize-1) / pdb->blocksize;
2461 buffer = DBG_alloc( nBlocks * pdb->blocksize );
2463 for ( i = 0; i < nBlocks; i++ )
2464 memcpy( buffer + i*pdb->blocksize,
2465 image + block_list[i]*pdb->blocksize, pdb->blocksize );
2467 return buffer;
2470 static void *pdb_read_file( LPBYTE image, PPDB_TOC toc, DWORD fileNr )
2472 PPDB_HEADER pdb = (PPDB_HEADER)image;
2473 WORD *block_list;
2474 DWORD i;
2476 if ( !toc || fileNr >= toc->nFiles )
2477 return NULL;
2479 block_list = (WORD *) &toc->file[ toc->nFiles ];
2480 for ( i = 0; i < fileNr; i++ )
2481 block_list += (toc->file[i].size + pdb->blocksize-1) / pdb->blocksize;
2483 return pdb_read( image, block_list, toc->file[fileNr].size );
2486 static void pdb_free( void *buffer )
2488 DBG_free( buffer );
2491 static void pdb_convert_types_header( PDB_TYPES *types, char *image )
2493 memset( types, 0, sizeof(PDB_TYPES) );
2494 if ( !image ) return;
2496 if ( *(DWORD *)image < 19960000 ) /* FIXME: correct version? */
2498 /* Old version of the types record header */
2499 PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
2500 types->version = old->version;
2501 types->type_offset = sizeof(PDB_TYPES_OLD);
2502 types->type_size = old->type_size;
2503 types->first_index = old->first_index;
2504 types->last_index = old->last_index;
2505 types->file = old->file;
2507 else
2509 /* New version of the types record header */
2510 *types = *(PDB_TYPES *)image;
2514 static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
2515 int *header_size, char *image )
2517 memset( symbols, 0, sizeof(PDB_SYMBOLS) );
2518 if ( !image ) return;
2520 if ( *(DWORD *)image != 0xffffffff )
2522 /* Old version of the symbols record header */
2523 PDB_SYMBOLS_OLD *old = (PDB_SYMBOLS_OLD *)image;
2524 symbols->version = 0;
2525 symbols->module_size = old->module_size;
2526 symbols->offset_size = old->offset_size;
2527 symbols->hash_size = old->hash_size;
2528 symbols->srcmodule_size = old->srcmodule_size;
2529 symbols->pdbimport_size = 0;
2530 symbols->hash1_file = old->hash1_file;
2531 symbols->hash2_file = old->hash2_file;
2532 symbols->gsym_file = old->gsym_file;
2534 *header_size = sizeof(PDB_SYMBOLS_OLD);
2536 else
2538 /* New version of the symbols record header */
2539 *symbols = *(PDB_SYMBOLS *)image;
2541 *header_size = sizeof(PDB_SYMBOLS);
2545 static enum DbgInfoLoad DEBUG_ProcessPDBFile( DBG_MODULE *module,
2546 const char *filename, DWORD timestamp )
2548 enum DbgInfoLoad dil = DIL_ERROR;
2549 HANDLE hFile, hMap;
2550 char *image = NULL;
2551 PDB_HEADER *pdb = NULL;
2552 PDB_TOC *toc = NULL;
2553 PDB_ROOT *root = NULL;
2554 char *types_image = NULL;
2555 char *symbols_image = NULL;
2556 PDB_TYPES types;
2557 PDB_SYMBOLS symbols;
2558 int header_size = 0;
2559 char *modimage, *file;
2561 DEBUG_Printf( DBG_CHN_TRACE, "Processing PDB file %s\n", filename );
2564 * Open and map() .PDB file
2566 image = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2567 if ( !image )
2569 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .PDB file %s\n", filename );
2570 goto leave;
2574 * Read in TOC and well-known files
2577 pdb = (PPDB_HEADER)image;
2578 toc = pdb_read( image, pdb->toc_block, pdb->toc.size );
2579 root = pdb_read_file( image, toc, 1 );
2580 types_image = pdb_read_file( image, toc, 2 );
2581 symbols_image = pdb_read_file( image, toc, 3 );
2583 pdb_convert_types_header( &types, types_image );
2584 pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2587 * Check for unknown versions
2590 switch ( root->version )
2592 case 19950623: /* VC 4.0 */
2593 case 19950814:
2594 case 19960307: /* VC 5.0 */
2595 case 19970604: /* VC 6.0 */
2596 break;
2597 default:
2598 DEBUG_Printf( DBG_CHN_ERR, "-Unknown root block version %ld\n", root->version );
2601 switch ( types.version )
2603 case 19950410: /* VC 4.0 */
2604 case 19951122:
2605 case 19961031: /* VC 5.0 / 6.0 */
2606 break;
2607 default:
2608 DEBUG_Printf( DBG_CHN_ERR, "-Unknown type info version %ld\n", types.version );
2611 switch ( symbols.version )
2613 case 0: /* VC 4.0 */
2614 case 19960307: /* VC 5.0 */
2615 case 19970606: /* VC 6.0 */
2616 break;
2617 default:
2618 DEBUG_Printf( DBG_CHN_ERR, "-Unknown symbol info version %ld\n", symbols.version );
2623 * Check .PDB time stamp
2626 if ( root->TimeDateStamp != timestamp )
2628 DEBUG_Printf( DBG_CHN_ERR, "-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2629 filename, root->TimeDateStamp, timestamp );
2633 * Read type table
2636 DEBUG_ParseTypeTable( types_image + types.type_offset, types.type_size );
2639 * Read type-server .PDB imports
2642 if ( symbols.pdbimport_size )
2644 /* FIXME */
2645 DEBUG_Printf(DBG_CHN_ERR, "-Type server .PDB imports ignored!\n" );
2649 * Read global symbol table
2652 modimage = pdb_read_file( image, toc, symbols.gsym_file );
2653 if ( modimage )
2655 DEBUG_SnarfCodeView( module, modimage, 0,
2656 toc->file[symbols.gsym_file].size, NULL );
2657 pdb_free( modimage );
2661 * Read per-module symbol / linenumber tables
2664 file = symbols_image + header_size;
2665 while ( file - symbols_image < header_size + symbols.module_size )
2667 int file_nr, file_index, symbol_size, lineno_size;
2668 char *file_name;
2670 if ( symbols.version < 19970000 )
2672 PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
2673 file_nr = sym_file->file;
2674 file_name = sym_file->filename;
2675 file_index = sym_file->range.index;
2676 symbol_size = sym_file->symbol_size;
2677 lineno_size = sym_file->lineno_size;
2679 else
2681 PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
2682 file_nr = sym_file->file;
2683 file_name = sym_file->filename;
2684 file_index = sym_file->range.index;
2685 symbol_size = sym_file->symbol_size;
2686 lineno_size = sym_file->lineno_size;
2689 modimage = pdb_read_file( image, toc, file_nr );
2690 if ( modimage )
2692 struct codeview_linetab_hdr *linetab = NULL;
2694 if ( lineno_size )
2695 linetab = DEBUG_SnarfLinetab( modimage + symbol_size, lineno_size );
2697 if ( symbol_size )
2698 DEBUG_SnarfCodeView( module, modimage, sizeof(DWORD),
2699 symbol_size, linetab );
2701 pdb_free( modimage );
2704 file_name += strlen(file_name) + 1;
2705 file = (char *)( (DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3 );
2708 dil = DIL_LOADED;
2710 leave:
2713 * Cleanup
2716 DEBUG_ClearTypeTable();
2718 if ( symbols_image ) pdb_free( symbols_image );
2719 if ( types_image ) pdb_free( types_image );
2720 if ( root ) pdb_free( root );
2721 if ( toc ) pdb_free( toc );
2723 DEBUG_UnmapDebugInfoFile(hFile, hMap, image);
2725 return dil;
2731 /*========================================================================
2732 * Process CodeView debug information.
2735 #define CODEVIEW_NB09_SIG ( 'N' | ('B' << 8) | ('0' << 16) | ('9' << 24) )
2736 #define CODEVIEW_NB10_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('0' << 24) )
2737 #define CODEVIEW_NB11_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('1' << 24) )
2739 typedef struct _CODEVIEW_HEADER
2741 DWORD dwSignature;
2742 DWORD lfoDirectory;
2744 } CODEVIEW_HEADER, *PCODEVIEW_HEADER;
2746 typedef struct _CODEVIEW_PDB_DATA
2748 DWORD timestamp;
2749 DWORD unknown;
2750 CHAR name[ 1 ];
2752 } CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA;
2754 typedef struct _CV_DIRECTORY_HEADER
2756 WORD cbDirHeader;
2757 WORD cbDirEntry;
2758 DWORD cDir;
2759 DWORD lfoNextDir;
2760 DWORD flags;
2762 } CV_DIRECTORY_HEADER, *PCV_DIRECTORY_HEADER;
2764 typedef struct _CV_DIRECTORY_ENTRY
2766 WORD subsection;
2767 WORD iMod;
2768 DWORD lfo;
2769 DWORD cb;
2771 } CV_DIRECTORY_ENTRY, *PCV_DIRECTORY_ENTRY;
2774 #define sstAlignSym 0x125
2775 #define sstSrcModule 0x127
2778 static enum DbgInfoLoad DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
2780 PCODEVIEW_HEADER cv = (PCODEVIEW_HEADER)root;
2781 enum DbgInfoLoad dil = DIL_ERROR;
2783 switch ( cv->dwSignature )
2785 case CODEVIEW_NB09_SIG:
2786 case CODEVIEW_NB11_SIG:
2788 PCV_DIRECTORY_HEADER hdr = (PCV_DIRECTORY_HEADER)(root + cv->lfoDirectory);
2789 PCV_DIRECTORY_ENTRY ent, prev, next;
2790 unsigned int i;
2792 ent = (PCV_DIRECTORY_ENTRY)((LPBYTE)hdr + hdr->cbDirHeader);
2793 for ( i = 0; i < hdr->cDir; i++, ent = next )
2795 next = (i == hdr->cDir-1)? NULL :
2796 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent + hdr->cbDirEntry);
2797 prev = (i == 0)? NULL :
2798 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent - hdr->cbDirEntry);
2800 if ( ent->subsection == sstAlignSym )
2803 * Check the next and previous entry. If either is a
2804 * sstSrcModule, it contains the line number info for
2805 * this file.
2807 * FIXME: This is not a general solution!
2809 struct codeview_linetab_hdr *linetab = NULL;
2811 if ( next && next->iMod == ent->iMod
2812 && next->subsection == sstSrcModule )
2813 linetab = DEBUG_SnarfLinetab( root + next->lfo, next->cb );
2815 if ( prev && prev->iMod == ent->iMod
2816 && prev->subsection == sstSrcModule )
2817 linetab = DEBUG_SnarfLinetab( root + prev->lfo, prev->cb );
2820 DEBUG_SnarfCodeView( module, root + ent->lfo, sizeof(DWORD),
2821 ent->cb, linetab );
2825 dil = DIL_LOADED;
2826 break;
2829 case CODEVIEW_NB10_SIG:
2831 PCODEVIEW_PDB_DATA pdb = (PCODEVIEW_PDB_DATA)(cv + 1);
2833 dil = DEBUG_ProcessPDBFile( module, pdb->name, pdb->timestamp );
2834 break;
2837 default:
2838 DEBUG_Printf( DBG_CHN_ERR, "Unknown CODEVIEW signature %08lX in module %s\n",
2839 cv->dwSignature, module->module_name );
2840 break;
2843 return dil;
2847 /*========================================================================
2848 * Process debug directory.
2850 static enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module,
2851 LPBYTE file_map,
2852 PIMAGE_DEBUG_DIRECTORY dbg,
2853 int nDbg )
2855 enum DbgInfoLoad dil = DIL_ERROR;
2856 int i;
2858 /* First, watch out for OMAP data */
2859 for ( i = 0; i < nDbg; i++ )
2861 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC )
2863 module->msc_info->nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
2864 module->msc_info->omapp = (OMAP_DATA *)(file_map + dbg[i].PointerToRawData);
2865 break;
2869 /* Now, try to parse CodeView debug info */
2870 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
2872 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW )
2874 dil = DEBUG_ProcessCodeView( module, file_map + dbg[i].PointerToRawData );
2878 /* If not found, try to parse COFF debug info */
2879 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
2881 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_COFF )
2882 dil = DEBUG_ProcessCoff( module, file_map + dbg[i].PointerToRawData );
2884 #if 0
2885 /* FIXME: this should be supported... this is the debug information for
2886 * functions compiled without a frame pointer (FPO = frame pointer omission)
2887 * the associated data helps finding out the relevant information
2889 for ( i = 0; i < nDbg; i++ )
2890 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_FPO )
2891 DEBUG_Printf(DBG_CHN_MESG, "This guy has FPO information\n");
2893 #define FRAME_FPO 0
2894 #define FRAME_TRAP 1
2895 #define FRAME_TSS 2
2897 typedef struct _FPO_DATA {
2898 DWORD ulOffStart; /* offset 1st byte of function code */
2899 DWORD cbProcSize; /* # bytes in function */
2900 DWORD cdwLocals; /* # bytes in locals/4 */
2901 WORD cdwParams; /* # bytes in params/4 */
2903 WORD cbProlog : 8; /* # bytes in prolog */
2904 WORD cbRegs : 3; /* # regs saved */
2905 WORD fHasSEH : 1; /* TRUE if SEH in func */
2906 WORD fUseBP : 1; /* TRUE if EBP has been allocated */
2907 WORD reserved : 1; /* reserved for future use */
2908 WORD cbFrame : 2; /* frame type */
2909 } FPO_DATA;
2910 #endif
2912 return dil;
2916 /*========================================================================
2917 * Process DBG file.
2919 static enum DbgInfoLoad DEBUG_ProcessDBGFile( DBG_MODULE *module,
2920 const char *filename, DWORD timestamp )
2922 enum DbgInfoLoad dil = DIL_ERROR;
2923 HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
2924 LPBYTE file_map = NULL;
2925 PIMAGE_SEPARATE_DEBUG_HEADER hdr;
2926 PIMAGE_DEBUG_DIRECTORY dbg;
2927 int nDbg;
2930 DEBUG_Printf( DBG_CHN_TRACE, "Processing DBG file %s\n", filename );
2932 file_map = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2933 if ( !file_map )
2935 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .DBG file %s\n", filename );
2936 goto leave;
2939 hdr = (PIMAGE_SEPARATE_DEBUG_HEADER) file_map;
2941 if ( hdr->TimeDateStamp != timestamp )
2943 DEBUG_Printf( DBG_CHN_ERR, "Warning - %s has incorrect internal timestamp\n",
2944 filename );
2946 * Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
2947 * files but nonetheless this check fails. Anyway, WINDBG (debugger for
2948 * Windows by Microsoft) loads debug symbols which have incorrect timestamps.
2953 dbg = (PIMAGE_DEBUG_DIRECTORY) ( file_map + sizeof(*hdr)
2954 + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
2955 + hdr->ExportedNamesSize );
2957 nDbg = hdr->DebugDirectorySize / sizeof(*dbg);
2959 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
2962 leave:
2963 DEBUG_UnmapDebugInfoFile( hFile, hMap, file_map );
2964 return dil;
2968 /*========================================================================
2969 * Process MSC debug information in PE file.
2971 enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
2972 void *_nth, unsigned long nth_ofs )
2974 enum DbgInfoLoad dil = DIL_ERROR;
2975 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
2976 PIMAGE_DATA_DIRECTORY dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
2977 PIMAGE_DEBUG_DIRECTORY dbg = NULL;
2978 int nDbg;
2979 MSC_DBG_INFO extra_info = { 0, NULL, 0, NULL };
2980 HANDLE hMap = 0;
2981 LPBYTE file_map = NULL;
2984 /* Read in section data */
2986 module->msc_info = &extra_info;
2987 extra_info.nsect = nth->FileHeader.NumberOfSections;
2988 extra_info.sectp = DBG_alloc( extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) );
2989 if ( !extra_info.sectp )
2990 goto leave;
2992 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr +
2993 nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
2994 nth->FileHeader.SizeOfOptionalHeader,
2995 extra_info.sectp,
2996 extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) ) )
2997 goto leave;
2999 /* Read in debug directory */
3001 nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
3002 if ( !nDbg )
3003 goto leave;
3005 dbg = (PIMAGE_DEBUG_DIRECTORY) DBG_alloc( nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) );
3006 if ( !dbg )
3007 goto leave;
3009 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr + dir->VirtualAddress,
3010 dbg, nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) ) )
3011 goto leave;
3014 /* Map in PE file */
3015 file_map = DEBUG_MapDebugInfoFile( NULL, 0, 0, &hFile, &hMap );
3016 if ( !file_map )
3017 goto leave;
3020 /* Parse debug directory */
3022 if ( nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED )
3024 /* Debug info is stripped to .DBG file */
3026 PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)(file_map + dbg->PointerToRawData);
3028 if ( nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC
3029 || misc->DataType != IMAGE_DEBUG_MISC_EXENAME )
3031 DEBUG_Printf( DBG_CHN_ERR, "-Debug info stripped, but no .DBG file in module %s\n",
3032 module->module_name );
3033 goto leave;
3036 dil = DEBUG_ProcessDBGFile( module, misc->Data, nth->FileHeader.TimeDateStamp );
3038 else
3040 /* Debug info is embedded into PE module */
3041 /* FIXME: the nDBG information we're manipulating comes from the debuggee
3042 * address space. However, the following code will be made against the
3043 * version mapped in the debugger address space. There are cases (for example
3044 * when the PE sections are compressed in the file and become decompressed
3045 * in the debuggee address space) where the two don't match.
3046 * Therefore, redo the DBG information lookup with the mapped data
3048 PIMAGE_NT_HEADERS mpd_nth = (PIMAGE_NT_HEADERS)(file_map + nth_ofs);
3049 PIMAGE_DATA_DIRECTORY mpd_dir;
3050 PIMAGE_DEBUG_DIRECTORY mpd_dbg = NULL;
3052 /* sanity checks */
3053 if ( mpd_nth->Signature != IMAGE_NT_SIGNATURE ||
3054 mpd_nth->FileHeader.NumberOfSections != nth->FileHeader.NumberOfSections ||
3055 !(mpd_nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED ))
3056 goto leave;
3057 mpd_dir = mpd_nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
3059 if ((mpd_dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY)) != nDbg)
3060 goto leave;
3062 mpd_dbg = (PIMAGE_DEBUG_DIRECTORY)(file_map + mpd_dir->VirtualAddress);
3064 dil = DEBUG_ProcessDebugDirectory( module, file_map, mpd_dbg, nDbg );
3068 leave:
3069 module->msc_info = NULL;
3071 DEBUG_UnmapDebugInfoFile( 0, hMap, file_map );
3072 if ( extra_info.sectp ) DBG_free( extra_info.sectp );
3073 if ( dbg ) DBG_free( dbg );
3074 return dil;
3078 /*========================================================================
3079 * look for stabs information in PE header (it's how mingw compiler provides its
3080 * debugging information), and also wine PE <-> ELF linking through .wsolnk sections
3082 enum DbgInfoLoad DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile,
3083 void* _nth, unsigned long nth_ofs)
3085 IMAGE_SECTION_HEADER pe_seg;
3086 unsigned long pe_seg_ofs;
3087 int i, stabsize = 0, stabstrsize = 0;
3088 unsigned int stabs = 0, stabstr = 0;
3089 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
3090 enum DbgInfoLoad dil = DIL_ERROR;
3092 pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
3093 nth->FileHeader.SizeOfOptionalHeader;
3095 for (i = 0; i < nth->FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
3096 if (!DEBUG_READ_MEM_VERBOSE((void*)((char *)module->load_addr + pe_seg_ofs),
3097 &pe_seg, sizeof(pe_seg)))
3098 continue;
3100 if (!strcasecmp(pe_seg.Name, ".stab")) {
3101 stabs = pe_seg.VirtualAddress;
3102 stabsize = pe_seg.SizeOfRawData;
3103 } else if (!strncasecmp(pe_seg.Name, ".stabstr", 8)) {
3104 stabstr = pe_seg.VirtualAddress;
3105 stabstrsize = pe_seg.SizeOfRawData;
3109 if (stabstrsize && stabsize) {
3110 char* s1 = DBG_alloc(stabsize+stabstrsize);
3112 if (s1) {
3113 if (DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabs, s1, stabsize) &&
3114 DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabstr,
3115 s1 + stabsize, stabstrsize)) {
3116 dil = DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
3117 } else {
3118 DEBUG_Printf(DBG_CHN_MESG, "couldn't read data block\n");
3120 DBG_free(s1);
3121 } else {
3122 DEBUG_Printf(DBG_CHN_MESG, "couldn't alloc %d bytes\n",
3123 stabsize + stabstrsize);
3125 } else {
3126 dil = DIL_NOINFO;
3128 return dil;