Added and fixed some Japanese resources.
[wine/multimedia.git] / debugger / msc.c
blob31911299e226d4850d563eee522f0b66c2e10ee4
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;
127 return ret;
130 /***********************************************************************
131 * DEBUG_UnmapDebugInfoFile
133 static void DEBUG_UnmapDebugInfoFile(HANDLE hFile, HANDLE hMap, void* addr)
135 if (addr) UnmapViewOfFile(addr);
136 if (hMap) CloseHandle(hMap);
137 if (hFile!=INVALID_HANDLE_VALUE) CloseHandle(hFile);
142 /*========================================================================
143 * Process COFF debug information.
146 struct CoffFile
148 unsigned int startaddr;
149 unsigned int endaddr;
150 const char *filename;
151 int linetab_offset;
152 int linecnt;
153 struct name_hash **entries;
154 int neps;
155 int neps_alloc;
158 struct CoffFileSet
160 struct CoffFile *files;
161 int nfiles;
162 int nfiles_alloc;
165 static const char* DEBUG_GetCoffName( PIMAGE_SYMBOL coff_sym, const char* coff_strtab )
167 static char namebuff[9];
168 const char* nampnt;
170 if( coff_sym->N.Name.Short )
172 memcpy(namebuff, coff_sym->N.ShortName, 8);
173 namebuff[8] = '\0';
174 nampnt = &namebuff[0];
176 else
178 nampnt = coff_strtab + coff_sym->N.Name.Long;
181 if( nampnt[0] == '_' )
182 nampnt++;
183 return nampnt;
186 static int DEBUG_AddCoffFile( struct CoffFileSet* coff_files, const char* filename )
188 struct CoffFile* file;
190 if( coff_files->nfiles + 1 >= coff_files->nfiles_alloc )
192 coff_files->nfiles_alloc += 10;
193 coff_files->files = (struct CoffFile *) DBG_realloc(coff_files->files,
194 coff_files->nfiles_alloc * sizeof(struct CoffFile));
196 file = coff_files->files + coff_files->nfiles;
197 file->startaddr = 0xffffffff;
198 file->endaddr = 0;
199 file->filename = filename;
200 file->linetab_offset = -1;
201 file->linecnt = 0;
202 file->entries = NULL;
203 file->neps = file->neps_alloc = 0;
205 return coff_files->nfiles++;
208 static void DEBUG_AddCoffSymbol( struct CoffFile* coff_file, struct name_hash* sym )
210 if( coff_file->neps + 1 >= coff_file->neps_alloc )
212 coff_file->neps_alloc += 10;
213 coff_file->entries = (struct name_hash **)
214 DBG_realloc(coff_file->entries,
215 coff_file->neps_alloc * sizeof(struct name_hash *));
217 coff_file->entries[coff_file->neps++] = sym;
220 static enum DbgInfoLoad DEBUG_ProcessCoff( DBG_MODULE *module, LPBYTE root )
222 PIMAGE_AUX_SYMBOL aux;
223 PIMAGE_COFF_SYMBOLS_HEADER coff;
224 PIMAGE_LINENUMBER coff_linetab;
225 PIMAGE_LINENUMBER linepnt;
226 char * coff_strtab;
227 PIMAGE_SYMBOL coff_sym;
228 PIMAGE_SYMBOL coff_symbols;
229 struct CoffFileSet coff_files;
230 int curr_file_idx = -1;
231 unsigned int i;
232 int j;
233 int k;
234 int l;
235 int linetab_indx;
236 const char * nampnt;
237 int naux;
238 DBG_VALUE new_value;
239 enum DbgInfoLoad dil = DIL_ERROR;
241 DEBUG_Printf(DBG_CHN_TRACE, "Processing COFF symbols...\n");
243 assert(sizeof(IMAGE_SYMBOL) == IMAGE_SIZEOF_SYMBOL);
244 assert(sizeof(IMAGE_LINENUMBER) == IMAGE_SIZEOF_LINENUMBER);
246 coff_files.files = NULL;
247 coff_files.nfiles = coff_files.nfiles_alloc = 0;
249 coff = (PIMAGE_COFF_SYMBOLS_HEADER) root;
251 coff_symbols = (PIMAGE_SYMBOL) ((unsigned int) coff + coff->LvaToFirstSymbol);
252 coff_linetab = (PIMAGE_LINENUMBER) ((unsigned int) coff + coff->LvaToFirstLinenumber);
253 coff_strtab = (char *) (coff_symbols + coff->NumberOfSymbols);
255 linetab_indx = 0;
257 new_value.cookie = DV_TARGET;
258 new_value.type = NULL;
260 for(i=0; i < coff->NumberOfSymbols; i++ )
262 coff_sym = coff_symbols + i;
263 naux = coff_sym->NumberOfAuxSymbols;
265 if( coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE )
267 curr_file_idx = DEBUG_AddCoffFile( &coff_files, (char *) (coff_sym + 1) );
268 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
269 i += naux;
270 continue;
273 if (curr_file_idx < 0) {
274 assert(coff_files.nfiles == 0 && coff_files.nfiles_alloc == 0);
275 curr_file_idx = DEBUG_AddCoffFile( &coff_files, "<none>" );
276 DEBUG_Printf(DBG_CHN_TRACE,"New file %s\n", coff_files.files[curr_file_idx].filename);
280 * This guy marks the size and location of the text section
281 * for the current file. We need to keep track of this so
282 * we can figure out what file the different global functions
283 * go with.
285 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
286 && (naux != 0)
287 && (coff_sym->Type == 0)
288 && (coff_sym->SectionNumber == 1) )
290 aux = (PIMAGE_AUX_SYMBOL) (coff_sym + 1);
292 if( coff_files.files[curr_file_idx].linetab_offset != -1 )
295 * Save this so we can still get the old name.
297 const char* fn = coff_files.files[curr_file_idx].filename;
299 #ifdef MORE_DBG
300 DEBUG_Printf(DBG_CHN_TRACE, "Duplicating sect from %s: %lx %x %x %d %d\n",
301 coff_files.files[curr_file_idx].filename,
302 aux->Section.Length,
303 aux->Section.NumberOfRelocations,
304 aux->Section.NumberOfLinenumbers,
305 aux->Section.Number,
306 aux->Section.Selection);
307 DEBUG_Printf(DBG_CHN_TRACE, "More sect %d %s %08lx %d %d %d\n",
308 coff_sym->SectionNumber,
309 DEBUG_GetCoffName( coff_sym, coff_strtab ),
310 coff_sym->Value,
311 coff_sym->Type,
312 coff_sym->StorageClass,
313 coff_sym->NumberOfAuxSymbols);
314 #endif
317 * Duplicate the file entry. We have no way to describe
318 * multiple text sections in our current way of handling things.
320 DEBUG_AddCoffFile( &coff_files, fn );
322 #ifdef MORE_DBG
323 else
325 DEBUG_Printf(DBG_CHN_TRACE, "New text sect from %s: %lx %x %x %d %d\n",
326 coff_files.files[curr_file_idx].filename,
327 aux->Section.Length,
328 aux->Section.NumberOfRelocations,
329 aux->Section.NumberOfLinenumbers,
330 aux->Section.Number,
331 aux->Section.Selection);
333 #endif
335 if( coff_files.files[curr_file_idx].startaddr > coff_sym->Value )
337 coff_files.files[curr_file_idx].startaddr = coff_sym->Value;
340 if( coff_files.files[curr_file_idx].endaddr < coff_sym->Value + aux->Section.Length )
342 coff_files.files[curr_file_idx].endaddr = coff_sym->Value + aux->Section.Length;
345 coff_files.files[curr_file_idx].linetab_offset = linetab_indx;
346 coff_files.files[curr_file_idx].linecnt = aux->Section.NumberOfLinenumbers;
347 linetab_indx += aux->Section.NumberOfLinenumbers;
348 i += naux;
349 continue;
352 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
353 && (naux == 0)
354 && (coff_sym->SectionNumber == 1) )
356 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
358 * This is a normal static function when naux == 0.
359 * Just register it. The current file is the correct
360 * one in this instance.
362 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
364 new_value.addr.seg = 0;
365 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
367 #ifdef MORE_DBG
368 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding static symbol %s\n", nampnt);
369 #endif
371 /* FIXME: was adding symbol to this_file ??? */
372 DEBUG_AddCoffSymbol( &coff_files.files[curr_file_idx],
373 DEBUG_AddSymbol( nampnt, &new_value,
374 coff_files.files[curr_file_idx].filename,
375 SYM_WIN32 | SYM_FUNC ) );
376 i += naux;
377 continue;
380 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
381 && ISFCN(coff_sym->Type)
382 && (coff_sym->SectionNumber > 0) )
384 const char* this_file = NULL;
385 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
386 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
388 new_value.addr.seg = 0;
389 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
391 #ifdef MORE_DBG
392 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
394 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global symbol %s (sect=%s)\n",
395 nampnt, MSC_INFO(module)->sectp[coff_sym->SectionNumber - 1].Name);
396 #endif
399 * Now we need to figure out which file this guy belongs to.
401 for(j=0; j < coff_files.nfiles; j++)
403 if( coff_files.files[j].startaddr <= base + coff_sym->Value
404 && coff_files.files[j].endaddr > base + coff_sym->Value )
406 this_file = coff_files.files[j].filename;
407 break;
410 if (j < coff_files.nfiles) {
411 DEBUG_AddCoffSymbol( &coff_files.files[j],
412 DEBUG_AddSymbol( nampnt, &new_value, this_file, SYM_WIN32 | SYM_FUNC ) );
413 } else {
414 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_FUNC );
416 i += naux;
417 continue;
420 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
421 && (coff_sym->SectionNumber > 0) )
423 DWORD base = module->msc_info->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
425 * Similar to above, but for the case of data symbols.
426 * These aren't treated as entrypoints.
428 nampnt = DEBUG_GetCoffName( coff_sym, coff_strtab );
430 new_value.addr.seg = 0;
431 new_value.addr.off = (int) ((char *)module->load_addr + base + coff_sym->Value);
433 #ifdef MORE_DBG
434 DEBUG_Printf(DBG_CHN_TRACE, "%d: %lx %s\n", i, new_value.addr.off, nampnt);
436 DEBUG_Printf(DBG_CHN_TRACE,"\tAdding global data symbol %s\n", nampnt);
437 #endif
440 * Now we need to figure out which file this guy belongs to.
442 DEBUG_AddSymbol( nampnt, &new_value, NULL, SYM_WIN32 | SYM_DATA );
443 i += naux;
444 continue;
447 if( (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC)
448 && (naux == 0) )
451 * Ignore these. They don't have anything to do with
452 * reality.
454 i += naux;
455 continue;
458 #ifdef MORE_DBG
459 DEBUG_Printf(DBG_CHN_TRACE,"Skipping unknown entry '%s' %d %d %d\n",
460 DEBUG_GetCoffName( coff_sym, coff_strtab ),
461 coff_sym->StorageClass, coff_sym->SectionNumber, naux);
462 #endif
465 * For now, skip past the aux entries.
467 i += naux;
472 * OK, we now should have a list of files, and we should have a list
473 * of entrypoints. We need to sort the entrypoints so that we are
474 * able to tie the line numbers with the given functions within the
475 * file.
477 if( coff_files.files != NULL )
479 for(j=0; j < coff_files.nfiles; j++)
481 if( coff_files.files[j].entries != NULL )
483 qsort(coff_files.files[j].entries, coff_files.files[j].neps,
484 sizeof(struct name_hash *), DEBUG_cmp_sym);
489 * Now pick apart the line number tables, and attach the entries
490 * to the given functions.
492 for(j=0; j < coff_files.nfiles; j++)
494 l = 0;
495 if( coff_files.files[j].neps != 0 )
496 for(k=0; k < coff_files.files[j].linecnt; k++)
498 linepnt = coff_linetab + coff_files.files[j].linetab_offset + k;
500 * If we have spilled onto the next entrypoint, then
501 * bump the counter..
503 while(TRUE)
505 if (l+1 >= coff_files.files[j].neps) break;
506 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l+1], &new_value.addr);
507 if( (((unsigned int)module->load_addr +
508 linepnt->Type.VirtualAddress) >= new_value.addr.off) )
510 l++;
511 } else break;
515 * Add the line number. This is always relative to the
516 * start of the function, so we need to subtract that offset
517 * first.
519 DEBUG_GetSymbolAddr(coff_files.files[j].entries[l], &new_value.addr);
520 DEBUG_AddLineNumber(coff_files.files[j].entries[l],
521 linepnt->Linenumber,
522 (unsigned int) module->load_addr
523 + linepnt->Type.VirtualAddress
524 - new_value.addr.off);
529 dil = DIL_LOADED;
531 if( coff_files.files != NULL )
533 for(j=0; j < coff_files.nfiles; j++)
535 if( coff_files.files[j].entries != NULL )
537 DBG_free(coff_files.files[j].entries);
540 DBG_free(coff_files.files);
543 return dil;
549 /*========================================================================
550 * Process CodeView type information.
553 union codeview_type
555 struct
557 unsigned short int len;
558 short int id;
559 } generic;
561 struct
563 unsigned short int len;
564 short int id;
565 short int attribute;
566 short int datatype;
567 unsigned char variant[1];
568 } pointer;
570 struct
572 unsigned short int len;
573 short int id;
574 unsigned int datatype;
575 unsigned int attribute;
576 unsigned char variant[1];
577 } pointer32;
579 struct
581 unsigned short int len;
582 short int id;
583 unsigned char nbits;
584 unsigned char bitoff;
585 unsigned short type;
586 } bitfield;
588 struct
590 unsigned short int len;
591 short int id;
592 unsigned int type;
593 unsigned char nbits;
594 unsigned char bitoff;
595 } bitfield32;
597 struct
599 unsigned short int len;
600 short int id;
601 short int elemtype;
602 short int idxtype;
603 unsigned short int arrlen; /* numeric leaf */
604 #if 0
605 unsigned char name[1];
606 #endif
607 } array;
609 struct
611 unsigned short int len;
612 short int id;
613 unsigned int elemtype;
614 unsigned int idxtype;
615 unsigned short int arrlen; /* numeric leaf */
616 #if 0
617 unsigned char name[1];
618 #endif
619 } array32;
621 struct
623 unsigned short int len;
624 short int id;
625 short int n_element;
626 short int fieldlist;
627 short int property;
628 short int derived;
629 short int vshape;
630 unsigned short int structlen; /* numeric leaf */
631 #if 0
632 unsigned char name[1];
633 #endif
634 } structure;
636 struct
638 unsigned short int len;
639 short int id;
640 short int n_element;
641 short int property;
642 unsigned int fieldlist;
643 unsigned int derived;
644 unsigned int vshape;
645 unsigned short int structlen; /* numeric leaf */
646 #if 0
647 unsigned char name[1];
648 #endif
649 } structure32;
651 struct
653 unsigned short int len;
654 short int id;
655 short int count;
656 short int fieldlist;
657 short int property;
658 unsigned short int un_len; /* numeric leaf */
659 #if 0
660 unsigned char name[1];
661 #endif
662 } t_union;
664 struct
666 unsigned short int len;
667 short int id;
668 short int count;
669 short int property;
670 unsigned int fieldlist;
671 unsigned short int un_len; /* numeric leaf */
672 #if 0
673 unsigned char name[1];
674 #endif
675 } t_union32;
677 struct
679 unsigned short int len;
680 short int id;
681 short int count;
682 short int type;
683 short int field;
684 short int property;
685 unsigned char name[1];
686 } enumeration;
688 struct
690 unsigned short int len;
691 short int id;
692 short int count;
693 short int property;
694 unsigned int type;
695 unsigned int field;
696 unsigned char name[1];
697 } enumeration32;
699 struct
701 unsigned short int len;
702 short int id;
703 unsigned char list[1];
704 } fieldlist;
707 union codeview_fieldtype
709 struct
711 short int id;
712 } generic;
714 struct
716 short int id;
717 short int type;
718 short int attribute;
719 unsigned short int offset; /* numeric leaf */
720 } bclass;
722 struct
724 short int id;
725 short int attribute;
726 unsigned int type;
727 unsigned short int offset; /* numeric leaf */
728 } bclass32;
730 struct
732 short int id;
733 short int btype;
734 short int vbtype;
735 short int attribute;
736 unsigned short int vbpoff; /* numeric leaf */
737 #if 0
738 unsigned short int vboff; /* numeric leaf */
739 #endif
740 } vbclass;
742 struct
744 short int id;
745 short int attribute;
746 unsigned int btype;
747 unsigned int vbtype;
748 unsigned short int vbpoff; /* numeric leaf */
749 #if 0
750 unsigned short int vboff; /* numeric leaf */
751 #endif
752 } vbclass32;
754 struct
756 short int id;
757 short int attribute;
758 unsigned short int value; /* numeric leaf */
759 #if 0
760 unsigned char name[1];
761 #endif
762 } enumerate;
764 struct
766 short int id;
767 short int type;
768 unsigned char name[1];
769 } friendfcn;
771 struct
773 short int id;
774 short int _pad0;
775 unsigned int type;
776 unsigned char name[1];
777 } friendfcn32;
779 struct
781 short int id;
782 short int type;
783 short int attribute;
784 unsigned short int offset; /* numeric leaf */
785 #if 0
786 unsigned char name[1];
787 #endif
788 } member;
790 struct
792 short int id;
793 short int attribute;
794 unsigned int type;
795 unsigned short int offset; /* numeric leaf */
796 #if 0
797 unsigned char name[1];
798 #endif
799 } member32;
801 struct
803 short int id;
804 short int type;
805 short int attribute;
806 unsigned char name[1];
807 } stmember;
809 struct
811 short int id;
812 short int attribute;
813 unsigned int type;
814 unsigned char name[1];
815 } stmember32;
817 struct
819 short int id;
820 short int count;
821 short int mlist;
822 unsigned char name[1];
823 } method;
825 struct
827 short int id;
828 short int count;
829 unsigned int mlist;
830 unsigned char name[1];
831 } method32;
833 struct
835 short int id;
836 short int index;
837 unsigned char name[1];
838 } nesttype;
840 struct
842 short int id;
843 short int _pad0;
844 unsigned int index;
845 unsigned char name[1];
846 } nesttype32;
848 struct
850 short int id;
851 short int type;
852 } vfunctab;
854 struct
856 short int id;
857 short int _pad0;
858 unsigned int type;
859 } vfunctab32;
861 struct
863 short int id;
864 short int type;
865 } friendcls;
867 struct
869 short int id;
870 short int _pad0;
871 unsigned int type;
872 } friendcls32;
875 struct
877 short int id;
878 short int attribute;
879 short int type;
880 unsigned char name[1];
881 } onemethod;
882 struct
884 short int id;
885 short int attribute;
886 short int type;
887 unsigned int vtab_offset;
888 unsigned char name[1];
889 } onemethod_virt;
891 struct
893 short int id;
894 short int attribute;
895 unsigned int type;
896 unsigned char name[1];
897 } onemethod32;
898 struct
900 short int id;
901 short int attribute;
902 unsigned int type;
903 unsigned int vtab_offset;
904 unsigned char name[1];
905 } onemethod32_virt;
907 struct
909 short int id;
910 short int type;
911 unsigned int offset;
912 } vfuncoff;
914 struct
916 short int id;
917 short int _pad0;
918 unsigned int type;
919 unsigned int offset;
920 } vfuncoff32;
922 struct
924 short int id;
925 short int attribute;
926 short int index;
927 unsigned char name[1];
928 } nesttypeex;
930 struct
932 short int id;
933 short int attribute;
934 unsigned int index;
935 unsigned char name[1];
936 } nesttypeex32;
938 struct
940 short int id;
941 short int attribute;
942 unsigned int type;
943 unsigned char name[1];
944 } membermodify;
949 * This covers the basic datatypes that VC++ seems to be using these days.
950 * 32 bit mode only. There are additional numbers for the pointers in 16
951 * bit mode. There are many other types listed in the documents, but these
952 * are apparently not used by the compiler, or represent pointer types
953 * that are not used.
955 #define T_NOTYPE 0x0000 /* Notype */
956 #define T_ABS 0x0001 /* Abs */
957 #define T_VOID 0x0003 /* Void */
958 #define T_CHAR 0x0010 /* signed char */
959 #define T_SHORT 0x0011 /* short */
960 #define T_LONG 0x0012 /* long */
961 #define T_QUAD 0x0013 /* long long */
962 #define T_UCHAR 0x0020 /* unsigned char */
963 #define T_USHORT 0x0021 /* unsigned short */
964 #define T_ULONG 0x0022 /* unsigned long */
965 #define T_UQUAD 0x0023 /* unsigned long long */
966 #define T_REAL32 0x0040 /* float */
967 #define T_REAL64 0x0041 /* double */
968 #define T_RCHAR 0x0070 /* real char */
969 #define T_WCHAR 0x0071 /* wide char */
970 #define T_INT4 0x0074 /* int */
971 #define T_UINT4 0x0075 /* unsigned int */
973 #define T_32PVOID 0x0403 /* 32 bit near pointer to void */
974 #define T_32PCHAR 0x0410 /* 16:32 near pointer to signed char */
975 #define T_32PSHORT 0x0411 /* 16:32 near pointer to short */
976 #define T_32PLONG 0x0412 /* 16:32 near pointer to int */
977 #define T_32PQUAD 0x0413 /* 16:32 near pointer to long long */
978 #define T_32PUCHAR 0x0420 /* 16:32 near pointer to unsigned char */
979 #define T_32PUSHORT 0x0421 /* 16:32 near pointer to unsigned short */
980 #define T_32PULONG 0x0422 /* 16:32 near pointer to unsigned int */
981 #define T_32PUQUAD 0x0423 /* 16:32 near pointer to long long */
982 #define T_32PREAL32 0x0440 /* 16:32 near pointer to float */
983 #define T_32PREAL64 0x0441 /* 16:32 near pointer to float */
984 #define T_32PRCHAR 0x0470 /* 16:32 near pointer to real char */
985 #define T_32PWCHAR 0x0471 /* 16:32 near pointer to real char */
986 #define T_32PINT4 0x0474 /* 16:32 near pointer to int */
987 #define T_32PUINT4 0x0475 /* 16:32 near pointer to unsigned int */
990 #define LF_MODIFIER 0x0001
991 #define LF_POINTER 0x0002
992 #define LF_ARRAY 0x0003
993 #define LF_CLASS 0x0004
994 #define LF_STRUCTURE 0x0005
995 #define LF_UNION 0x0006
996 #define LF_ENUM 0x0007
997 #define LF_PROCEDURE 0x0008
998 #define LF_MFUNCTION 0x0009
999 #define LF_VTSHAPE 0x000a
1000 #define LF_COBOL0 0x000b
1001 #define LF_COBOL1 0x000c
1002 #define LF_BARRAY 0x000d
1003 #define LF_LABEL 0x000e
1004 #define LF_NULL 0x000f
1005 #define LF_NOTTRAN 0x0010
1006 #define LF_DIMARRAY 0x0011
1007 #define LF_VFTPATH 0x0012
1008 #define LF_PRECOMP 0x0013
1009 #define LF_ENDPRECOMP 0x0014
1010 #define LF_OEM 0x0015
1011 #define LF_TYPESERVER 0x0016
1013 #define LF_MODIFIER_32 0x1001 /* variants with new 32-bit type indices */
1014 #define LF_POINTER_32 0x1002
1015 #define LF_ARRAY_32 0x1003
1016 #define LF_CLASS_32 0x1004
1017 #define LF_STRUCTURE_32 0x1005
1018 #define LF_UNION_32 0x1006
1019 #define LF_ENUM_32 0x1007
1020 #define LF_PROCEDURE_32 0x1008
1021 #define LF_MFUNCTION_32 0x1009
1022 #define LF_COBOL0_32 0x100a
1023 #define LF_BARRAY_32 0x100b
1024 #define LF_DIMARRAY_32 0x100c
1025 #define LF_VFTPATH_32 0x100d
1026 #define LF_PRECOMP_32 0x100e
1027 #define LF_OEM_32 0x100f
1029 #define LF_SKIP 0x0200
1030 #define LF_ARGLIST 0x0201
1031 #define LF_DEFARG 0x0202
1032 #define LF_LIST 0x0203
1033 #define LF_FIELDLIST 0x0204
1034 #define LF_DERIVED 0x0205
1035 #define LF_BITFIELD 0x0206
1036 #define LF_METHODLIST 0x0207
1037 #define LF_DIMCONU 0x0208
1038 #define LF_DIMCONLU 0x0209
1039 #define LF_DIMVARU 0x020a
1040 #define LF_DIMVARLU 0x020b
1041 #define LF_REFSYM 0x020c
1043 #define LF_SKIP_32 0x1200 /* variants with new 32-bit type indices */
1044 #define LF_ARGLIST_32 0x1201
1045 #define LF_DEFARG_32 0x1202
1046 #define LF_FIELDLIST_32 0x1203
1047 #define LF_DERIVED_32 0x1204
1048 #define LF_BITFIELD_32 0x1205
1049 #define LF_METHODLIST_32 0x1206
1050 #define LF_DIMCONU_32 0x1207
1051 #define LF_DIMCONLU_32 0x1208
1052 #define LF_DIMVARU_32 0x1209
1053 #define LF_DIMVARLU_32 0x120a
1055 #define LF_BCLASS 0x0400
1056 #define LF_VBCLASS 0x0401
1057 #define LF_IVBCLASS 0x0402
1058 #define LF_ENUMERATE 0x0403
1059 #define LF_FRIENDFCN 0x0404
1060 #define LF_INDEX 0x0405
1061 #define LF_MEMBER 0x0406
1062 #define LF_STMEMBER 0x0407
1063 #define LF_METHOD 0x0408
1064 #define LF_NESTTYPE 0x0409
1065 #define LF_VFUNCTAB 0x040a
1066 #define LF_FRIENDCLS 0x040b
1067 #define LF_ONEMETHOD 0x040c
1068 #define LF_VFUNCOFF 0x040d
1069 #define LF_NESTTYPEEX 0x040e
1070 #define LF_MEMBERMODIFY 0x040f
1072 #define LF_BCLASS_32 0x1400 /* variants with new 32-bit type indices */
1073 #define LF_VBCLASS_32 0x1401
1074 #define LF_IVBCLASS_32 0x1402
1075 #define LF_FRIENDFCN_32 0x1403
1076 #define LF_INDEX_32 0x1404
1077 #define LF_MEMBER_32 0x1405
1078 #define LF_STMEMBER_32 0x1406
1079 #define LF_METHOD_32 0x1407
1080 #define LF_NESTTYPE_32 0x1408
1081 #define LF_VFUNCTAB_32 0x1409
1082 #define LF_FRIENDCLS_32 0x140a
1083 #define LF_ONEMETHOD_32 0x140b
1084 #define LF_VFUNCOFF_32 0x140c
1085 #define LF_NESTTYPEEX_32 0x140d
1087 #define LF_NUMERIC 0x8000 /* numeric leaf types */
1088 #define LF_CHAR 0x8000
1089 #define LF_SHORT 0x8001
1090 #define LF_USHORT 0x8002
1091 #define LF_LONG 0x8003
1092 #define LF_ULONG 0x8004
1093 #define LF_REAL32 0x8005
1094 #define LF_REAL64 0x8006
1095 #define LF_REAL80 0x8007
1096 #define LF_REAL128 0x8008
1097 #define LF_QUADWORD 0x8009
1098 #define LF_UQUADWORD 0x800a
1099 #define LF_REAL48 0x800b
1100 #define LF_COMPLEX32 0x800c
1101 #define LF_COMPLEX64 0x800d
1102 #define LF_COMPLEX80 0x800e
1103 #define LF_COMPLEX128 0x800f
1104 #define LF_VARSTRING 0x8010
1108 #define MAX_BUILTIN_TYPES 0x480
1109 static struct datatype * cv_basic_types[MAX_BUILTIN_TYPES];
1110 static unsigned int num_cv_defined_types = 0;
1111 static struct datatype **cv_defined_types = NULL;
1113 void
1114 DEBUG_InitCVDataTypes(void)
1117 * These are the common builtin types that are used by VC++.
1119 cv_basic_types[T_NOTYPE] = NULL;
1120 cv_basic_types[T_ABS] = NULL;
1121 cv_basic_types[T_VOID] = DEBUG_GetBasicType(DT_BASIC_VOID);
1122 cv_basic_types[T_CHAR] = DEBUG_GetBasicType(DT_BASIC_CHAR);
1123 cv_basic_types[T_SHORT] = DEBUG_GetBasicType(DT_BASIC_SHORTINT);
1124 cv_basic_types[T_LONG] = DEBUG_GetBasicType(DT_BASIC_LONGINT);
1125 cv_basic_types[T_QUAD] = DEBUG_GetBasicType(DT_BASIC_LONGLONGINT);
1126 cv_basic_types[T_UCHAR] = DEBUG_GetBasicType(DT_BASIC_UCHAR);
1127 cv_basic_types[T_USHORT] = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
1128 cv_basic_types[T_ULONG] = DEBUG_GetBasicType(DT_BASIC_ULONGINT);
1129 cv_basic_types[T_UQUAD] = DEBUG_GetBasicType(DT_BASIC_ULONGLONGINT);
1130 cv_basic_types[T_REAL32] = DEBUG_GetBasicType(DT_BASIC_FLOAT);
1131 cv_basic_types[T_REAL64] = DEBUG_GetBasicType(DT_BASIC_DOUBLE);
1132 cv_basic_types[T_RCHAR] = DEBUG_GetBasicType(DT_BASIC_CHAR);
1133 cv_basic_types[T_WCHAR] = DEBUG_GetBasicType(DT_BASIC_SHORTINT);
1134 cv_basic_types[T_INT4] = DEBUG_GetBasicType(DT_BASIC_INT);
1135 cv_basic_types[T_UINT4] = DEBUG_GetBasicType(DT_BASIC_UINT);
1137 cv_basic_types[T_32PVOID] = DEBUG_FindOrMakePointerType(cv_basic_types[T_VOID]);
1138 cv_basic_types[T_32PCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_CHAR]);
1139 cv_basic_types[T_32PSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_SHORT]);
1140 cv_basic_types[T_32PLONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_LONG]);
1141 cv_basic_types[T_32PQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_QUAD]);
1142 cv_basic_types[T_32PUCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UCHAR]);
1143 cv_basic_types[T_32PUSHORT] = DEBUG_FindOrMakePointerType(cv_basic_types[T_USHORT]);
1144 cv_basic_types[T_32PULONG] = DEBUG_FindOrMakePointerType(cv_basic_types[T_ULONG]);
1145 cv_basic_types[T_32PUQUAD] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UQUAD]);
1146 cv_basic_types[T_32PREAL32] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL32]);
1147 cv_basic_types[T_32PREAL64] = DEBUG_FindOrMakePointerType(cv_basic_types[T_REAL64]);
1148 cv_basic_types[T_32PRCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_RCHAR]);
1149 cv_basic_types[T_32PWCHAR] = DEBUG_FindOrMakePointerType(cv_basic_types[T_WCHAR]);
1150 cv_basic_types[T_32PINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_INT4]);
1151 cv_basic_types[T_32PUINT4] = DEBUG_FindOrMakePointerType(cv_basic_types[T_UINT4]);
1155 static int
1156 numeric_leaf( int *value, unsigned short int *leaf )
1158 unsigned short int type = *leaf++;
1159 int length = 2;
1161 if ( type < LF_NUMERIC )
1163 *value = type;
1165 else
1167 switch ( type )
1169 case LF_CHAR:
1170 length += 1;
1171 *value = *(char *)leaf;
1172 break;
1174 case LF_SHORT:
1175 length += 2;
1176 *value = *(short *)leaf;
1177 break;
1179 case LF_USHORT:
1180 length += 2;
1181 *value = *(unsigned short *)leaf;
1182 break;
1184 case LF_LONG:
1185 length += 4;
1186 *value = *(int *)leaf;
1187 break;
1189 case LF_ULONG:
1190 length += 4;
1191 *value = *(unsigned int *)leaf;
1192 break;
1194 case LF_QUADWORD:
1195 case LF_UQUADWORD:
1196 length += 8;
1197 *value = 0; /* FIXME */
1198 break;
1200 case LF_REAL32:
1201 length += 4;
1202 *value = 0; /* FIXME */
1203 break;
1205 case LF_REAL48:
1206 length += 6;
1207 *value = 0; /* FIXME */
1208 break;
1210 case LF_REAL64:
1211 length += 8;
1212 *value = 0; /* FIXME */
1213 break;
1215 case LF_REAL80:
1216 length += 10;
1217 *value = 0; /* FIXME */
1218 break;
1220 case LF_REAL128:
1221 length += 16;
1222 *value = 0; /* FIXME */
1223 break;
1225 case LF_COMPLEX32:
1226 length += 4;
1227 *value = 0; /* FIXME */
1228 break;
1230 case LF_COMPLEX64:
1231 length += 8;
1232 *value = 0; /* FIXME */
1233 break;
1235 case LF_COMPLEX80:
1236 length += 10;
1237 *value = 0; /* FIXME */
1238 break;
1240 case LF_COMPLEX128:
1241 length += 16;
1242 *value = 0; /* FIXME */
1243 break;
1245 case LF_VARSTRING:
1246 length += 2 + *leaf;
1247 *value = 0; /* FIXME */
1248 break;
1250 default:
1251 DEBUG_Printf( DBG_CHN_MESG, "Unknown numeric leaf type %04x\n", type );
1252 *value = 0;
1253 break;
1257 return length;
1260 static char *
1261 terminate_string( unsigned char *name )
1263 static char symname[256];
1265 int namelen = name[0];
1266 assert( namelen >= 0 && namelen < 256 );
1268 memcpy( symname, name+1, namelen );
1269 symname[namelen] = '\0';
1271 if ( !*symname || strcmp( symname, "__unnamed" ) == 0 )
1272 return NULL;
1273 else
1274 return symname;
1277 static
1278 struct datatype * DEBUG_GetCVType(unsigned int typeno)
1280 struct datatype * dt = NULL;
1283 * Convert Codeview type numbers into something we can grok internally.
1284 * Numbers < 0x1000 are all fixed builtin types. Numbers from 0x1000 and
1285 * up are all user defined (structs, etc).
1287 if ( typeno < 0x1000 )
1289 if ( typeno < MAX_BUILTIN_TYPES )
1290 dt = cv_basic_types[typeno];
1292 else
1294 if ( typeno - 0x1000 < num_cv_defined_types )
1295 dt = cv_defined_types[typeno - 0x1000];
1298 return dt;
1301 static int
1302 DEBUG_AddCVType( unsigned int typeno, struct datatype *dt )
1304 while ( typeno - 0x1000 >= num_cv_defined_types )
1306 num_cv_defined_types += 0x100;
1307 cv_defined_types = (struct datatype **)
1308 DBG_realloc( cv_defined_types,
1309 num_cv_defined_types * sizeof(struct datatype *) );
1311 memset( cv_defined_types + num_cv_defined_types - 0x100,
1313 0x100 * sizeof(struct datatype *) );
1315 if ( cv_defined_types == NULL )
1316 return FALSE;
1319 cv_defined_types[ typeno - 0x1000 ] = dt;
1320 return TRUE;
1323 static void
1324 DEBUG_ClearTypeTable( void )
1326 if ( cv_defined_types )
1327 DBG_free( cv_defined_types );
1329 cv_defined_types = NULL;
1330 num_cv_defined_types = 0;
1333 static int
1334 DEBUG_AddCVType_Pointer( unsigned int typeno, unsigned int datatype )
1336 struct datatype *dt =
1337 DEBUG_FindOrMakePointerType( DEBUG_GetCVType( datatype ) );
1339 return DEBUG_AddCVType( typeno, dt );
1342 static int
1343 DEBUG_AddCVType_Array( unsigned int typeno, char *name,
1344 unsigned int elemtype, unsigned int arr_len )
1346 struct datatype *dt = DEBUG_NewDataType( DT_ARRAY, name );
1347 struct datatype *elem = DEBUG_GetCVType( elemtype );
1348 unsigned int elem_size = elem? DEBUG_GetObjectSize( elem ) : 0;
1349 unsigned int arr_max = elem_size? arr_len / elem_size : 0;
1351 DEBUG_SetArrayParams( dt, 0, arr_max, elem );
1352 return DEBUG_AddCVType( typeno, dt );
1355 static int
1356 DEBUG_AddCVType_Bitfield( unsigned int typeno,
1357 unsigned int bitoff, unsigned int nbits,
1358 unsigned int basetype )
1360 struct datatype *dt = DEBUG_NewDataType( DT_BITFIELD, NULL );
1361 struct datatype *base = DEBUG_GetCVType( basetype );
1363 DEBUG_SetBitfieldParams( dt, bitoff, nbits, base );
1364 return DEBUG_AddCVType( typeno, dt );
1367 static int
1368 DEBUG_AddCVType_EnumFieldList( unsigned int typeno, unsigned char *list, int len )
1370 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, NULL );
1371 unsigned char *ptr = list;
1373 while ( ptr - list < len )
1375 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1377 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1379 ptr += *ptr & 0x0f;
1380 continue;
1383 switch ( type->generic.id )
1385 case LF_ENUMERATE:
1387 int value, vlen = numeric_leaf( &value, &type->enumerate.value );
1388 unsigned char *name = (unsigned char *)&type->enumerate.value + vlen;
1390 DEBUG_AddStructElement( dt, terminate_string( name ),
1391 NULL, value, 0 );
1393 ptr += 2 + 2 + vlen + (1 + name[0]);
1394 break;
1397 default:
1398 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in ENUM field list\n",
1399 type->generic.id );
1400 return FALSE;
1404 return DEBUG_AddCVType( typeno, dt );
1407 static int
1408 DEBUG_AddCVType_StructFieldList( unsigned int typeno, unsigned char *list, int len )
1410 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, NULL );
1411 unsigned char *ptr = list;
1413 while ( ptr - list < len )
1415 union codeview_fieldtype *type = (union codeview_fieldtype *)ptr;
1417 if ( *ptr >= 0xf0 ) /* LF_PAD... */
1419 ptr += *ptr & 0x0f;
1420 continue;
1423 switch ( type->generic.id )
1425 case LF_BCLASS:
1427 int offset, olen = numeric_leaf( &offset, &type->bclass.offset );
1429 /* FIXME: ignored for now */
1431 ptr += 2 + 2 + 2 + olen;
1432 break;
1435 case LF_BCLASS_32:
1437 int offset, olen = numeric_leaf( &offset, &type->bclass32.offset );
1439 /* FIXME: ignored for now */
1441 ptr += 2 + 2 + 4 + olen;
1442 break;
1445 case LF_VBCLASS:
1446 case LF_IVBCLASS:
1448 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass.vbpoff );
1449 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass.vbpoff + vbpoff);
1450 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1452 /* FIXME: ignored for now */
1454 ptr += 2 + 2 + 2 + 2 + vbplen + vplen;
1455 break;
1458 case LF_VBCLASS_32:
1459 case LF_IVBCLASS_32:
1461 int vbpoff, vbplen = numeric_leaf( &vbpoff, &type->vbclass32.vbpoff );
1462 unsigned short int *p_vboff = (unsigned short int *)((char *)&type->vbclass32.vbpoff + vbpoff);
1463 int vpoff, vplen = numeric_leaf( &vpoff, p_vboff );
1465 /* FIXME: ignored for now */
1467 ptr += 2 + 2 + 4 + 4 + vbplen + vplen;
1468 break;
1471 case LF_MEMBER:
1473 int offset, olen = numeric_leaf( &offset, &type->member.offset );
1474 unsigned char *name = (unsigned char *)&type->member.offset + olen;
1476 struct datatype *subtype = DEBUG_GetCVType( type->member.type );
1477 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1479 DEBUG_AddStructElement( dt, terminate_string( name ),
1480 subtype, offset << 3, elem_size << 3 );
1482 ptr += 2 + 2 + 2 + olen + (1 + name[0]);
1483 break;
1486 case LF_MEMBER_32:
1488 int offset, olen = numeric_leaf( &offset, &type->member32.offset );
1489 unsigned char *name = (unsigned char *)&type->member32.offset + olen;
1491 struct datatype *subtype = DEBUG_GetCVType( type->member32.type );
1492 int elem_size = subtype? DEBUG_GetObjectSize( subtype ) : 0;
1494 DEBUG_AddStructElement( dt, terminate_string( name ),
1495 subtype, offset << 3, elem_size << 3 );
1497 ptr += 2 + 2 + 4 + olen + (1 + name[0]);
1498 break;
1501 case LF_STMEMBER:
1502 /* FIXME: ignored for now */
1503 ptr += 2 + 2 + 2 + (1 + type->stmember.name[0]);
1504 break;
1506 case LF_STMEMBER_32:
1507 /* FIXME: ignored for now */
1508 ptr += 2 + 4 + 2 + (1 + type->stmember32.name[0]);
1509 break;
1511 case LF_METHOD:
1512 /* FIXME: ignored for now */
1513 ptr += 2 + 2 + 2 + (1 + type->method.name[0]);
1514 break;
1516 case LF_METHOD_32:
1517 /* FIXME: ignored for now */
1518 ptr += 2 + 2 + 4 + (1 + type->method32.name[0]);
1519 break;
1521 case LF_NESTTYPE:
1522 /* FIXME: ignored for now */
1523 ptr += 2 + 2 + (1 + type->nesttype.name[0]);
1524 break;
1526 case LF_NESTTYPE_32:
1527 /* FIXME: ignored for now */
1528 ptr += 2 + 2 + 4 + (1 + type->nesttype32.name[0]);
1529 break;
1531 case LF_VFUNCTAB:
1532 /* FIXME: ignored for now */
1533 ptr += 2 + 2;
1534 break;
1536 case LF_VFUNCTAB_32:
1537 /* FIXME: ignored for now */
1538 ptr += 2 + 2 + 4;
1539 break;
1541 case LF_ONEMETHOD:
1542 /* FIXME: ignored for now */
1543 switch ( (type->onemethod.attribute >> 2) & 7 )
1545 case 4: case 6: /* (pure) introducing virtual method */
1546 ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt.name[0]);
1547 break;
1549 default:
1550 ptr += 2 + 2 + 2 + (1 + type->onemethod.name[0]);
1551 break;
1553 break;
1555 case LF_ONEMETHOD_32:
1556 /* FIXME: ignored for now */
1557 switch ( (type->onemethod32.attribute >> 2) & 7 )
1559 case 4: case 6: /* (pure) introducing virtual method */
1560 ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod32_virt.name[0]);
1561 break;
1563 default:
1564 ptr += 2 + 2 + 4 + (1 + type->onemethod32.name[0]);
1565 break;
1567 break;
1569 default:
1570 DEBUG_Printf( DBG_CHN_MESG, "Unhandled type %04x in STRUCT field list\n",
1571 type->generic.id );
1572 return FALSE;
1576 return DEBUG_AddCVType( typeno, dt );
1579 static int
1580 DEBUG_AddCVType_Enum( unsigned int typeno, char *name, unsigned int fieldlist )
1582 struct datatype *dt = DEBUG_NewDataType( DT_ENUM, name );
1583 struct datatype *list = DEBUG_GetCVType( fieldlist );
1585 if ( list )
1586 if(DEBUG_CopyFieldlist( dt, list ) == FALSE)
1587 return FALSE;
1589 return DEBUG_AddCVType( typeno, dt );
1592 static int
1593 DEBUG_AddCVType_Struct( unsigned int typeno, char *name, int structlen, unsigned int fieldlist )
1595 struct datatype *dt = DEBUG_NewDataType( DT_STRUCT, name );
1596 struct datatype *list = DEBUG_GetCVType( fieldlist );
1598 if ( list )
1600 DEBUG_SetStructSize( dt, structlen );
1601 if(DEBUG_CopyFieldlist( dt, list ) == FALSE)
1602 return FALSE;
1605 return DEBUG_AddCVType( typeno, dt );
1608 static int
1609 DEBUG_ParseTypeTable( char *table, int len )
1611 unsigned int curr_type = 0x1000;
1612 char *ptr = table;
1614 while ( ptr - table < len )
1616 union codeview_type *type = (union codeview_type *) ptr;
1617 int retv = TRUE;
1619 switch ( type->generic.id )
1621 case LF_POINTER:
1622 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer.datatype );
1623 break;
1624 case LF_POINTER_32:
1625 retv = DEBUG_AddCVType_Pointer( curr_type, type->pointer32.datatype );
1626 break;
1628 case LF_ARRAY:
1630 int arrlen, alen = numeric_leaf( &arrlen, &type->array.arrlen );
1631 unsigned char *name = (unsigned char *)&type->array.arrlen + alen;
1633 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1634 type->array.elemtype, arrlen );
1635 break;
1637 case LF_ARRAY_32:
1639 int arrlen, alen = numeric_leaf( &arrlen, &type->array32.arrlen );
1640 unsigned char *name = (unsigned char *)&type->array32.arrlen + alen;
1642 retv = DEBUG_AddCVType_Array( curr_type, terminate_string( name ),
1643 type->array32.elemtype, type->array32.arrlen );
1644 break;
1647 case LF_BITFIELD:
1648 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield.bitoff,
1649 type->bitfield.nbits,
1650 type->bitfield.type );
1651 break;
1652 case LF_BITFIELD_32:
1653 retv = DEBUG_AddCVType_Bitfield( curr_type, type->bitfield32.bitoff,
1654 type->bitfield32.nbits,
1655 type->bitfield32.type );
1656 break;
1658 case LF_FIELDLIST:
1659 case LF_FIELDLIST_32:
1662 * A 'field list' is a CodeView-specific data type which doesn't
1663 * directly correspond to any high-level data type. It is used
1664 * to hold the collection of members of a struct, class, union
1665 * or enum type. The actual definition of that type will follow
1666 * later, and refer to the field list definition record.
1668 * As we don't have a field list type ourselves, we look ahead
1669 * in the field list to try to find out whether this field list
1670 * will be used for an enum or struct type, and create a dummy
1671 * type of the corresponding sort. Later on, the definition of
1672 * the 'real' type will copy the member / enumeration data.
1675 char *list = type->fieldlist.list;
1676 int len = (ptr + type->generic.len + 2) - list;
1678 if ( ((union codeview_fieldtype *)list)->generic.id == LF_ENUMERATE )
1679 retv = DEBUG_AddCVType_EnumFieldList( curr_type, list, len );
1680 else
1681 retv = DEBUG_AddCVType_StructFieldList( curr_type, list, len );
1682 break;
1685 case LF_STRUCTURE:
1686 case LF_CLASS:
1688 int structlen, slen = numeric_leaf( &structlen, &type->structure.structlen );
1689 unsigned char *name = (unsigned char *)&type->structure.structlen + slen;
1691 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1692 structlen, type->structure.fieldlist );
1693 break;
1695 case LF_STRUCTURE_32:
1696 case LF_CLASS_32:
1698 int structlen, slen = numeric_leaf( &structlen, &type->structure32.structlen );
1699 unsigned char *name = (unsigned char *)&type->structure32.structlen + slen;
1701 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1702 structlen, type->structure32.fieldlist );
1703 break;
1706 case LF_UNION:
1708 int un_len, ulen = numeric_leaf( &un_len, &type->t_union.un_len );
1709 unsigned char *name = (unsigned char *)&type->t_union.un_len + ulen;
1711 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1712 un_len, type->t_union.fieldlist );
1713 break;
1715 case LF_UNION_32:
1717 int un_len, ulen = numeric_leaf( &un_len, &type->t_union32.un_len );
1718 unsigned char *name = (unsigned char *)&type->t_union32.un_len + ulen;
1720 retv = DEBUG_AddCVType_Struct( curr_type, terminate_string( name ),
1721 un_len, type->t_union32.fieldlist );
1722 break;
1725 case LF_ENUM:
1726 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration.name ),
1727 type->enumeration.field );
1728 break;
1729 case LF_ENUM_32:
1730 retv = DEBUG_AddCVType_Enum( curr_type, terminate_string( type->enumeration32.name ),
1731 type->enumeration32.field );
1732 break;
1734 default:
1735 break;
1738 if ( !retv )
1739 return FALSE;
1741 curr_type++;
1742 ptr += type->generic.len + 2;
1745 return TRUE;
1749 /*========================================================================
1750 * Process CodeView line number information.
1753 union any_size
1755 char * c;
1756 short * s;
1757 int * i;
1758 unsigned int * ui;
1761 struct startend
1763 unsigned int start;
1764 unsigned int end;
1767 struct codeview_linetab_hdr
1769 unsigned int nline;
1770 unsigned int segno;
1771 unsigned int start;
1772 unsigned int end;
1773 char * sourcefile;
1774 unsigned short * linetab;
1775 unsigned int * offtab;
1778 static struct codeview_linetab_hdr *
1779 DEBUG_SnarfLinetab(char * linetab,
1780 int size)
1782 int file_segcount;
1783 char filename[PATH_MAX];
1784 unsigned int * filetab;
1785 char * fn;
1786 int i;
1787 int k;
1788 struct codeview_linetab_hdr * lt_hdr;
1789 unsigned int * lt_ptr;
1790 int nfile;
1791 int nseg;
1792 union any_size pnt;
1793 union any_size pnt2;
1794 struct startend * start;
1795 int this_seg;
1798 * Now get the important bits.
1800 pnt.c = linetab;
1801 nfile = *pnt.s++;
1802 nseg = *pnt.s++;
1804 filetab = (unsigned int *) pnt.c;
1807 * Now count up the number of segments in the file.
1809 nseg = 0;
1810 for(i=0; i<nfile; i++)
1812 pnt2.c = linetab + filetab[i];
1813 nseg += *pnt2.s;
1817 * Next allocate the header we will be returning.
1818 * There is one header for each segment, so that we can reach in
1819 * and pull bits as required.
1821 lt_hdr = (struct codeview_linetab_hdr *)
1822 DBG_alloc((nseg + 1) * sizeof(*lt_hdr));
1823 if( lt_hdr == NULL )
1825 goto leave;
1828 memset(lt_hdr, 0, sizeof(*lt_hdr) * (nseg+1));
1831 * Now fill the header we will be returning, one for each segment.
1832 * Note that this will basically just contain pointers into the existing
1833 * line table, and we do not actually copy any additional information
1834 * or allocate any additional memory.
1837 this_seg = 0;
1838 for(i=0; i<nfile; i++)
1841 * Get the pointer into the segment information.
1843 pnt2.c = linetab + filetab[i];
1844 file_segcount = *pnt2.s;
1846 pnt2.ui++;
1847 lt_ptr = (unsigned int *) pnt2.c;
1848 start = (struct startend *) (lt_ptr + file_segcount);
1851 * Now snarf the filename for all of the segments for this file.
1853 fn = (unsigned char *) (start + file_segcount);
1854 memset(filename, 0, sizeof(filename));
1855 memcpy(filename, fn + 1, *fn);
1856 fn = DBG_strdup(filename);
1858 for(k = 0; k < file_segcount; k++, this_seg++)
1860 pnt2.c = linetab + lt_ptr[k];
1861 lt_hdr[this_seg].start = start[k].start;
1862 lt_hdr[this_seg].end = start[k].end;
1863 lt_hdr[this_seg].sourcefile = fn;
1864 lt_hdr[this_seg].segno = *pnt2.s++;
1865 lt_hdr[this_seg].nline = *pnt2.s++;
1866 lt_hdr[this_seg].offtab = pnt2.ui;
1867 lt_hdr[this_seg].linetab = (unsigned short *)
1868 (pnt2.ui + lt_hdr[this_seg].nline);
1872 leave:
1874 return lt_hdr;
1879 /*========================================================================
1880 * Process CodeView symbol information.
1883 union codeview_symbol
1885 struct
1887 short int len;
1888 short int id;
1889 } generic;
1891 struct
1893 short int len;
1894 short int id;
1895 unsigned int offset;
1896 unsigned short seg;
1897 unsigned short symtype;
1898 unsigned char namelen;
1899 unsigned char name[1];
1900 } data;
1902 struct
1904 short int len;
1905 short int id;
1906 unsigned int symtype;
1907 unsigned int offset;
1908 unsigned short seg;
1909 unsigned char namelen;
1910 unsigned char name[1];
1911 } data32;
1913 struct
1915 short int len;
1916 short int id;
1917 unsigned int pparent;
1918 unsigned int pend;
1919 unsigned int next;
1920 unsigned int offset;
1921 unsigned short segment;
1922 unsigned short thunk_len;
1923 unsigned char thtype;
1924 unsigned char namelen;
1925 unsigned char name[1];
1926 } thunk;
1928 struct
1930 short int len;
1931 short int id;
1932 unsigned int pparent;
1933 unsigned int pend;
1934 unsigned int next;
1935 unsigned int proc_len;
1936 unsigned int debug_start;
1937 unsigned int debug_end;
1938 unsigned int offset;
1939 unsigned short segment;
1940 unsigned short proctype;
1941 unsigned char flags;
1942 unsigned char namelen;
1943 unsigned char name[1];
1944 } proc;
1946 struct
1948 short int len;
1949 short int id;
1950 unsigned int pparent;
1951 unsigned int pend;
1952 unsigned int next;
1953 unsigned int proc_len;
1954 unsigned int debug_start;
1955 unsigned int debug_end;
1956 unsigned int proctype;
1957 unsigned int offset;
1958 unsigned short segment;
1959 unsigned char flags;
1960 unsigned char namelen;
1961 unsigned char name[1];
1962 } proc32;
1964 struct
1966 short int len; /* Total length of this entry */
1967 short int id; /* Always S_BPREL32 */
1968 unsigned int offset; /* Stack offset relative to BP */
1969 unsigned short symtype;
1970 unsigned char namelen;
1971 unsigned char name[1];
1972 } stack;
1974 struct
1976 short int len; /* Total length of this entry */
1977 short int id; /* Always S_BPREL32 */
1978 unsigned int offset; /* Stack offset relative to BP */
1979 unsigned int symtype;
1980 unsigned char namelen;
1981 unsigned char name[1];
1982 } stack32;
1986 #define S_COMPILE 0x0001
1987 #define S_REGISTER 0x0002
1988 #define S_CONSTANT 0x0003
1989 #define S_UDT 0x0004
1990 #define S_SSEARCH 0x0005
1991 #define S_END 0x0006
1992 #define S_SKIP 0x0007
1993 #define S_CVRESERVE 0x0008
1994 #define S_OBJNAME 0x0009
1995 #define S_ENDARG 0x000a
1996 #define S_COBOLUDT 0x000b
1997 #define S_MANYREG 0x000c
1998 #define S_RETURN 0x000d
1999 #define S_ENTRYTHIS 0x000e
2001 #define S_BPREL 0x0200
2002 #define S_LDATA 0x0201
2003 #define S_GDATA 0x0202
2004 #define S_PUB 0x0203
2005 #define S_LPROC 0x0204
2006 #define S_GPROC 0x0205
2007 #define S_THUNK 0x0206
2008 #define S_BLOCK 0x0207
2009 #define S_WITH 0x0208
2010 #define S_LABEL 0x0209
2011 #define S_CEXMODEL 0x020a
2012 #define S_VFTPATH 0x020b
2013 #define S_REGREL 0x020c
2014 #define S_LTHREAD 0x020d
2015 #define S_GTHREAD 0x020e
2017 #define S_PROCREF 0x0400
2018 #define S_DATAREF 0x0401
2019 #define S_ALIGN 0x0402
2020 #define S_LPROCREF 0x0403
2022 #define S_REGISTER_32 0x1001 /* Variants with new 32-bit type indices */
2023 #define S_CONSTANT_32 0x1002
2024 #define S_UDT_32 0x1003
2025 #define S_COBOLUDT_32 0x1004
2026 #define S_MANYREG_32 0x1005
2028 #define S_BPREL_32 0x1006
2029 #define S_LDATA_32 0x1007
2030 #define S_GDATA_32 0x1008
2031 #define S_PUB_32 0x1009
2032 #define S_LPROC_32 0x100a
2033 #define S_GPROC_32 0x100b
2034 #define S_VFTTABLE_32 0x100c
2035 #define S_REGREL_32 0x100d
2036 #define S_LTHREAD_32 0x100e
2037 #define S_GTHREAD_32 0x100f
2041 static unsigned int
2042 DEBUG_MapCVOffset( DBG_MODULE *module, unsigned int offset )
2044 int nomap = module->msc_info->nomap;
2045 OMAP_DATA *omapp = module->msc_info->omapp;
2046 int i;
2048 if ( !nomap || !omapp )
2049 return offset;
2051 /* FIXME: use binary search */
2052 for ( i = 0; i < nomap-1; i++ )
2053 if ( omapp[i].from <= offset && omapp[i+1].from > offset )
2054 return !omapp[i].to? 0 : omapp[i].to + (offset - omapp[i].from);
2056 return 0;
2059 static struct name_hash *
2060 DEBUG_AddCVSymbol( DBG_MODULE *module, char *name, int namelen,
2061 int type, unsigned int seg, unsigned int offset,
2062 int size, int cookie, int flags,
2063 struct codeview_linetab_hdr *linetab )
2065 int nsect = module->msc_info->nsect;
2066 PIMAGE_SECTION_HEADER sectp = module->msc_info->sectp;
2068 struct name_hash *symbol;
2069 char symname[PATH_MAX];
2070 DBG_VALUE value;
2073 * Some sanity checks
2076 if ( !name || !namelen )
2077 return NULL;
2079 if ( !seg || seg > nsect )
2080 return NULL;
2083 * Convert type, address, and symbol name
2085 value.type = type? DEBUG_GetCVType( type ) : NULL;
2086 value.cookie = cookie;
2088 value.addr.seg = 0;
2089 value.addr.off = (unsigned int) module->load_addr +
2090 DEBUG_MapCVOffset( module, sectp[seg-1].VirtualAddress + offset );
2092 memcpy( symname, name, namelen );
2093 symname[namelen] = '\0';
2097 * Check whether we have line number information
2099 if ( linetab )
2101 for ( ; linetab->linetab; linetab++ )
2102 if ( linetab->segno == seg
2103 && linetab->start <= offset
2104 && linetab->end > offset )
2105 break;
2107 if ( !linetab->linetab )
2108 linetab = NULL;
2113 * Create Wine symbol record
2115 symbol = DEBUG_AddSymbol( symname, &value,
2116 linetab? linetab->sourcefile : NULL, flags );
2118 if ( size )
2119 DEBUG_SetSymbolSize( symbol, size );
2123 * Add line numbers if found
2125 if ( linetab )
2127 unsigned int i;
2128 for ( i = 0; i < linetab->nline; i++ )
2129 if ( linetab->offtab[i] >= offset
2130 && linetab->offtab[i] < offset + size )
2132 DEBUG_AddLineNumber( symbol, linetab->linetab[i],
2133 linetab->offtab[i] - offset );
2137 return symbol;
2140 static struct wine_locals *
2141 DEBUG_AddCVLocal( struct name_hash *func, char *name, int namelen,
2142 int type, int offset )
2144 struct wine_locals *local;
2145 char symname[PATH_MAX];
2147 memcpy( symname, name, namelen );
2148 symname[namelen] = '\0';
2150 local = DEBUG_AddLocal( func, 0, offset, 0, 0, symname );
2151 DEBUG_SetLocalSymbolType( local, DEBUG_GetCVType( type ) );
2153 return local;
2156 static int
2157 DEBUG_SnarfCodeView( DBG_MODULE *module, LPBYTE root, int offset, int size,
2158 struct codeview_linetab_hdr *linetab )
2160 struct name_hash *curr_func = NULL;
2161 int i, length;
2165 * Loop over the different types of records and whenever we
2166 * find something we are interested in, record it and move on.
2168 for ( i = offset; i < size; i += length )
2170 union codeview_symbol *sym = (union codeview_symbol *)(root + i);
2171 length = sym->generic.len + 2;
2173 switch ( sym->generic.id )
2176 * Global and local data symbols. We don't associate these
2177 * with any given source file.
2179 case S_GDATA:
2180 case S_LDATA:
2181 case S_PUB:
2182 DEBUG_AddCVSymbol( module, sym->data.name, sym->data.namelen,
2183 sym->data.symtype, sym->data.seg,
2184 sym->data.offset, 0,
2185 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2186 break;
2187 case S_GDATA_32:
2188 case S_LDATA_32:
2189 case S_PUB_32:
2190 DEBUG_AddCVSymbol( module, sym->data32.name, sym->data32.namelen,
2191 sym->data32.symtype, sym->data32.seg,
2192 sym->data32.offset, 0,
2193 DV_TARGET, SYM_WIN32 | SYM_DATA, NULL );
2194 break;
2197 * Sort of like a global function, but it just points
2198 * to a thunk, which is a stupid name for what amounts to
2199 * a PLT slot in the normal jargon that everyone else uses.
2201 case S_THUNK:
2202 DEBUG_AddCVSymbol( module, sym->thunk.name, sym->thunk.namelen,
2203 0, sym->thunk.segment,
2204 sym->thunk.offset, sym->thunk.thunk_len,
2205 DV_TARGET, SYM_WIN32 | SYM_FUNC, NULL );
2206 break;
2209 * Global and static functions.
2211 case S_GPROC:
2212 case S_LPROC:
2213 DEBUG_Normalize( curr_func );
2215 curr_func = DEBUG_AddCVSymbol( module, sym->proc.name, sym->proc.namelen,
2216 sym->proc.proctype, sym->proc.segment,
2217 sym->proc.offset, sym->proc.proc_len,
2218 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
2220 DEBUG_SetSymbolBPOff( curr_func, sym->proc.debug_start );
2221 break;
2222 case S_GPROC_32:
2223 case S_LPROC_32:
2224 DEBUG_Normalize( curr_func );
2226 curr_func = DEBUG_AddCVSymbol( module, sym->proc32.name, sym->proc32.namelen,
2227 sym->proc32.proctype, sym->proc32.segment,
2228 sym->proc32.offset, sym->proc32.proc_len,
2229 DV_TARGET, SYM_WIN32 | SYM_FUNC, linetab );
2231 DEBUG_SetSymbolBPOff( curr_func, sym->proc32.debug_start );
2232 break;
2236 * Function parameters and stack variables.
2238 case S_BPREL:
2239 DEBUG_AddCVLocal( curr_func, sym->stack.name, sym->stack.namelen,
2240 sym->stack.symtype, sym->stack.offset );
2241 break;
2242 case S_BPREL_32:
2243 DEBUG_AddCVLocal( curr_func, sym->stack32.name, sym->stack32.namelen,
2244 sym->stack32.symtype, sym->stack32.offset );
2245 break;
2249 * These are special, in that they are always followed by an
2250 * additional length-prefixed string which is *not* included
2251 * into the symbol length count. We need to skip it.
2253 case S_PROCREF:
2254 case S_DATAREF:
2255 case S_LPROCREF:
2257 LPBYTE name = (LPBYTE)sym + length;
2258 length += (*name + 1 + 3) & ~3;
2259 break;
2264 DEBUG_Normalize( curr_func );
2266 if ( linetab ) DBG_free(linetab);
2267 return TRUE;
2272 /*========================================================================
2273 * Process PDB file.
2276 #pragma pack(1)
2277 typedef struct _PDB_FILE
2279 DWORD size;
2280 DWORD unknown;
2282 } PDB_FILE, *PPDB_FILE;
2284 typedef struct _PDB_HEADER
2286 CHAR ident[40];
2287 DWORD signature;
2288 DWORD blocksize;
2289 WORD freelist;
2290 WORD total_alloc;
2291 PDB_FILE toc;
2292 WORD toc_block[ 1 ];
2294 } PDB_HEADER, *PPDB_HEADER;
2296 typedef struct _PDB_TOC
2298 DWORD nFiles;
2299 PDB_FILE file[ 1 ];
2301 } PDB_TOC, *PPDB_TOC;
2303 typedef struct _PDB_ROOT
2305 DWORD version;
2306 DWORD TimeDateStamp;
2307 DWORD unknown;
2308 DWORD cbNames;
2309 CHAR names[ 1 ];
2311 } PDB_ROOT, *PPDB_ROOT;
2313 typedef struct _PDB_TYPES_OLD
2315 DWORD version;
2316 WORD first_index;
2317 WORD last_index;
2318 DWORD type_size;
2319 WORD file;
2320 WORD pad;
2322 } PDB_TYPES_OLD, *PPDB_TYPES_OLD;
2324 typedef struct _PDB_TYPES
2326 DWORD version;
2327 DWORD type_offset;
2328 DWORD first_index;
2329 DWORD last_index;
2330 DWORD type_size;
2331 WORD file;
2332 WORD pad;
2333 DWORD hash_size;
2334 DWORD hash_base;
2335 DWORD hash_offset;
2336 DWORD hash_len;
2337 DWORD search_offset;
2338 DWORD search_len;
2339 DWORD unknown_offset;
2340 DWORD unknown_len;
2342 } PDB_TYPES, *PPDB_TYPES;
2344 typedef struct _PDB_SYMBOL_RANGE
2346 WORD segment;
2347 WORD pad1;
2348 DWORD offset;
2349 DWORD size;
2350 DWORD characteristics;
2351 WORD index;
2352 WORD pad2;
2354 } PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
2356 typedef struct _PDB_SYMBOL_RANGE_EX
2358 WORD segment;
2359 WORD pad1;
2360 DWORD offset;
2361 DWORD size;
2362 DWORD characteristics;
2363 WORD index;
2364 WORD pad2;
2365 DWORD timestamp;
2366 DWORD unknown;
2368 } PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
2370 typedef struct _PDB_SYMBOL_FILE
2372 DWORD unknown1;
2373 PDB_SYMBOL_RANGE range;
2374 WORD flag;
2375 WORD file;
2376 DWORD symbol_size;
2377 DWORD lineno_size;
2378 DWORD unknown2;
2379 DWORD nSrcFiles;
2380 DWORD attribute;
2381 CHAR filename[ 1 ];
2383 } PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
2385 typedef struct _PDB_SYMBOL_FILE_EX
2387 DWORD unknown1;
2388 PDB_SYMBOL_RANGE_EX range;
2389 WORD flag;
2390 WORD file;
2391 DWORD symbol_size;
2392 DWORD lineno_size;
2393 DWORD unknown2;
2394 DWORD nSrcFiles;
2395 DWORD attribute;
2396 DWORD reserved[ 2 ];
2397 CHAR filename[ 1 ];
2399 } PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
2401 typedef struct _PDB_SYMBOL_SOURCE
2403 WORD nModules;
2404 WORD nSrcFiles;
2405 WORD table[ 1 ];
2407 } PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
2409 typedef struct _PDB_SYMBOL_IMPORT
2411 DWORD unknown1;
2412 DWORD unknown2;
2413 DWORD TimeDateStamp;
2414 DWORD nRequests;
2415 CHAR filename[ 1 ];
2417 } PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
2419 typedef struct _PDB_SYMBOLS_OLD
2421 WORD hash1_file;
2422 WORD hash2_file;
2423 WORD gsym_file;
2424 WORD pad;
2425 DWORD module_size;
2426 DWORD offset_size;
2427 DWORD hash_size;
2428 DWORD srcmodule_size;
2430 } PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
2432 typedef struct _PDB_SYMBOLS
2434 DWORD signature;
2435 DWORD version;
2436 DWORD unknown;
2437 DWORD hash1_file;
2438 DWORD hash2_file;
2439 DWORD gsym_file;
2440 DWORD module_size;
2441 DWORD offset_size;
2442 DWORD hash_size;
2443 DWORD srcmodule_size;
2444 DWORD pdbimport_size;
2445 DWORD resvd[ 5 ];
2447 } PDB_SYMBOLS, *PPDB_SYMBOLS;
2448 #pragma pack()
2451 static void *pdb_read( LPBYTE image, WORD *block_list, int size )
2453 PPDB_HEADER pdb = (PPDB_HEADER)image;
2454 int i, nBlocks;
2455 LPBYTE buffer;
2457 if ( !size ) return NULL;
2459 nBlocks = (size + pdb->blocksize-1) / pdb->blocksize;
2460 buffer = DBG_alloc( nBlocks * pdb->blocksize );
2462 for ( i = 0; i < nBlocks; i++ )
2463 memcpy( buffer + i*pdb->blocksize,
2464 image + block_list[i]*pdb->blocksize, pdb->blocksize );
2466 return buffer;
2469 static void *pdb_read_file( LPBYTE image, PPDB_TOC toc, DWORD fileNr )
2471 PPDB_HEADER pdb = (PPDB_HEADER)image;
2472 WORD *block_list;
2473 DWORD i;
2475 if ( !toc || fileNr >= toc->nFiles )
2476 return NULL;
2478 block_list = (WORD *) &toc->file[ toc->nFiles ];
2479 for ( i = 0; i < fileNr; i++ )
2480 block_list += (toc->file[i].size + pdb->blocksize-1) / pdb->blocksize;
2482 return pdb_read( image, block_list, toc->file[fileNr].size );
2485 static void pdb_free( void *buffer )
2487 DBG_free( buffer );
2490 static void pdb_convert_types_header( PDB_TYPES *types, char *image )
2492 memset( types, 0, sizeof(PDB_TYPES) );
2493 if ( !image ) return;
2495 if ( *(DWORD *)image < 19960000 ) /* FIXME: correct version? */
2497 /* Old version of the types record header */
2498 PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
2499 types->version = old->version;
2500 types->type_offset = sizeof(PDB_TYPES_OLD);
2501 types->type_size = old->type_size;
2502 types->first_index = old->first_index;
2503 types->last_index = old->last_index;
2504 types->file = old->file;
2506 else
2508 /* New version of the types record header */
2509 *types = *(PDB_TYPES *)image;
2513 static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
2514 int *header_size, char *image )
2516 memset( symbols, 0, sizeof(PDB_SYMBOLS) );
2517 if ( !image ) return;
2519 if ( *(DWORD *)image != 0xffffffff )
2521 /* Old version of the symbols record header */
2522 PDB_SYMBOLS_OLD *old = (PDB_SYMBOLS_OLD *)image;
2523 symbols->version = 0;
2524 symbols->module_size = old->module_size;
2525 symbols->offset_size = old->offset_size;
2526 symbols->hash_size = old->hash_size;
2527 symbols->srcmodule_size = old->srcmodule_size;
2528 symbols->pdbimport_size = 0;
2529 symbols->hash1_file = old->hash1_file;
2530 symbols->hash2_file = old->hash2_file;
2531 symbols->gsym_file = old->gsym_file;
2533 *header_size = sizeof(PDB_SYMBOLS_OLD);
2535 else
2537 /* New version of the symbols record header */
2538 *symbols = *(PDB_SYMBOLS *)image;
2540 *header_size = sizeof(PDB_SYMBOLS);
2544 static enum DbgInfoLoad DEBUG_ProcessPDBFile( DBG_MODULE *module,
2545 const char *filename, DWORD timestamp )
2547 enum DbgInfoLoad dil = DIL_ERROR;
2548 HANDLE hFile, hMap;
2549 char *image = NULL;
2550 PDB_HEADER *pdb = NULL;
2551 PDB_TOC *toc = NULL;
2552 PDB_ROOT *root = NULL;
2553 char *types_image = NULL;
2554 char *symbols_image = NULL;
2555 PDB_TYPES types;
2556 PDB_SYMBOLS symbols;
2557 int header_size = 0;
2558 char *modimage, *file;
2560 DEBUG_Printf( DBG_CHN_TRACE, "Processing PDB file %s\n", filename );
2563 * Open and map() .PDB file
2565 image = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2566 if ( !image )
2568 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .PDB file %s\n", filename );
2569 goto leave;
2573 * Read in TOC and well-known files
2576 pdb = (PPDB_HEADER)image;
2577 toc = pdb_read( image, pdb->toc_block, pdb->toc.size );
2578 root = pdb_read_file( image, toc, 1 );
2579 types_image = pdb_read_file( image, toc, 2 );
2580 symbols_image = pdb_read_file( image, toc, 3 );
2582 pdb_convert_types_header( &types, types_image );
2583 pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2586 * Check for unknown versions
2589 switch ( root->version )
2591 case 19950623: /* VC 4.0 */
2592 case 19950814:
2593 case 19960307: /* VC 5.0 */
2594 case 19970604: /* VC 6.0 */
2595 break;
2596 default:
2597 DEBUG_Printf( DBG_CHN_ERR, "-Unknown root block version %ld\n", root->version );
2600 switch ( types.version )
2602 case 19950410: /* VC 4.0 */
2603 case 19951122:
2604 case 19961031: /* VC 5.0 / 6.0 */
2605 break;
2606 default:
2607 DEBUG_Printf( DBG_CHN_ERR, "-Unknown type info version %ld\n", types.version );
2610 switch ( symbols.version )
2612 case 0: /* VC 4.0 */
2613 case 19960307: /* VC 5.0 */
2614 case 19970606: /* VC 6.0 */
2615 break;
2616 default:
2617 DEBUG_Printf( DBG_CHN_ERR, "-Unknown symbol info version %ld\n", symbols.version );
2622 * Check .PDB time stamp
2625 if ( root->TimeDateStamp != timestamp )
2627 DEBUG_Printf( DBG_CHN_ERR, "-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2628 filename, root->TimeDateStamp, timestamp );
2632 * Read type table
2635 DEBUG_ParseTypeTable( types_image + types.type_offset, types.type_size );
2638 * Read type-server .PDB imports
2641 if ( symbols.pdbimport_size )
2643 /* FIXME */
2644 DEBUG_Printf(DBG_CHN_ERR, "-Type server .PDB imports ignored!\n" );
2648 * Read global symbol table
2651 modimage = pdb_read_file( image, toc, symbols.gsym_file );
2652 if ( modimage )
2654 DEBUG_SnarfCodeView( module, modimage, 0,
2655 toc->file[symbols.gsym_file].size, NULL );
2656 pdb_free( modimage );
2660 * Read per-module symbol / linenumber tables
2663 file = symbols_image + header_size;
2664 while ( file - symbols_image < header_size + symbols.module_size )
2666 int file_nr, file_index, symbol_size, lineno_size;
2667 char *file_name;
2669 if ( symbols.version < 19970000 )
2671 PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
2672 file_nr = sym_file->file;
2673 file_name = sym_file->filename;
2674 file_index = sym_file->range.index;
2675 symbol_size = sym_file->symbol_size;
2676 lineno_size = sym_file->lineno_size;
2678 else
2680 PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
2681 file_nr = sym_file->file;
2682 file_name = sym_file->filename;
2683 file_index = sym_file->range.index;
2684 symbol_size = sym_file->symbol_size;
2685 lineno_size = sym_file->lineno_size;
2688 modimage = pdb_read_file( image, toc, file_nr );
2689 if ( modimage )
2691 struct codeview_linetab_hdr *linetab = NULL;
2693 if ( lineno_size )
2694 linetab = DEBUG_SnarfLinetab( modimage + symbol_size, lineno_size );
2696 if ( symbol_size )
2697 DEBUG_SnarfCodeView( module, modimage, sizeof(DWORD),
2698 symbol_size, linetab );
2700 pdb_free( modimage );
2703 file_name += strlen(file_name) + 1;
2704 file = (char *)( (DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3 );
2707 dil = DIL_LOADED;
2709 leave:
2712 * Cleanup
2715 DEBUG_ClearTypeTable();
2717 if ( symbols_image ) pdb_free( symbols_image );
2718 if ( types_image ) pdb_free( types_image );
2719 if ( root ) pdb_free( root );
2720 if ( toc ) pdb_free( toc );
2722 DEBUG_UnmapDebugInfoFile(hFile, hMap, image);
2724 return dil;
2730 /*========================================================================
2731 * Process CodeView debug information.
2734 #define CODEVIEW_NB09_SIG ( 'N' | ('B' << 8) | ('0' << 16) | ('9' << 24) )
2735 #define CODEVIEW_NB10_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('0' << 24) )
2736 #define CODEVIEW_NB11_SIG ( 'N' | ('B' << 8) | ('1' << 16) | ('1' << 24) )
2738 typedef struct _CODEVIEW_HEADER
2740 DWORD dwSignature;
2741 DWORD lfoDirectory;
2743 } CODEVIEW_HEADER, *PCODEVIEW_HEADER;
2745 typedef struct _CODEVIEW_PDB_DATA
2747 DWORD timestamp;
2748 DWORD unknown;
2749 CHAR name[ 1 ];
2751 } CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA;
2753 typedef struct _CV_DIRECTORY_HEADER
2755 WORD cbDirHeader;
2756 WORD cbDirEntry;
2757 DWORD cDir;
2758 DWORD lfoNextDir;
2759 DWORD flags;
2761 } CV_DIRECTORY_HEADER, *PCV_DIRECTORY_HEADER;
2763 typedef struct _CV_DIRECTORY_ENTRY
2765 WORD subsection;
2766 WORD iMod;
2767 DWORD lfo;
2768 DWORD cb;
2770 } CV_DIRECTORY_ENTRY, *PCV_DIRECTORY_ENTRY;
2773 #define sstAlignSym 0x125
2774 #define sstSrcModule 0x127
2777 static enum DbgInfoLoad DEBUG_ProcessCodeView( DBG_MODULE *module, LPBYTE root )
2779 PCODEVIEW_HEADER cv = (PCODEVIEW_HEADER)root;
2780 enum DbgInfoLoad dil = DIL_ERROR;
2782 switch ( cv->dwSignature )
2784 case CODEVIEW_NB09_SIG:
2785 case CODEVIEW_NB11_SIG:
2787 PCV_DIRECTORY_HEADER hdr = (PCV_DIRECTORY_HEADER)(root + cv->lfoDirectory);
2788 PCV_DIRECTORY_ENTRY ent, prev, next;
2789 unsigned int i;
2791 ent = (PCV_DIRECTORY_ENTRY)((LPBYTE)hdr + hdr->cbDirHeader);
2792 for ( i = 0; i < hdr->cDir; i++, ent = next )
2794 next = (i == hdr->cDir-1)? NULL :
2795 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent + hdr->cbDirEntry);
2796 prev = (i == 0)? NULL :
2797 (PCV_DIRECTORY_ENTRY)((LPBYTE)ent - hdr->cbDirEntry);
2799 if ( ent->subsection == sstAlignSym )
2802 * Check the next and previous entry. If either is a
2803 * sstSrcModule, it contains the line number info for
2804 * this file.
2806 * FIXME: This is not a general solution!
2808 struct codeview_linetab_hdr *linetab = NULL;
2810 if ( next && next->iMod == ent->iMod
2811 && next->subsection == sstSrcModule )
2812 linetab = DEBUG_SnarfLinetab( root + next->lfo, next->cb );
2814 if ( prev && prev->iMod == ent->iMod
2815 && prev->subsection == sstSrcModule )
2816 linetab = DEBUG_SnarfLinetab( root + prev->lfo, prev->cb );
2819 DEBUG_SnarfCodeView( module, root + ent->lfo, sizeof(DWORD),
2820 ent->cb, linetab );
2824 dil = DIL_LOADED;
2825 break;
2828 case CODEVIEW_NB10_SIG:
2830 PCODEVIEW_PDB_DATA pdb = (PCODEVIEW_PDB_DATA)(cv + 1);
2832 dil = DEBUG_ProcessPDBFile( module, pdb->name, pdb->timestamp );
2833 break;
2836 default:
2837 DEBUG_Printf( DBG_CHN_ERR, "Unknown CODEVIEW signature %08lX in module %s\n",
2838 cv->dwSignature, module->module_name );
2839 break;
2842 return dil;
2846 /*========================================================================
2847 * Process debug directory.
2849 static enum DbgInfoLoad DEBUG_ProcessDebugDirectory( DBG_MODULE *module,
2850 LPBYTE file_map,
2851 PIMAGE_DEBUG_DIRECTORY dbg,
2852 int nDbg )
2854 enum DbgInfoLoad dil = DIL_ERROR;
2855 int i;
2857 /* First, watch out for OMAP data */
2858 for ( i = 0; i < nDbg; i++ )
2859 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC )
2861 module->msc_info->nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
2862 module->msc_info->omapp = (OMAP_DATA *)(file_map + dbg[i].PointerToRawData);
2863 break;
2867 /* Now, try to parse CodeView debug info */
2868 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
2869 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW )
2870 dil = DEBUG_ProcessCodeView( module, file_map + dbg[i].PointerToRawData );
2873 /* If not found, try to parse COFF debug info */
2874 for ( i = 0; dil != DIL_LOADED && i < nDbg; i++ )
2875 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_COFF )
2876 dil = DEBUG_ProcessCoff( module, file_map + dbg[i].PointerToRawData );
2878 #if 0
2879 /* FIXME: this should be supported... this is the debug information for
2880 * functions compiled without a frame pointer (FPO = frame pointer omission)
2881 * the associated data helps finding out the relevant information
2883 for ( i = 0; i < nDbg; i++ )
2884 if ( dbg[i].Type == IMAGE_DEBUG_TYPE_FPO )
2885 DEBUG_Printf(DBG_CHN_MESG, "This guy has FPO information\n");
2887 #define FRAME_FPO 0
2888 #define FRAME_TRAP 1
2889 #define FRAME_TSS 2
2891 typedef struct _FPO_DATA {
2892 DWORD ulOffStart; /* offset 1st byte of function code */
2893 DWORD cbProcSize; /* # bytes in function */
2894 DWORD cdwLocals; /* # bytes in locals/4 */
2895 WORD cdwParams; /* # bytes in params/4 */
2897 WORD cbProlog : 8; /* # bytes in prolog */
2898 WORD cbRegs : 3; /* # regs saved */
2899 WORD fHasSEH : 1; /* TRUE if SEH in func */
2900 WORD fUseBP : 1; /* TRUE if EBP has been allocated */
2901 WORD reserved : 1; /* reserved for future use */
2902 WORD cbFrame : 2; /* frame type */
2903 } FPO_DATA;
2904 #endif
2906 return dil;
2910 /*========================================================================
2911 * Process DBG file.
2913 static enum DbgInfoLoad DEBUG_ProcessDBGFile( DBG_MODULE *module,
2914 const char *filename, DWORD timestamp )
2916 enum DbgInfoLoad dil = DIL_ERROR;
2917 HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
2918 LPBYTE file_map = NULL;
2919 PIMAGE_SEPARATE_DEBUG_HEADER hdr;
2920 PIMAGE_DEBUG_DIRECTORY dbg;
2921 int nDbg;
2924 DEBUG_Printf( DBG_CHN_TRACE, "Processing DBG file %s\n", filename );
2926 file_map = DEBUG_MapDebugInfoFile( filename, 0, 0, &hFile, &hMap );
2927 if ( !file_map )
2929 DEBUG_Printf( DBG_CHN_ERR, "-Unable to peruse .DBG file %s\n", filename );
2930 goto leave;
2933 hdr = (PIMAGE_SEPARATE_DEBUG_HEADER) file_map;
2935 if ( hdr->TimeDateStamp != timestamp )
2937 DEBUG_Printf( DBG_CHN_ERR, "Warning - %s has incorrect internal timestamp\n",
2938 filename );
2940 * Well, sometimes this happens to DBG files which ARE REALLY the right .DBG
2941 * files but nonetheless this check fails. Anyway, WINDBG (debugger for
2942 * Windows by Microsoft) loads debug symbols which have incorrect timestamps.
2947 dbg = (PIMAGE_DEBUG_DIRECTORY) ( file_map + sizeof(*hdr)
2948 + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
2949 + hdr->ExportedNamesSize );
2951 nDbg = hdr->DebugDirectorySize / sizeof(*dbg);
2953 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
2956 leave:
2957 DEBUG_UnmapDebugInfoFile( hFile, hMap, file_map );
2958 return dil;
2962 /*========================================================================
2963 * Process MSC debug information in PE file.
2965 enum DbgInfoLoad DEBUG_RegisterMSCDebugInfo( DBG_MODULE *module, HANDLE hFile,
2966 void *_nth, unsigned long nth_ofs )
2968 enum DbgInfoLoad dil = DIL_ERROR;
2969 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
2970 PIMAGE_DATA_DIRECTORY dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
2971 PIMAGE_DEBUG_DIRECTORY dbg = NULL;
2972 int nDbg;
2973 MSC_DBG_INFO extra_info = { 0, NULL, 0, NULL };
2974 HANDLE hMap = 0;
2975 LPBYTE file_map = NULL;
2978 /* Read in section data */
2980 module->msc_info = &extra_info;
2981 extra_info.nsect = nth->FileHeader.NumberOfSections;
2982 extra_info.sectp = DBG_alloc( extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) );
2983 if ( !extra_info.sectp )
2984 goto leave;
2986 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr +
2987 nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
2988 nth->FileHeader.SizeOfOptionalHeader,
2989 extra_info.sectp,
2990 extra_info.nsect * sizeof(IMAGE_SECTION_HEADER) ) )
2991 goto leave;
2993 /* Read in debug directory */
2995 nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
2996 if ( !nDbg )
2997 goto leave;
2999 dbg = (PIMAGE_DEBUG_DIRECTORY) DBG_alloc( nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) );
3000 if ( !dbg )
3001 goto leave;
3003 if ( !DEBUG_READ_MEM_VERBOSE( (char *)module->load_addr + dir->VirtualAddress,
3004 dbg, nDbg * sizeof(IMAGE_DEBUG_DIRECTORY) ) )
3005 goto leave;
3008 /* Map in PE file */
3009 file_map = DEBUG_MapDebugInfoFile( NULL, 0, 0, &hFile, &hMap );
3010 if ( !file_map )
3011 goto leave;
3014 /* Parse debug directory */
3016 if ( nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED )
3018 /* Debug info is stripped to .DBG file */
3020 PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)(file_map + dbg->PointerToRawData);
3022 if ( nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC
3023 || misc->DataType != IMAGE_DEBUG_MISC_EXENAME )
3025 DEBUG_Printf( DBG_CHN_ERR, "-Debug info stripped, but no .DBG file in module %s\n",
3026 module->module_name );
3027 goto leave;
3030 dil = DEBUG_ProcessDBGFile( module, misc->Data, nth->FileHeader.TimeDateStamp );
3032 else
3034 /* Debug info is embedded into PE module */
3036 dil = DEBUG_ProcessDebugDirectory( module, file_map, dbg, nDbg );
3040 leave:
3041 module->msc_info = NULL;
3043 DEBUG_UnmapDebugInfoFile( 0, hMap, file_map );
3044 if ( extra_info.sectp ) DBG_free( extra_info.sectp );
3045 if ( dbg ) DBG_free( dbg );
3046 return dil;
3050 /*========================================================================
3051 * look for stabs information in PE header (it's how mingw compiler provides its
3052 * debugging information), and also wine PE <-> ELF linking through .wsolnk sections
3054 enum DbgInfoLoad DEBUG_RegisterStabsDebugInfo(DBG_MODULE* module, HANDLE hFile,
3055 void* _nth, unsigned long nth_ofs)
3057 IMAGE_SECTION_HEADER pe_seg;
3058 unsigned long pe_seg_ofs;
3059 int i, stabsize = 0, stabstrsize = 0;
3060 unsigned int stabs = 0, stabstr = 0;
3061 PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)_nth;
3062 enum DbgInfoLoad dil = DIL_ERROR;
3064 pe_seg_ofs = nth_ofs + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) +
3065 nth->FileHeader.SizeOfOptionalHeader;
3067 for (i = 0; i < nth->FileHeader.NumberOfSections; i++, pe_seg_ofs += sizeof(pe_seg)) {
3068 if (!DEBUG_READ_MEM_VERBOSE((void*)((char *)module->load_addr + pe_seg_ofs),
3069 &pe_seg, sizeof(pe_seg)))
3070 continue;
3072 if (!strcasecmp(pe_seg.Name, ".stab")) {
3073 stabs = pe_seg.VirtualAddress;
3074 stabsize = pe_seg.SizeOfRawData;
3075 } else if (!strncasecmp(pe_seg.Name, ".stabstr", 8)) {
3076 stabstr = pe_seg.VirtualAddress;
3077 stabstrsize = pe_seg.SizeOfRawData;
3081 if (stabstrsize && stabsize) {
3082 char* s1 = DBG_alloc(stabsize+stabstrsize);
3084 if (s1) {
3085 if (DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabs, s1, stabsize) &&
3086 DEBUG_READ_MEM_VERBOSE((char*)module->load_addr + stabstr,
3087 s1 + stabsize, stabstrsize)) {
3088 dil = DEBUG_ParseStabs(s1, 0, 0, stabsize, stabsize, stabstrsize);
3089 } else {
3090 DEBUG_Printf(DBG_CHN_MESG, "couldn't read data block\n");
3092 DBG_free(s1);
3093 } else {
3094 DEBUG_Printf(DBG_CHN_MESG, "couldn't alloc %d bytes\n",
3095 stabsize + stabstrsize);
3097 } else {
3098 dil = DIL_NOINFO;
3100 return dil;