1
2/*--------------------------------------------------------------------*/
3/*--- Reading of syms & debug info from PDB-format files.         ---*/
4/*---                                                   readpdb.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8   This file is part of Valgrind, a dynamic binary instrumentation
9   framework.
10   Spring 2008:
11      derived from readelf.c and valgrind-20031012-wine/vg_symtab2.c
12      derived from wine-1.0/tools/winedump/pdb.c and msc.c
13
14   Copyright (C) 2000-2013 Julian Seward
15      jseward@acm.org
16   Copyright 2006 Eric Pouech (winedump/pdb.c and msc.c)
17      GNU Lesser General Public License version 2.1 or later applies.
18   Copyright (C) 2008 BitWagon Software LLC
19
20   This program is free software; you can redistribute it and/or
21   modify it under the terms of the GNU General Public License as
22   published by the Free Software Foundation; either version 2 of the
23   License, or (at your option) any later version.
24
25   This program is distributed in the hope that it will be useful, but
26   WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
28   General Public License for more details.
29
30   You should have received a copy of the GNU General Public License
31   along with this program; if not, write to the Free Software
32   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
33   02111-1307, USA.
34
35   The GNU General Public License is contained in the file COPYING.
36*/
37
38#if defined(VGO_linux) || defined(VGO_darwin)
39
40#include "pub_core_basics.h"
41#include "pub_core_debuginfo.h"
42#include "pub_core_vki.h"          // VKI_PAGE_SIZE
43#include "pub_core_libcbase.h"
44#include "pub_core_libcassert.h"
45#include "pub_core_libcfile.h"     // VG_(open), read, lseek, close
46#include "pub_core_libcprint.h"
47#include "pub_core_libcproc.h"     // VG_(getpid), system
48#include "pub_core_options.h"      // VG_(clo_verbosity)
49#include "pub_core_xarray.h"       // keeps priv_storage.h happy
50#include "pub_core_redir.h"
51
52#include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
53#include "priv_image.h"
54#include "priv_d3basics.h"
55#include "priv_storage.h"
56#include "priv_readpdb.h"          // self
57
58
59/*------------------------------------------------------------*/
60/*---                                                      ---*/
61/*--- Biasing                                              ---*/
62/*---                                                      ---*/
63/*------------------------------------------------------------*/
64
65/* There are just two simple ways of biasing in use here.
66
67   The CodeView debug info entries contain virtual addresses
68   relative to segment (here it is one PE section), which in
69   turn specifies its start as a VA relative to "image base".
70
71   The second type of debug info (FPOs) contain VAs relative
72   directly to the image base, without the segment indirection.
73
74   The original/preferred image base is set in the PE header,
75   but it can change as long as the file contains relocation
76   data. So everything is biased using the current image base,
77   which is the base AVMA passed by Wine.
78
79   The difference between the original image base and current
80   image base, which is what Wine sends here in the last
81   argument of VG_(di_notify_pdb_debuginfo), is not used.
82*/
83
84/* This module leaks space; enable m_main's calling of
85   VG_(di_discard_ALL_debuginfo)() at shutdown and run with
86   --profile-heap=yes to see.  The main culprit appears to be
87   di.readpe.pdr.1.  I haven't bothered to chase it further. */
88
89
90/*------------------------------------------------------------*/
91/*---                                                      ---*/
92/*--- PE/PDB definitions                                   ---*/
93/*---                                                      ---*/
94/*------------------------------------------------------------*/
95
96typedef  UInt   DWORD;
97typedef  UShort WORD;
98typedef  UChar  BYTE;
99
100
101/* the following DOS and WINDOWS structures, defines and PE/PDB
102 * parsing code are copied or derived from the WINE
103 * project - http://www.winehq.com/
104 */
105
106/*
107 * File formats definitions
108 */
109#define   OFFSET_OF(__c,__f)   ((int)(((char*)&(((__c*)0)->__f))-((char*)0)))
110#define   WIN32_PATH_MAX 256
111
112#pragma pack(2)
113typedef struct _IMAGE_DOS_HEADER {
114    unsigned short  e_magic;      /* 00: MZ Header signature */
115    unsigned short  e_cblp;       /* 02: Bytes on last page of file */
116    unsigned short  e_cp;         /* 04: Pages in file */
117    unsigned short  e_crlc;       /* 06: Relocations */
118    unsigned short  e_cparhdr;    /* 08: Size of header in paragraphs */
119    unsigned short  e_minalloc;   /* 0a: Minimum extra paragraphs needed */
120    unsigned short  e_maxalloc;   /* 0c: Maximum extra paragraphs needed */
121    unsigned short  e_ss;         /* 0e: Initial (relative) SS value */
122    unsigned short  e_sp;         /* 10: Initial SP value */
123    unsigned short  e_csum;       /* 12: Checksum */
124    unsigned short  e_ip;         /* 14: Initial IP value */
125    unsigned short  e_cs;         /* 16: Initial (relative) CS value */
126    unsigned short  e_lfarlc;     /* 18: File address of relocation table */
127    unsigned short  e_ovno;       /* 1a: Overlay number */
128    unsigned short  e_res[4];     /* 1c: Reserved words */
129    unsigned short  e_oemid;      /* 24: OEM identifier (for e_oeminfo) */
130    unsigned short  e_oeminfo;    /* 26: OEM information; e_oemid specific */
131    unsigned short  e_res2[10];   /* 28: Reserved words */
132    unsigned long   e_lfanew;     /* 3c: Offset to extended header */
133} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
134
135#define IMAGE_DOS_SIGNATURE    0x5A4D     /* MZ   */
136#define IMAGE_OS2_SIGNATURE    0x454E     /* NE   */
137#define IMAGE_OS2_SIGNATURE_LE 0x454C     /* LE   */
138#define IMAGE_OS2_SIGNATURE_LX 0x584C     /* LX */
139#define IMAGE_VXD_SIGNATURE    0x454C     /* LE   */
140#define IMAGE_NT_SIGNATURE     0x00004550 /* PE00 */
141
142/* Subsystem Values */
143
144#define IMAGE_SUBSYSTEM_UNKNOWN     0
145#define IMAGE_SUBSYSTEM_NATIVE      1
146#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2  /* Windows GUI subsystem */
147#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3  /* Windows character subsystem*/
148#define IMAGE_SUBSYSTEM_OS2_CUI     5
149#define IMAGE_SUBSYSTEM_POSIX_CUI   7
150
151typedef struct _IMAGE_FILE_HEADER {
152  unsigned short  Machine;
153  unsigned short  NumberOfSections;
154  unsigned long   TimeDateStamp;
155  unsigned long   PointerToSymbolTable;
156  unsigned long   NumberOfSymbols;
157  unsigned short  SizeOfOptionalHeader;
158  unsigned short  Characteristics;
159} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
160
161typedef struct _IMAGE_DATA_DIRECTORY {
162  unsigned long VirtualAddress;
163  unsigned long Size;
164} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
165
166#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
167
168typedef struct _IMAGE_OPTIONAL_HEADER {
169
170  /* Standard fields */
171
172  unsigned short Magic; /* 0x10b or 0x107 */ /* 0x00 */
173  unsigned char  MajorLinkerVersion;
174  unsigned char  MinorLinkerVersion;
175  unsigned long  SizeOfCode;
176  unsigned long  SizeOfInitializedData;
177  unsigned long  SizeOfUninitializedData;
178  unsigned long  AddressOfEntryPoint;        /* 0x10 */
179  unsigned long  BaseOfCode;
180  unsigned long  BaseOfData;
181
182  /* NT additional fields */
183
184  unsigned long ImageBase;
185  unsigned long SectionAlignment;            /* 0x20 */
186  unsigned long FileAlignment;
187  unsigned short MajorOperatingSystemVersion;
188  unsigned short MinorOperatingSystemVersion;
189  unsigned short MajorImageVersion;
190  unsigned short MinorImageVersion;
191  unsigned short MajorSubsystemVersion;      /* 0x30 */
192  unsigned short MinorSubsystemVersion;
193  unsigned long Win32VersionValue;
194  unsigned long SizeOfImage;
195  unsigned long SizeOfHeaders;
196  unsigned long CheckSum;                    /* 0x40 */
197  unsigned short Subsystem;
198  unsigned short DllCharacteristics;
199  unsigned long SizeOfStackReserve;
200  unsigned long SizeOfStackCommit;
201  unsigned long SizeOfHeapReserve;           /* 0x50 */
202  unsigned long SizeOfHeapCommit;
203  unsigned long LoaderFlags;
204  unsigned long NumberOfRvaAndSizes;
205  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /* 0x60 */
206  /* 0xE0 */
207} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
208
209typedef struct _IMAGE_NT_HEADERS {
210  unsigned long Signature; /* "PE"\0\0 */       /* 0x00 */
211  IMAGE_FILE_HEADER FileHeader;                 /* 0x04 */
212  IMAGE_OPTIONAL_HEADER OptionalHeader;         /* 0x18 */
213} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
214
215#define IMAGE_SIZEOF_SHORT_NAME 8
216
217typedef struct _IMAGE_SECTION_HEADER {
218  unsigned char Name[IMAGE_SIZEOF_SHORT_NAME];
219  union {
220    unsigned long PhysicalAddress;
221    unsigned long VirtualSize;
222  } Misc;
223  unsigned long VirtualAddress;
224  unsigned long SizeOfRawData;
225  unsigned long PointerToRawData;
226  unsigned long PointerToRelocations;
227  unsigned long PointerToLinenumbers;
228  unsigned short NumberOfRelocations;
229  unsigned short NumberOfLinenumbers;
230  unsigned long Characteristics;
231} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
232
233#define	IMAGE_SIZEOF_SECTION_HEADER 40
234
235#define IMAGE_FIRST_SECTION(ntheader) \
236  ((PIMAGE_SECTION_HEADER)((LPunsigned char)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \
237                           ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader))
238
239/* These defines are for the Characteristics bitfield. */
240/* #define IMAGE_SCN_TYPE_REG			0x00000000 - Reserved */
241/* #define IMAGE_SCN_TYPE_DSECT			0x00000001 - Reserved */
242/* #define IMAGE_SCN_TYPE_NOLOAD		0x00000002 - Reserved */
243/* #define IMAGE_SCN_TYPE_GROUP			0x00000004 - Reserved */
244/* #define IMAGE_SCN_TYPE_NO_PAD		0x00000008 - Reserved */
245/* #define IMAGE_SCN_TYPE_COPY			0x00000010 - Reserved */
246
247#define IMAGE_SCN_CNT_CODE			0x00000020
248#define IMAGE_SCN_CNT_INITIALIZED_DATA		0x00000040
249#define IMAGE_SCN_CNT_UNINITIALIZED_DATA	0x00000080
250
251#define	IMAGE_SCN_LNK_OTHER			0x00000100
252#define	IMAGE_SCN_LNK_INFO			0x00000200
253/* #define	IMAGE_SCN_TYPE_OVER		0x00000400 - Reserved */
254#define	IMAGE_SCN_LNK_REMOVE			0x00000800
255#define	IMAGE_SCN_LNK_COMDAT			0x00001000
256
257/* 						0x00002000 - Reserved */
258/* #define IMAGE_SCN_MEM_PROTECTED 		0x00004000 - Obsolete */
259#define	IMAGE_SCN_MEM_FARDATA			0x00008000
260
261/* #define IMAGE_SCN_MEM_SYSHEAP		0x00010000 - Obsolete */
262#define	IMAGE_SCN_MEM_PURGEABLE			0x00020000
263#define	IMAGE_SCN_MEM_16BIT			0x00020000
264#define	IMAGE_SCN_MEM_LOCKED			0x00040000
265#define	IMAGE_SCN_MEM_PRELOAD			0x00080000
266
267#define	IMAGE_SCN_ALIGN_1BYTES			0x00100000
268#define	IMAGE_SCN_ALIGN_2BYTES			0x00200000
269#define	IMAGE_SCN_ALIGN_4BYTES			0x00300000
270#define	IMAGE_SCN_ALIGN_8BYTES			0x00400000
271#define	IMAGE_SCN_ALIGN_16BYTES			0x00500000  /* Default */
272#define IMAGE_SCN_ALIGN_32BYTES			0x00600000
273#define IMAGE_SCN_ALIGN_64BYTES			0x00700000
274/* 						0x00800000 - Unused */
275
276#define IMAGE_SCN_LNK_NRELOC_OVFL		0x01000000
277
278
279#define IMAGE_SCN_MEM_DISCARDABLE		0x02000000
280#define IMAGE_SCN_MEM_NOT_CACHED		0x04000000
281#define IMAGE_SCN_MEM_NOT_PAGED			0x08000000
282#define IMAGE_SCN_MEM_SHARED			0x10000000
283#define IMAGE_SCN_MEM_EXECUTE			0x20000000
284#define IMAGE_SCN_MEM_READ			0x40000000
285#define IMAGE_SCN_MEM_WRITE			0x80000000
286
287#pragma pack()
288
289typedef struct _GUID  /* 16 bytes */
290{
291    unsigned int   Data1;
292    unsigned short Data2;
293    unsigned short Data3;
294    unsigned char  Data4[ 8 ];
295} GUID;
296
297/*========================================================================
298 * Process PDB file.
299 */
300
301#pragma pack(1)
302typedef struct _PDB_FILE
303{
304    unsigned long size;
305    unsigned long unknown;
306
307} PDB_FILE, *PPDB_FILE;
308
309// A .pdb file begins with a variable-length one-line text string
310// that ends in "\r\n\032".  This is followed by a 4-byte "signature"
311// ("DS\0\0" for newer files, "JG\0\0" for older files), then
312// aligned up to a 4-byte boundary, then the struct below:
313struct PDB_JG_HEADER
314{
315    //char ident[40];  // "Microsoft C/C++ program database 2.00\r\n\032"
316    //unsigned long  signature;  // "JG\0\0"
317    unsigned int   blocksize;  // 0x400 typical; also 0x800, 0x1000
318    unsigned short freelist;
319    unsigned short total_alloc;
320    PDB_FILE toc;
321    unsigned short toc_block[ 1 ];
322};
323
324struct PDB_DS_HEADER
325{
326    //char   signature[32];  // "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0"
327    unsigned int  block_size;
328    unsigned int unknown1;
329    unsigned int num_pages;
330    unsigned int toc_size;
331    unsigned int unknown2;
332    unsigned int toc_page;
333};
334
335struct PDB_JG_TOC
336{
337    unsigned int  nFiles;
338    PDB_FILE file[ 1 ];
339
340};
341
342struct PDB_DS_TOC
343{
344    unsigned int num_files;
345    unsigned int file_size[1];
346};
347
348struct PDB_JG_ROOT
349{
350    unsigned int  version;
351    unsigned int  TimeDateStamp;
352    unsigned int  age;
353    unsigned int  cbNames;
354    char names[ 1 ];
355};
356
357struct PDB_DS_ROOT
358{
359    unsigned int version;
360    unsigned int TimeDateStamp;
361    unsigned int age;
362    GUID guid;
363    unsigned int cbNames;
364    char names[1];
365};
366
367typedef struct _PDB_TYPES_OLD
368{
369    unsigned long  version;
370    unsigned short first_index;
371    unsigned short last_index;
372    unsigned long  type_size;
373    unsigned short file;
374    unsigned short pad;
375
376} PDB_TYPES_OLD, *PPDB_TYPES_OLD;
377
378typedef struct _PDB_TYPES
379{
380    unsigned long  version;
381    unsigned long  type_offset;
382    unsigned long  first_index;
383    unsigned long  last_index;
384    unsigned long  type_size;
385    unsigned short file;
386    unsigned short pad;
387    unsigned long  hash_size;
388    unsigned long  hash_base;
389    unsigned long  hash_offset;
390    unsigned long  hash_len;
391    unsigned long  search_offset;
392    unsigned long  search_len;
393    unsigned long  unknown_offset;
394    unsigned long  unknown_len;
395
396} PDB_TYPES, *PPDB_TYPES;
397
398typedef struct _PDB_SYMBOL_RANGE
399{
400    unsigned short segment;
401    unsigned short pad1;
402    unsigned long  offset;
403    unsigned long  size;
404    unsigned long  characteristics;
405    unsigned short index;
406    unsigned short pad2;
407
408} PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
409
410typedef struct _PDB_SYMBOL_RANGE_EX
411{
412    unsigned short segment;
413    unsigned short pad1;
414    unsigned long  offset;
415    unsigned long  size;
416    unsigned long  characteristics;
417    unsigned short index;
418    unsigned short pad2;
419    unsigned long  timestamp;
420    unsigned long  unknown;
421
422} PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
423
424typedef struct _PDB_SYMBOL_FILE
425{
426    unsigned long  unknown1;
427    PDB_SYMBOL_RANGE range;
428    unsigned short flag;
429    unsigned short file;
430    unsigned long  symbol_size;
431    unsigned long  lineno_size;
432    unsigned long  unknown2;
433    unsigned long  nSrcFiles;
434    unsigned long  attribute;
435    char filename[ 1 ];
436
437} PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
438
439typedef struct _PDB_SYMBOL_FILE_EX
440{
441    unsigned long  unknown1;
442    PDB_SYMBOL_RANGE_EX range;
443    unsigned short flag;
444    unsigned short file;
445    unsigned long  symbol_size;
446    unsigned long  lineno_size;
447    unsigned long  unknown2;
448    unsigned long  nSrcFiles;
449    unsigned long  attribute;
450    unsigned long  reserved[ 2 ];
451    char filename[ 1 ];
452
453} PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
454
455typedef struct _PDB_SYMBOL_SOURCE
456{
457    unsigned short nModules;
458    unsigned short nSrcFiles;
459    unsigned short table[ 1 ];
460
461} PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
462
463typedef struct _PDB_SYMBOL_IMPORT
464{
465    unsigned long unknown1;
466    unsigned long unknown2;
467    unsigned long TimeDateStamp;
468    unsigned long nRequests;
469    char filename[ 1 ];
470
471} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
472
473typedef struct _PDB_SYMBOLS_OLD
474{
475    unsigned short hash1_file;
476    unsigned short hash2_file;
477    unsigned short gsym_file;
478    unsigned short pad;
479    unsigned long  module_size;
480    unsigned long  offset_size;
481    unsigned long  hash_size;
482    unsigned long  srcmodule_size;
483
484} PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
485
486typedef struct _PDB_SYMBOLS
487{
488    unsigned long  signature;
489    unsigned long  version;
490    unsigned long  unknown;
491    unsigned long  hash1_file;
492    unsigned long  hash2_file;
493    unsigned long  gsym_file;
494    unsigned long  module_size;
495    unsigned long  offset_size;
496    unsigned long  hash_size;
497    unsigned long  srcmodule_size;
498    unsigned long  pdbimport_size;
499    unsigned long  resvd[ 5 ];
500
501} PDB_SYMBOLS, *PPDB_SYMBOLS;
502#pragma pack()
503
504/*========================================================================
505 * Process CodeView symbol information.
506 */
507
508/* from wine-1.0/include/wine/mscvpdb.h */
509
510struct p_string  /* "Pascal string": prefixed by byte containing length */
511{
512    unsigned char               namelen;
513    char                        name[1];
514};
515/* The other kind of "char name[1]" is a "C++ string" terminated by '\0'.
516 * "Name mangling" to encode type information often exceeds 255 bytes.
517 * Instead of using a 2-byte explicit length, they save one byte of space
518 * but incur a strlen().  This is justified by other code that wants
519 * a "C string" [terminated by '\0'] anyway.
520 */
521
522union codeview_symbol
523{
524    struct
525    {
526        short int	        len;
527        short int	        id;
528    } generic;
529
530    struct
531    {
532	short int	        len;
533	short int	        id;
534	unsigned int	        offset;
535	unsigned short	        segment;
536	unsigned short	        symtype;
537        struct p_string         p_name;
538    } data_v1;
539
540    struct
541    {
542	short int	        len;
543	short int	        id;
544	unsigned int	        symtype;
545	unsigned int	        offset;
546	unsigned short	        segment;
547        struct p_string         p_name;
548    } data_v2;
549
550    struct
551    {
552        short int               len;
553        short int               id;
554        unsigned int            symtype;
555        unsigned int            offset;
556        unsigned short          segment;
557        char                    name[1];  /* terminated by '\0' */
558    } data_v3;
559
560    struct
561    {
562	short int	        len;
563	short int	        id;
564	unsigned int	        pparent;
565	unsigned int	        pend;
566	unsigned int	        next;
567	unsigned int	        offset;
568	unsigned short	        segment;
569	unsigned short	        thunk_len;
570	unsigned char	        thtype;
571        struct p_string         p_name;
572    } thunk_v1;
573
574    struct
575    {
576        short int               len;
577        short int               id;
578        unsigned int            pparent;
579        unsigned int            pend;
580        unsigned int            next;
581        unsigned int            offset;
582        unsigned short          segment;
583        unsigned short          thunk_len;
584        unsigned char           thtype;
585        char                    name[1];  /* terminated by '\0' */
586    } thunk_v3;
587
588    struct
589    {
590	short int	        len;
591	short int	        id;
592	unsigned int	        pparent;
593	unsigned int	        pend;
594	unsigned int	        next;
595	unsigned int	        proc_len;
596	unsigned int	        debug_start;
597	unsigned int	        debug_end;
598	unsigned int	        offset;
599	unsigned short	        segment;
600	unsigned short	        proctype;
601	unsigned char	        flags;
602        struct p_string         p_name;
603    } proc_v1;
604
605    struct
606    {
607	short int	        len;
608	short int	        id;
609	unsigned int	        pparent;
610	unsigned int	        pend;
611	unsigned int	        next;
612	unsigned int	        proc_len;
613	unsigned int	        debug_start;
614	unsigned int	        debug_end;
615	unsigned int	        proctype;
616	unsigned int	        offset;
617	unsigned short	        segment;
618	unsigned char	        flags;
619        struct p_string         p_name;
620    } proc_v2;
621
622    struct
623    {
624        short int               len;
625        short int               id;
626        unsigned int            pparent;
627        unsigned int            pend;
628        unsigned int            next;
629        unsigned int            proc_len;
630        unsigned int            debug_start;
631        unsigned int            debug_end;
632        unsigned int            proctype;
633        unsigned int            offset;
634        unsigned short          segment;
635        unsigned char           flags;
636        char                    name[1];  /* terminated by '\0' */
637    } proc_v3;
638
639    struct
640    {
641        short int               len;
642        short int               id;
643        unsigned int            symtype;
644        unsigned int            offset;
645        unsigned short          segment;
646        struct p_string         p_name;
647    } public_v2;
648
649    struct
650    {
651        short int               len;
652        short int               id;
653        unsigned int            symtype;
654        unsigned int            offset;
655        unsigned short          segment;
656        char                    name[1];  /* terminated by '\0' */
657    } public_v3;
658
659    struct
660    {
661	short int	        len;	        /* Total length of this entry */
662	short int	        id;		/* Always S_BPREL_V1 */
663	unsigned int	        offset;	        /* Stack offset relative to BP */
664	unsigned short	        symtype;
665        struct p_string         p_name;
666    } stack_v1;
667
668    struct
669    {
670	short int	        len;	        /* Total length of this entry */
671	short int	        id;		/* Always S_BPREL_V2 */
672	unsigned int	        offset;	        /* Stack offset relative to EBP */
673	unsigned int	        symtype;
674        struct p_string         p_name;
675    } stack_v2;
676
677    struct
678    {
679        short int               len;            /* Total length of this entry */
680        short int               id;             /* Always S_BPREL_V3 */
681        int                     offset;         /* Stack offset relative to BP */
682        unsigned int            symtype;
683        char                    name[1];  /* terminated by '\0' */
684    } stack_v3;
685
686    struct
687    {
688        short int               len;            /* Total length of this entry */
689        short int               id;             /* Always S_BPREL_V3 */
690        int                     offset;         /* Stack offset relative to BP */
691        unsigned int            symtype;
692        unsigned short          unknown;
693        char                    name[1];  /* terminated by '\0' */
694    } stack_xxxx_v3;
695
696    struct
697    {
698	short int	        len;	        /* Total length of this entry */
699	short int	        id;		/* Always S_REGISTER */
700        unsigned short          type;
701        unsigned short          reg;
702        struct p_string         p_name;
703        /* don't handle register tracking */
704    } register_v1;
705
706    struct
707    {
708	short int	        len;	        /* Total length of this entry */
709	short int	        id;		/* Always S_REGISTER_V2 */
710        unsigned int            type;           /* check whether type & reg are correct */
711        unsigned short          reg;
712        struct p_string         p_name;
713        /* don't handle register tracking */
714    } register_v2;
715
716    struct
717    {
718	short int	        len;	        /* Total length of this entry */
719	short int	        id;		/* Always S_REGISTER_V3 */
720        unsigned int            type;           /* check whether type & reg are correct */
721        unsigned short          reg;
722        char                    name[1];  /* terminated by '\0' */
723        /* don't handle register tracking */
724    } register_v3;
725
726    struct
727    {
728        short int               len;
729        short int               id;
730        unsigned int            parent;
731        unsigned int            end;
732        unsigned int            length;
733        unsigned int            offset;
734        unsigned short          segment;
735        struct p_string         p_name;
736    } block_v1;
737
738    struct
739    {
740        short int               len;
741        short int               id;
742        unsigned int            parent;
743        unsigned int            end;
744        unsigned int            length;
745        unsigned int            offset;
746        unsigned short          segment;
747        char                    name[1];  /* terminated by '\0' */
748    } block_v3;
749
750    struct
751    {
752        short int               len;
753        short int               id;
754        unsigned int            offset;
755        unsigned short          segment;
756        unsigned char           flags;
757        struct p_string         p_name;
758    } label_v1;
759
760    struct
761    {
762        short int               len;
763        short int               id;
764        unsigned int            offset;
765        unsigned short          segment;
766        unsigned char           flags;
767        char                    name[1];  /* terminated by '\0' */
768    } label_v3;
769
770    struct
771    {
772        short int               len;
773        short int               id;
774        unsigned short          type;
775        unsigned short          cvalue;         /* numeric leaf */
776#if 0
777        struct p_string         p_name;
778#endif
779    } constant_v1;
780
781    struct
782    {
783        short int               len;
784        short int               id;
785        unsigned                type;
786        unsigned short          cvalue;         /* numeric leaf */
787#if 0
788        struct p_string         p_name;
789#endif
790    } constant_v2;
791
792    struct
793    {
794        short int               len;
795        short int               id;
796        unsigned                type;
797        unsigned short          cvalue;
798#if 0
799        char                    name[1];  /* terminated by '\0' */
800#endif
801    } constant_v3;
802
803    struct
804    {
805        short int               len;
806        short int               id;
807        unsigned short          type;
808        struct p_string         p_name;
809    } udt_v1;
810
811    struct
812    {
813        short int               len;
814        short int               id;
815        unsigned                type;
816        struct p_string         p_name;
817    } udt_v2;
818
819    struct
820    {
821        short int               len;
822        short int               id;
823        unsigned int            type;
824        char                    name[1];  /* terminated by '\0' */
825    } udt_v3;
826
827    struct
828    {
829        short int               len;
830        short int               id;
831        char                    signature[4];
832        struct p_string         p_name;
833    } objname_v1;
834
835    struct
836    {
837        short int               len;
838        short int               id;
839        unsigned int            unknown;
840        struct p_string         p_name;
841    } compiland_v1;
842
843    struct
844    {
845        short int               len;
846        short int               id;
847        unsigned                unknown1[4];
848        unsigned short          unknown2;
849        struct p_string         p_name;
850    } compiland_v2;
851
852    struct
853    {
854        short int               len;
855        short int               id;
856        unsigned int            unknown;
857        char                    name[1];  /* terminated by '\0' */
858    } compiland_v3;
859
860    struct
861    {
862        short int               len;
863        short int               id;
864        unsigned int            offset;
865        unsigned short          segment;
866    } ssearch_v1;
867};
868
869#define S_COMPILAND_V1  0x0001
870#define S_REGISTER_V1   0x0002
871#define S_CONSTANT_V1   0x0003
872#define S_UDT_V1        0x0004
873#define S_SSEARCH_V1    0x0005
874#define S_END_V1        0x0006
875#define S_SKIP_V1       0x0007
876#define S_CVRESERVE_V1  0x0008
877#define S_OBJNAME_V1    0x0009
878#define S_ENDARG_V1     0x000a
879#define S_COBOLUDT_V1   0x000b
880#define S_MANYREG_V1    0x000c
881#define S_RETURN_V1     0x000d
882#define S_ENTRYTHIS_V1  0x000e
883
884#define S_BPREL_V1      0x0200
885#define S_LDATA_V1      0x0201
886#define S_GDATA_V1      0x0202
887#define S_PUB_V1        0x0203
888#define S_LPROC_V1      0x0204
889#define S_GPROC_V1      0x0205
890#define S_THUNK_V1      0x0206
891#define S_BLOCK_V1      0x0207
892#define S_WITH_V1       0x0208
893#define S_LABEL_V1      0x0209
894#define S_CEXMODEL_V1   0x020a
895#define S_VFTPATH_V1    0x020b
896#define S_REGREL_V1     0x020c
897#define S_LTHREAD_V1    0x020d
898#define S_GTHREAD_V1    0x020e
899
900#define S_PROCREF_V1    0x0400
901#define S_DATAREF_V1    0x0401
902#define S_ALIGN_V1      0x0402
903#define S_LPROCREF_V1   0x0403
904
905#define S_REGISTER_V2   0x1001 /* Variants with new 32-bit type indices */
906#define S_CONSTANT_V2   0x1002
907#define S_UDT_V2        0x1003
908#define S_COBOLUDT_V2   0x1004
909#define S_MANYREG_V2    0x1005
910#define S_BPREL_V2      0x1006
911#define S_LDATA_V2      0x1007
912#define S_GDATA_V2      0x1008
913#define S_PUB_V2        0x1009
914#define S_LPROC_V2      0x100a
915#define S_GPROC_V2      0x100b
916#define S_VFTTABLE_V2   0x100c
917#define S_REGREL_V2     0x100d
918#define S_LTHREAD_V2    0x100e
919#define S_GTHREAD_V2    0x100f
920#if 0
921#define S_XXXXXXXXX_32  0x1012  /* seems linked to a function, content unknown */
922#endif
923#define S_COMPILAND_V2  0x1013
924
925#define S_COMPILAND_V3  0x1101
926#define S_THUNK_V3      0x1102
927#define S_BLOCK_V3      0x1103
928#define S_LABEL_V3      0x1105
929#define S_REGISTER_V3   0x1106
930#define S_CONSTANT_V3   0x1107
931#define S_UDT_V3        0x1108
932#define S_BPREL_V3      0x110B
933#define S_LDATA_V3      0x110C
934#define S_GDATA_V3      0x110D
935#define S_PUB_V3        0x110E
936#define S_LPROC_V3      0x110F
937#define S_GPROC_V3      0x1110
938#define S_BPREL_XXXX_V3 0x1111  /* not really understood, but looks like bprel... */
939#define S_MSTOOL_V3     0x1116  /* compiler command line options and build information */
940#define S_PUB_FUNC1_V3  0x1125  /* didn't get the difference between the two */
941#define S_PUB_FUNC2_V3  0x1127
942
943
944/*------------------------------------------------------------*/
945/*---                                                      ---*/
946/*--- pdb-reading: bits and pieces                         ---*/
947/*---                                                      ---*/
948/*------------------------------------------------------------*/
949
950struct pdb_reader
951{
952   void* (*read_file)(struct pdb_reader*, unsigned, unsigned *);
953   // JRS 2009-Apr-8: .uu_n_pdbimage is never used.
954   UChar* pdbimage;      // image address
955   SizeT  uu_n_pdbimage; // size
956   union {
957      struct {
958         struct PDB_JG_HEADER* header;
959         struct PDB_JG_TOC* toc;
960      } jg;
961      struct {
962         struct PDB_DS_HEADER* header;
963         struct PDB_DS_TOC* toc;
964      } ds;
965   } u;
966};
967
968
969static void* pdb_ds_read( struct pdb_reader* pdb,
970                          unsigned* block_list,
971                          unsigned  size )
972{
973   unsigned  blocksize, nBlocks;
974   UChar* buffer;
975   UInt i;
976
977   if (!size) return NULL;
978   if (size > 512 * 1024 * 1024) {
979      VG_(umsg)("Warning: pdb_ds_read: implausible size "
980                "(%u); skipping -- possible invalid .pdb file?\n", size);
981      return NULL;
982   }
983
984   blocksize = pdb->u.ds.header->block_size;
985   nBlocks   = (size + blocksize - 1) / blocksize;
986   buffer    = ML_(dinfo_zalloc)("di.readpe.pdr.1", nBlocks * blocksize);
987   for (i = 0; i < nBlocks; i++)
988      VG_(memcpy)( buffer + i * blocksize,
989                   pdb->pdbimage + block_list[i] * blocksize,
990                   blocksize );
991   return buffer;
992}
993
994
995static void* pdb_jg_read( struct pdb_reader* pdb,
996                          unsigned short* block_list,
997                          int size )
998{
999   unsigned  blocksize, nBlocks;
1000   UChar* buffer;
1001   UInt i;
1002   //VG_(printf)("pdb_read %p %p %d\n", pdb, block_list, size);
1003   if ( !size ) return NULL;
1004
1005   blocksize = pdb->u.jg.header->blocksize;
1006   nBlocks = (size + blocksize-1) / blocksize;
1007   buffer = ML_(dinfo_zalloc)("di.readpe.pjr.1", nBlocks * blocksize);
1008   for ( i = 0; i < nBlocks; i++ )
1009      VG_(memcpy)( buffer + i*blocksize,
1010                   pdb->pdbimage + block_list[i]*blocksize, blocksize );
1011   return buffer;
1012}
1013
1014
1015static void* find_pdb_header( void* pdbimage,
1016                              unsigned* signature )
1017{
1018   static const HChar pdbtxt[]= "Microsoft C/C++";
1019   HChar* txteof = VG_(strchr)(pdbimage, '\032');
1020   if (! txteof)
1021      return NULL;
1022   if (0!=VG_(strncmp)(pdbimage, pdbtxt, -1+ sizeof(pdbtxt)))
1023      return NULL;
1024
1025   *signature = *(unsigned*)(1+ txteof);
1026   HChar *img_addr = pdbimage;    // so we can do address arithmetic
1027   return ((~3& (3+ (4+ 1+ (txteof - img_addr)))) + img_addr);
1028}
1029
1030
1031static void* pdb_ds_read_file( struct pdb_reader* reader,
1032                               unsigned  file_number,
1033                               unsigned* plength )
1034{
1035   unsigned i, *block_list;
1036   if (!reader->u.ds.toc || file_number >= reader->u.ds.toc->num_files)
1037      return NULL;
1038   if (reader->u.ds.toc->file_size[file_number] == 0
1039       || reader->u.ds.toc->file_size[file_number] == 0xFFFFFFFF)
1040      return NULL;
1041
1042   block_list
1043      = reader->u.ds.toc->file_size + reader->u.ds.toc->num_files;
1044   for (i = 0; i < file_number; i++)
1045      block_list += (reader->u.ds.toc->file_size[i]
1046                     + reader->u.ds.header->block_size - 1)
1047                    /
1048                    reader->u.ds.header->block_size;
1049   if (plength)
1050      *plength = reader->u.ds.toc->file_size[file_number];
1051   return pdb_ds_read( reader, block_list,
1052                       reader->u.ds.toc->file_size[file_number]);
1053}
1054
1055
1056static void* pdb_jg_read_file( struct pdb_reader* pdb,
1057                               unsigned fileNr,
1058                               unsigned *plength )
1059{
1060   //VG_(printf)("pdb_read_file %p %d\n", pdb, fileNr);
1061   unsigned blocksize = pdb->u.jg.header->blocksize;
1062   struct PDB_JG_TOC* toc = pdb->u.jg.toc;
1063   unsigned i;
1064   unsigned short* block_list;
1065
1066   if ( !toc || fileNr >= toc->nFiles )
1067       return NULL;
1068
1069   block_list
1070      = (unsigned short *) &toc->file[ toc->nFiles ];
1071   for ( i = 0; i < fileNr; i++ )
1072      block_list += (toc->file[i].size + blocksize-1) / blocksize;
1073
1074   if (plength)
1075      *plength = toc->file[fileNr].size;
1076   return pdb_jg_read( pdb, block_list, toc->file[fileNr].size );
1077}
1078
1079
1080static void pdb_ds_init( struct pdb_reader * reader,
1081                         UChar* pdbimage,
1082                         SizeT  n_pdbimage )
1083{
1084   reader->read_file     = pdb_ds_read_file;
1085   reader->pdbimage      = pdbimage;
1086   reader->uu_n_pdbimage = n_pdbimage;
1087   reader->u.ds.toc
1088      = pdb_ds_read(
1089           reader,
1090           (unsigned*)(reader->u.ds.header->block_size
1091                       * reader->u.ds.header->toc_page
1092                       + reader->pdbimage),
1093           reader->u.ds.header->toc_size
1094        );
1095}
1096
1097
1098static void pdb_jg_init( struct pdb_reader* reader,
1099                         void* pdbimage,
1100                         unsigned n_pdbimage )
1101{
1102   reader->read_file     = pdb_jg_read_file;
1103   reader->pdbimage      = pdbimage;
1104   reader->uu_n_pdbimage = n_pdbimage;
1105   reader->u.jg.toc = pdb_jg_read(reader,
1106                                  reader->u.jg.header->toc_block,
1107                                  reader->u.jg.header->toc.size);
1108}
1109
1110
1111
1112
1113static
1114void pdb_check_root_version_and_timestamp( HChar* pdbname,
1115                                           ULong  pdbmtime,
1116                                           unsigned  version,
1117                                           UInt TimeDateStamp )
1118{
1119   switch ( version ) {
1120      case 19950623:      /* VC 4.0 */
1121      case 19950814:
1122      case 19960307:      /* VC 5.0 */
1123      case 19970604:      /* VC 6.0 */
1124      case 20000404:      /* VC 7.0  FIXME?? */
1125         break;
1126      default:
1127         if (VG_(clo_verbosity) > 1)
1128            VG_(message)(Vg_UserMsg,
1129                         "Unknown .pdb root block version %d\n", version );
1130   }
1131   if ( TimeDateStamp != pdbmtime ) {
1132      if (VG_(clo_verbosity) > 1)
1133         VG_(message)(Vg_UserMsg,
1134                     "Wrong time stamp of .PDB file %s (0x%08x, 0x%08llx)\n",
1135                      pdbname, TimeDateStamp, pdbmtime );
1136   }
1137}
1138
1139
1140static DWORD pdb_get_file_size( struct pdb_reader* reader, unsigned idx )
1141{
1142   if (reader->read_file == pdb_jg_read_file)
1143      return reader->u.jg.toc->file[idx].size;
1144   else
1145      return reader->u.ds.toc->file_size[idx];
1146}
1147
1148
1149static void pdb_convert_types_header( PDB_TYPES *types, char* image )
1150{
1151   VG_(memset)( types, 0, sizeof(PDB_TYPES) );
1152   if ( !image )
1153      return;
1154   if ( *(unsigned long *)image < 19960000 ) {  /* FIXME: correct version? */
1155      /* Old version of the types record header */
1156      PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
1157      types->version     = old->version;
1158      types->type_offset = sizeof(PDB_TYPES_OLD);
1159      types->type_size   = old->type_size;
1160      types->first_index = old->first_index;
1161      types->last_index  = old->last_index;
1162      types->file        = old->file;
1163   } else {
1164      /* New version of the types record header */
1165      *types = *(PDB_TYPES *)image;
1166   }
1167}
1168
1169
1170static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
1171                                        int *header_size, char* image )
1172{
1173   VG_(memset)( symbols, 0, sizeof(PDB_SYMBOLS) );
1174   if ( !image )
1175      return;
1176   if ( *(unsigned long *)image != 0xffffffff ) {
1177      /* Old version of the symbols record header */
1178      PDB_SYMBOLS_OLD *old     = (PDB_SYMBOLS_OLD *)image;
1179      symbols->version         = 0;
1180      symbols->module_size     = old->module_size;
1181      symbols->offset_size     = old->offset_size;
1182      symbols->hash_size       = old->hash_size;
1183      symbols->srcmodule_size  = old->srcmodule_size;
1184      symbols->pdbimport_size  = 0;
1185      symbols->hash1_file      = old->hash1_file;
1186      symbols->hash2_file      = old->hash2_file;
1187      symbols->gsym_file       = old->gsym_file;
1188      *header_size = sizeof(PDB_SYMBOLS_OLD);
1189   } else {
1190      /* New version of the symbols record header */
1191      *symbols = *(PDB_SYMBOLS *)image;
1192      *header_size = sizeof(PDB_SYMBOLS);
1193   }
1194}
1195
1196
1197/*------------------------------------------------------------*/
1198/*---                                                      ---*/
1199/*--- Main stuff: reading of symbol addresses              ---*/
1200/*---                                                      ---*/
1201/*------------------------------------------------------------*/
1202
1203static ULong DEBUG_SnarfCodeView(
1204                DebugInfo* di,
1205                PtrdiffT bias,
1206                IMAGE_SECTION_HEADER* sectp,
1207                void* root, /* FIXME: better name */
1208                Int offset,
1209                Int size
1210             )
1211{
1212   Int    i, length;
1213   DiSym  vsym;
1214   HChar* nmstr;
1215   HChar  symname[4096 /*WIN32_PATH_MAX*/];
1216
1217   Bool  debug = di->trace_symtab;
1218   ULong n_syms_read = 0;
1219
1220   if (debug)
1221      VG_(message)(Vg_UserMsg,
1222                   "BEGIN SnarfCodeView addr=%p offset=%d length=%d\n",
1223                   root, offset, size );
1224
1225   VG_(memset)(&vsym, 0, sizeof(vsym));  /* avoid holes */
1226   /*
1227    * Loop over the different types of records and whenever we
1228    * find something we are interested in, record it and move on.
1229    */
1230   for ( i = offset; i < size; i += length )
1231   {
1232      union codeview_symbol *sym = (union codeview_symbol *)((char *)root + i);
1233
1234      length = sym->generic.len + 2;
1235
1236      //VG_(printf)("id=%x  len=%d\n", sym->generic.id, length);
1237      switch ( sym->generic.id ) {
1238
1239      default:
1240         if (0) {
1241            VG_(printf)("unknown id 0x%x len=0x%x at %p\n",
1242                        sym->generic.id, sym->generic.len, sym);
1243            VG_(printf)("  %8x  %8x  %8x  %8x\n",
1244                        ((int *)sym)[1],((int *)sym)[2],
1245                        ((int *)sym)[3],((int *)sym)[4]);
1246            VG_(printf)("  %8x  %8x  %8x  %8x\n",
1247                        ((int *)sym)[5],((int *)sym)[6],
1248                        ((int *)sym)[7],((int *)sym)[8]);
1249         }
1250         break;
1251      /*
1252       * Global and local data symbols.  We don't associate these
1253       * with any given source file.
1254       */
1255      case S_GDATA_V1:
1256      case S_LDATA_V1:
1257      case S_PUB_V1:
1258         VG_(memcpy)(symname, sym->data_v1.p_name.name,
1259                              sym->data_v1.p_name.namelen);
1260         symname[sym->data_v1.p_name.namelen] = '\0';
1261
1262         if (debug)
1263            VG_(message)(Vg_UserMsg, "  Data %s\n", symname );
1264
1265         if (0 /*VG_(needs).data_syms*/) {
1266            nmstr = ML_(addStr)(di, symname, sym->data_v1.p_name.namelen);
1267            vsym.addr      = bias + sectp[sym->data_v1.segment-1].VirtualAddress
1268                                 + sym->data_v1.offset;
1269            vsym.tocptr    = 0;
1270            vsym.pri_name  = nmstr;
1271            vsym.sec_names = NULL;
1272            vsym.size      = sym->data_v1.p_name.namelen;
1273                             // FIXME: .namelen is sizeof(.data) including .name[]
1274            vsym.isText    = (sym->generic.id == S_PUB_V1);
1275            vsym.isIFunc   = False;
1276            ML_(addSym)( di, &vsym );
1277            n_syms_read++;
1278         }
1279         break;
1280      case S_GDATA_V2:
1281      case S_LDATA_V2:
1282      case S_PUB_V2: {
1283         Int const k = sym->data_v2.p_name.namelen;
1284         VG_(memcpy)(symname, sym->data_v2.p_name.name, k);
1285         symname[k] = '\0';
1286
1287         if (debug)
1288            VG_(message)(Vg_UserMsg,
1289                         "  S_GDATA_V2/S_LDATA_V2/S_PUB_V2 %s\n", symname );
1290
1291         if (sym->generic.id==S_PUB_V2 /*VG_(needs).data_syms*/) {
1292            nmstr = ML_(addStr)(di, symname, k);
1293            vsym.addr      = bias + sectp[sym->data_v2.segment-1].VirtualAddress
1294                                  + sym->data_v2.offset;
1295            vsym.tocptr    = 0;
1296            vsym.pri_name  = nmstr;
1297            vsym.sec_names = NULL;
1298            vsym.size      = 4000;
1299                             // FIXME: data_v2.len is sizeof(.data),
1300                             // not size of function!
1301            vsym.isText    = !!(IMAGE_SCN_CNT_CODE
1302                                & sectp[sym->data_v2.segment-1].Characteristics);
1303            vsym.isIFunc   = False;
1304            ML_(addSym)( di, &vsym );
1305            n_syms_read++;
1306         }
1307         break;
1308      }
1309      case S_PUB_V3:
1310      /* not completely sure of those two anyway */
1311      case S_PUB_FUNC1_V3:
1312      case S_PUB_FUNC2_V3: {
1313         Int k = sym->public_v3.len - (-1+ sizeof(sym->public_v3));
1314         if ((-1+ sizeof(symname)) < k)
1315            k = -1+ sizeof(symname);
1316         VG_(memcpy)(symname, sym->public_v3.name, k);
1317         symname[k] = '\0';
1318
1319         if (debug)
1320            VG_(message)(Vg_UserMsg,
1321                         "  S_PUB_FUNC1_V3/S_PUB_FUNC2_V3/S_PUB_V3 %s\n",
1322                         symname );
1323
1324         if (1  /*sym->generic.id==S_PUB_FUNC1_V3
1325                  || sym->generic.id==S_PUB_FUNC2_V3*/) {
1326            nmstr = ML_(addStr)(di, symname, k);
1327            vsym.addr      = bias + sectp[sym->public_v3.segment-1].VirtualAddress
1328                                  + sym->public_v3.offset;
1329            vsym.tocptr    = 0;
1330            vsym.pri_name  = nmstr;
1331            vsym.sec_names = NULL;
1332            vsym.size      = 4000;
1333                             // FIXME: public_v3.len is not length of the
1334                             // .text of the function
1335            vsym.isText    = !!(IMAGE_SCN_CNT_CODE
1336                                & sectp[sym->data_v2.segment-1].Characteristics);
1337            vsym.isIFunc   = False;
1338            ML_(addSym)( di, &vsym );
1339            n_syms_read++;
1340         }
1341         break;
1342      }
1343
1344      /*
1345       * Sort of like a global function, but it just points
1346       * to a thunk, which is a stupid name for what amounts to
1347       * a PLT slot in the normal jargon that everyone else uses.
1348       */
1349      case S_THUNK_V3:
1350      case S_THUNK_V1:
1351         /* valgrind ignores PLTs */ /* JRS: it does? */
1352         break;
1353
1354      /*
1355       * Global and static functions.
1356       */
1357      case S_GPROC_V1:
1358      case S_LPROC_V1:
1359         VG_(memcpy)(symname, sym->proc_v1.p_name.name,
1360                              sym->proc_v1.p_name.namelen);
1361         symname[sym->proc_v1.p_name.namelen] = '\0';
1362         nmstr = ML_(addStr)(di, symname, sym->proc_v1.p_name.namelen);
1363         vsym.addr      = bias + sectp[sym->proc_v1.segment-1].VirtualAddress
1364                               + sym->proc_v1.offset;
1365         vsym.tocptr    = 0;
1366         vsym.pri_name  = nmstr;
1367         vsym.sec_names = NULL;
1368         vsym.size      = sym->proc_v1.proc_len;
1369         vsym.isText    = True;
1370         vsym.isIFunc   = False;
1371         if (debug)
1372             VG_(message)(Vg_UserMsg,
1373                         "  Adding function %s addr=%#lx length=%d\n",
1374                         symname, vsym.addr, vsym.size );
1375         ML_(addSym)( di, &vsym );
1376         n_syms_read++;
1377         break;
1378
1379      case S_GPROC_V2:
1380      case S_LPROC_V2:
1381         VG_(memcpy)(symname, sym->proc_v2.p_name.name,
1382                              sym->proc_v2.p_name.namelen);
1383         symname[sym->proc_v2.p_name.namelen] = '\0';
1384         nmstr = ML_(addStr)(di, symname, sym->proc_v2.p_name.namelen);
1385         vsym.addr      = bias + sectp[sym->proc_v2.segment-1].VirtualAddress
1386                               + sym->proc_v2.offset;
1387         vsym.tocptr    = 0;
1388         vsym.pri_name  = nmstr;
1389         vsym.sec_names = NULL;
1390         vsym.size      = sym->proc_v2.proc_len;
1391         vsym.isText    = True;
1392         vsym.isIFunc   = False;
1393         if (debug)
1394            VG_(message)(Vg_UserMsg,
1395                         "  Adding function %s addr=%#lx length=%d\n",
1396                         symname, vsym.addr, vsym.size );
1397         ML_(addSym)( di, &vsym );
1398         n_syms_read++;
1399         break;
1400      case S_LPROC_V3:
1401      case S_GPROC_V3: {
1402         if (debug)
1403            VG_(message)(Vg_UserMsg,
1404                         "  S_LPROC_V3/S_GPROC_V3 %s\n", sym->proc_v3.name );
1405
1406         if (1) {
1407            nmstr = ML_(addStr)(di, sym->proc_v3.name,
1408                                    VG_(strlen)(sym->proc_v3.name));
1409            vsym.addr      = bias + sectp[sym->proc_v3.segment-1].VirtualAddress
1410                                  + sym->proc_v3.offset;
1411            vsym.tocptr    = 0;
1412            vsym.pri_name  = nmstr;
1413            vsym.sec_names = NULL;
1414            vsym.size      = sym->proc_v3.proc_len;
1415            vsym.isText    = 1;
1416            vsym.isIFunc   = False;
1417            ML_(addSym)( di, &vsym );
1418            n_syms_read++;
1419         }
1420         break;
1421      }
1422      /* JRS: how is flow supposed to arrive at commented out code below? */
1423      //if (nest_block)
1424      //{
1425      //   printf(">>> prev func '%s' still has nest_block %u count\n",
1426      //          curr_func, nest_block);
1427      //   nest_block = 0;
1428      //}
1429      //curr_func = strdup(sym->proc_v3.name);
1430      /* EPP  unsigned int    pparent; */
1431      /* EPP  unsigned int    pend; */
1432      /* EPP  unsigned int    next; */
1433      /* EPP  unsigned int    debug_start; */
1434      /* EPP  unsigned int    debug_end; */
1435      /* EPP  unsigned char   flags; */
1436      // break;
1437
1438
1439      /*
1440       * Function parameters and stack variables.
1441       */
1442      case S_BPREL_XXXX_V3:
1443      case S_BPREL_V3:
1444      case S_BPREL_V2:
1445      case S_BPREL_V1:
1446         /* ignored */
1447         break;
1448
1449      case S_LABEL_V3:  // FIXME
1450      case S_LABEL_V1:
1451         break;
1452
1453      case S_SSEARCH_V1:
1454      case S_ALIGN_V1:
1455      case S_MSTOOL_V3:
1456      case S_UDT_V3:
1457      case S_UDT_V2:
1458      case S_UDT_V1:
1459      case S_CONSTANT_V3:
1460      case S_CONSTANT_V1:
1461      case S_OBJNAME_V1:
1462      case S_END_V1:
1463      case S_COMPILAND_V3:
1464      case S_COMPILAND_V2:
1465      case S_COMPILAND_V1:
1466      case S_BLOCK_V3:
1467      case S_BLOCK_V1:
1468      case S_REGISTER_V3:
1469      case S_REGISTER_V2:
1470      case S_REGISTER_V1:
1471         /* ignored */
1472         break;
1473
1474      /*
1475       * These are special, in that they are always followed by an
1476       * additional length-prefixed string which is *not* included
1477       * into the symbol length count.  We need to skip it.
1478       */
1479      case S_PROCREF_V1:
1480      case S_DATAREF_V1:
1481      case S_LPROCREF_V1: {
1482         unsigned char *name = (unsigned char *)sym + length;
1483         length += (*name + 1 + 3) & ~3;
1484         break;
1485      }
1486      } /* switch ( sym->generic.id ) */
1487
1488   } /* for ( i = offset; i < size; i += length ) */
1489
1490   if (debug)
1491      VG_(message)(Vg_UserMsg,
1492                   "END SnarfCodeView addr=%p offset=%d length=%d\n",
1493                   root, offset, size );
1494   return n_syms_read;
1495}
1496
1497
1498/*------------------------------------------------------------*/
1499/*---                                                      ---*/
1500/*--- Main stuff: reading of line number tables            ---*/
1501/*---                                                      ---*/
1502/*------------------------------------------------------------*/
1503
1504union any_size
1505{
1506          char const *c;
1507         short const *s;
1508           int const *i;
1509  unsigned int const *ui;
1510};
1511
1512struct startend
1513{
1514  unsigned int          start;
1515  unsigned int          end;
1516};
1517
1518static ULong DEBUG_SnarfLinetab(
1519          DebugInfo* di,
1520          PtrdiffT bias,
1521          IMAGE_SECTION_HEADER* sectp,
1522          void* linetab,
1523          Int size
1524       )
1525{
1526   //VG_(printf)("DEBUG_SnarfLinetab %p %p %p %d\n", di, sectp, linetab, size);
1527   Int                file_segcount;
1528   HChar              filename[WIN32_PATH_MAX];
1529   const UInt         * filetab;
1530   const UChar        * fn;
1531   Int                i;
1532   Int                k;
1533   const UInt         * lt_ptr;
1534   Int                nfile;
1535   Int                nseg;
1536   union any_size     pnt;
1537   union any_size     pnt2;
1538   const struct startend * start;
1539   Int                this_seg;
1540
1541   Bool  debug = di->trace_symtab;
1542   ULong n_lines_read = 0;
1543
1544   if (debug)
1545      VG_(message)(Vg_UserMsg,
1546                   "BEGIN SnarfLineTab linetab=%p size=%d\n",
1547                   linetab, size );
1548
1549   /*
1550    * Now get the important bits.
1551    */
1552   pnt.c = linetab;
1553   nfile = *pnt.s++;
1554   nseg  = *pnt.s++;
1555
1556   filetab = pnt.ui;
1557
1558   /*
1559    * Now count up the number of segments in the file.
1560    */
1561   nseg = 0;
1562   for (i = 0; i < nfile; i++) {
1563      pnt2.c = (HChar *)linetab + filetab[i];
1564      nseg += *pnt2.s;
1565   }
1566
1567   this_seg = 0;
1568   for (i = 0; i < nfile; i++) {
1569      HChar *fnmstr;
1570      HChar *dirstr;
1571
1572      /*
1573       * Get the pointer into the segment information.
1574       */
1575      pnt2.c = (HChar *)linetab + filetab[i];
1576      file_segcount = *pnt2.s;
1577
1578      pnt2.ui++;
1579      lt_ptr = pnt2.ui;
1580      start = (const struct startend *) (lt_ptr + file_segcount);
1581
1582      /*
1583       * Now snarf the filename for all of the segments for this file.
1584       */
1585      fn = (const UChar*) (start + file_segcount);
1586      /* fn now points at a Pascal-style string, that is, the first
1587         byte is the length, and the remaining up to 255 (presumably)
1588         are the contents. */
1589      vg_assert(WIN32_PATH_MAX >= 256);
1590      VG_(memset)(filename, 0, sizeof(filename));
1591      VG_(memcpy)(filename, fn + 1, *fn);
1592      vg_assert(filename[ sizeof(filename)-1 ] == 0);
1593      filename[(Int)*fn] = 0;
1594      fnmstr = VG_(strrchr)(filename, '\\');
1595      if (fnmstr == NULL)
1596         fnmstr = filename;
1597      else
1598         ++fnmstr;
1599      k = VG_(strlen)(fnmstr);
1600      dirstr = ML_(addStr)(di, filename, *fn - k);
1601      fnmstr = ML_(addStr)(di, fnmstr, k);
1602
1603      for (k = 0; k < file_segcount; k++, this_seg++) {
1604         Int linecount;
1605         Int segno;
1606
1607         pnt2.c = (HChar *)linetab + lt_ptr[k];
1608
1609         segno = *pnt2.s++;
1610         linecount = *pnt2.s++;
1611
1612         if ( linecount > 0 ) {
1613            UInt j;
1614
1615            if (debug)
1616               VG_(message)(Vg_UserMsg,
1617                  "  Adding %d lines for file %s segment %d addr=%#x end=%#x\n",
1618                  linecount, filename, segno, start[k].start, start[k].end );
1619
1620            for ( j = 0; j < linecount; j++ ) {
1621               Addr startaddr = bias + sectp[segno-1].VirtualAddress
1622                                     + pnt2.ui[j];
1623               Addr endaddr   = bias + sectp[segno-1].VirtualAddress
1624                                     + ((j < (linecount - 1))
1625                                           ? pnt2.ui[j+1]
1626                                           : start[k].end);
1627               if (debug)
1628                  VG_(message)(Vg_UserMsg,
1629                     "  Adding line %d addr=%#lx end=%#lx\n",
1630                        ((const unsigned short *)(pnt2.ui + linecount))[j],
1631                        startaddr, endaddr );
1632                  ML_(addLineInfo)(
1633                     di, fnmstr, dirstr, startaddr, endaddr,
1634                     ((const unsigned short *)(pnt2.ui + linecount))[j], j );
1635                  n_lines_read++;
1636               }
1637            }
1638        }
1639    }
1640
1641   if (debug)
1642      VG_(message)(Vg_UserMsg,
1643                   "END SnarfLineTab linetab=%p size=%d\n",
1644                   linetab, size );
1645
1646    return n_lines_read;
1647}
1648
1649
1650
1651/* there's a new line tab structure from MS Studio 2005 and after
1652 * it's made of:
1653 * DWORD        000000f4
1654 * DWORD        lineblk_offset (counting bytes after this field)
1655 * an array of codeview_linetab2_file structures
1656 * an array (starting at <lineblk_offset>) of codeview_linetab2_block structures
1657 */
1658
1659struct codeview_linetab2_file
1660{
1661    DWORD       offset;         /* offset in string table for filename */
1662    WORD        unk;            /* always 0x0110... type of following
1663                                   information ??? */
1664    BYTE        md5[16];        /* MD5 signature of file (signature on
1665                                   file's content or name ???) */
1666    WORD        pad0;           /* always 0 */
1667};
1668
1669struct codeview_linetab2_block
1670{
1671    DWORD       header;         /* 0x000000f2 */
1672    DWORD       size_of_block;  /* next block is at # bytes after this field */
1673    DWORD       start;          /* start address of function with line numbers */
1674    DWORD       seg;            /* segment of function with line numbers */
1675    DWORD       size;           /* size of function with line numbers */
1676    DWORD       file_offset;    /* offset for accessing corresponding
1677                                   codeview_linetab2_file */
1678    DWORD       nlines;         /* number of lines in this block */
1679    DWORD       size_lines;     /* number of bytes following for line
1680                                   number information */
1681    struct {
1682        DWORD   offset;         /* offset (from <seg>:<start>) for line number */
1683        DWORD   lineno;         /* the line number (OR:ed with
1684                                   0x80000000 why ???) */
1685    } l[1];                     /* actually array of <nlines> */
1686};
1687
1688static ULong codeview_dump_linetab2(
1689                DebugInfo* di,
1690                Addr bias,
1691                IMAGE_SECTION_HEADER* sectp,
1692                HChar* linetab,
1693                DWORD size,
1694                HChar* strimage,
1695                DWORD strsize,
1696                const HChar* pfx
1697             )
1698{
1699   DWORD       offset;
1700   unsigned    i;
1701   struct codeview_linetab2_block* lbh;
1702   struct codeview_linetab2_file* fd;
1703
1704   Bool  debug = di->trace_symtab;
1705   ULong n_line2s_read = 0;
1706
1707   if (*(const DWORD*)linetab != 0x000000f4)
1708      return 0;
1709   offset = *((DWORD*)linetab + 1);
1710   lbh = (struct codeview_linetab2_block*)(linetab + 8 + offset);
1711
1712   while ((HChar*)lbh < linetab + size) {
1713
1714      HChar *filename, *dirname;
1715      Addr svma_s, svma_e;
1716      if (lbh->header != 0x000000f2) {
1717         /* FIXME: should also check that whole lbh fits in linetab + size */
1718         if (debug)
1719            VG_(printf)("%sblock end %x\n", pfx, lbh->header);
1720         break;
1721      }
1722      if (debug)
1723         VG_(printf)("%sblock from %04x:%08x-%08x (size %u) (%u lines)\n",
1724                     pfx, lbh->seg, lbh->start, lbh->start + lbh->size - 1,
1725                     lbh->size, lbh->nlines);
1726      fd = (struct codeview_linetab2_file*)(linetab + 8 + lbh->file_offset);
1727      if (debug)
1728         VG_(printf)(
1729            "%s  md5=%02x%02x%02x%02x%02x%02x%02x%02x"
1730                    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
1731             pfx, fd->md5[ 0], fd->md5[ 1], fd->md5[ 2], fd->md5[ 3],
1732                  fd->md5[ 4], fd->md5[ 5], fd->md5[ 6], fd->md5[ 7],
1733                  fd->md5[ 8], fd->md5[ 9], fd->md5[10], fd->md5[11],
1734                  fd->md5[12], fd->md5[13], fd->md5[14], fd->md5[15] );
1735      /* FIXME: should check that string is within strimage + strsize */
1736      if (strimage) {
1737         dirname  = strimage + fd->offset;
1738         filename = VG_(strrchr)(dirname, '\\');
1739         if (filename == NULL) {
1740            filename = ML_(addStr)(di, dirname, -1);
1741            dirname  = NULL;
1742         } else {
1743            dirname  = ML_(addStr)(di, dirname, VG_(strlen)(dirname)
1744                                                - VG_(strlen)(filename));
1745            filename = ML_(addStr)(di, filename+1, -1);
1746         }
1747      } else {
1748         filename = ML_(addStr)(di, "???", -1);
1749         dirname  = NULL;
1750      }
1751
1752      if (debug)
1753         VG_(printf)("%s  file=%s\n", pfx, filename);
1754
1755      for (i = 0; i < lbh->nlines; i++) {
1756         if (debug)
1757            VG_(printf)("%s  offset=%08x line=%d\n",
1758                        pfx, lbh->l[i].offset, lbh->l[i].lineno ^ 0x80000000);
1759      }
1760
1761      if (lbh->nlines > 1) {
1762         for (i = 0; i < lbh->nlines-1; i++) {
1763            svma_s = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1764                     + lbh->l[i].offset;
1765            svma_e = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1766                     + lbh->l[i+1].offset-1;
1767            if (debug)
1768               VG_(printf)("%s  line %d: %08lx to %08lx\n",
1769                           pfx, lbh->l[i].lineno ^ 0x80000000, svma_s, svma_e);
1770            ML_(addLineInfo)( di, filename, dirname,
1771                              bias + svma_s,
1772                              bias + svma_e + 1,
1773                              lbh->l[i].lineno ^ 0x80000000, 0 );
1774            n_line2s_read++;
1775         }
1776         svma_s = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1777                  + lbh->l[ lbh->nlines-1].offset;
1778         svma_e = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1779                  + lbh->size - 1;
1780         if (debug)
1781            VG_(printf)("%s  line %d: %08lx to %08lx\n",
1782                        pfx, lbh->l[ lbh->nlines-1  ].lineno ^ 0x80000000,
1783                        svma_s, svma_e);
1784          ML_(addLineInfo)( di, filename, dirname,
1785                            bias + svma_s,
1786                            bias + svma_e + 1,
1787                            lbh->l[lbh->nlines-1].lineno ^ 0x80000000, 0 );
1788          n_line2s_read++;
1789       }
1790
1791       lbh = (struct codeview_linetab2_block*)
1792                ((char*)lbh + 8 + lbh->size_of_block);
1793    }
1794    return n_line2s_read;
1795}
1796
1797
1798/*------------------------------------------------------------*/
1799/*---                                                      ---*/
1800/*--- Main stuff: pdb_dump                                 ---*/
1801/*---                                                      ---*/
1802/*------------------------------------------------------------*/
1803
1804static Int cmp_FPO_DATA_for_canonicalisation ( const void* f1V,
1805                                               const void* f2V )
1806{
1807   /* Cause FPO data to be sorted first in ascending order of range
1808      starts, and for entries with the same range start, with the
1809      shorter range (length) first. */
1810   const FPO_DATA* f1 = f1V;
1811   const FPO_DATA* f2 = f2V;
1812   if (f1->ulOffStart < f2->ulOffStart) return -1;
1813   if (f1->ulOffStart > f2->ulOffStart) return  1;
1814   if (f1->cbProcSize < f2->cbProcSize) return -1;
1815   if (f1->cbProcSize > f2->cbProcSize) return  1;
1816   return 0; /* identical in both start and length */
1817}
1818
1819
1820/* JRS fixme: compare with version in current Wine sources */
1821static void pdb_dump( struct pdb_reader* pdb,
1822                      DebugInfo* di,
1823                      Addr       pe_avma,
1824                      PtrdiffT   pe_bias,
1825                      IMAGE_SECTION_HEADER* sectp_avma )
1826{
1827   Int header_size;
1828
1829   PDB_TYPES types;
1830   PDB_SYMBOLS symbols;
1831   unsigned len_modimage;
1832   char *modimage;
1833   char *file;
1834
1835   Bool debug = di->trace_symtab;
1836
1837   ULong n_fpos_read = 0, n_syms_read = 0,
1838         n_lines_read = 0, n_line2s_read = 0;
1839
1840   // FIXME: symbols for bare indices 1,2,3,5 in .pdb file
1841
1842   char* types_image   = pdb->read_file( pdb, 2, 0 );
1843   char* symbols_image = pdb->read_file( pdb, 3, 0 );
1844
1845   /* establish filesimage and filessize.  These are only needed for
1846      reading linetab2 tables, as far as I can deduce from the Wine
1847      sources. */
1848   char* filesimage = pdb->read_file( pdb, 12, 0);   /* FIXME: really fixed ??? */
1849   UInt  filessize  = 0;
1850   if (filesimage) {
1851      if (*(const DWORD*)filesimage == 0xeffeeffe) {
1852         filessize = *(const DWORD*)(filesimage + 8);
1853      } else {
1854         if (0)
1855            VG_(printf)("wrong header %x expecting 0xeffeeffe\n",
1856                        *(const DWORD*)filesimage);
1857         ML_(dinfo_free)( (void*)filesimage);
1858         filesimage = NULL;
1859      }
1860   }
1861
1862   /* Since we just use the FPO data without reformatting, at least
1863      do a basic sanity check on the struct layout. */
1864   vg_assert(sizeof(FPO_DATA) == 16);
1865   if (di->text_present) {
1866      /* only load FPO if there's text present (otherwise it's
1867         meaningless?) */
1868      unsigned sz = 0;
1869      di->fpo = pdb->read_file( pdb, 5, &sz );
1870
1871      // FIXME: seems like the size can be a non-integral number
1872      // of FPO_DATAs.  Force-align it (moronically).  Perhaps this
1873      // signifies that we're not looking at a valid FPO table ..
1874      // who knows.  Needs investigation.
1875      while (sz > 0 && (sz % sizeof(FPO_DATA)) != 0)
1876         sz--;
1877
1878      di->fpo_size = sz;
1879      if (0) VG_(printf)("FPO: got fpo_size %lu\n", (UWord)sz);
1880      vg_assert(0 == (di->fpo_size % sizeof(FPO_DATA)));
1881      di->fpo_base_avma = pe_avma;
1882   } else {
1883      vg_assert(di->fpo == NULL);
1884      vg_assert(di->fpo_size == 0);
1885   }
1886
1887   // BEGIN clean up FPO data
1888   if (di->fpo && di->fpo_size > 0) {
1889      Word i, j;
1890      Bool anyChanges;
1891      Int itersAvail = 10;
1892
1893      vg_assert(sizeof(di->fpo[0]) == 16);
1894      di->fpo_size /= sizeof(di->fpo[0]);
1895
1896      // BEGIN FPO-data tidying-up loop
1897      do {
1898
1899         vg_assert(itersAvail >= 0); /* safety check -- don't loop forever */
1900         itersAvail--;
1901
1902         anyChanges = False;
1903
1904         /* First get them in ascending order of start point */
1905         VG_(ssort)( di->fpo, (SizeT)di->fpo_size, (SizeT)sizeof(FPO_DATA),
1906                              cmp_FPO_DATA_for_canonicalisation );
1907         /* Get rid of any zero length entries */
1908         j = 0;
1909         for (i = 0; i < di->fpo_size; i++) {
1910            if (di->fpo[i].cbProcSize == 0) {
1911               anyChanges = True;
1912               continue;
1913            }
1914            di->fpo[j++] = di->fpo[i];
1915         }
1916         vg_assert(j >= 0 && j <= di->fpo_size);
1917         di->fpo_size = j;
1918
1919         /* Get rid of any dups */
1920         if (di->fpo_size > 1) {
1921            j = 1;
1922            for (i = 1; i < di->fpo_size; i++) {
1923               Bool dup
1924                  = di->fpo[j-1].ulOffStart == di->fpo[i].ulOffStart
1925                    && di->fpo[j-1].cbProcSize == di->fpo[i].cbProcSize;
1926               if (dup) {
1927                 anyChanges = True;
1928                 continue;
1929               }
1930               di->fpo[j++] = di->fpo[i];
1931            }
1932            vg_assert(j >= 0 && j <= di->fpo_size);
1933            di->fpo_size = j;
1934         }
1935
1936         /* Truncate any overlapping ranges */
1937         for (i = 1; i < di->fpo_size; i++) {
1938            vg_assert(di->fpo[i-1].ulOffStart <= di->fpo[i].ulOffStart);
1939            if (di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
1940                > di->fpo[i].ulOffStart) {
1941               anyChanges = True;
1942               di->fpo[i-1].cbProcSize
1943                  = di->fpo[i].ulOffStart - di->fpo[i-1].ulOffStart;
1944            }
1945         }
1946
1947      } while (anyChanges);
1948      // END FPO-data tidying-up loop
1949
1950      /* Should now be in ascending order, non overlapping, no zero ranges.
1951         Check this, get the min and max avmas, and bias the entries. */
1952      for (i = 0; i < di->fpo_size; i++) {
1953         vg_assert(di->fpo[i].cbProcSize > 0);
1954
1955         if (i > 0) {
1956            vg_assert(di->fpo[i-1].ulOffStart < di->fpo[i].ulOffStart);
1957            vg_assert(di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
1958                      <= di->fpo[i].ulOffStart);
1959         }
1960      }
1961
1962      /* Now bias the table.  This can't be done in the same pass as
1963         the sanity check, hence a second loop. */
1964      for (i = 0; i < di->fpo_size; i++) {
1965         di->fpo[i].ulOffStart += pe_avma;
1966         // make sure the biasing didn't royally screw up, by wrapping
1967         // the range around the end of the address space
1968         vg_assert(0xFFFFFFFF - di->fpo[i].ulOffStart /* "remaining space" */
1969                   >= di->fpo[i].cbProcSize);
1970      }
1971
1972      /* Dump any entries which point outside the text segment and
1973         compute the min/max avma "hint" addresses. */
1974      Addr min_avma = ~(Addr)0;
1975      Addr max_avma = (Addr)0;
1976      vg_assert(di->text_present);
1977      j = 0;
1978      for (i = 0; i < di->fpo_size; i++) {
1979         if ((Addr)(di->fpo[i].ulOffStart) >= di->text_avma
1980             && (Addr)(di->fpo[i].ulOffStart + di->fpo[i].cbProcSize)
1981                <= di->text_avma + di->text_size) {
1982            /* Update min/max limits as we go along. */
1983            if (di->fpo[i].ulOffStart < min_avma)
1984               min_avma = di->fpo[i].ulOffStart;
1985            if (di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1 > max_avma)
1986               max_avma = di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1;
1987            /* Keep */
1988            di->fpo[j++] = di->fpo[i];
1989            if (0)
1990            VG_(printf)("FPO: keep text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
1991                        di->text_avma, di->text_avma + di->text_size,
1992                        (Addr)di->fpo[i].ulOffStart,
1993                        (Addr)di->fpo[i].ulOffStart
1994                        + (Addr)di->fpo[i].cbProcSize - 1);
1995         } else {
1996            if (0)
1997            VG_(printf)("FPO: SKIP text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
1998                        di->text_avma, di->text_avma + di->text_size,
1999                        (Addr)di->fpo[i].ulOffStart,
2000                        (Addr)di->fpo[i].ulOffStart
2001                        + (Addr)di->fpo[i].cbProcSize - 1);
2002            /* out of range; ignore */
2003         }
2004      }
2005      vg_assert(j >= 0 && j <= di->fpo_size);
2006      di->fpo_size = j;
2007
2008      /* And record min/max */
2009      /* biasing shouldn't cause wraparound (?!) */
2010      if (di->fpo_size > 0) {
2011         vg_assert(min_avma <= max_avma); /* should always hold */
2012         di->fpo_minavma = min_avma;
2013         di->fpo_maxavma = max_avma;
2014      } else {
2015         di->fpo_minavma = 0;
2016         di->fpo_maxavma = 0;
2017      }
2018
2019      if (0) {
2020         VG_(printf)("FPO: min/max avma %#lx %#lx\n",
2021                     di->fpo_minavma, di->fpo_maxavma);
2022      }
2023
2024      n_fpos_read += (ULong)di->fpo_size;
2025   }
2026   // END clean up FPO data
2027
2028   pdb_convert_types_header( &types, types_image );
2029   switch ( types.version ) {
2030      case 19950410:      /* VC 4.0 */
2031      case 19951122:
2032      case 19961031:      /* VC 5.0 / 6.0 */
2033      case 20040203:      /* VC 7.0  FIXME??  */
2034         break;
2035      default:
2036         if (VG_(clo_verbosity) > 1)
2037            VG_(message)(Vg_UserMsg,
2038                         "Unknown .pdb type info version %ld\n",
2039                         types.version );
2040   }
2041
2042   header_size = 0;
2043   pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2044   switch ( symbols.version ) {
2045      case 0:            /* VC 4.0 */
2046      case 19960307:     /* VC 5.0 */
2047      case 19970606:     /* VC 6.0 */
2048      case 19990903:     /* VC 7.0  FIXME?? */
2049         break;
2050      default:
2051         if (VG_(clo_verbosity) > 1)
2052            VG_(message)(Vg_UserMsg,
2053                         "Unknown .pdb symbol info version %ld\n",
2054                         symbols.version );
2055   }
2056
2057   /*
2058    * Read global symbol table
2059    */
2060   modimage = pdb->read_file( pdb, symbols.gsym_file, &len_modimage );
2061   if (modimage) {
2062      if (debug)
2063         VG_(umsg)("\n");
2064      if (VG_(clo_verbosity) > 1)
2065         VG_(message)(Vg_UserMsg, "Reading global symbols\n" );
2066      DEBUG_SnarfCodeView( di, pe_avma, sectp_avma, modimage, 0, len_modimage );
2067      ML_(dinfo_free)( (void*)modimage );
2068   }
2069
2070   /*
2071    * Read per-module symbol / linenumber tables
2072    */
2073   file = symbols_image + header_size;
2074   while ( file - symbols_image < header_size + symbols.module_size ) {
2075      int file_nr, /* file_index, */ symbol_size, lineno_size;
2076      char *file_name;
2077
2078      if ( symbols.version < 19970000 ) {
2079         PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
2080         file_nr     = sym_file->file;
2081         file_name   = sym_file->filename;
2082         /* file_index  = sym_file->range.index; */ /* UNUSED */
2083         symbol_size = sym_file->symbol_size;
2084         lineno_size = sym_file->lineno_size;
2085      } else {
2086         PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
2087         file_nr     = sym_file->file;
2088         file_name   = sym_file->filename;
2089         /* file_index  = sym_file->range.index; */ /* UNUSED */
2090         symbol_size = sym_file->symbol_size;
2091         lineno_size = sym_file->lineno_size;
2092      }
2093
2094      modimage = pdb->read_file( pdb, file_nr, 0 );
2095      if (modimage) {
2096         Int total_size;
2097         if (0) VG_(printf)("lineno_size %d symbol_size %d\n",
2098                            lineno_size, symbol_size );
2099
2100         total_size = pdb_get_file_size(pdb, file_nr);
2101
2102         if (symbol_size) {
2103            if (debug)
2104               VG_(umsg)("\n");
2105            if (VG_(clo_verbosity) > 1)
2106               VG_(message)(Vg_UserMsg, "Reading symbols for %s\n",
2107                                        file_name );
2108            n_syms_read
2109               += DEBUG_SnarfCodeView( di, pe_avma, sectp_avma, modimage,
2110                                           sizeof(unsigned long),
2111                                           symbol_size );
2112         }
2113
2114         if (lineno_size) {
2115            if (debug)
2116               VG_(umsg)("\n");
2117            if (VG_(clo_verbosity) > 1)
2118               VG_(message)(Vg_UserMsg, "Reading lines for %s\n", file_name );
2119            n_lines_read
2120               += DEBUG_SnarfLinetab( di, pe_avma, sectp_avma,
2121                                          modimage + symbol_size, lineno_size );
2122         }
2123
2124         /* anyway, lineno_size doesn't see to really be the size of
2125          * the line number information, and it's not clear yet when
2126          * to call for linetab2...
2127          */
2128         n_line2s_read
2129            += codeview_dump_linetab2(
2130                  di, pe_avma, sectp_avma,
2131                      (HChar*)modimage + symbol_size + lineno_size,
2132                      total_size - (symbol_size + lineno_size),
2133                  /* if filesimage is NULL, pass that directly onwards
2134                     to codeview_dump_linetab2, so it knows not to
2135                     poke around in there. */
2136                  filesimage ? filesimage + 12 : NULL,
2137                  filessize, "        "
2138               );
2139
2140         ML_(dinfo_free)( (void*)modimage );
2141      }
2142
2143      file_name += VG_(strlen)(file_name) + 1;
2144      file = (char *)(
2145                (unsigned long)(file_name
2146                                + VG_(strlen)(file_name) + 1 + 3) & ~3 );
2147   }
2148
2149   /*
2150    * Cleanup
2151    */
2152   if ( symbols_image ) ML_(dinfo_free)( symbols_image );
2153   if ( types_image ) ML_(dinfo_free)( types_image );
2154   if ( pdb->u.jg.toc ) ML_(dinfo_free)( pdb->u.jg.toc );
2155
2156   if (VG_(clo_verbosity) > 1) {
2157      VG_(message)(Vg_DebugMsg,
2158                   "   # symbols read = %llu\n", n_syms_read );
2159      VG_(message)(Vg_DebugMsg,
2160                   "   # lines   read = %llu\n", n_lines_read );
2161      VG_(message)(Vg_DebugMsg,
2162                   "   # line2s  read = %llu\n", n_line2s_read );
2163      VG_(message)(Vg_DebugMsg,
2164                   "   # fpos    read = %llu\n", n_fpos_read );
2165   }
2166}
2167
2168
2169/*------------------------------------------------------------*/
2170/*---                                                      ---*/
2171/*--- TOP LEVEL for PDB reading                            ---*/
2172/*---                                                      ---*/
2173/*------------------------------------------------------------*/
2174
2175/* Read line, symbol and unwind information from a PDB file.
2176*/
2177Bool ML_(read_pdb_debug_info)(
2178        DebugInfo* di,
2179        Addr       obj_avma,
2180        PtrdiffT   obj_bias,
2181        void*      pdbimage,
2182        SizeT      n_pdbimage,
2183        HChar*     pdbname,
2184        ULong      pdbmtime
2185     )
2186{
2187   Char*    pe_seg_avma;
2188   Int      i;
2189   Addr     mapped_avma, mapped_end_avma;
2190   unsigned signature;
2191   void*    hdr;
2192   struct pdb_reader     reader;
2193   IMAGE_DOS_HEADER*     dos_avma;
2194   IMAGE_NT_HEADERS*     ntheaders_avma;
2195   IMAGE_SECTION_HEADER* sectp_avma;
2196   IMAGE_SECTION_HEADER* pe_sechdr_avma;
2197
2198   if (VG_(clo_verbosity) > 1)
2199       VG_(message)(Vg_UserMsg, "Processing PDB file %s\n", pdbname );
2200
2201   dos_avma = (IMAGE_DOS_HEADER *)obj_avma;
2202   if (dos_avma->e_magic != IMAGE_DOS_SIGNATURE)
2203      return False;
2204
2205   ntheaders_avma
2206      = (IMAGE_NT_HEADERS *)((Char*)dos_avma + dos_avma->e_lfanew);
2207   if (ntheaders_avma->Signature != IMAGE_NT_SIGNATURE)
2208      return False;
2209
2210   sectp_avma
2211      = (IMAGE_SECTION_HEADER *)(
2212           (Char*)ntheaders_avma
2213           + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2214           + ntheaders_avma->FileHeader.SizeOfOptionalHeader
2215        );
2216
2217   /* JRS: this seems like something of a hack. */
2218   di->soname = ML_(dinfo_strdup)("di.readpdb.rpdi.1", pdbname);
2219
2220   /* someone (ie WINE) is loading a Windows PE format object.  we
2221      need to use its details to determine which area of memory is
2222      executable... */
2223   pe_seg_avma
2224      = (Char*)ntheaders_avma
2225        + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2226        + ntheaders_avma->FileHeader.SizeOfOptionalHeader;
2227
2228   /* Iterate over PE headers and fill our section mapping table. */
2229   for ( i = 0;
2230         i < ntheaders_avma->FileHeader.NumberOfSections;
2231         i++, pe_seg_avma += sizeof(IMAGE_SECTION_HEADER) ) {
2232      pe_sechdr_avma = (IMAGE_SECTION_HEADER *)pe_seg_avma;
2233
2234      if (VG_(clo_verbosity) > 1) {
2235         /* Copy name, it can be 8 chars and not NUL-terminated */
2236         char name[9];
2237         VG_(memcpy)(name, pe_sechdr_avma->Name, 8);
2238         name[8] = '\0';
2239         VG_(message)(Vg_UserMsg,
2240                      "  Scanning PE section %ps at avma %#lx svma %#lx\n",
2241                      name, obj_avma + pe_sechdr_avma->VirtualAddress,
2242                      pe_sechdr_avma->VirtualAddress);
2243      }
2244
2245      if (pe_sechdr_avma->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2246         continue;
2247
2248      mapped_avma     = (Addr)obj_avma + pe_sechdr_avma->VirtualAddress;
2249      mapped_end_avma = mapped_avma + pe_sechdr_avma->Misc.VirtualSize;
2250
2251      struct _DebugInfoMapping map;
2252      map.avma = mapped_avma;
2253      map.size = pe_sechdr_avma->Misc.VirtualSize;
2254      map.foff = pe_sechdr_avma->PointerToRawData;
2255      map.ro   = False;
2256
2257      if (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_CODE) {
2258         /* Ignore uninitialised code sections - if you have
2259            incremental linking enabled in Visual Studio then you will
2260            get a uninitialised code section called .textbss before
2261            the real text section and valgrind will compute the wrong
2262            avma value and hence the wrong bias. */
2263         if (!(pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
2264            map.rx   = True;
2265            map.rw   = False;
2266            VG_(addToXA)(di->fsm.maps, &map);
2267            di->fsm.have_rx_map = True;
2268
2269            di->text_present = True;
2270            if (di->text_avma == 0) {
2271               di->text_svma = pe_sechdr_avma->VirtualAddress;
2272               di->text_avma = mapped_avma;
2273               di->text_size = pe_sechdr_avma->Misc.VirtualSize;
2274            } else {
2275               di->text_size = mapped_end_avma - di->text_avma;
2276            }
2277         }
2278      }
2279      else if (pe_sechdr_avma->Characteristics
2280               & IMAGE_SCN_CNT_INITIALIZED_DATA) {
2281         map.rx   = False;
2282         map.rw   = True;
2283         VG_(addToXA)(di->fsm.maps, &map);
2284         di->fsm.have_rw_map = True;
2285
2286         di->data_present = True;
2287         if (di->data_avma == 0) {
2288            di->data_avma = mapped_avma;
2289            di->data_size = pe_sechdr_avma->Misc.VirtualSize;
2290         } else {
2291            di->data_size = mapped_end_avma - di->data_avma;
2292         }
2293      }
2294      else if (pe_sechdr_avma->Characteristics
2295               & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
2296         di->bss_present = True;
2297         if (di->bss_avma == 0) {
2298            di->bss_avma = mapped_avma;
2299            di->bss_size = pe_sechdr_avma->Misc.VirtualSize;
2300         } else {
2301            di->bss_size = mapped_end_avma - di->bss_avma;
2302         }
2303      }
2304   }
2305
2306   if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
2307      vg_assert(di->fsm.filename);
2308      TRACE_SYMTAB("\n");
2309      TRACE_SYMTAB("------ start PE OBJECT with PDB INFO "
2310                   "---------------------\n");
2311      TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
2312      TRACE_SYMTAB("\n");
2313   }
2314
2315   di->text_bias = obj_bias;
2316
2317   if (VG_(clo_verbosity) > 1) {
2318      for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2319         struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2320         if (map->rx)
2321            VG_(message)(Vg_DebugMsg,
2322                         "rx_map: avma %#lx size %7lu foff %llu\n",
2323                         map->avma, map->size, (Off64T)map->foff);
2324      }
2325      for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2326         struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2327         if (map->rw)
2328            VG_(message)(Vg_DebugMsg,
2329                         "rw_map: avma %#lx size %7lu foff %llu\n",
2330                         map->avma, map->size, (Off64T)map->foff);
2331      }
2332
2333      VG_(message)(Vg_DebugMsg,
2334                   "  text: avma %#lx svma %#lx size %7lu bias %#lx\n",
2335                   di->text_avma, di->text_svma,
2336                   di->text_size, di->text_bias);
2337   }
2338
2339   /*
2340    * Read in TOC and well-known files
2341    */
2342   signature = 0;
2343   hdr = find_pdb_header( pdbimage, &signature );
2344   if (0==hdr)
2345      return False; /* JRS: significance? no pdb header? */
2346
2347   VG_(memset)(&reader, 0, sizeof(reader));
2348   reader.u.jg.header = hdr;
2349
2350   if (0==VG_(strncmp)((char const *)&signature, "DS\0\0", 4)) {
2351      struct PDB_DS_ROOT* root;
2352      pdb_ds_init( &reader, pdbimage, n_pdbimage );
2353      root = reader.read_file( &reader, 1, 0 );
2354      if (root) {
2355         pdb_check_root_version_and_timestamp(
2356            pdbname, pdbmtime, root->version, root->TimeDateStamp );
2357         ML_(dinfo_free)( root );
2358      }
2359      pdb_dump( &reader, di, obj_avma, obj_bias, sectp_avma );
2360   }
2361   else
2362   if (0==VG_(strncmp)((char const *)&signature, "JG\0\0", 4)) {
2363      struct PDB_JG_ROOT* root;
2364      pdb_jg_init( &reader, pdbimage, n_pdbimage );
2365      root = reader.read_file( &reader, 1, 0 );
2366      if (root) {
2367         pdb_check_root_version_and_timestamp(
2368            pdbname, pdbmtime, root->version, root->TimeDateStamp);
2369         ML_(dinfo_free)( root );
2370      }
2371      pdb_dump( &reader, di, obj_avma, obj_bias, sectp_avma );
2372   }
2373
2374   if (1) {
2375      TRACE_SYMTAB("\n------ Canonicalising the "
2376                   "acquired info ------\n");
2377      /* prepare read data for use */
2378      ML_(canonicaliseTables)( di );
2379      /* notify m_redir about it */
2380      TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
2381      VG_(redir_notify_new_DebugInfo)( di );
2382      /* Note that we succeeded */
2383      di->have_dinfo = True;
2384   } else {
2385      TRACE_SYMTAB("\n------ PE with PDB reading failed ------\n");
2386      /* Something went wrong (eg. bad ELF file).  Should we delete
2387         this DebugInfo?  No - it contains info on the rw/rx
2388         mappings, at least. */
2389   }
2390
2391   TRACE_SYMTAB("\n");
2392   TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
2393   TRACE_SYMTAB("------ end PE OBJECT with PDB INFO "
2394                "--------------------\n");
2395   TRACE_SYMTAB("\n");
2396
2397   return True;
2398}
2399
2400
2401/* Examine a PE file to see if it states the path of an associated PDB
2402   file; if so return that.  Caller must deallocate with
2403   ML_(dinfo_free).
2404*/
2405
2406HChar* ML_(find_name_of_pdb_file)( HChar* pename )
2407{
2408   /* This is a giant kludge, of the kind "you did WTF?!?", but it
2409      works. */
2410   Bool   do_cleanup = False;
2411   HChar  tmpname[VG_(mkstemp_fullname_bufsz)(50-1)], tmpnameroot[50];
2412   Int    fd, r;
2413   HChar* res = NULL;
2414
2415   if (!pename)
2416      goto out;
2417
2418   fd = -1;
2419   VG_(memset)(tmpnameroot, 0, sizeof(tmpnameroot));
2420   VG_(sprintf)(tmpnameroot, "petmp%d", VG_(getpid)());
2421   VG_(memset)(tmpname, 0, sizeof(tmpname));
2422   fd = VG_(mkstemp)( tmpnameroot, tmpname );
2423   if (fd == -1) {
2424      VG_(message)(Vg_UserMsg,
2425                   "Find PDB file: Can't create /tmp file %s\n", tmpname);
2426      goto out;
2427   }
2428   do_cleanup = True;
2429
2430   /* Make up the command to run, essentially:
2431      sh -c "strings (pename) | egrep '\.pdb|\.PDB' > (tmpname)"
2432   */
2433   const HChar* sh      = "/bin/sh";
2434   const HChar* strings = "/usr/bin/strings";
2435   const HChar* egrep   = "/usr/bin/egrep";
2436
2437   /* (sh) -c "(strings) (pename) | (egrep) 'pdb' > (tmpname) */
2438   Int cmdlen = VG_(strlen)(strings) + VG_(strlen)(pename)
2439                + VG_(strlen)(egrep) + VG_(strlen)(tmpname)
2440                + 100/*misc*/;
2441   HChar* cmd = ML_(dinfo_zalloc)("di.readpe.fnopf.cmd", cmdlen);
2442   vg_assert(cmd);
2443   VG_(sprintf)(cmd, "%s -c \"%s '%s' | %s '\\.pdb|\\.PDB' >> %s\"",
2444                     sh, strings, pename, egrep, tmpname);
2445   vg_assert(cmd[cmdlen-1] == 0);
2446   if (0) VG_(printf)("QQQQQQQQ: %s\n", cmd);
2447
2448   r = VG_(system)( cmd );
2449   if (r) {
2450      VG_(message)(Vg_DebugMsg,
2451                   "Find PDB file: Command failed:\n   %s\n", cmd);
2452      goto out;
2453   }
2454
2455   /* Find out how big the file is, and get it aboard. */
2456   struct vg_stat stat_buf;
2457   VG_(memset)(&stat_buf, 0, sizeof(stat_buf));
2458
2459   SysRes sr = VG_(stat)(tmpname, &stat_buf);
2460   if (sr_isError(sr)) {
2461      VG_(umsg)("Find PDB file: can't stat %s\n", tmpname);
2462      goto out;
2463   }
2464
2465   Int szB = (Int)stat_buf.size;
2466   if (szB == 0) {
2467      VG_(umsg)("Find PDB file: %s is empty\n", tmpname);
2468      goto out;
2469   }
2470   /* 6 == strlen("X.pdb\n") */
2471   if (szB < 6 || szB > 1024/*let's say*/) {
2472      VG_(umsg)("Find PDB file: %s has implausible size %d\n",
2473                tmpname, szB);
2474      goto out;
2475   }
2476
2477   HChar* pdbname = ML_(dinfo_zalloc)("di.readpe.fnopf.pdbname", szB + 1);
2478   vg_assert(pdbname);
2479   pdbname[szB] = 0;
2480
2481   Int nread = VG_(read)(fd, pdbname, szB);
2482   if (nread != szB) {
2483      VG_(umsg)("Find PDB file: read of %s failed\n", tmpname);
2484      goto out;
2485   }
2486   vg_assert(pdbname[szB] == 0);
2487
2488   /* Check we've got something remotely sane -- must have one dot and
2489      one \n in it, and the \n must be at the end */
2490   Bool saw_dot = False;
2491   Int  saw_n_crs = 0;
2492   Int  i;
2493   for (i = 0; pdbname[i]; i++) {
2494      if (pdbname[i] == '.')  saw_dot = True;
2495      if (pdbname[i] == '\n') saw_n_crs++;
2496   }
2497   if (!saw_dot || saw_n_crs != 1 || pdbname[szB-1] != '\n') {
2498      VG_(umsg)("Find PDB file: can't make sense of: %s\n", pdbname);
2499      goto out;
2500   }
2501   /* Change the \n to a terminating zero, so we have a "normal" string */
2502   pdbname[szB-1] = 0;
2503
2504   if (0) VG_(printf)("QQQQQQQQ: got %s\n", pdbname);
2505
2506   res = pdbname;
2507   goto out;
2508
2509  out:
2510   if (do_cleanup) {
2511      VG_(close)(fd);
2512      VG_(unlink)( tmpname );
2513   }
2514   return res;
2515}
2516
2517#endif // defined(VGO_linux) || defined(VGO_darwin)
2518
2519/*--------------------------------------------------------------------*/
2520/*--- end                                                          ---*/
2521/*--------------------------------------------------------------------*/
2522