First shot at implementing dbghelp.
[wine] / dlls / dbghelp / msc.c
1 /*
2  * File msc.c - read VC++ debug information from COFF and eventually
3  * from PDB files.
4  *
5  * Copyright (C) 1996,      Eric Youngdale.
6  * Copyright (C) 1999-2000, Ulrich Weigand.
7  * Copyright (C) 2004,      Eric Pouech.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 /*
25  * Note - this handles reading debug information for 32 bit applications
26  * that run under Windows-NT for example.  I doubt that this would work well
27  * for 16 bit applications, but I don't think it really matters since the
28  * file format is different, and we should never get in here in such cases.
29  *
30  * TODO:
31  *      Get 16 bit CV stuff working.
32  *      Add symbol size to internal symbol table.
33  */
34
35 #include "config.h"
36 #include "wine/port.h"
37
38 #include <assert.h>
39 #include <stdlib.h>
40
41 #include <string.h>
42 #ifdef HAVE_UNISTD_H
43 # include <unistd.h>
44 #endif
45 #ifndef PATH_MAX
46 #define PATH_MAX MAX_PATH
47 #endif
48 #include <stdarg.h>
49 #include "windef.h"
50 #include "winbase.h"
51 #include "winreg.h"
52 #include "winternl.h"
53
54 #include "wine/exception.h"
55 #include "wine/debug.h"
56 #include "excpt.h"
57 #include "dbghelp_private.h"
58
59 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
60
61 #define MAX_PATHNAME_LEN 1024
62
63 typedef struct
64 {
65     DWORD  from;
66     DWORD  to;
67 } OMAP_DATA;
68
69 struct msc_debug_info
70 {
71     struct module*              module;
72     int                         nsect;
73     PIMAGE_SECTION_HEADER       sectp;
74     int                         nomap;
75     OMAP_DATA*                  omapp;
76     const BYTE*                 root;
77 };
78
79 /*========================================================================
80  * Debug file access helper routines
81  */
82
83 static WINE_EXCEPTION_FILTER(page_fault)
84 {
85     if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
86         return EXCEPTION_EXECUTE_HANDLER;
87     return EXCEPTION_CONTINUE_SEARCH;
88 }
89
90 /*========================================================================
91  * Process COFF debug information.
92  */
93
94 struct CoffFile
95 {
96     unsigned int                startaddr;
97     unsigned int                endaddr;
98     struct symt_compiland*      compiland;
99     int                         linetab_offset;
100     int                         linecnt;
101     struct symt**               entries;
102     int                         neps;
103     int                         neps_alloc;
104 };
105
106 struct CoffFileSet
107 {
108     struct CoffFile*    files;
109     int                 nfiles;
110     int                 nfiles_alloc;
111 };
112
113 static const char*      coff_get_name(const IMAGE_SYMBOL* coff_sym, 
114                                       const char* coff_strtab)
115 {
116     static      char    namebuff[9];
117     const char*         nampnt;
118
119     if (coff_sym->N.Name.Short)
120     {
121         memcpy(namebuff, coff_sym->N.ShortName, 8);
122         namebuff[8] = '\0';
123         nampnt = &namebuff[0];
124     }
125     else
126     {
127         nampnt = coff_strtab + coff_sym->N.Name.Long;
128     }
129
130     if (nampnt[0] == '_') nampnt++;
131     return nampnt;
132 }
133
134 static int coff_add_file(struct CoffFileSet* coff_files, struct module* module,
135                          const char* filename)
136 {
137     struct CoffFile* file;
138
139     if (coff_files->nfiles + 1 >= coff_files->nfiles_alloc)
140     {
141         coff_files->nfiles_alloc += 10;
142         coff_files->files = (coff_files->files) ?
143             HeapReAlloc(GetProcessHeap(), 0, coff_files->files,
144                         coff_files->nfiles_alloc * sizeof(struct CoffFile)) :
145             HeapAlloc(GetProcessHeap(), 0,
146                       coff_files->nfiles_alloc * sizeof(struct CoffFile));
147     }
148     file = coff_files->files + coff_files->nfiles;
149     file->startaddr = 0xffffffff;
150     file->endaddr   = 0;
151     file->compiland = symt_new_compiland(module, filename);
152     file->linetab_offset = -1;
153     file->linecnt = 0;
154     file->entries = NULL;
155     file->neps = file->neps_alloc = 0;
156
157     return coff_files->nfiles++;
158 }
159
160 static void coff_add_symbol(struct CoffFile* coff_file, struct symt* sym)
161 {
162     if (coff_file->neps + 1 >= coff_file->neps_alloc)
163     {
164         coff_file->neps_alloc += 10;
165         coff_file->entries = (coff_file->entries) ?
166             HeapReAlloc(GetProcessHeap(), 0, coff_file->entries,
167                         coff_file->neps_alloc * sizeof(struct symt*)) :
168             HeapAlloc(GetProcessHeap(), 0, 
169                       coff_file->neps_alloc * sizeof(struct symt*));
170     }
171     coff_file->entries[coff_file->neps++] = sym;
172 }
173
174 static SYM_TYPE coff_process_info(const struct msc_debug_info* msc_dbg)
175 {
176     const IMAGE_AUX_SYMBOL*             aux;
177     const IMAGE_COFF_SYMBOLS_HEADER*    coff;
178     const IMAGE_LINENUMBER*             coff_linetab;
179     const IMAGE_LINENUMBER*             linepnt;
180     const char*                         coff_strtab;
181     const IMAGE_SYMBOL*                 coff_sym;
182     const IMAGE_SYMBOL*                 coff_symbols;
183     struct CoffFileSet                  coff_files;
184     int                                 curr_file_idx = -1;
185     unsigned int                        i;
186     int                                 j;
187     int                                 k;
188     int                                 l;
189     int                                 linetab_indx;
190     const char*                         nampnt;
191     int                                 naux;
192     SYM_TYPE                            sym_type = SymNone;
193     DWORD                               addr;
194
195     TRACE("Processing COFF symbols...\n");
196
197     assert(sizeof(IMAGE_SYMBOL) == IMAGE_SIZEOF_SYMBOL);
198     assert(sizeof(IMAGE_LINENUMBER) == IMAGE_SIZEOF_LINENUMBER);
199
200     coff_files.files = NULL;
201     coff_files.nfiles = coff_files.nfiles_alloc = 0;
202
203     coff = (const IMAGE_COFF_SYMBOLS_HEADER*)msc_dbg->root;
204
205     coff_symbols = (const IMAGE_SYMBOL*)((unsigned int)coff + 
206                                          coff->LvaToFirstSymbol);
207     coff_linetab = (const IMAGE_LINENUMBER*)((unsigned int)coff + 
208                                              coff->LvaToFirstLinenumber);
209     coff_strtab = (const char*)(coff_symbols + coff->NumberOfSymbols);
210
211     linetab_indx = 0;
212
213     for (i = 0; i < coff->NumberOfSymbols; i++)
214     {
215         coff_sym = coff_symbols + i;
216         naux = coff_sym->NumberOfAuxSymbols;
217
218         if (coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE)
219         {
220             curr_file_idx = coff_add_file(&coff_files, msc_dbg->module, 
221                                           (char*)(coff_sym + 1));
222             TRACE("New file %s\n", (char*)(coff_sym + 1));
223             i += naux;
224             continue;
225         }
226
227         if (curr_file_idx < 0)
228         {
229             assert(coff_files.nfiles == 0 && coff_files.nfiles_alloc == 0);
230             curr_file_idx = coff_add_file(&coff_files, msc_dbg->module, "<none>");
231             TRACE("New file <none>\n");
232         }
233
234         /*
235          * This guy marks the size and location of the text section
236          * for the current file.  We need to keep track of this so
237          * we can figure out what file the different global functions
238          * go with.
239          */
240         if (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC &&
241             naux != 0 && coff_sym->Type == 0 && coff_sym->SectionNumber == 1)
242         {
243             aux = (const IMAGE_AUX_SYMBOL*) (coff_sym + 1);
244
245             if (coff_files.files[curr_file_idx].linetab_offset != -1)
246             {
247                 /*
248                  * Save this so we can still get the old name.
249                  */
250                 const char* fn;
251
252                 fn = source_get(msc_dbg->module, 
253                                 coff_files.files[curr_file_idx].compiland->source);
254
255                 TRACE("Duplicating sect from %s: %lx %x %x %d %d\n",
256                       fn, aux->Section.Length,
257                       aux->Section.NumberOfRelocations,
258                       aux->Section.NumberOfLinenumbers,
259                       aux->Section.Number, aux->Section.Selection);
260                 TRACE("More sect %d %s %08lx %d %d %d\n",
261                       coff_sym->SectionNumber,
262                       coff_get_name(coff_sym, coff_strtab),
263                       coff_sym->Value, coff_sym->Type,
264                       coff_sym->StorageClass, coff_sym->NumberOfAuxSymbols);
265
266                 /*
267                  * Duplicate the file entry.  We have no way to describe
268                  * multiple text sections in our current way of handling things.
269                  */
270                 coff_add_file(&coff_files, msc_dbg->module, fn);
271             }
272             else
273             {
274                 TRACE("New text sect from %s: %lx %x %x %d %d\n",
275                       source_get(msc_dbg->module, coff_files.files[curr_file_idx].compiland->source),
276                       aux->Section.Length,
277                       aux->Section.NumberOfRelocations,
278                       aux->Section.NumberOfLinenumbers,
279                       aux->Section.Number, aux->Section.Selection);
280             }
281
282             if (coff_files.files[curr_file_idx].startaddr > coff_sym->Value)
283             {
284                 coff_files.files[curr_file_idx].startaddr = coff_sym->Value;
285             }
286
287             if (coff_files.files[curr_file_idx].endaddr < coff_sym->Value + aux->Section.Length)
288             {
289                 coff_files.files[curr_file_idx].endaddr = coff_sym->Value + aux->Section.Length;
290             }
291
292             coff_files.files[curr_file_idx].linetab_offset = linetab_indx;
293             coff_files.files[curr_file_idx].linecnt = aux->Section.NumberOfLinenumbers;
294             linetab_indx += aux->Section.NumberOfLinenumbers;
295             i += naux;
296             continue;
297         }
298
299         if (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC && naux == 0 && 
300             coff_sym->SectionNumber == 1)
301         {
302             DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
303             /*
304              * This is a normal static function when naux == 0.
305              * Just register it.  The current file is the correct
306              * one in this instance.
307              */
308             nampnt = coff_get_name(coff_sym, coff_strtab);
309
310             TRACE("\tAdding static symbol %s\n", nampnt);
311
312             /* FIXME: was adding symbol to this_file ??? */
313             coff_add_symbol(&coff_files.files[curr_file_idx],
314                             &symt_new_function(msc_dbg->module, 
315                                                coff_files.files[curr_file_idx].compiland, 
316                                                nampnt,
317                                                msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
318                                                0 /* FIXME */,
319                                                NULL /* FIXME */)->symt);
320             i += naux;
321             continue;
322         }
323
324         if (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
325             ISFCN(coff_sym->Type) && coff_sym->SectionNumber > 0)
326         {
327             struct symt_compiland* compiland = NULL;
328             DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
329             nampnt = coff_get_name(coff_sym, coff_strtab);
330
331             TRACE("%d: %lx %s\n",
332                   i, msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
333                   nampnt);
334             TRACE("\tAdding global symbol %s (sect=%s)\n",
335                   nampnt, msc_dbg->sectp[coff_sym->SectionNumber - 1].Name);
336
337             /*
338              * Now we need to figure out which file this guy belongs to.
339              */
340             for (j = 0; j < coff_files.nfiles; j++)
341             {
342                 if (coff_files.files[j].startaddr <= base + coff_sym->Value
343                      && coff_files.files[j].endaddr > base + coff_sym->Value)
344                 {
345                     compiland = coff_files.files[j].compiland;
346                     break;
347                 }
348             }
349             if (j < coff_files.nfiles)
350             {
351                 coff_add_symbol(&coff_files.files[j],
352                                 &symt_new_function(msc_dbg->module, compiland, nampnt, 
353                                                    msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
354                                                    0 /* FIXME */, NULL /* FIXME */)->symt);
355             } 
356             else 
357             {
358                 symt_new_function(msc_dbg->module, NULL, nampnt, 
359                                   msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
360                                   0 /* FIXME */, NULL /* FIXME */);
361             }
362             i += naux;
363             continue;
364         }
365
366         if (coff_sym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
367             coff_sym->SectionNumber > 0)
368         {
369             DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
370             /*
371              * Similar to above, but for the case of data symbols.
372              * These aren't treated as entrypoints.
373              */
374             nampnt = coff_get_name(coff_sym, coff_strtab);
375
376             TRACE("%d: %lx %s\n",
377                   i, msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
378                   nampnt);
379             TRACE("\tAdding global data symbol %s\n", nampnt);
380
381             /*
382              * Now we need to figure out which file this guy belongs to.
383              */
384             symt_new_global_variable(msc_dbg->module, NULL, nampnt, TRUE /* FIXME */,
385                                      msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
386                                      0 /* FIXME */, NULL /* FIXME */);
387             i += naux;
388             continue;
389         }
390
391         if (coff_sym->StorageClass == IMAGE_SYM_CLASS_STATIC && naux == 0)
392         {
393             /*
394              * Ignore these.  They don't have anything to do with
395              * reality.
396              */
397             i += naux;
398             continue;
399         }
400
401         TRACE("Skipping unknown entry '%s' %d %d %d\n",
402               coff_get_name(coff_sym, coff_strtab),
403               coff_sym->StorageClass, coff_sym->SectionNumber, naux);
404         
405         /*
406          * For now, skip past the aux entries.
407          */
408         i += naux;
409     }
410
411     if (coff_files.files != NULL)
412     {
413         /*
414          * OK, we now should have a list of files, and we should have a list
415          * of entrypoints.  We need to sort the entrypoints so that we are
416          * able to tie the line numbers with the given functions within the
417          * file.
418          */
419         for (j = 0; j < coff_files.nfiles; j++)
420         {
421             if (coff_files.files[j].entries != NULL)
422             {
423                 qsort(coff_files.files[j].entries, coff_files.files[j].neps,
424                       sizeof(struct symt*), symt_cmp_addr);
425             }
426         }
427
428         /*
429          * Now pick apart the line number tables, and attach the entries
430          * to the given functions.
431          */
432         for (j = 0; j < coff_files.nfiles; j++)
433         {
434             l = 0;
435             if (coff_files.files[j].neps != 0)
436             {
437                 for (k = 0; k < coff_files.files[j].linecnt; k++)
438                 {
439                     linepnt = coff_linetab + coff_files.files[j].linetab_offset + k;
440                     /*
441                      * If we have spilled onto the next entrypoint, then
442                      * bump the counter..
443                      */
444                     for (;;)
445                     {
446                         if (l+1 >= coff_files.files[j].neps) break;
447                         symt_get_info(coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
448                         if (((msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress) < addr))
449                             break;
450                         l++;
451                     }
452
453                     if (coff_files.files[j].entries[l+1]->tag == SymTagFunction)
454                     {
455                         /*
456                          * Add the line number.  This is always relative to the
457                          * start of the function, so we need to subtract that offset
458                          * first.
459                          */
460                         symt_get_info(coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
461                         symt_add_func_line(msc_dbg->module, (struct symt_function*)coff_files.files[j].entries[l+1], 
462                                            coff_files.files[j].compiland->source, linepnt->Linenumber,
463                                            msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress - addr);
464                     }
465                 }
466             }
467         }
468
469         sym_type = SymCoff;
470
471         for (j = 0; j < coff_files.nfiles; j++)
472         {
473             if (coff_files.files[j].entries != NULL)
474             {
475                 HeapFree(GetProcessHeap(), 0, coff_files.files[j].entries);
476             }
477         }
478         HeapFree(GetProcessHeap(), 0, coff_files.files);
479     }
480
481     return sym_type;
482 }
483
484
485 /*========================================================================
486  * Process CodeView type information.
487  */
488
489 union codeview_type
490 {
491     struct
492     {
493         unsigned short int  len;
494         short int           id;
495     } generic;
496
497     struct
498     {
499         unsigned short int len;
500         short int          id;
501         short int          attribute;
502         short int          datatype;
503         unsigned char      variant[1];
504     } pointer;
505
506     struct
507     {
508         unsigned short int len;
509         short int          id;
510         unsigned int       datatype;
511         unsigned int       attribute;
512         unsigned char      variant[1];
513     } pointer32;
514
515     struct
516     {
517         unsigned short int len;
518         short int          id;
519         unsigned char      nbits;
520         unsigned char      bitoff;
521         unsigned short     type;
522     } bitfield;
523     
524     struct
525     {
526         unsigned short int len;
527         short int          id;
528         unsigned int       type;
529         unsigned char      nbits;
530         unsigned char      bitoff;
531     } bitfield32;
532
533     struct
534     {
535         unsigned short int len;
536         short int          id;
537         short int          elemtype;
538         short int          idxtype;
539         unsigned short int arrlen;     /* numeric leaf */
540 #if 0
541         unsigned char      name[1];
542 #endif
543     } array;
544
545     struct
546     {
547         unsigned short int len;
548         short int          id;
549         unsigned int       elemtype;
550         unsigned int       idxtype;
551         unsigned short int arrlen;    /* numeric leaf */
552 #if 0
553         unsigned char      name[1];
554 #endif
555     } array32;
556
557     struct
558     {
559         unsigned short int len;
560         short int          id;
561         short int          n_element;
562         short int          fieldlist;
563         short int          property;
564         short int          derived;
565         short int          vshape;
566         unsigned short int structlen;  /* numeric leaf */
567 #if 0
568         unsigned char      name[1];
569 #endif
570     } structure;
571
572   struct
573   {
574       unsigned short int len;
575       short int          id;
576       short int          n_element;
577       short int          property;
578       unsigned int       fieldlist;
579       unsigned int       derived;
580       unsigned int       vshape;
581       unsigned short int structlen;  /* numeric leaf */
582 #if 0
583       unsigned char      name[1];
584 #endif
585   } structure32;
586
587   struct
588   {
589       unsigned short int len;
590       short int          id;
591       short int          count;
592       short int          fieldlist;
593       short int          property;
594       unsigned short int un_len;     /* numeric leaf */
595 #if 0
596       unsigned char      name[1];
597 #endif
598   } t_union;
599
600     struct
601     {
602         unsigned short int len;
603         short int          id;
604         short int          count;
605         short int          property;
606         unsigned int       fieldlist;
607         unsigned short int un_len;     /* numeric leaf */
608 #if 0
609         unsigned char      name[1];
610 #endif
611     } t_union32;
612
613     struct
614     {
615         unsigned short int len;
616         short int          id;
617         short int          count;
618         short int          type;
619         short int          field;
620         short int          property;
621         unsigned char      name[1];
622     } enumeration;
623
624     struct
625     {
626         unsigned short int len;
627         short int          id;
628         short int          count;
629         short int          property;
630         unsigned int       type;
631         unsigned int       field;
632         unsigned char      name[1];
633     } enumeration32;
634
635     struct
636     {
637         unsigned short int len;
638         short int          id;
639         unsigned char      list[1];
640     } fieldlist;
641 };
642
643 union codeview_fieldtype
644 {
645     struct
646     {
647         short int               id;
648     } generic;
649
650     struct
651     {
652         short int               id;
653         short int               type;
654         short int               attribute;
655         unsigned short int      offset;     /* numeric leaf */
656     } bclass;
657
658     struct
659     {
660         short int               id;
661         short int               attribute;
662         unsigned int            type;
663         unsigned short int      offset;     /* numeric leaf */
664     } bclass32;
665
666     struct
667     {
668         short int               id;
669         short int               btype;
670         short int               vbtype;
671         short int               attribute;
672         unsigned short int      vbpoff;     /* numeric leaf */
673 #if 0
674         unsigned short int      vboff;      /* numeric leaf */
675 #endif
676     } vbclass;
677
678     struct
679     {
680         short int               id;
681         short int               attribute;
682         unsigned int            btype;
683         unsigned int            vbtype;
684         unsigned short int      vbpoff;     /* numeric leaf */
685 #if 0
686         unsigned short int      vboff;      /* numeric leaf */
687 #endif
688     } vbclass32;
689
690     struct
691     {
692         short int               id;
693         short int               attribute;
694         unsigned short int      value;     /* numeric leaf */
695 #if 0
696         unsigned char           name[1];
697 #endif
698     } enumerate;
699
700     struct
701     {
702         short int               id;
703         short int               type;
704         unsigned char           name[1];
705     } friendfcn;
706
707     struct
708     {
709         short int               id;
710         short int               _pad0;
711         unsigned int            type;
712         unsigned char           name[1];
713     } friendfcn32;
714
715     struct
716     {
717         short int               id;
718         short int               type;
719         short int               attribute;
720         unsigned short int      offset;    /* numeric leaf */
721 #if 0
722         unsigned char           name[1];
723 #endif
724     } member;
725
726     struct
727     {
728         short int               id;
729         short int               attribute;
730         unsigned int            type;
731         unsigned short int      offset;    /* numeric leaf */
732 #if 0
733         unsigned char           name[1];
734 #endif
735     } member32;
736
737     struct
738     {
739         short int               id;
740         short int               type;
741         short int               attribute;
742         unsigned char           name[1];
743     } stmember;
744
745     struct
746     {
747         short int               id;
748         short int               attribute;
749         unsigned int            type;
750         unsigned char           name[1];
751     } stmember32;
752
753     struct
754     {
755         short int               id;
756         short int               count;
757         short int               mlist;
758         unsigned char           name[1];
759     } method;
760
761     struct
762     {
763         short int               id;
764         short int               count;
765         unsigned int            mlist;
766         unsigned char           name[1];
767     } method32;
768
769     struct
770     {
771         short int               id;
772         short int               index;
773         unsigned char           name[1];
774     } nesttype;
775
776     struct
777     {
778         short int               id;
779         short int               _pad0;
780         unsigned int            index;
781         unsigned char           name[1];
782     } nesttype32;
783
784     struct
785     {
786         short int               id;
787         short int               type;
788     } vfunctab;
789
790     struct
791     {
792         short int               id;
793         short int               _pad0;
794         unsigned int            type;
795     } vfunctab32;
796
797     struct
798     {
799         short int               id;
800         short int               type;
801     } friendcls;
802
803     struct
804     {
805         short int               id;
806         short int               _pad0;
807         unsigned int            type;
808     } friendcls32;
809
810     struct
811     {
812         short int               id;
813         short int               attribute;
814         short int               type;
815         unsigned char           name[1];
816     } onemethod;
817
818     struct
819     {
820         short int               id;
821         short int               attribute;
822         short int               type;
823         unsigned int            vtab_offset;
824         unsigned char           name[1];
825     } onemethod_virt;
826
827     struct
828     {
829         short int               id;
830         short int               attribute;
831         unsigned int            type;
832         unsigned char           name[1];
833     } onemethod32;
834
835     struct
836     {
837         short int               id;
838         short int               attribute;
839         unsigned int            type;
840         unsigned int            vtab_offset;
841         unsigned char           name[1];
842     } onemethod32_virt;
843
844     struct
845     {
846         short int               id;
847         short int               type;
848         unsigned int            offset;
849     } vfuncoff;
850
851     struct
852     {
853         short int               id;
854         short int               _pad0;
855         unsigned int            type;
856         unsigned int            offset;
857     } vfuncoff32;
858
859     struct
860     {
861         short int               id;
862         short int               attribute;
863         short int               index;
864         unsigned char           name[1];
865     } nesttypeex;
866
867     struct
868     {
869         short int               id;
870         short int               attribute;
871         unsigned int            index;
872         unsigned char           name[1];
873     } nesttypeex32;
874
875     struct
876     {
877         short int               id;
878         short int               attribute;
879         unsigned int            type;
880         unsigned char           name[1];
881     } membermodify;
882 };
883
884
885 /*
886  * This covers the basic datatypes that VC++ seems to be using these days.
887  * 32 bit mode only.  There are additional numbers for the pointers in 16
888  * bit mode.  There are many other types listed in the documents, but these
889  * are apparently not used by the compiler, or represent pointer types
890  * that are not used.
891  */
892 #define T_NOTYPE        0x0000  /* Notype */
893 #define T_ABS           0x0001  /* Abs */
894 #define T_VOID          0x0003  /* Void */
895 #define T_CHAR          0x0010  /* signed char */
896 #define T_SHORT         0x0011  /* short */
897 #define T_LONG          0x0012  /* long */
898 #define T_QUAD          0x0013  /* long long */
899 #define T_UCHAR         0x0020  /* unsigned  char */
900 #define T_USHORT        0x0021  /* unsigned short */
901 #define T_ULONG         0x0022  /* unsigned long */
902 #define T_UQUAD         0x0023  /* unsigned long long */
903 #define T_REAL32        0x0040  /* float */
904 #define T_REAL64        0x0041  /* double */
905 #define T_RCHAR         0x0070  /* real char */
906 #define T_WCHAR         0x0071  /* wide char */
907 #define T_INT4          0x0074  /* int */
908 #define T_UINT4         0x0075  /* unsigned int */
909
910 #define T_32PVOID       0x0403  /* 32 bit near pointer to void */
911 #define T_32PCHAR       0x0410  /* 16:32 near pointer to signed char */
912 #define T_32PSHORT      0x0411  /* 16:32 near pointer to short */
913 #define T_32PLONG       0x0412  /* 16:32 near pointer to int */
914 #define T_32PQUAD       0x0413  /* 16:32 near pointer to long long */
915 #define T_32PUCHAR      0x0420  /* 16:32 near pointer to unsigned char */
916 #define T_32PUSHORT     0x0421  /* 16:32 near pointer to unsigned short */
917 #define T_32PULONG      0x0422  /* 16:32 near pointer to unsigned int */
918 #define T_32PUQUAD      0x0423  /* 16:32 near pointer to long long */
919 #define T_32PREAL32     0x0440  /* 16:32 near pointer to float */
920 #define T_32PREAL64     0x0441  /* 16:32 near pointer to float */
921 #define T_32PRCHAR      0x0470  /* 16:32 near pointer to real char */
922 #define T_32PWCHAR      0x0471  /* 16:32 near pointer to real char */
923 #define T_32PINT4       0x0474  /* 16:32 near pointer to int */
924 #define T_32PUINT4      0x0475  /* 16:32 near pointer to unsigned int */
925
926
927 #define LF_MODIFIER     0x0001
928 #define LF_POINTER      0x0002
929 #define LF_ARRAY        0x0003
930 #define LF_CLASS        0x0004
931 #define LF_STRUCTURE    0x0005
932 #define LF_UNION        0x0006
933 #define LF_ENUM         0x0007
934 #define LF_PROCEDURE    0x0008
935 #define LF_MFUNCTION    0x0009
936 #define LF_VTSHAPE      0x000a
937 #define LF_COBOL0       0x000b
938 #define LF_COBOL1       0x000c
939 #define LF_BARRAY       0x000d
940 #define LF_LABEL        0x000e
941 #define LF_NULL         0x000f
942 #define LF_NOTTRAN      0x0010
943 #define LF_DIMARRAY     0x0011
944 #define LF_VFTPATH      0x0012
945 #define LF_PRECOMP      0x0013
946 #define LF_ENDPRECOMP   0x0014
947 #define LF_OEM          0x0015
948 #define LF_TYPESERVER   0x0016
949
950 #define LF_MODIFIER_32  0x1001     /* variants with new 32-bit type indices */
951 #define LF_POINTER_32   0x1002
952 #define LF_ARRAY_32     0x1003
953 #define LF_CLASS_32     0x1004
954 #define LF_STRUCTURE_32 0x1005
955 #define LF_UNION_32     0x1006
956 #define LF_ENUM_32      0x1007
957 #define LF_PROCEDURE_32 0x1008
958 #define LF_MFUNCTION_32 0x1009
959 #define LF_COBOL0_32    0x100a
960 #define LF_BARRAY_32    0x100b
961 #define LF_DIMARRAY_32  0x100c
962 #define LF_VFTPATH_32   0x100d
963 #define LF_PRECOMP_32   0x100e
964 #define LF_OEM_32       0x100f
965
966 #define LF_SKIP         0x0200
967 #define LF_ARGLIST      0x0201
968 #define LF_DEFARG       0x0202
969 #define LF_LIST         0x0203
970 #define LF_FIELDLIST    0x0204
971 #define LF_DERIVED      0x0205
972 #define LF_BITFIELD     0x0206
973 #define LF_METHODLIST   0x0207
974 #define LF_DIMCONU      0x0208
975 #define LF_DIMCONLU     0x0209
976 #define LF_DIMVARU      0x020a
977 #define LF_DIMVARLU     0x020b
978 #define LF_REFSYM       0x020c
979
980 #define LF_SKIP_32      0x1200    /* variants with new 32-bit type indices */
981 #define LF_ARGLIST_32   0x1201
982 #define LF_DEFARG_32    0x1202
983 #define LF_FIELDLIST_32 0x1203
984 #define LF_DERIVED_32   0x1204
985 #define LF_BITFIELD_32  0x1205
986 #define LF_METHODLIST_32 0x1206
987 #define LF_DIMCONU_32   0x1207
988 #define LF_DIMCONLU_32  0x1208
989 #define LF_DIMVARU_32   0x1209
990 #define LF_DIMVARLU_32  0x120a
991
992 #define LF_BCLASS       0x0400
993 #define LF_VBCLASS      0x0401
994 #define LF_IVBCLASS     0x0402
995 #define LF_ENUMERATE    0x0403
996 #define LF_FRIENDFCN    0x0404
997 #define LF_INDEX        0x0405
998 #define LF_MEMBER       0x0406
999 #define LF_STMEMBER     0x0407
1000 #define LF_METHOD       0x0408
1001 #define LF_NESTTYPE     0x0409
1002 #define LF_VFUNCTAB     0x040a
1003 #define LF_FRIENDCLS    0x040b
1004 #define LF_ONEMETHOD    0x040c
1005 #define LF_VFUNCOFF     0x040d
1006 #define LF_NESTTYPEEX   0x040e
1007 #define LF_MEMBERMODIFY 0x040f
1008
1009 #define LF_BCLASS_32    0x1400    /* variants with new 32-bit type indices */
1010 #define LF_VBCLASS_32   0x1401
1011 #define LF_IVBCLASS_32  0x1402
1012 #define LF_FRIENDFCN_32 0x1403
1013 #define LF_INDEX_32     0x1404
1014 #define LF_MEMBER_32    0x1405
1015 #define LF_STMEMBER_32  0x1406
1016 #define LF_METHOD_32    0x1407
1017 #define LF_NESTTYPE_32  0x1408
1018 #define LF_VFUNCTAB_32  0x1409
1019 #define LF_FRIENDCLS_32 0x140a
1020 #define LF_ONEMETHOD_32 0x140b
1021 #define LF_VFUNCOFF_32  0x140c
1022 #define LF_NESTTYPEEX_32 0x140d
1023
1024 #define LF_NUMERIC      0x8000    /* numeric leaf types */
1025 #define LF_CHAR         0x8000
1026 #define LF_SHORT        0x8001
1027 #define LF_USHORT       0x8002
1028 #define LF_LONG         0x8003
1029 #define LF_ULONG        0x8004
1030 #define LF_REAL32       0x8005
1031 #define LF_REAL64       0x8006
1032 #define LF_REAL80       0x8007
1033 #define LF_REAL128      0x8008
1034 #define LF_QUADWORD     0x8009
1035 #define LF_UQUADWORD    0x800a
1036 #define LF_REAL48       0x800b
1037 #define LF_COMPLEX32    0x800c
1038 #define LF_COMPLEX64    0x800d
1039 #define LF_COMPLEX80    0x800e
1040 #define LF_COMPLEX128   0x800f
1041 #define LF_VARSTRING    0x8010
1042
1043 #define MAX_BUILTIN_TYPES       0x480
1044 static struct symt*     cv_basic_types[MAX_BUILTIN_TYPES];
1045 static unsigned int     num_cv_defined_types = 0;
1046 static struct symt**    cv_defined_types = NULL;
1047 #define SymTagCVBitField        (SymTagMax + 0x100)
1048 struct codeview_bitfield
1049 {
1050     struct symt symt;
1051     unsigned    subtype;
1052     unsigned    bitposition;
1053     unsigned    bitlength;
1054 };
1055 static struct codeview_bitfield*        cv_bitfields;
1056 static unsigned                         num_cv_bitfields;
1057 static unsigned                         used_cv_bitfields;
1058
1059 static void codeview_init_basic_types(struct module* module)
1060 {
1061     /*
1062      * These are the common builtin types that are used by VC++.
1063      */
1064     cv_basic_types[T_NOTYPE] = NULL;
1065     cv_basic_types[T_ABS]    = NULL;
1066     cv_basic_types[T_VOID]   = &symt_new_basic(module, btVoid,  "void", 0)->symt;
1067     cv_basic_types[T_CHAR]   = &symt_new_basic(module, btChar,  "char", 1)->symt;
1068     cv_basic_types[T_SHORT]  = &symt_new_basic(module, btInt,   "short int", 2)->symt;
1069     cv_basic_types[T_LONG]   = &symt_new_basic(module, btInt,   "long int", 4)->symt;
1070     cv_basic_types[T_QUAD]   = &symt_new_basic(module, btInt,   "long long int", 8)->symt;
1071     cv_basic_types[T_UCHAR]  = &symt_new_basic(module, btUInt,  "unsignd char", 1)->symt;
1072     cv_basic_types[T_USHORT] = &symt_new_basic(module, btUInt,  "unsigned short", 2)->symt;
1073     cv_basic_types[T_ULONG]  = &symt_new_basic(module, btUInt,  "unsigned long", 4)->symt;
1074     cv_basic_types[T_UQUAD]  = &symt_new_basic(module, btUInt,  "unsigned long long", 8)->symt;
1075     cv_basic_types[T_REAL32] = &symt_new_basic(module, btFloat, "float", 4)->symt;
1076     cv_basic_types[T_REAL64] = &symt_new_basic(module, btFloat, "double", 8)->symt;
1077     cv_basic_types[T_RCHAR]  = &symt_new_basic(module, btInt,   "signed char", 1)->symt;
1078     cv_basic_types[T_WCHAR]  = &symt_new_basic(module, btWChar, "wchar_t", 2)->symt;
1079     cv_basic_types[T_INT4]   = &symt_new_basic(module, btInt,   "INT4", 4)->symt;
1080     cv_basic_types[T_UINT4]  = &symt_new_basic(module, btUInt,  "UINT4", 4)->symt;
1081
1082     cv_basic_types[T_32PVOID]   = &symt_new_pointer(module, cv_basic_types[T_VOID])->symt;
1083     cv_basic_types[T_32PCHAR]   = &symt_new_pointer(module, cv_basic_types[T_CHAR])->symt;
1084     cv_basic_types[T_32PSHORT]  = &symt_new_pointer(module, cv_basic_types[T_SHORT])->symt;
1085     cv_basic_types[T_32PLONG]   = &symt_new_pointer(module, cv_basic_types[T_LONG])->symt;
1086     cv_basic_types[T_32PQUAD]   = &symt_new_pointer(module, cv_basic_types[T_QUAD])->symt;
1087     cv_basic_types[T_32PUCHAR]  = &symt_new_pointer(module, cv_basic_types[T_UCHAR])->symt;
1088     cv_basic_types[T_32PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT])->symt;
1089     cv_basic_types[T_32PULONG]  = &symt_new_pointer(module, cv_basic_types[T_ULONG])->symt;
1090     cv_basic_types[T_32PUQUAD]  = &symt_new_pointer(module, cv_basic_types[T_UQUAD])->symt;
1091     cv_basic_types[T_32PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32])->symt;
1092     cv_basic_types[T_32PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64])->symt;
1093     cv_basic_types[T_32PRCHAR]  = &symt_new_pointer(module, cv_basic_types[T_RCHAR])->symt;
1094     cv_basic_types[T_32PWCHAR]  = &symt_new_pointer(module, cv_basic_types[T_WCHAR])->symt;
1095     cv_basic_types[T_32PINT4]   = &symt_new_pointer(module, cv_basic_types[T_INT4])->symt;
1096     cv_basic_types[T_32PUINT4]  = &symt_new_pointer(module, cv_basic_types[T_UINT4])->symt;
1097 }
1098
1099 static int numeric_leaf(int* value, const unsigned short int* leaf)
1100 {
1101     unsigned short int type = *leaf++;
1102     int length = 2;
1103
1104     if (type < LF_NUMERIC)
1105     {
1106         *value = type;
1107     }
1108     else
1109     {
1110         switch (type)
1111         {
1112         case LF_CHAR:
1113             length += 1;
1114             *value = *(char*)leaf;
1115             break;
1116
1117         case LF_SHORT:
1118             length += 2;
1119             *value = *(short*)leaf;
1120             break;
1121
1122         case LF_USHORT:
1123             length += 2;
1124             *value = *(unsigned short*)leaf;
1125             break;
1126
1127         case LF_LONG:
1128             length += 4;
1129             *value = *(int*)leaf;
1130             break;
1131
1132         case LF_ULONG:
1133             length += 4;
1134             *value = *(unsigned int*)leaf;
1135             break;
1136
1137         case LF_QUADWORD:
1138         case LF_UQUADWORD:
1139             length += 8;
1140             *value = 0;    /* FIXME */
1141             break;
1142
1143         case LF_REAL32:
1144             length += 4;
1145             *value = 0;    /* FIXME */
1146             break;
1147
1148         case LF_REAL48:
1149             length += 6;
1150             *value = 0;    /* FIXME */
1151             break;
1152
1153         case LF_REAL64:
1154             length += 8;
1155             *value = 0;    /* FIXME */
1156             break;
1157
1158         case LF_REAL80:
1159             length += 10;
1160             *value = 0;    /* FIXME */
1161             break;
1162
1163         case LF_REAL128:
1164             length += 16;
1165             *value = 0;    /* FIXME */
1166             break;
1167
1168         case LF_COMPLEX32:
1169             length += 4;
1170             *value = 0;    /* FIXME */
1171             break;
1172
1173         case LF_COMPLEX64:
1174             length += 8;
1175             *value = 0;    /* FIXME */
1176             break;
1177
1178         case LF_COMPLEX80:
1179             length += 10;
1180             *value = 0;    /* FIXME */
1181             break;
1182
1183         case LF_COMPLEX128:
1184             length += 16;
1185             *value = 0;    /* FIXME */
1186             break;
1187
1188         case LF_VARSTRING:
1189             length += 2 + *leaf;
1190             *value = 0;    /* FIXME */
1191             break;
1192
1193         default:
1194             FIXME("Unknown numeric leaf type %04x\n", type);
1195             *value = 0;
1196             break;
1197         }
1198     }
1199
1200     return length;
1201 }
1202
1203 static const char* terminate_string(const unsigned char* name)
1204 {
1205     static char symname[256];
1206
1207     int namelen = name[0];
1208     assert(namelen >= 0 && namelen < 256);
1209
1210     memcpy(symname, name + 1, namelen);
1211     symname[namelen] = '\0';
1212
1213     return (!*symname || strcmp(symname, "__unnamed") == 0) ? NULL : symname;
1214 }
1215
1216 static struct symt*  codeview_get_type(unsigned int typeno, BOOL allow_special)
1217 {
1218     struct symt*        symt = NULL;
1219
1220     /*
1221      * Convert Codeview type numbers into something we can grok internally.
1222      * Numbers < 0x1000 are all fixed builtin types.  Numbers from 0x1000 and
1223      * up are all user defined (structs, etc).
1224      */
1225     if (typeno < 0x1000)
1226     {
1227         if (typeno < MAX_BUILTIN_TYPES)
1228             symt = cv_basic_types[typeno];
1229     }
1230     else
1231     {
1232         if (typeno - 0x1000 < num_cv_defined_types)
1233             symt = cv_defined_types[typeno - 0x1000];
1234     }
1235     if (!allow_special && symt && symt->tag == SymTagCVBitField)
1236         FIXME("bitfields are only handled for UDTs\n");
1237     return symt;
1238 }
1239
1240 static int codeview_add_type(unsigned int typeno, struct symt* dt)
1241 {
1242     while (typeno - 0x1000 >= num_cv_defined_types)
1243     {
1244         num_cv_defined_types += 0x100;
1245         if (cv_defined_types)
1246             cv_defined_types = (struct symt**)
1247                 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cv_defined_types,
1248                             num_cv_defined_types * sizeof(struct symt*));
1249         else
1250             cv_defined_types = (struct symt**)
1251                 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1252                           num_cv_defined_types * sizeof(struct symt*));
1253
1254         if (cv_defined_types == NULL) return FALSE;
1255     }
1256
1257     cv_defined_types[typeno - 0x1000] = dt;
1258     return TRUE;
1259 }
1260
1261 static void codeview_clear_type_table(void)
1262 {
1263     if (cv_defined_types) HeapFree(GetProcessHeap(), 0, cv_defined_types);
1264     cv_defined_types = NULL;
1265     num_cv_defined_types = 0;
1266
1267     if (cv_bitfields) HeapFree(GetProcessHeap(), 0, cv_bitfields);
1268     cv_bitfields = NULL;
1269     num_cv_bitfields = used_cv_bitfields = 0;
1270 }
1271
1272 static int codeview_add_type_pointer(struct module* module, unsigned int typeno, 
1273                                      unsigned int datatype)
1274 {
1275     struct symt* symt = &symt_new_pointer(module, codeview_get_type(datatype, FALSE))->symt;
1276     return codeview_add_type(typeno, symt);
1277 }
1278
1279 static int codeview_add_type_array(struct module* module, 
1280                                    unsigned int typeno, const char* name,
1281                                    unsigned int elemtype, unsigned int arr_len)
1282 {
1283     struct symt*        symt;
1284     struct symt*        elem = codeview_get_type(elemtype, FALSE);
1285     DWORD               arr_max = 0;
1286
1287     if (elem)
1288     {
1289         DWORD elem_size;
1290         symt_get_info(elem, TI_GET_LENGTH, &elem_size);
1291         if (elem_size) arr_max = arr_len / elem_size;
1292     }
1293     symt = &symt_new_array(module, 0, arr_max, elem)->symt;
1294     return codeview_add_type(typeno, symt);
1295 }
1296
1297 static int codeview_add_type_bitfield(unsigned int typeno, unsigned int bitoff,
1298                                       unsigned int nbits, unsigned int basetype)
1299 {
1300     if (used_cv_bitfields >= num_cv_bitfields)
1301     {
1302         num_cv_bitfields *= 2;
1303         if (cv_bitfields)
1304             cv_bitfields = HeapReAlloc(GetProcessHeap(), 0, cv_bitfields, 
1305                                        num_cv_bitfields * sizeof(struct codeview_bitfield));
1306         else
1307             cv_bitfields = HeapAlloc(GetProcessHeap(), 0, 
1308                                      num_cv_bitfields * sizeof(struct codeview_bitfield));
1309         if (!cv_bitfields) return 0;
1310     }
1311     
1312     cv_bitfields[used_cv_bitfields].symt.tag    = SymTagCVBitField;
1313     cv_bitfields[used_cv_bitfields].subtype     = basetype;
1314     cv_bitfields[used_cv_bitfields].bitposition = bitoff;
1315     cv_bitfields[used_cv_bitfields].bitlength   = nbits;
1316
1317     return codeview_add_type(typeno, &cv_bitfields[used_cv_bitfields++].symt);
1318 }
1319
1320 static int codeview_add_type_enum_field_list(struct module* module, 
1321                                              unsigned int typeno, 
1322                                              const unsigned char* list, int len)
1323 {
1324     struct symt_enum*           symt;
1325     const unsigned char*        ptr = list;
1326
1327     symt = symt_new_enum(module, NULL);
1328     while (ptr - list < len)
1329     {
1330         union codeview_fieldtype* type = (union codeview_fieldtype*)ptr;
1331
1332         if (*ptr >= 0xf0)       /* LF_PAD... */
1333         {
1334             ptr += *ptr & 0x0f;
1335             continue;
1336         }
1337
1338         switch (type->generic.id)
1339         {
1340         case LF_ENUMERATE:
1341         {
1342             int value, vlen = numeric_leaf(&value, &type->enumerate.value);
1343             unsigned char* name = (unsigned char*)&type->enumerate.value + vlen;
1344
1345             symt_add_enum_element(module, symt, terminate_string(name), value);
1346             ptr += 2 + 2 + vlen + (1 + name[0]);
1347             break;
1348         }
1349
1350         default:
1351             FIXME("Unhandled type %04x in ENUM field list\n", type->generic.id);
1352             return FALSE;
1353         }
1354     }
1355
1356     return codeview_add_type(typeno, &symt->symt);
1357 }
1358
1359 static int codeview_add_type_struct_field_list(struct module* module, 
1360                                                unsigned int typeno, 
1361                                                const unsigned char* list, int len)
1362 {
1363     struct symt_udt*            symt;
1364     const unsigned char*        ptr = list;
1365
1366     symt = symt_new_udt(module, NULL, 0, UdtStruct /* don't care */);
1367     while (ptr - list < len)
1368     {
1369         const union codeview_fieldtype* type = (const union codeview_fieldtype*)ptr;
1370
1371         if (*ptr >= 0xf0)       /* LF_PAD... */
1372         {
1373             ptr +=* ptr & 0x0f;
1374             continue;
1375         }
1376
1377         switch (type->generic.id)
1378         {
1379         case LF_BCLASS:
1380         {
1381             int offset, olen = numeric_leaf(&offset, &type->bclass.offset);
1382
1383             /* FIXME: ignored for now */
1384
1385             ptr += 2 + 2 + 2 + olen;
1386             break;
1387         }
1388
1389         case LF_BCLASS_32:
1390         {
1391             int offset, olen = numeric_leaf(&offset, &type->bclass32.offset);
1392
1393             /* FIXME: ignored for now */
1394
1395             ptr += 2 + 2 + 4 + olen;
1396             break;
1397         }
1398
1399         case LF_VBCLASS:
1400         case LF_IVBCLASS:
1401         {
1402             int vbpoff, vbplen = numeric_leaf(&vbpoff, &type->vbclass.vbpoff);
1403             const unsigned short int* p_vboff = (const unsigned short int*)((char*)&type->vbclass.vbpoff + vbpoff);
1404             int vpoff, vplen = numeric_leaf(&vpoff, p_vboff);
1405
1406             /* FIXME: ignored for now */
1407
1408             ptr += 2 + 2 + 2 + 2 + vbplen + vplen;
1409             break;
1410         }
1411
1412         case LF_VBCLASS_32:
1413         case LF_IVBCLASS_32:
1414         {
1415             int vbpoff, vbplen = numeric_leaf(&vbpoff, &type->vbclass32.vbpoff);
1416             const unsigned short int* p_vboff = (const unsigned short int*)((char*)&type->vbclass32.vbpoff + vbpoff);
1417             int vpoff, vplen = numeric_leaf(&vpoff, p_vboff);
1418
1419             /* FIXME: ignored for now */
1420
1421             ptr += 2 + 2 + 4 + 4 + vbplen + vplen;
1422             break;
1423         }
1424
1425         case LF_MEMBER:
1426         {
1427             int offset, olen = numeric_leaf(&offset, &type->member.offset);
1428             const unsigned char* name = (const unsigned char*)&type->member.offset + olen;
1429             struct symt* subtype = codeview_get_type(type->member.type, TRUE);
1430
1431             if (!subtype || subtype->tag != SymTagCVBitField)
1432             {
1433                 DWORD elem_size = 0;
1434                 if (subtype) symt_get_info(subtype, TI_GET_LENGTH, &elem_size);
1435                 symt_add_udt_element(module, symt, terminate_string(name),
1436                                      subtype, offset << 3, elem_size << 3);
1437             }
1438             else
1439             {
1440                 struct codeview_bitfield* cvbf = (struct codeview_bitfield*)subtype;
1441                 symt_add_udt_element(module, symt, terminate_string(name),
1442                                      codeview_get_type(cvbf->subtype, FALSE),
1443                                      cvbf->bitposition, cvbf->bitlength);
1444             }
1445
1446             ptr += 2 + 2 + 2 + olen + (1 + name[0]);
1447             break;
1448         }
1449
1450         case LF_MEMBER_32:
1451         {
1452             int offset, olen = numeric_leaf(&offset, &type->member32.offset);
1453             const unsigned char* name = (const unsigned char*)&type->member32.offset + olen;
1454             struct symt* subtype = codeview_get_type(type->member32.type, TRUE);
1455
1456             if (!subtype || subtype->tag != SymTagCVBitField)
1457             {
1458                 DWORD elem_size = 0;
1459                 if (subtype) symt_get_info(subtype, TI_GET_LENGTH, &elem_size);
1460                 symt_add_udt_element(module, symt, terminate_string(name),
1461                                      subtype, offset << 3, elem_size << 3);
1462             }
1463             else
1464             {
1465                 struct codeview_bitfield* cvbf = (struct codeview_bitfield*)subtype;
1466                 symt_add_udt_element(module, symt, terminate_string(name),
1467                                      codeview_get_type(cvbf->subtype, FALSE),
1468                                      cvbf->bitposition, cvbf->bitlength);
1469             }
1470
1471             ptr += 2 + 2 + 4 + olen + (1 + name[0]);
1472             break;
1473         }
1474
1475         case LF_STMEMBER:
1476             /* FIXME: ignored for now */
1477             ptr += 2 + 2 + 2 + (1 + type->stmember.name[0]);
1478             break;
1479
1480         case LF_STMEMBER_32:
1481             /* FIXME: ignored for now */
1482             ptr += 2 + 4 + 2 + (1 + type->stmember32.name[0]);
1483             break;
1484
1485         case LF_METHOD:
1486             /* FIXME: ignored for now */
1487             ptr += 2 + 2 + 2 + (1 + type->method.name[0]);
1488             break;
1489
1490         case LF_METHOD_32:
1491             /* FIXME: ignored for now */
1492             ptr += 2 + 2 + 4 + (1 + type->method32.name[0]);
1493             break;
1494
1495         case LF_NESTTYPE:
1496             /* FIXME: ignored for now */
1497             ptr += 2 + 2 + (1 + type->nesttype.name[0]);
1498             break;
1499
1500         case LF_NESTTYPE_32:
1501             /* FIXME: ignored for now */
1502             ptr += 2 + 2 + 4 + (1 + type->nesttype32.name[0]);
1503             break;
1504
1505         case LF_VFUNCTAB:
1506             /* FIXME: ignored for now */
1507             ptr += 2 + 2;
1508             break;
1509
1510         case LF_VFUNCTAB_32:
1511             /* FIXME: ignored for now */
1512             ptr += 2 + 2 + 4;
1513             break;
1514
1515         case LF_ONEMETHOD:
1516             /* FIXME: ignored for now */
1517             switch ((type->onemethod.attribute >> 2) & 7)
1518             {
1519             case 4: case 6: /* (pure) introducing virtual method */
1520                 ptr += 2 + 2 + 2 + 4 + (1 + type->onemethod_virt.name[0]);
1521                 break;
1522
1523             default:
1524                 ptr += 2 + 2 + 2 + (1 + type->onemethod.name[0]);
1525                 break;
1526             }
1527             break;
1528
1529         case LF_ONEMETHOD_32:
1530             /* FIXME: ignored for now */
1531             switch ((type->onemethod32.attribute >> 2) & 7)
1532             {
1533             case 4: case 6: /* (pure) introducing virtual method */
1534                 ptr += 2 + 2 + 4 + 4 + (1 + type->onemethod32_virt.name[0]);
1535                 break;
1536
1537             default:
1538                 ptr += 2 + 2 + 4 + (1 + type->onemethod32.name[0]);
1539                 break;
1540             }
1541             break;
1542
1543         default:
1544             FIXME("Unhandled type %04x in STRUCT field list\n", type->generic.id);
1545             return FALSE;
1546         }
1547     }
1548
1549     return codeview_add_type(typeno, &symt->symt);
1550 }
1551
1552 static int codeview_add_type_enum(struct module* module, unsigned int typeno, 
1553                                   const char* name, unsigned int fieldlist)
1554 {
1555     struct symt_enum*   symt = symt_new_enum(module, name);
1556     struct symt*        list = codeview_get_type(fieldlist, FALSE);
1557
1558     /* FIXME: this is rather ugly !!! */
1559     if (list) symt->vchildren = ((struct symt_enum*)list)->vchildren;
1560
1561     return codeview_add_type(typeno, &symt->symt);
1562 }
1563
1564 static int codeview_add_type_struct(struct module* module, unsigned int typeno, 
1565                                     const char* name, int structlen, 
1566                                     unsigned int fieldlist, enum UdtKind kind)
1567 {
1568     struct symt_udt*    symt = symt_new_udt(module, name, structlen, kind);
1569     struct symt*        list = codeview_get_type(fieldlist, FALSE);
1570
1571     /* FIXME: this is rather ugly !!! */
1572     if (list) symt->vchildren = ((struct symt_udt*)list)->vchildren;
1573
1574     return codeview_add_type(typeno, &symt->symt);
1575 }
1576
1577 static int codeview_parse_type_table(struct module* module, const char* table, int len)
1578 {
1579     unsigned int        curr_type = 0x1000;
1580     const char*         ptr = table;
1581
1582     while (ptr - table < len)
1583     {
1584         const union codeview_type* type = (const union codeview_type*)ptr;
1585         int retv = TRUE;
1586
1587         switch (type->generic.id)
1588         {
1589         case LF_POINTER:
1590             retv = codeview_add_type_pointer(module, curr_type, 
1591                                              type->pointer.datatype);
1592             break;
1593         case LF_POINTER_32:
1594             retv = codeview_add_type_pointer(module, curr_type, 
1595                                              type->pointer32.datatype);
1596             break;
1597
1598         case LF_ARRAY:
1599         {
1600             int arrlen, alen = numeric_leaf(&arrlen, &type->array.arrlen);
1601             const unsigned char* name = (const unsigned char*)&type->array.arrlen + alen;
1602
1603             retv = codeview_add_type_array(module, curr_type, terminate_string(name),
1604                                            type->array.elemtype, arrlen);
1605             break;
1606         }
1607         case LF_ARRAY_32:
1608         {
1609             int arrlen, alen = numeric_leaf(&arrlen, &type->array32.arrlen);
1610             const unsigned char* name = (const unsigned char*)&type->array32.arrlen + alen;
1611
1612             retv = codeview_add_type_array(module, curr_type, terminate_string(name),
1613                                            type->array32.elemtype, 
1614                                            type->array32.arrlen);
1615             break;
1616         }
1617
1618         /* a bitfields is a CodeView specific data type which represent a bitfield
1619          * in a structure or a class. For now, we store it in a SymTag-like type
1620          * (so that the rest of the process is seamless), but check at udt inclusion
1621          * type for its presence
1622          */
1623         case LF_BITFIELD:
1624             retv = codeview_add_type_bitfield(curr_type, type->bitfield.bitoff,
1625                                               type->bitfield.nbits,
1626                                               type->bitfield.type);
1627             break;
1628         case LF_BITFIELD_32:
1629             retv = codeview_add_type_bitfield(curr_type, type->bitfield32.bitoff,
1630                                               type->bitfield32.nbits,
1631                                               type->bitfield32.type);
1632             break;
1633
1634         case LF_FIELDLIST:
1635         case LF_FIELDLIST_32:
1636         {
1637             /*
1638              * A 'field list' is a CodeView-specific data type which doesn't
1639              * directly correspond to any high-level data type.  It is used
1640              * to hold the collection of members of a struct, class, union
1641              * or enum type.  The actual definition of that type will follow
1642              * later, and refer to the field list definition record.
1643              *
1644              * As we don't have a field list type ourselves, we look ahead
1645              * in the field list to try to find out whether this field list
1646              * will be used for an enum or struct type, and create a dummy
1647              * type of the corresponding sort.  Later on, the definition of
1648              * the 'real' type will copy the member / enumeration data.
1649              */
1650
1651             const char* list = type->fieldlist.list;
1652             int   len  = (ptr + type->generic.len + 2) - list;
1653
1654             if (((union codeview_fieldtype*)list)->generic.id == LF_ENUMERATE)
1655                 retv = codeview_add_type_enum_field_list(module, curr_type, list, len);
1656             else
1657                 retv = codeview_add_type_struct_field_list(module, curr_type, list, len);
1658             break;
1659         }
1660
1661         case LF_STRUCTURE:
1662         case LF_CLASS:
1663         {
1664             int structlen, slen = numeric_leaf(&structlen, &type->structure.structlen);
1665             const unsigned char* name = (const unsigned char*)&type->structure.structlen + slen;
1666
1667             retv = codeview_add_type_struct(module, curr_type, terminate_string(name),
1668                                             structlen, type->structure.fieldlist,
1669                                             type->generic.id == LF_CLASS ? UdtClass : UdtStruct);
1670             break;
1671         }
1672         case LF_STRUCTURE_32:
1673         case LF_CLASS_32:
1674         {
1675             int structlen, slen = numeric_leaf(&structlen, &type->structure32.structlen);
1676             const unsigned char* name = (const unsigned char*)&type->structure32.structlen + slen;
1677
1678             retv = codeview_add_type_struct(module, curr_type, terminate_string(name),
1679                                             structlen, type->structure32.fieldlist,
1680                                             type->generic.id == LF_CLASS ? UdtClass : UdtStruct);
1681             break;
1682         }
1683
1684         case LF_UNION:
1685         {
1686             int un_len, ulen = numeric_leaf(&un_len, &type->t_union.un_len);
1687             const unsigned char* name = (const unsigned char*)&type->t_union.un_len + ulen;
1688
1689             retv = codeview_add_type_struct(module, curr_type, terminate_string(name),
1690                                             un_len, type->t_union.fieldlist, UdtUnion);
1691             break;
1692         }
1693         case LF_UNION_32:
1694         {
1695             int un_len, ulen = numeric_leaf(&un_len, &type->t_union32.un_len);
1696             const unsigned char* name = (const unsigned char*)&type->t_union32.un_len + ulen;
1697
1698             retv = codeview_add_type_struct(module, curr_type, terminate_string(name),
1699                                             un_len, type->t_union32.fieldlist, UdtUnion);
1700             break;
1701         }
1702
1703         case LF_ENUM:
1704             retv = codeview_add_type_enum(module, curr_type, terminate_string(type->enumeration.name),
1705                                           type->enumeration.field);
1706             break;
1707         case LF_ENUM_32:
1708             retv = codeview_add_type_enum(module, curr_type, terminate_string(type->enumeration32.name),
1709                                           type->enumeration32.field);
1710             break;
1711
1712         default:
1713             FIXME("Unhandled leaf %x\n", type->generic.id);
1714             break;
1715         }
1716
1717         if (!retv)
1718             return FALSE;
1719
1720         curr_type++;
1721         ptr += type->generic.len + 2;
1722     }
1723
1724     return TRUE;
1725 }
1726
1727 /*========================================================================
1728  * Process CodeView line number information.
1729  */
1730
1731 union any_size
1732 {
1733     const char*           c;
1734     const short*          s;
1735     const int*            i;
1736     const unsigned int*   ui;
1737 };
1738
1739 struct startend
1740 {
1741     unsigned int          start;
1742     unsigned int          end;
1743 };
1744
1745 struct codeview_linetab
1746 {
1747     unsigned int                nline;
1748     unsigned int                segno;
1749     unsigned int                start;
1750     unsigned int                end;
1751     struct symt_compiland*      compiland;
1752     const unsigned short*       linetab;
1753     const unsigned int*         offtab;
1754 };
1755
1756 static struct codeview_linetab* codeview_snarf_linetab(struct module* module, 
1757                                                        const char* linetab, int size)
1758 {
1759     int                         file_segcount;
1760     char                        filename[PATH_MAX];
1761     const unsigned int*         filetab;
1762     char*                       fn;
1763     int                         i;
1764     int                         k;
1765     struct codeview_linetab*    lt_hdr;
1766     unsigned int*               lt_ptr;
1767     int                         nfile;
1768     int                         nseg;
1769     union any_size              pnt;
1770     union any_size              pnt2;
1771     struct startend*            start;
1772     int                         this_seg;
1773     struct symt_compiland*      compiland;
1774
1775     /*
1776      * Now get the important bits.
1777      */
1778     pnt.c = linetab;
1779     nfile = *pnt.s++;
1780     nseg = *pnt.s++;
1781
1782     filetab = (const unsigned int*) pnt.c;
1783
1784     /*
1785      * Now count up the number of segments in the file.
1786      */
1787     nseg = 0;
1788     for (i = 0; i < nfile; i++)
1789     {
1790         pnt2.c = linetab + filetab[i];
1791         nseg += *pnt2.s;
1792     }
1793
1794     /*
1795      * Next allocate the header we will be returning.
1796      * There is one header for each segment, so that we can reach in
1797      * and pull bits as required.
1798      */
1799     lt_hdr = (struct codeview_linetab*)
1800         HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nseg + 1) * sizeof(*lt_hdr));
1801     if (lt_hdr == NULL)
1802     {
1803         goto leave;
1804     }
1805
1806     /*
1807      * Now fill the header we will be returning, one for each segment.
1808      * Note that this will basically just contain pointers into the existing
1809      * line table, and we do not actually copy any additional information
1810      * or allocate any additional memory.
1811      */
1812
1813     this_seg = 0;
1814     for (i = 0; i < nfile; i++)
1815     {
1816         /*
1817          * Get the pointer into the segment information.
1818          */
1819         pnt2.c = linetab + filetab[i];
1820         file_segcount = *pnt2.s;
1821
1822         pnt2.ui++;
1823         lt_ptr = (unsigned int*) pnt2.c;
1824         start = (struct startend*)(lt_ptr + file_segcount);
1825
1826         /*
1827          * Now snarf the filename for all of the segments for this file.
1828          */
1829         fn = (unsigned char*)(start + file_segcount);
1830         memset(filename, 0, sizeof(filename));
1831         memcpy(filename, fn + 1, *fn);
1832         compiland = symt_new_compiland(module, filename);
1833         
1834         for (k = 0; k < file_segcount; k++, this_seg++)
1835         {
1836             pnt2.c = linetab + lt_ptr[k];
1837             lt_hdr[this_seg].start      = start[k].start;
1838             lt_hdr[this_seg].end        = start[k].end;
1839             lt_hdr[this_seg].compiland  = compiland;
1840             lt_hdr[this_seg].segno      = *pnt2.s++;
1841             lt_hdr[this_seg].nline      = *pnt2.s++;
1842             lt_hdr[this_seg].offtab     = pnt2.ui;
1843             lt_hdr[this_seg].linetab    = (unsigned short*)(pnt2.ui + lt_hdr[this_seg].nline);
1844         }
1845     }
1846
1847 leave:
1848
1849   return lt_hdr;
1850
1851 }
1852
1853 /*========================================================================
1854  * Process CodeView symbol information.
1855  */
1856
1857 union codeview_symbol
1858 {
1859     struct
1860     {
1861         short int       len;
1862         short int       id;
1863     } generic;
1864
1865     struct
1866     {
1867         short int       len;
1868         short int       id;
1869         unsigned int    offset;
1870         unsigned short  seg;
1871         unsigned short  symtype;
1872         unsigned char   namelen;
1873         unsigned char   name[1];
1874     } data;
1875
1876     struct
1877     {
1878         short int       len;
1879         short int       id;
1880         unsigned int    symtype;
1881         unsigned int    offset;
1882         unsigned short  seg;
1883         unsigned char   namelen;
1884         unsigned char   name[1];
1885     } data32;
1886
1887     struct
1888     {
1889         short int       len;
1890         short int       id;
1891         unsigned int    pparent;
1892         unsigned int    pend;
1893         unsigned int    next;
1894         unsigned int    offset;
1895         unsigned short  segment;
1896         unsigned short  thunk_len;
1897         unsigned char   thtype;
1898         unsigned char   namelen;
1899         unsigned char   name[1];
1900     } thunk;
1901
1902     struct
1903     {
1904         short int       len;
1905         short int       id;
1906         unsigned int    pparent;
1907         unsigned int    pend;
1908         unsigned int    next;
1909         unsigned int    proc_len;
1910         unsigned int    debug_start;
1911         unsigned int    debug_end;
1912         unsigned int    offset;
1913         unsigned short  segment;
1914         unsigned short  proctype;
1915         unsigned char   flags;
1916         unsigned char   namelen;
1917         unsigned char   name[1];
1918     } proc;
1919
1920     struct
1921     {
1922         short int       len;
1923         short int       id;
1924         unsigned int    pparent;
1925         unsigned int    pend;
1926         unsigned int    next;
1927         unsigned int    proc_len;
1928         unsigned int    debug_start;
1929         unsigned int    debug_end;
1930         unsigned int    proctype;
1931         unsigned int    offset;
1932         unsigned short  segment;
1933         unsigned char   flags;
1934         unsigned char   namelen;
1935         unsigned char   name[1];
1936     } proc32;
1937
1938     struct
1939     {
1940         short int       len;    /* Total length of this entry */
1941         short int       id;             /* Always S_BPREL32 */
1942         unsigned int    offset; /* Stack offset relative to BP */
1943         unsigned short  symtype;
1944         unsigned char   namelen;
1945         unsigned char   name[1];
1946     } stack;
1947
1948     struct
1949     {
1950         short int       len;    /* Total length of this entry */
1951         short int       id;             /* Always S_BPREL32 */
1952         unsigned int    offset; /* Stack offset relative to BP */
1953         unsigned int    symtype;
1954         unsigned char   namelen;
1955         unsigned char   name[1];
1956     } stack32;
1957 };
1958
1959 #define S_COMPILE       0x0001
1960 #define S_REGISTER      0x0002
1961 #define S_CONSTANT      0x0003
1962 #define S_UDT           0x0004
1963 #define S_SSEARCH       0x0005
1964 #define S_END           0x0006
1965 #define S_SKIP          0x0007
1966 #define S_CVRESERVE     0x0008
1967 #define S_OBJNAME       0x0009
1968 #define S_ENDARG        0x000a
1969 #define S_COBOLUDT      0x000b
1970 #define S_MANYREG       0x000c
1971 #define S_RETURN        0x000d
1972 #define S_ENTRYTHIS     0x000e
1973
1974 #define S_BPREL         0x0200
1975 #define S_LDATA         0x0201
1976 #define S_GDATA         0x0202
1977 #define S_PUB           0x0203
1978 #define S_LPROC         0x0204
1979 #define S_GPROC         0x0205
1980 #define S_THUNK         0x0206
1981 #define S_BLOCK         0x0207
1982 #define S_WITH          0x0208
1983 #define S_LABEL         0x0209
1984 #define S_CEXMODEL      0x020a
1985 #define S_VFTPATH       0x020b
1986 #define S_REGREL        0x020c
1987 #define S_LTHREAD       0x020d
1988 #define S_GTHREAD       0x020e
1989
1990 #define S_PROCREF       0x0400
1991 #define S_DATAREF       0x0401
1992 #define S_ALIGN         0x0402
1993 #define S_LPROCREF      0x0403
1994
1995 #define S_REGISTER_32   0x1001 /* Variants with new 32-bit type indices */
1996 #define S_CONSTANT_32   0x1002
1997 #define S_UDT_32        0x1003
1998 #define S_COBOLUDT_32   0x1004
1999 #define S_MANYREG_32    0x1005
2000
2001 #define S_BPREL_32      0x1006
2002 #define S_LDATA_32      0x1007
2003 #define S_GDATA_32      0x1008
2004 #define S_PUB_32        0x1009
2005 #define S_LPROC_32      0x100a
2006 #define S_GPROC_32      0x100b
2007 #define S_VFTTABLE_32   0x100c
2008 #define S_REGREL_32     0x100d
2009 #define S_LTHREAD_32    0x100e
2010 #define S_GTHREAD_32    0x100f
2011
2012 static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
2013                                         unsigned int offset)
2014 {
2015     int                 nomap = msc_dbg->nomap;
2016     const OMAP_DATA*    omapp = msc_dbg->omapp;
2017     int                 i;
2018
2019     if (!nomap || !omapp) return offset;
2020
2021     /* FIXME: use binary search */
2022     for (i = 0; i < nomap - 1; i++)
2023         if (omapp[i].from <= offset && omapp[i+1].from > offset)
2024             return !omapp[i].to ? 0 : omapp[i].to + (offset - omapp[i].from);
2025
2026     return 0;
2027 }
2028
2029 static const struct codeview_linetab*
2030 codeview_get_linetab(const struct codeview_linetab* linetab,
2031                      unsigned seg, unsigned offset)
2032 {
2033     /*
2034      * Check whether we have line number information
2035      */
2036     if (linetab)
2037     {
2038         for (; linetab->linetab; linetab++)
2039             if (linetab->segno == seg &&
2040                 linetab->start <= offset && linetab->end   >  offset)
2041                 break;
2042         if (!linetab->linetab) linetab = NULL;
2043     }
2044     return linetab;
2045 }
2046
2047 static unsigned codeview_get_address(const struct msc_debug_info* msc_dbg, 
2048                                      unsigned seg, unsigned offset)
2049 {
2050     int                         nsect = msc_dbg->nsect;
2051     const IMAGE_SECTION_HEADER* sectp = msc_dbg->sectp;
2052
2053     if (!seg || seg > nsect) return 0;
2054     return msc_dbg->module->module.BaseOfImage +
2055         codeview_map_offset(msc_dbg, sectp[seg-1].VirtualAddress + offset);
2056 }
2057
2058 static void codeview_add_func_linenum(struct module* module, 
2059                                       struct symt_function* func,
2060                                       const struct codeview_linetab* linetab,
2061                                       unsigned offset, unsigned size)
2062 {
2063     unsigned int        i;
2064
2065     if (!linetab) return;
2066     for (i = 0; i < linetab->nline; i++)
2067     {
2068         if (linetab->offtab[i] >= offset && linetab->offtab[i] < offset + size)
2069         {
2070             symt_add_func_line(module, func, linetab->compiland->source,
2071                                linetab->linetab[i], linetab->offtab[i] - offset);
2072         }
2073     }
2074 }
2075
2076 static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root, 
2077                           int offset, int size,
2078                           struct codeview_linetab* linetab)
2079 {
2080     struct symt_function*               curr_func = NULL;
2081     int                                 i, length;
2082     char                                symname[PATH_MAX];
2083     const struct codeview_linetab*      flt;
2084
2085     /*
2086      * Loop over the different types of records and whenever we
2087      * find something we are interested in, record it and move on.
2088      */
2089     for (i = offset; i < size; i += length)
2090     {
2091         const union codeview_symbol* sym = (const union codeview_symbol*)(root + i);
2092         length = sym->generic.len + 2;
2093
2094         switch (sym->generic.id)
2095         {
2096         /*
2097          * Global and local data symbols.  We don't associate these
2098          * with any given source file.
2099          */
2100         case S_GDATA:
2101         case S_LDATA:
2102             memcpy(symname, sym->data.name, sym->data.namelen);
2103             symname[sym->data.namelen] = '\0';
2104             flt = codeview_get_linetab(linetab, sym->data.seg, sym->data.offset);
2105             /* global data should be the only one of type global var...
2106              * the other ones sound different
2107              * FIXME
2108              */
2109             symt_new_global_variable(msc_dbg->module, 
2110                                      flt ? flt->compiland : NULL,
2111                                      symname, sym->generic.id == S_GDATA,
2112                                      codeview_get_address(msc_dbg, sym->data.seg, sym->data.offset),
2113                                      0,
2114                                      codeview_get_type(sym->data.symtype, FALSE));
2115             break;
2116
2117         case S_GDATA_32:
2118         case S_LDATA_32:
2119             memcpy(symname, sym->data32.name, sym->data32.namelen);
2120             symname[sym->data32.namelen] = '\0';
2121             flt = codeview_get_linetab(linetab, sym->data32.seg, sym->data32.offset);
2122             /* global data should be the only one of type global var...
2123              * the other ones sound different
2124              * FIXME
2125              */
2126             symt_new_global_variable(msc_dbg->module, flt ? flt->compiland : NULL,
2127                                      symname, sym->generic.id == S_GDATA_32,
2128                                      codeview_get_address(msc_dbg, sym->data32.seg, sym->data32.offset),
2129                                      0,
2130                                      codeview_get_type(sym->data32.symtype, FALSE));
2131             break;
2132
2133         case S_PUB: /* FIXME is this really a 'data' structure ?? */
2134             memcpy(symname, sym->data.name, sym->data.namelen);
2135             symname[sym->data.namelen] = '\0';
2136             flt = codeview_get_linetab(linetab, sym->data.seg, sym->data.offset);
2137             symt_new_public(msc_dbg->module, flt ? flt->compiland : NULL,
2138                             symname, 
2139                             codeview_get_address(msc_dbg, sym->data.seg, sym->data.offset),
2140                             0, TRUE /* FIXME */, TRUE /* FIXME */);
2141             break;
2142
2143         case S_PUB_32: /* FIXME is this really a 'data32' structure ?? */
2144             memcpy(symname, sym->data32.name, sym->data32.namelen);
2145             symname[sym->data32.namelen] = '\0';
2146             flt = codeview_get_linetab(linetab, sym->data32.seg, sym->data32.offset);
2147             symt_new_public(msc_dbg->module, flt ? flt->compiland : NULL,
2148                             symname, 
2149                             codeview_get_address(msc_dbg, sym->data32.seg, sym->data32.offset),
2150                             0, TRUE /* FIXME */, TRUE /* FIXME */);
2151             break;
2152
2153         /*
2154          * Sort of like a global function, but it just points
2155          * to a thunk, which is a stupid name for what amounts to
2156          * a PLT slot in the normal jargon that everyone else uses.
2157          */
2158         case S_THUNK:
2159             memcpy(symname, sym->thunk.name, sym->thunk.namelen);
2160             symname[sym->thunk.namelen] = '\0';
2161             flt = codeview_get_linetab(linetab, sym->thunk.segment, sym->thunk.offset);
2162             symt_new_function(msc_dbg->module, flt ? flt->compiland : NULL,
2163                               symname, 
2164                               codeview_get_address(msc_dbg, sym->thunk.segment, sym->thunk.offset),
2165                               sym->thunk.thunk_len,
2166                               codeview_get_type(sym->thunk.thtype, FALSE));
2167             break;
2168
2169         /*
2170          * Global and static functions.
2171          */
2172         case S_GPROC:
2173         case S_LPROC:
2174             if (curr_func) symt_normalize_function(msc_dbg->module, curr_func);
2175
2176             memcpy(symname, sym->proc.name, sym->proc.namelen);
2177             symname[sym->proc.namelen] = '\0';
2178             flt = codeview_get_linetab(linetab, sym->proc.segment, sym->proc.offset);
2179             curr_func = symt_new_function(msc_dbg->module, 
2180                                           flt ? flt->compiland : NULL, symname, 
2181                                           codeview_get_address(msc_dbg, sym->proc.segment, sym->proc.offset),
2182                                           sym->proc.proc_len,
2183                                           codeview_get_type(sym->proc.proctype, FALSE));
2184
2185             codeview_add_func_linenum(msc_dbg->module, curr_func, flt, 
2186                                       sym->proc.offset, sym->proc.proc_len);
2187             /* DEBUG_SetSymbolBPOff(curr_func, sym->proc.debug_start); */
2188             break;
2189         case S_GPROC_32:
2190         case S_LPROC_32:
2191             if (curr_func) symt_normalize_function(msc_dbg->module, curr_func);
2192
2193             memcpy(symname, sym->proc32.name, sym->proc32.namelen);
2194             symname[sym->proc32.namelen] = '\0';
2195             flt = codeview_get_linetab(linetab, sym->proc32.segment, sym->proc32.offset);
2196             curr_func = symt_new_function(msc_dbg->module,
2197                                           flt ? flt->compiland : NULL, symname, 
2198                                           codeview_get_address(msc_dbg, sym->proc32.segment, sym->proc32.offset),
2199                                           sym->proc32.proc_len,
2200                                           codeview_get_type(sym->proc32.proctype, FALSE));
2201
2202             codeview_add_func_linenum(msc_dbg->module, curr_func, flt, 
2203                                       sym->proc32.offset, sym->proc32.proc_len);
2204             /* DEBUG_SetSymbolBPOff(curr_func, sym->proc32.debug_start); */
2205             break;
2206
2207         /*
2208          * Function parameters and stack variables.
2209          */
2210         case S_BPREL:
2211             memcpy(symname, sym->stack.name, sym->stack.namelen);
2212             symname[sym->stack.namelen] = '\0';
2213             symt_add_func_local(msc_dbg->module, curr_func, 0, sym->stack.offset,
2214                                 NULL, codeview_get_type(sym->stack.symtype, FALSE),
2215                                 symname);
2216             break;
2217         case S_BPREL_32:
2218             memcpy(symname, sym->stack32.name, sym->stack32.namelen);
2219             symname[sym->stack32.namelen] = '\0';
2220             symt_add_func_local(msc_dbg->module, curr_func, 0, sym->stack32.offset,
2221                                 NULL, codeview_get_type(sym->stack32.symtype, FALSE),
2222                                 symname);
2223             break;
2224
2225         /*
2226          * These are special, in that they are always followed by an
2227          * additional length-prefixed string which is *not* included
2228          * into the symbol length count.  We need to skip it.
2229          */
2230         case S_PROCREF:
2231         case S_DATAREF:
2232         case S_LPROCREF:
2233             {
2234                 LPBYTE name = (LPBYTE)sym + length;
2235                 length += (*name + 1 + 3) & ~3;
2236             }
2237             break;
2238         default:
2239             FIXME("Unsupported id %x\n", sym->generic.id);
2240         }
2241     }
2242
2243     if (curr_func) symt_normalize_function(msc_dbg->module, curr_func);
2244
2245     if (linetab) HeapFree(GetProcessHeap(), 0, linetab);
2246     return TRUE;
2247 }
2248
2249 /*========================================================================
2250  * Process PDB file.
2251  */
2252
2253 #pragma pack(1)
2254 typedef struct _PDB_FILE
2255 {
2256     DWORD size;
2257     DWORD unknown;
2258 } PDB_FILE,* PPDB_FILE;
2259
2260 typedef struct _PDB_HEADER
2261 {
2262     CHAR        ident[40];
2263     DWORD       signature;
2264     DWORD       blocksize;
2265     WORD        freelist;
2266     WORD        total_alloc;
2267     PDB_FILE    toc;
2268     WORD        toc_block[1];
2269 } PDB_HEADER, *PPDB_HEADER;
2270
2271 typedef struct _PDB_TOC
2272 {
2273     DWORD       nFiles;
2274     PDB_FILE    file[ 1 ];
2275 } PDB_TOC, *PPDB_TOC;
2276
2277 typedef struct _PDB_ROOT
2278 {
2279     DWORD       version;
2280     DWORD       TimeDateStamp;
2281     DWORD       unknown;
2282     DWORD       cbNames;
2283     CHAR        names[1];
2284 } PDB_ROOT, *PPDB_ROOT;
2285
2286 typedef struct _PDB_TYPES_OLD
2287 {
2288     DWORD       version;
2289     WORD        first_index;
2290     WORD        last_index;
2291     DWORD       type_size;
2292     WORD        file;
2293     WORD        pad;
2294 } PDB_TYPES_OLD, *PPDB_TYPES_OLD;
2295
2296 typedef struct _PDB_TYPES
2297 {
2298     DWORD       version;
2299     DWORD       type_offset;
2300     DWORD       first_index;
2301     DWORD       last_index;
2302     DWORD       type_size;
2303     WORD        file;
2304     WORD        pad;
2305     DWORD       hash_size;
2306     DWORD       hash_base;
2307     DWORD       hash_offset;
2308     DWORD       hash_len;
2309     DWORD       search_offset;
2310     DWORD       search_len;
2311     DWORD       unknown_offset;
2312     DWORD       unknown_len;
2313 } PDB_TYPES, *PPDB_TYPES;
2314
2315 typedef struct _PDB_SYMBOL_RANGE
2316 {
2317     WORD        segment;
2318     WORD        pad1;
2319     DWORD       offset;
2320     DWORD       size;
2321     DWORD       characteristics;
2322     WORD        index;
2323     WORD        pad2;
2324 } PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
2325
2326 typedef struct _PDB_SYMBOL_RANGE_EX
2327 {
2328     WORD        segment;
2329     WORD        pad1;
2330     DWORD       offset;
2331     DWORD       size;
2332     DWORD       characteristics;
2333     WORD        index;
2334     WORD        pad2;
2335     DWORD       timestamp;
2336     DWORD       unknown;
2337 } PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
2338
2339 typedef struct _PDB_SYMBOL_FILE
2340 {
2341     DWORD       unknown1;
2342     PDB_SYMBOL_RANGE range;
2343     WORD        flag;
2344     WORD        file;
2345     DWORD       symbol_size;
2346     DWORD       lineno_size;
2347     DWORD       unknown2;
2348     DWORD       nSrcFiles;
2349     DWORD       attribute;
2350     CHAR        filename[1];
2351 } PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
2352
2353 typedef struct _PDB_SYMBOL_FILE_EX
2354 {
2355     DWORD       unknown1;
2356     PDB_SYMBOL_RANGE_EX range;
2357     WORD        flag;
2358     WORD        file;
2359     DWORD       symbol_size;
2360     DWORD       lineno_size;
2361     DWORD       unknown2;
2362     DWORD       nSrcFiles;
2363     DWORD       attribute;
2364     DWORD       reserved[2];
2365     CHAR        filename[1];
2366 } PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
2367
2368 typedef struct _PDB_SYMBOL_SOURCE
2369 {
2370     WORD        nModules;
2371     WORD        nSrcFiles;
2372     WORD        table[1];
2373 } PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
2374
2375 typedef struct _PDB_SYMBOL_IMPORT
2376 {
2377     DWORD       unknown1;
2378     DWORD       unknown2;
2379     DWORD       TimeDateStamp;
2380     DWORD       nRequests;
2381     CHAR        filename[1];
2382 } PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
2383
2384 typedef struct _PDB_SYMBOLS_OLD
2385 {
2386     WORD        hash1_file;
2387     WORD        hash2_file;
2388     WORD        gsym_file;
2389     WORD        pad;
2390     DWORD       module_size;
2391     DWORD       offset_size;
2392     DWORD       hash_size;
2393     DWORD       srcmodule_size;
2394 } PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
2395
2396 typedef struct _PDB_SYMBOLS
2397 {
2398     DWORD       signature;
2399     DWORD       version;
2400     DWORD       unknown;
2401     DWORD       hash1_file;
2402     DWORD       hash2_file;
2403     DWORD       gsym_file;
2404     DWORD       module_size;
2405     DWORD       offset_size;
2406     DWORD       hash_size;
2407     DWORD       srcmodule_size;
2408     DWORD       pdbimport_size;
2409     DWORD       resvd[5];
2410 } PDB_SYMBOLS, *PPDB_SYMBOLS;
2411 #pragma pack()
2412
2413 static void* pdb_read(const BYTE* image, const WORD* block_list, int size)
2414 {
2415     const PDB_HEADER*   pdb = (const PDB_HEADER*)image;
2416     int                 i, nBlocks;
2417     BYTE*               buffer;
2418
2419     if (!size) return NULL;
2420
2421     nBlocks = (size + pdb->blocksize - 1) / pdb->blocksize;
2422     buffer = HeapAlloc(GetProcessHeap(), 0, nBlocks * pdb->blocksize);
2423
2424     for (i = 0; i < nBlocks; i++)
2425         memcpy(buffer + i * pdb->blocksize,
2426                image + block_list[i] * pdb->blocksize, pdb->blocksize);
2427
2428     return buffer;
2429 }
2430
2431 static void* pdb_read_file(const BYTE* image, const PDB_TOC* toc, DWORD fileNr)
2432 {
2433     const PDB_HEADER*   pdb = (const PDB_HEADER*)image;
2434     const WORD*         block_list;
2435     DWORD               i;
2436
2437     if (!toc || fileNr >= toc->nFiles) return NULL;
2438
2439     block_list = (const WORD*) &toc->file[toc->nFiles];
2440     for (i = 0; i < fileNr; i++)
2441         block_list += (toc->file[i].size + pdb->blocksize - 1) / pdb->blocksize;
2442
2443     return pdb_read(image, block_list, toc->file[fileNr].size);
2444 }
2445
2446 static void pdb_free(void* buffer)
2447 {
2448     HeapFree(GetProcessHeap(), 0, buffer);
2449 }
2450
2451 static void pdb_convert_types_header(PDB_TYPES* types, const BYTE* image)
2452 {
2453     memset(types, 0, sizeof(PDB_TYPES));
2454     if (!image) return;
2455
2456     if (*(DWORD*)image < 19960000)   /* FIXME: correct version? */
2457     {
2458         /* Old version of the types record header */
2459         const PDB_TYPES_OLD*    old = (const PDB_TYPES_OLD*)image;
2460         types->version     = old->version;
2461         types->type_offset = sizeof(PDB_TYPES_OLD);
2462         types->type_size   = old->type_size;
2463         types->first_index = old->first_index;
2464         types->last_index  = old->last_index;
2465         types->file        = old->file;
2466     }
2467     else
2468     {
2469         /* New version of the types record header */
2470         *types = *(const PDB_TYPES*)image;
2471     }
2472 }
2473
2474 static void pdb_convert_symbols_header(PDB_SYMBOLS* symbols,
2475                                        int* header_size, const BYTE* image)
2476 {
2477     memset(symbols, 0, sizeof(PDB_SYMBOLS));
2478     if (!image) return;
2479
2480     if (*(DWORD*)image != 0xffffffff)
2481     {
2482         /* Old version of the symbols record header */
2483         const PDB_SYMBOLS_OLD*  old = (const PDB_SYMBOLS_OLD*)image;
2484         symbols->version         = 0;
2485         symbols->module_size     = old->module_size;
2486         symbols->offset_size     = old->offset_size;
2487         symbols->hash_size       = old->hash_size;
2488         symbols->srcmodule_size  = old->srcmodule_size;
2489         symbols->pdbimport_size  = 0;
2490         symbols->hash1_file      = old->hash1_file;
2491         symbols->hash2_file      = old->hash2_file;
2492         symbols->gsym_file       = old->gsym_file;
2493
2494         *header_size = sizeof(PDB_SYMBOLS_OLD);
2495     }
2496     else
2497     {
2498         /* New version of the symbols record header */
2499         *symbols = *(const PDB_SYMBOLS*)image;
2500         *header_size = sizeof(PDB_SYMBOLS);
2501     }
2502 }
2503
2504 static const char*  get_last_sep(const char* str)
2505 {
2506     char*       a;
2507
2508     if ((a = strrchr(str, '/'))) str = a;
2509     return (a = strrchr(str, '\\')) ? a : str;
2510 }
2511
2512 static HANDLE open_pdb_file(const struct process* pcs, struct module* module,
2513                             char* filename)
2514 {
2515     HANDLE      h;
2516     char        dbg_file_path[MAX_PATH];
2517
2518     h = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, 
2519                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2520     if (h == INVALID_HANDLE_VALUE)
2521     {
2522         h = FindDebugInfoFile(filename, pcs->search_path, dbg_file_path);
2523         if (h == NULL)
2524         {
2525             const char* p;
2526             const char* q;
2527
2528             strcpy(dbg_file_path, module->module.LoadedImageName);
2529             if ((p = get_last_sep(dbg_file_path)))
2530             {
2531                 if ((q = get_last_sep(filename))) q++; else q = filename;
2532                 strcpy((char*)p + 1, q);
2533                 h = CreateFileA(dbg_file_path, GENERIC_READ, FILE_SHARE_READ, NULL, 
2534                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2535             }
2536         }
2537     }
2538     return (h == INVALID_HANDLE_VALUE) ? NULL : h;
2539 }
2540
2541 static SYM_TYPE pdb_process_file(const struct process* pcs, 
2542                                  const struct msc_debug_info* msc_dbg,
2543                                  char* filename, DWORD timestamp)
2544 {
2545     SYM_TYPE    sym_type = -1;
2546     HANDLE      hFile, hMap = NULL;
2547     char*       image = NULL;
2548     PDB_HEADER* pdb = NULL;
2549     PDB_TOC*    toc = NULL;
2550     PDB_ROOT*   root = NULL;
2551     char*       types_image = NULL;
2552     char*       symbols_image = NULL;
2553     PDB_TYPES   types;
2554     PDB_SYMBOLS symbols;
2555     int         header_size = 0;
2556     char*       modimage;
2557     char*       file;
2558
2559     TRACE("Processing PDB file %s\n", filename);
2560
2561     /*
2562     *  Open and map() .PDB file
2563      */
2564     if ((hFile = open_pdb_file(pcs, msc_dbg->module, filename)) == NULL ||
2565         ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) ||
2566         ((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
2567     {
2568         ERR("-Unable to peruse .PDB file %s\n", filename);
2569         goto leave;
2570     }
2571
2572     /*
2573      * Read in TOC and well-known files
2574      */
2575     pdb = (PPDB_HEADER)image;
2576     toc = pdb_read(image, pdb->toc_block, pdb->toc.size);
2577     root = pdb_read_file(image, toc, 1);
2578     types_image = pdb_read_file(image, toc, 2);
2579     symbols_image = pdb_read_file(image, toc, 3);
2580
2581     pdb_convert_types_header(&types, types_image);
2582     pdb_convert_symbols_header(&symbols, &header_size, symbols_image);
2583
2584     if (!root)
2585     {
2586         ERR("-Unable to get root from .PDB file %s\n", filename);
2587         goto leave;
2588     }
2589
2590     /*
2591      * Check for unknown versions
2592      */
2593
2594     switch (root->version)
2595     {
2596         case 19950623:      /* VC 4.0 */
2597         case 19950814:
2598         case 19960307:      /* VC 5.0 */
2599         case 19970604:      /* VC 6.0 */
2600             break;
2601         default:
2602             ERR("-Unknown root block version %ld\n", root->version);
2603     }
2604
2605     switch (types.version)
2606     {
2607         case 19950410:      /* VC 4.0 */
2608         case 19951122:
2609         case 19961031:      /* VC 5.0 / 6.0 */
2610             break;
2611         default:
2612             ERR("-Unknown type info version %ld\n", types.version);
2613     }
2614
2615     switch (symbols.version)
2616     {
2617         case 0:            /* VC 4.0 */
2618         case 19960307:     /* VC 5.0 */
2619         case 19970606:     /* VC 6.0 */
2620             break;
2621         default:
2622             ERR("-Unknown symbol info version %ld\n", symbols.version);
2623     }
2624
2625
2626     /* Check .PDB time stamp */
2627     if (root->TimeDateStamp != timestamp)
2628     {
2629         ERR("-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
2630             filename, root->TimeDateStamp, timestamp);
2631     }
2632
2633     /* Read type table */
2634     codeview_parse_type_table(msc_dbg->module, types_image + types.type_offset, types.type_size);
2635
2636     /* Read type-server .PDB imports */
2637     if (symbols.pdbimport_size)
2638     {
2639         /* FIXME */
2640         ERR("-Type server .PDB imports ignored!\n");
2641     }
2642
2643     /* Read global symbol table */
2644     modimage = pdb_read_file(image, toc, symbols.gsym_file);
2645     if (modimage)
2646     {
2647         codeview_snarf(msc_dbg, modimage, 0, toc->file[symbols.gsym_file].size, NULL);
2648         pdb_free(modimage);
2649     }
2650
2651     /* Read per-module symbol / linenumber tables */
2652     file = symbols_image + header_size;
2653     while (file - symbols_image < header_size + symbols.module_size)
2654     {
2655         int file_nr, file_index, symbol_size, lineno_size;
2656         char* file_name;
2657
2658         if (symbols.version < 19970000)
2659         {
2660             PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE*) file;
2661             file_nr     = sym_file->file;
2662             file_name   = sym_file->filename;
2663             file_index  = sym_file->range.index;
2664             symbol_size = sym_file->symbol_size;
2665             lineno_size = sym_file->lineno_size;
2666         }
2667         else
2668         {
2669             PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX*) file;
2670             file_nr     = sym_file->file;
2671             file_name   = sym_file->filename;
2672             file_index  = sym_file->range.index;
2673             symbol_size = sym_file->symbol_size;
2674             lineno_size = sym_file->lineno_size;
2675         }
2676
2677         modimage = pdb_read_file(image, toc, file_nr);
2678         if (modimage)
2679         {
2680             struct codeview_linetab*    linetab = NULL;
2681
2682             if (lineno_size)
2683                 linetab = codeview_snarf_linetab(msc_dbg->module, modimage + symbol_size, lineno_size);
2684
2685             if (symbol_size)
2686                 codeview_snarf(msc_dbg, modimage, sizeof(DWORD), symbol_size, linetab);
2687
2688             pdb_free(modimage);
2689         }
2690
2691         file_name += strlen(file_name) + 1;
2692         file = (char*)((DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3);
2693     }
2694
2695     sym_type = SymCv;
2696
2697  leave:
2698
2699     /* Cleanup */
2700     codeview_clear_type_table();
2701
2702     if (symbols_image) pdb_free(symbols_image);
2703     if (types_image) pdb_free(types_image);
2704     if (root) pdb_free(root);
2705     if (toc) pdb_free(toc);
2706
2707     if (image) UnmapViewOfFile(image);
2708     if (hMap) CloseHandle(hMap);
2709     if (hFile) CloseHandle(hFile);
2710
2711     return sym_type;
2712 }
2713
2714 /*========================================================================
2715  * Process CodeView debug information.
2716  */
2717
2718 #define CODEVIEW_NB09_SIG  ('N' | ('B' << 8) | ('0' << 16) | ('9' << 24))
2719 #define CODEVIEW_NB10_SIG  ('N' | ('B' << 8) | ('1' << 16) | ('0' << 24))
2720 #define CODEVIEW_NB11_SIG  ('N' | ('B' << 8) | ('1' << 16) | ('1' << 24))
2721
2722 typedef struct _CODEVIEW_HEADER
2723 {
2724     DWORD       dwSignature;
2725     DWORD       lfoDirectory;
2726 } CODEVIEW_HEADER,* PCODEVIEW_HEADER;
2727
2728 typedef struct _CODEVIEW_PDB_DATA
2729 {
2730     DWORD       timestamp;
2731     DWORD       unknown;
2732     CHAR        name[1];
2733 } CODEVIEW_PDB_DATA, *PCODEVIEW_PDB_DATA;
2734
2735 typedef struct _CV_DIRECTORY_HEADER
2736 {
2737     WORD        cbDirHeader;
2738     WORD        cbDirEntry;
2739     DWORD       cDir;
2740     DWORD       lfoNextDir;
2741     DWORD       flags;
2742 } CV_DIRECTORY_HEADER, *PCV_DIRECTORY_HEADER;
2743
2744 typedef struct _CV_DIRECTORY_ENTRY
2745 {
2746     WORD        subsection;
2747     WORD        iMod;
2748     DWORD       lfo;
2749     DWORD       cb;
2750 } CV_DIRECTORY_ENTRY, *PCV_DIRECTORY_ENTRY;
2751
2752 #define sstAlignSym             0x125
2753 #define sstSrcModule            0x127
2754
2755 static SYM_TYPE codeview_process_info(const struct process* pcs, 
2756                                       const struct msc_debug_info* msc_dbg)
2757 {
2758     const CODEVIEW_HEADER*      cv = (const CODEVIEW_HEADER*)msc_dbg->root;
2759     SYM_TYPE                    sym_type = -1;
2760
2761     switch (cv->dwSignature)
2762     {
2763     case CODEVIEW_NB09_SIG:
2764     case CODEVIEW_NB11_SIG:
2765     {
2766         const CV_DIRECTORY_HEADER*      hdr = (const CV_DIRECTORY_HEADER*)(msc_dbg->root + cv->lfoDirectory);
2767         const CV_DIRECTORY_ENTRY*       ent;
2768         const CV_DIRECTORY_ENTRY*       prev;
2769         const CV_DIRECTORY_ENTRY*       next;
2770         unsigned int                    i;
2771
2772         codeview_init_basic_types(msc_dbg->module);
2773         ent = (const CV_DIRECTORY_ENTRY*)((const BYTE*)hdr + hdr->cbDirHeader);
2774         for (i = 0; i < hdr->cDir; i++, ent = next)
2775         {
2776             next = (i == hdr->cDir-1)? NULL :
2777                    (const CV_DIRECTORY_ENTRY*)((const BYTE*)ent + hdr->cbDirEntry);
2778             prev = (i == 0)? NULL :
2779                    (const CV_DIRECTORY_ENTRY*)((const BYTE*)ent - hdr->cbDirEntry);
2780
2781             if (ent->subsection == sstAlignSym)
2782             {
2783                 /*
2784                  * Check the next and previous entry.  If either is a
2785                  * sstSrcModule, it contains the line number info for
2786                  * this file.
2787                  *
2788                  * FIXME: This is not a general solution!
2789                  */
2790                 struct codeview_linetab*        linetab = NULL;
2791
2792                 if (next && next->iMod == ent->iMod && next->subsection == sstSrcModule)
2793                     linetab = codeview_snarf_linetab(msc_dbg->module, msc_dbg->root + next->lfo, next->cb);
2794
2795                 if (prev && prev->iMod == ent->iMod && prev->subsection == sstSrcModule)
2796                     linetab = codeview_snarf_linetab(msc_dbg->module, msc_dbg->root + prev->lfo, prev->cb);
2797
2798                 codeview_snarf(msc_dbg, msc_dbg->root + ent->lfo, sizeof(DWORD),
2799                                ent->cb, linetab);
2800             }
2801         }
2802
2803         sym_type = SymCv;
2804         break;
2805     }
2806
2807     case CODEVIEW_NB10_SIG:
2808     {
2809         PCODEVIEW_PDB_DATA pdb = (PCODEVIEW_PDB_DATA)(cv + 1);
2810
2811         codeview_init_basic_types(msc_dbg->module);
2812         sym_type = pdb_process_file(pcs, msc_dbg, pdb->name, pdb->timestamp);
2813         break;
2814     }
2815     default:
2816         ERR("Unknown CODEVIEW signature %08lX in module %s\n",
2817             cv->dwSignature, msc_dbg->module->module.ModuleName);
2818         break;
2819     }
2820
2821     return sym_type;
2822 }
2823
2824 /*========================================================================
2825  * Process debug directory.
2826  */
2827 SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* module, 
2828                                  const BYTE* mapping, PIMAGE_DEBUG_DIRECTORY dbg, 
2829                                  int nDbg)
2830 {
2831     SYM_TYPE                    sym_type;
2832     int                         i;
2833     struct msc_debug_info       msc_dbg;
2834     IMAGE_NT_HEADERS*           nth = RtlImageNtHeader((void*)mapping);
2835
2836     msc_dbg.module = module;
2837     msc_dbg.nsect  = nth->FileHeader.NumberOfSections;
2838     msc_dbg.sectp  = (PIMAGE_SECTION_HEADER)((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
2839     msc_dbg.nomap  = 0;
2840     msc_dbg.omapp  = NULL;
2841
2842     __TRY
2843     {
2844         sym_type = -1;
2845
2846         /* First, watch out for OMAP data */
2847         for (i = 0; i < nDbg; i++)
2848         {
2849             if (dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC)
2850             {
2851                 msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
2852                 msc_dbg.omapp = (OMAP_DATA*)(mapping + dbg[i].PointerToRawData);
2853                 break;
2854             }
2855         }
2856   
2857         /* Now, try to parse CodeView debug info */
2858         for (i = 0; i < nDbg; i++)
2859         {
2860             if (dbg[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW)
2861             {
2862                 msc_dbg.root = mapping + dbg[i].PointerToRawData;
2863                 sym_type = codeview_process_info(pcs, &msc_dbg);
2864                 if (sym_type == SymCv) goto done;
2865             }
2866         }
2867     
2868         /* If not found, try to parse COFF debug info */
2869         for (i = 0; i < nDbg; i++)
2870         {
2871             if (dbg[i].Type == IMAGE_DEBUG_TYPE_COFF)
2872             {
2873                 msc_dbg.root = mapping + dbg[i].PointerToRawData;
2874                 sym_type = coff_process_info(&msc_dbg);
2875                 if (sym_type == SymCoff) goto done;
2876             }
2877         }
2878     done:
2879 #if 0
2880          /* FIXME: this should be supported... this is the debug information for
2881           * functions compiled without a frame pointer (FPO = frame pointer omission)
2882           * the associated data helps finding out the relevant information
2883           */
2884         for (i = 0; i < nDbg; i++)
2885             if (dbg[i].Type == IMAGE_DEBUG_TYPE_FPO)
2886                 DEBUG_Printf("This guy has FPO information\n");
2887
2888 #define FRAME_FPO   0
2889 #define FRAME_TRAP  1
2890 #define FRAME_TSS   2
2891
2892 typedef struct _FPO_DATA 
2893 {
2894         DWORD       ulOffStart;            /* offset 1st byte of function code */
2895         DWORD       cbProcSize;            /* # bytes in function */
2896         DWORD       cdwLocals;             /* # bytes in locals/4 */
2897         WORD        cdwParams;             /* # bytes in params/4 */
2898
2899         WORD        cbProlog : 8;          /* # bytes in prolog */
2900         WORD        cbRegs   : 3;          /* # regs saved */
2901         WORD        fHasSEH  : 1;          /* TRUE if SEH in func */
2902         WORD        fUseBP   : 1;          /* TRUE if EBP has been allocated */
2903         WORD        reserved : 1;          /* reserved for future use */
2904         WORD        cbFrame  : 2;          /* frame type */
2905 } FPO_DATA;
2906 #else
2907 ;
2908 #endif
2909     }
2910     __EXCEPT(page_fault)
2911     {
2912         ERR("Got a page fault while loading symbols\n");
2913         sym_type = -1;
2914     }
2915     __ENDTRY
2916     return sym_type;
2917 }