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