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)(const 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         struct PDB_JG_ROOT* root;
961      } jg;
962      struct {
963         struct PDB_DS_HEADER* header;
964         struct PDB_DS_TOC* toc;
965         struct PDB_DS_ROOT* root;
966      } ds;
967   } u;
968};
969
970
971static void* pdb_ds_read( const struct pdb_reader* pdb,
972                          const unsigned* block_list,
973                          unsigned  size )
974{
975   unsigned  blocksize, nBlocks;
976   UChar* buffer;
977   UInt i;
978
979   if (!size) return NULL;
980   if (size > 512 * 1024 * 1024) {
981      VG_(umsg)("LOAD_PDB_DEBUGINFO: pdb_ds_read: implausible size "
982                "(%u); skipping -- possible invalid .pdb file?\n", size);
983      return NULL;
984   }
985
986   blocksize = pdb->u.ds.header->block_size;
987   nBlocks   = (size + blocksize - 1) / blocksize;
988   buffer    = ML_(dinfo_zalloc)("di.readpe.pdr.1", nBlocks * blocksize);
989   for (i = 0; i < nBlocks; i++)
990      VG_(memcpy)( buffer + i * blocksize,
991                   pdb->pdbimage + block_list[i] * blocksize,
992                   blocksize );
993   return buffer;
994}
995
996
997static void* pdb_jg_read( const struct pdb_reader* pdb,
998                          const unsigned short* block_list,
999                          int size )
1000{
1001   unsigned  blocksize, nBlocks;
1002   UChar* buffer;
1003   UInt i;
1004   //VG_(printf)("pdb_read %p %p %d\n", pdb, block_list, size);
1005   if ( !size ) return NULL;
1006
1007   blocksize = pdb->u.jg.header->blocksize;
1008   nBlocks = (size + blocksize-1) / blocksize;
1009   buffer = ML_(dinfo_zalloc)("di.readpe.pjr.1", nBlocks * blocksize);
1010   for ( i = 0; i < nBlocks; i++ )
1011      VG_(memcpy)( buffer + i*blocksize,
1012                   pdb->pdbimage + block_list[i]*blocksize, blocksize );
1013   return buffer;
1014}
1015
1016
1017static void* find_pdb_header( void* pdbimage,
1018                              unsigned* signature )
1019{
1020   static const HChar pdbtxt[]= "Microsoft C/C++";
1021   HChar* txteof = VG_(strchr)(pdbimage, '\032');
1022   if (! txteof)
1023      return NULL;
1024   if (0!=VG_(strncmp)(pdbimage, pdbtxt, -1+ sizeof(pdbtxt)))
1025      return NULL;
1026
1027   *signature = *(unsigned*)(1+ txteof);
1028   HChar *img_addr = pdbimage;    // so we can do address arithmetic
1029   return ((~3& (3+ (4+ 1+ (txteof - img_addr)))) + img_addr);
1030}
1031
1032
1033static void* pdb_ds_read_file( const struct pdb_reader* reader,
1034                               unsigned  file_number,
1035                               unsigned* plength )
1036{
1037   unsigned i, *block_list;
1038   if (!reader->u.ds.toc || file_number >= reader->u.ds.toc->num_files)
1039      return NULL;
1040   if (reader->u.ds.toc->file_size[file_number] == 0
1041       || reader->u.ds.toc->file_size[file_number] == 0xFFFFFFFF)
1042      return NULL;
1043
1044   block_list
1045      = reader->u.ds.toc->file_size + reader->u.ds.toc->num_files;
1046   for (i = 0; i < file_number; i++)
1047      block_list += (reader->u.ds.toc->file_size[i]
1048                     + reader->u.ds.header->block_size - 1)
1049                    /
1050                    reader->u.ds.header->block_size;
1051   if (plength)
1052      *plength = reader->u.ds.toc->file_size[file_number];
1053   return pdb_ds_read( reader, block_list,
1054                       reader->u.ds.toc->file_size[file_number]);
1055}
1056
1057
1058static void* pdb_jg_read_file( const struct pdb_reader* pdb,
1059                               unsigned fileNr,
1060                               unsigned *plength )
1061{
1062   //VG_(printf)("pdb_read_file %p %d\n", pdb, fileNr);
1063   unsigned blocksize = pdb->u.jg.header->blocksize;
1064   struct PDB_JG_TOC* toc = pdb->u.jg.toc;
1065   unsigned i;
1066   unsigned short* block_list;
1067
1068   if ( !toc || fileNr >= toc->nFiles )
1069       return NULL;
1070
1071   block_list
1072      = (unsigned short *) &toc->file[ toc->nFiles ];
1073   for ( i = 0; i < fileNr; i++ )
1074      block_list += (toc->file[i].size + blocksize-1) / blocksize;
1075
1076   if (plength)
1077      *plength = toc->file[fileNr].size;
1078   return pdb_jg_read( pdb, block_list, toc->file[fileNr].size );
1079}
1080
1081
1082static void pdb_ds_init( struct pdb_reader * reader,
1083                         UChar* pdbimage,
1084                         SizeT  n_pdbimage )
1085{
1086   reader->read_file     = pdb_ds_read_file;
1087   reader->pdbimage      = pdbimage;
1088   reader->uu_n_pdbimage = n_pdbimage;
1089   reader->u.ds.toc
1090      = pdb_ds_read(
1091           reader,
1092           (unsigned*)(reader->u.ds.header->block_size
1093                       * reader->u.ds.header->toc_page
1094                       + reader->pdbimage),
1095           reader->u.ds.header->toc_size
1096        );
1097}
1098
1099
1100static void pdb_jg_init( struct pdb_reader* reader,
1101                         void* pdbimage,
1102                         unsigned n_pdbimage )
1103{
1104   reader->read_file     = pdb_jg_read_file;
1105   reader->pdbimage      = pdbimage;
1106   reader->uu_n_pdbimage = n_pdbimage;
1107   reader->u.jg.toc = pdb_jg_read(reader,
1108                                  reader->u.jg.header->toc_block,
1109                                  reader->u.jg.header->toc.size);
1110}
1111
1112
1113static
1114void pdb_check_root_version_and_timestamp( const 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_(umsg)("LOAD_PDB_DEBUGINFO: "
1129                      "Unknown .pdb root block version %d\n", version );
1130   }
1131   if ( TimeDateStamp != pdbmtime ) {
1132      if (VG_(clo_verbosity) > 1)
1133         VG_(umsg)("LOAD_PDB_DEBUGINFO: Wrong time stamp of .PDB file "
1134                   "%s (0x%08x, 0x%08llx)\n",
1135                   pdbname, TimeDateStamp, pdbmtime );
1136   }
1137}
1138
1139
1140static DWORD pdb_get_file_size( const 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                const IMAGE_SECTION_HEADER* sectp,
1207                const void* root, /* FIXME: better name */
1208                Int offset,
1209                Int size
1210             )
1211{
1212   Int    i, length;
1213   DiSym  vsym;
1214   const  HChar* nmstr;
1215   HChar  symname[4096 /*WIN32_PATH_MAX*/];  // FIXME: really ?
1216
1217   Bool  debug = di->trace_symtab;
1218   ULong n_syms_read = 0;
1219
1220   if (debug)
1221      VG_(umsg)("BEGIN SnarfCodeView addr=%p offset=%d length=%d\n",
1222                root, offset, size );
1223
1224   VG_(memset)(&vsym, 0, sizeof(vsym));  /* avoid holes */
1225   /*
1226    * Loop over the different types of records and whenever we
1227    * find something we are interested in, record it and move on.
1228    */
1229   for ( i = offset; i < size; i += length )
1230   {
1231      const union codeview_symbol *sym =
1232         (const union codeview_symbol *)((const 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            const int *isym = (const int *)sym;
1242            VG_(printf)("unknown id 0x%x len=0x%x at %p\n",
1243                        sym->generic.id, sym->generic.len, sym);
1244            VG_(printf)("  %8x  %8x  %8x  %8x\n",
1245                        isym[1], isym[2], isym[3], isym[4]);
1246            VG_(printf)("  %8x  %8x  %8x  %8x\n",
1247                        isym[5], isym[6], isym[7], isym[8]);
1248         }
1249         break;
1250      /*
1251       * Global and local data symbols.  We don't associate these
1252       * with any given source file.
1253       */
1254      case S_GDATA_V1:
1255      case S_LDATA_V1:
1256      case S_PUB_V1:
1257         VG_(memcpy)(symname, sym->data_v1.p_name.name,
1258                              sym->data_v1.p_name.namelen);
1259         symname[sym->data_v1.p_name.namelen] = '\0';
1260
1261         if (debug)
1262            VG_(umsg)("  Data %s\n", symname );
1263
1264         if (0 /*VG_(needs).data_syms*/) {
1265            nmstr = ML_(addStr)(di, symname, sym->data_v1.p_name.namelen);
1266            vsym.avmas.main = bias + sectp[sym->data_v1.segment-1].VirtualAddress
1267                                 + sym->data_v1.offset;
1268            SET_TOCPTR_AVMA(vsym.avmas, 0);
1269            vsym.pri_name  = nmstr;
1270            vsym.sec_names = NULL;
1271            vsym.size      = sym->data_v1.p_name.namelen;
1272                             // FIXME: .namelen is sizeof(.data) including .name[]
1273            vsym.isText    = (sym->generic.id == S_PUB_V1);
1274            vsym.isIFunc   = False;
1275            ML_(addSym)( di, &vsym );
1276            n_syms_read++;
1277         }
1278         break;
1279      case S_GDATA_V2:
1280      case S_LDATA_V2:
1281      case S_PUB_V2: {
1282         Int const k = sym->data_v2.p_name.namelen;
1283         VG_(memcpy)(symname, sym->data_v2.p_name.name, k);
1284         symname[k] = '\0';
1285
1286         if (debug)
1287            VG_(umsg)("  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.avmas.main = bias + sectp[sym->data_v2.segment-1].VirtualAddress
1292                                  + sym->data_v2.offset;
1293            SET_TOCPTR_AVMA(vsym.avmas, 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_(umsg)("  S_PUB_FUNC1_V3/S_PUB_FUNC2_V3/S_PUB_V3 %s\n",
1319                      symname );
1320
1321         if (1  /*sym->generic.id==S_PUB_FUNC1_V3
1322                  || sym->generic.id==S_PUB_FUNC2_V3*/) {
1323            nmstr = ML_(addStr)(di, symname, k);
1324            vsym.avmas.main = bias + sectp[sym->public_v3.segment-1].VirtualAddress
1325                                  + sym->public_v3.offset;
1326            SET_TOCPTR_AVMA(vsym.avmas, 0);
1327            vsym.pri_name  = nmstr;
1328            vsym.sec_names = NULL;
1329            vsym.size      = 4000;
1330                             // FIXME: public_v3.len is not length of the
1331                             // .text of the function
1332            vsym.isText    = !!(IMAGE_SCN_CNT_CODE
1333                                & sectp[sym->data_v2.segment-1].Characteristics);
1334            vsym.isIFunc   = False;
1335            ML_(addSym)( di, &vsym );
1336            n_syms_read++;
1337         }
1338         break;
1339      }
1340
1341      /*
1342       * Sort of like a global function, but it just points
1343       * to a thunk, which is a stupid name for what amounts to
1344       * a PLT slot in the normal jargon that everyone else uses.
1345       */
1346      case S_THUNK_V3:
1347      case S_THUNK_V1:
1348         /* valgrind ignores PLTs */ /* JRS: it does? */
1349         break;
1350
1351      /*
1352       * Global and static functions.
1353       */
1354      case S_GPROC_V1:
1355      case S_LPROC_V1:
1356         VG_(memcpy)(symname, sym->proc_v1.p_name.name,
1357                              sym->proc_v1.p_name.namelen);
1358         symname[sym->proc_v1.p_name.namelen] = '\0';
1359         nmstr = ML_(addStr)(di, symname, sym->proc_v1.p_name.namelen);
1360         vsym.avmas.main = bias + sectp[sym->proc_v1.segment-1].VirtualAddress
1361                               + sym->proc_v1.offset;
1362         SET_TOCPTR_AVMA(vsym.avmas, 0);
1363         vsym.pri_name  = nmstr;
1364         vsym.sec_names = NULL;
1365         vsym.size      = sym->proc_v1.proc_len;
1366         vsym.isText    = True;
1367         vsym.isIFunc   = False;
1368         if (debug)
1369            VG_(umsg)("  Adding function %s addr=%#lx length=%d\n",
1370                      symname, vsym.avmas.main, vsym.size );
1371         ML_(addSym)( di, &vsym );
1372         n_syms_read++;
1373         break;
1374
1375      case S_GPROC_V2:
1376      case S_LPROC_V2:
1377         VG_(memcpy)(symname, sym->proc_v2.p_name.name,
1378                              sym->proc_v2.p_name.namelen);
1379         symname[sym->proc_v2.p_name.namelen] = '\0';
1380         nmstr = ML_(addStr)(di, symname, sym->proc_v2.p_name.namelen);
1381         vsym.avmas.main = bias + sectp[sym->proc_v2.segment-1].VirtualAddress
1382                               + sym->proc_v2.offset;
1383         SET_TOCPTR_AVMA(vsym.avmas, 0);
1384         vsym.pri_name  = nmstr;
1385         vsym.sec_names = NULL;
1386         vsym.size      = sym->proc_v2.proc_len;
1387         vsym.isText    = True;
1388         vsym.isIFunc   = False;
1389         if (debug)
1390            VG_(umsg)("  Adding function %s addr=%#lx length=%d\n",
1391                      symname, vsym.avmas.main, vsym.size );
1392         ML_(addSym)( di, &vsym );
1393         n_syms_read++;
1394         break;
1395      case S_LPROC_V3:
1396      case S_GPROC_V3: {
1397         if (debug)
1398            VG_(umsg)("  S_LPROC_V3/S_GPROC_V3 %s\n", sym->proc_v3.name );
1399
1400         if (1) {
1401            nmstr = ML_(addStr)(di, sym->proc_v3.name,
1402                                    VG_(strlen)(sym->proc_v3.name));
1403            vsym.avmas.main = bias + sectp[sym->proc_v3.segment-1].VirtualAddress
1404                                  + sym->proc_v3.offset;
1405            SET_TOCPTR_AVMA(vsym.avmas, 0);
1406            vsym.pri_name  = nmstr;
1407            vsym.sec_names = NULL;
1408            vsym.size      = sym->proc_v3.proc_len;
1409            vsym.isText    = 1;
1410            vsym.isIFunc   = False;
1411            ML_(addSym)( di, &vsym );
1412            n_syms_read++;
1413         }
1414         break;
1415      }
1416      /* JRS: how is flow supposed to arrive at commented out code below? */
1417      //if (nest_block)
1418      //{
1419      //   printf(">>> prev func '%s' still has nest_block %u count\n",
1420      //          curr_func, nest_block);
1421      //   nest_block = 0;
1422      //}
1423      //curr_func = strdup(sym->proc_v3.name);
1424      /* EPP  unsigned int    pparent; */
1425      /* EPP  unsigned int    pend; */
1426      /* EPP  unsigned int    next; */
1427      /* EPP  unsigned int    debug_start; */
1428      /* EPP  unsigned int    debug_end; */
1429      /* EPP  unsigned char   flags; */
1430      // break;
1431
1432
1433      /*
1434       * Function parameters and stack variables.
1435       */
1436      case S_BPREL_XXXX_V3:
1437      case S_BPREL_V3:
1438      case S_BPREL_V2:
1439      case S_BPREL_V1:
1440         /* ignored */
1441         break;
1442
1443      case S_LABEL_V3:  // FIXME
1444      case S_LABEL_V1:
1445         break;
1446
1447      case S_SSEARCH_V1:
1448      case S_ALIGN_V1:
1449      case S_MSTOOL_V3:
1450      case S_UDT_V3:
1451      case S_UDT_V2:
1452      case S_UDT_V1:
1453      case S_CONSTANT_V3:
1454      case S_CONSTANT_V1:
1455      case S_OBJNAME_V1:
1456      case S_END_V1:
1457      case S_COMPILAND_V3:
1458      case S_COMPILAND_V2:
1459      case S_COMPILAND_V1:
1460      case S_BLOCK_V3:
1461      case S_BLOCK_V1:
1462      case S_REGISTER_V3:
1463      case S_REGISTER_V2:
1464      case S_REGISTER_V1:
1465         /* ignored */
1466         break;
1467
1468      /*
1469       * These are special, in that they are always followed by an
1470       * additional length-prefixed string which is *not* included
1471       * into the symbol length count.  We need to skip it.
1472       */
1473      case S_PROCREF_V1:
1474      case S_DATAREF_V1:
1475      case S_LPROCREF_V1: {
1476         const unsigned char *name = (const unsigned char *)sym + length;
1477         length += (*name + 1 + 3) & ~3;
1478         break;
1479      }
1480      } /* switch ( sym->generic.id ) */
1481
1482   } /* for ( i = offset; i < size; i += length ) */
1483
1484   if (debug)
1485      VG_(umsg)("END SnarfCodeView addr=%p offset=%d length=%d\n",
1486                root, offset, size );
1487   return n_syms_read;
1488}
1489
1490
1491/*------------------------------------------------------------*/
1492/*---                                                      ---*/
1493/*--- Main stuff: reading of line number tables            ---*/
1494/*---                                                      ---*/
1495/*------------------------------------------------------------*/
1496
1497union any_size
1498{
1499          char const *c;
1500         short const *s;
1501           int const *i;
1502  unsigned int const *ui;
1503};
1504
1505struct startend
1506{
1507  unsigned int          start;
1508  unsigned int          end;
1509};
1510
1511static ULong DEBUG_SnarfLinetab(
1512          DebugInfo* di,
1513          PtrdiffT bias,
1514          const IMAGE_SECTION_HEADER* sectp,
1515          const void* linetab,
1516          Int size
1517       )
1518{
1519   //VG_(printf)("DEBUG_SnarfLinetab %p %p %p %d\n", di, sectp, linetab, size);
1520   Int                file_segcount;
1521   HChar              filename[WIN32_PATH_MAX];
1522   const UInt         * filetab;
1523   const UChar        * fn;
1524   Int                i;
1525   Int                k;
1526   const UInt         * lt_ptr;
1527   Int                nfile;
1528   Int                nseg;
1529   union any_size     pnt;
1530   union any_size     pnt2;
1531   const struct startend * start;
1532   Int                this_seg;
1533
1534   Bool  debug = di->trace_symtab;
1535   ULong n_lines_read = 0;
1536
1537   if (debug)
1538      VG_(umsg)("BEGIN SnarfLineTab linetab=%p size=%d\n", linetab, size);
1539
1540   /*
1541    * Now get the important bits.
1542    */
1543   pnt.c = linetab;
1544   nfile = *pnt.s++;
1545   nseg  = *pnt.s++;
1546
1547   filetab = pnt.ui;
1548
1549   /*
1550    * Now count up the number of segments in the file.
1551    */
1552   nseg = 0;
1553   for (i = 0; i < nfile; i++) {
1554      pnt2.c = (const HChar *)linetab + filetab[i];
1555      nseg += *pnt2.s;
1556   }
1557
1558   this_seg = 0;
1559   for (i = 0; i < nfile; i++) {
1560      const HChar *fnmstr;
1561      const HChar *dirstr;
1562      UInt  fnmdirstr_ix;
1563
1564      /*
1565       * Get the pointer into the segment information.
1566       */
1567      pnt2.c = (const HChar *)linetab + filetab[i];
1568      file_segcount = *pnt2.s;
1569
1570      pnt2.ui++;
1571      lt_ptr = pnt2.ui;
1572      start = (const struct startend *) (lt_ptr + file_segcount);
1573
1574      /*
1575       * Now snarf the filename for all of the segments for this file.
1576       */
1577      fn = (const UChar*) (start + file_segcount);
1578      /* fn now points at a Pascal-style string, that is, the first
1579         byte is the length, and the remaining up to 255 (presumably)
1580         are the contents. */
1581      vg_assert(WIN32_PATH_MAX >= 256);
1582      VG_(memset)(filename, 0, sizeof(filename));
1583      VG_(memcpy)(filename, fn + 1, *fn);
1584      vg_assert(filename[ sizeof(filename)-1 ] == 0);
1585      filename[(Int)*fn] = 0;
1586      fnmstr = VG_(strrchr)(filename, '\\');
1587      if (fnmstr == NULL)
1588         fnmstr = filename;
1589      else
1590         ++fnmstr;
1591      k = VG_(strlen)(fnmstr);
1592      dirstr = ML_(addStr)(di, filename, *fn - k);
1593      fnmstr = ML_(addStr)(di, fnmstr, k);
1594      fnmdirstr_ix = ML_(addFnDn) (di, fnmstr, dirstr);
1595
1596      for (k = 0; k < file_segcount; k++, this_seg++) {
1597         Int linecount;
1598         Int segno;
1599
1600         pnt2.c = (const HChar *)linetab + lt_ptr[k];
1601
1602         segno = *pnt2.s++;
1603         linecount = *pnt2.s++;
1604
1605         if ( linecount > 0 ) {
1606            UInt j;
1607
1608            if (debug)
1609               VG_(umsg)(
1610                  "  Adding %d lines for file %s segment %d addr=%#x end=%#x\n",
1611                  linecount, filename, segno, start[k].start, start[k].end );
1612
1613            for ( j = 0; j < linecount; j++ ) {
1614               Addr startaddr = bias + sectp[segno-1].VirtualAddress
1615                                     + pnt2.ui[j];
1616               Addr endaddr   = bias + sectp[segno-1].VirtualAddress
1617                                     + ((j < (linecount - 1))
1618                                           ? pnt2.ui[j+1]
1619                                           : start[k].end);
1620               if (debug)
1621                  VG_(umsg)(
1622                     "  Adding line %d addr=%#lx end=%#lx\n",
1623                     ((const unsigned short *)(pnt2.ui + linecount))[j],
1624                     startaddr, endaddr );
1625                  ML_(addLineInfo)(
1626                     di,
1627                     fnmdirstr_ix,
1628                     startaddr, endaddr,
1629                     ((const unsigned short *)(pnt2.ui + linecount))[j], j );
1630                  n_lines_read++;
1631               }
1632            }
1633        }
1634    }
1635
1636   if (debug)
1637      VG_(umsg)("END SnarfLineTab linetab=%p size=%d\n",
1638                linetab, size );
1639
1640    return n_lines_read;
1641}
1642
1643
1644
1645/* there's a new line tab structure from MS Studio 2005 and after
1646 * it's made of:
1647 * DWORD        000000f4
1648 * DWORD        lineblk_offset (counting bytes after this field)
1649 * an array of codeview_linetab2_file structures
1650 * an array (starting at <lineblk_offset>) of codeview_linetab2_block structures
1651 */
1652
1653typedef struct codeview_linetab2_file
1654{
1655    DWORD       offset;         /* offset in string table for filename */
1656    WORD        unk;            /* always 0x0110... type of following
1657                                   information ??? */
1658    BYTE        md5[16];        /* MD5 signature of file (signature on
1659                                   file's content or name ???) */
1660    WORD        pad0;           /* always 0 */
1661} codeview_linetab2_file;
1662
1663typedef struct codeview_linetab2_block
1664{
1665    DWORD       header;         /* 0x000000f2 */
1666    DWORD       size_of_block;  /* next block is at # bytes after this field */
1667    DWORD       start;          /* start address of function with line numbers */
1668    DWORD       seg;            /* segment of function with line numbers */
1669    DWORD       size;           /* size of function with line numbers */
1670    DWORD       file_offset;    /* offset for accessing corresponding
1671                                   codeview_linetab2_file */
1672    DWORD       nlines;         /* number of lines in this block */
1673    DWORD       size_lines;     /* number of bytes following for line
1674                                   number information */
1675    struct {
1676        DWORD   offset;         /* offset (from <seg>:<start>) for line number */
1677        DWORD   lineno;         /* the line number (OR:ed with
1678                                   0x80000000 why ???) */
1679    } l[1];                     /* actually array of <nlines> */
1680} codeview_linetab2_block;
1681
1682static ULong codeview_dump_linetab2(
1683                DebugInfo* di,
1684                Addr bias,
1685                const IMAGE_SECTION_HEADER* sectp,
1686                const HChar* linetab,
1687                DWORD size,
1688                const HChar* strimage,
1689                DWORD strsize,
1690                const HChar* pfx
1691             )
1692{
1693   DWORD       offset;
1694   unsigned    i;
1695   const codeview_linetab2_block* lbh;
1696   const codeview_linetab2_file* fd;
1697
1698   Bool  debug = di->trace_symtab;
1699   ULong n_line2s_read = 0;
1700
1701   if (*(const DWORD*)linetab != 0x000000f4)
1702      return 0;
1703   offset = *((const DWORD*)linetab + 1);
1704   lbh = (const codeview_linetab2_block*)(linetab + 8 + offset);
1705
1706   while ((const HChar*)lbh < linetab + size) {
1707
1708      UInt filedirname_ix;
1709      Addr svma_s, svma_e;
1710      if (lbh->header != 0x000000f2) {
1711         /* FIXME: should also check that whole lbh fits in linetab + size */
1712         if (debug)
1713            VG_(printf)("%sblock end %x\n", pfx, lbh->header);
1714         break;
1715      }
1716      if (debug)
1717         VG_(printf)("%sblock from %04x:%08x-%08x (size %u) (%u lines)\n",
1718                     pfx, lbh->seg, lbh->start, lbh->start + lbh->size - 1,
1719                     lbh->size, lbh->nlines);
1720      fd = (const codeview_linetab2_file*)(linetab + 8 + lbh->file_offset);
1721      if (debug)
1722         VG_(printf)(
1723            "%s  md5=%02x%02x%02x%02x%02x%02x%02x%02x"
1724                    "%02x%02x%02x%02x%02x%02x%02x%02x\n",
1725             pfx, fd->md5[ 0], fd->md5[ 1], fd->md5[ 2], fd->md5[ 3],
1726                  fd->md5[ 4], fd->md5[ 5], fd->md5[ 6], fd->md5[ 7],
1727                  fd->md5[ 8], fd->md5[ 9], fd->md5[10], fd->md5[11],
1728                  fd->md5[12], fd->md5[13], fd->md5[14], fd->md5[15] );
1729      /* FIXME: should check that string is within strimage + strsize */
1730      const HChar* filename = NULL; // in ML_(addStr) space
1731      const HChar* dirname  = NULL; // in ML_(addStr) space
1732      if (strimage) {
1733         const HChar* strI = strimage + fd->offset;
1734         /* Copy |strI| into mutable storage, temporarily, so we can put a zero
1735            byte in place of the last pathname separator. */
1736         HChar* strM  = ML_(dinfo_strdup)("di.readpe.cdl2.1", strI);
1737         HChar* fname = VG_(strrchr)(strM, '\\');
1738         if (fname == NULL) {
1739            filename = ML_(addStr)(di, strM, -1);
1740            dirname  = NULL;
1741         } else {
1742            *fname++ = '\0';
1743            filename = ML_(addStr)(di, fname, -1);
1744            dirname  = ML_(addStr)(di, strM, -1);
1745         }
1746         ML_(dinfo_free)(strM);
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      filedirname_ix = ML_(addFnDn) (di, filename, dirname);
1756
1757      for (i = 0; i < lbh->nlines; i++) {
1758         if (debug)
1759            VG_(printf)("%s  offset=%08x line=%d\n",
1760                        pfx, lbh->l[i].offset, lbh->l[i].lineno ^ 0x80000000);
1761      }
1762
1763      if (lbh->nlines > 1) {
1764         for (i = 0; i < lbh->nlines-1; i++) {
1765            svma_s = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1766                     + lbh->l[i].offset;
1767            svma_e = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1768                     + lbh->l[i+1].offset-1;
1769            if (debug)
1770               VG_(printf)("%s  line %d: %08lx to %08lx\n",
1771                           pfx, lbh->l[i].lineno ^ 0x80000000, svma_s, svma_e);
1772            ML_(addLineInfo)( di,
1773                              filedirname_ix,
1774                              bias + svma_s,
1775                              bias + svma_e + 1,
1776                              lbh->l[i].lineno ^ 0x80000000, 0 );
1777            n_line2s_read++;
1778         }
1779         svma_s = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1780                  + lbh->l[ lbh->nlines-1].offset;
1781         svma_e = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1782                  + lbh->size - 1;
1783         if (debug)
1784            VG_(printf)("%s  line %d: %08lx to %08lx\n",
1785                        pfx, lbh->l[ lbh->nlines-1  ].lineno ^ 0x80000000,
1786                        svma_s, svma_e);
1787          ML_(addLineInfo)( di,
1788                            filedirname_ix,
1789                            bias + svma_s,
1790                            bias + svma_e + 1,
1791                            lbh->l[lbh->nlines-1].lineno ^ 0x80000000, 0 );
1792          n_line2s_read++;
1793       }
1794
1795       lbh = (const codeview_linetab2_block*)
1796                ((const char*)lbh + 8 + lbh->size_of_block);
1797    }
1798    return n_line2s_read;
1799}
1800
1801
1802/*------------------------------------------------------------*/
1803/*---                                                      ---*/
1804/*--- Main stuff: pdb_dump                                 ---*/
1805/*---                                                      ---*/
1806/*------------------------------------------------------------*/
1807
1808static Int cmp_FPO_DATA_for_canonicalisation ( const void* f1V,
1809                                               const void* f2V )
1810{
1811   /* Cause FPO data to be sorted first in ascending order of range
1812      starts, and for entries with the same range start, with the
1813      shorter range (length) first. */
1814   const FPO_DATA* f1 = f1V;
1815   const FPO_DATA* f2 = f2V;
1816   if (f1->ulOffStart < f2->ulOffStart) return -1;
1817   if (f1->ulOffStart > f2->ulOffStart) return  1;
1818   if (f1->cbProcSize < f2->cbProcSize) return -1;
1819   if (f1->cbProcSize > f2->cbProcSize) return  1;
1820   return 0; /* identical in both start and length */
1821}
1822
1823static unsigned get_stream_by_name(const struct pdb_reader* pdb, const char* name)
1824{
1825    const DWORD* pdw;
1826    const DWORD* ok_bits;
1827    DWORD        cbstr, count;
1828    DWORD        string_idx, stream_idx;
1829    unsigned     i;
1830    const char*  str;
1831
1832    if (pdb->read_file == pdb_jg_read_file)
1833    {
1834        str = pdb->u.jg.root->names;
1835        cbstr = pdb->u.jg.root->cbNames;
1836    }
1837    else
1838    {
1839        str = pdb->u.ds.root->names;
1840        cbstr = pdb->u.ds.root->cbNames;
1841    }
1842
1843    pdw = (const DWORD*)(str + cbstr);
1844    pdw++; /* number of ok entries */
1845    count = *pdw++;
1846
1847    /* bitfield: first dword is len (in dword), then data */
1848    ok_bits = pdw;
1849    pdw += *ok_bits++ + 1;
1850    if (*pdw++ != 0)
1851    {
1852        if (VG_(clo_verbosity) > 1)
1853           VG_(umsg)("LOAD_PDB_DEBUGINFO: "
1854                     "get_stream_by_name: unexpected value\n");
1855        return -1;
1856    }
1857
1858    for (i = 0; i < count; i++)
1859    {
1860        if (ok_bits[i / 32] & (1 << (i % 32)))
1861        {
1862            string_idx = *pdw++;
1863            stream_idx = *pdw++;
1864            if (!VG_(strcmp)(name, &str[string_idx])) return stream_idx;
1865        }
1866    }
1867    return -1;
1868}
1869
1870
1871static void *read_string_table(const struct pdb_reader* pdb)
1872{
1873    unsigned    stream_idx;
1874    void*       ret;
1875
1876    stream_idx = get_stream_by_name(pdb, "/names");
1877    if (stream_idx == -1) return NULL;
1878    ret = pdb->read_file(pdb, stream_idx,0);
1879    if (ret && *(const DWORD*)ret == 0xeffeeffe) {
1880       return ret;
1881    }
1882    if (VG_(clo_verbosity) > 1)
1883       VG_(umsg)("LOAD_PDB_DEBUGINFO: read_string_table: "
1884                 "wrong header 0x%08x, expecting 0xeffeeffe\n",
1885                 *(const DWORD*)ret);
1886    ML_(dinfo_free)( ret );
1887    return NULL;
1888}
1889
1890/* JRS fixme: compare with version in current Wine sources */
1891static void pdb_dump( const struct pdb_reader* pdb,
1892                      DebugInfo* di,
1893                      Addr       pe_avma,
1894                      PtrdiffT   pe_bias,
1895                      const IMAGE_SECTION_HEADER* sectp_avma )
1896{
1897   Int header_size;
1898
1899   PDB_TYPES types;
1900   PDB_SYMBOLS symbols;
1901   unsigned len_modimage;
1902   char *modimage;
1903   const char *file;
1904
1905   Bool debug = di->trace_symtab;
1906
1907   ULong n_fpos_read = 0, n_syms_read = 0,
1908         n_lines_read = 0, n_line2s_read = 0;
1909
1910   // FIXME: symbols for bare indices 1,2,3,5 in .pdb file
1911
1912   char* types_image   = pdb->read_file( pdb, 2, 0 );
1913   char* symbols_image = pdb->read_file( pdb, 3, 0 );
1914
1915   /* establish filesimage and filessize.  These are only needed for
1916      reading linetab2 tables, as far as I can deduce from the Wine
1917      sources. */
1918   DWORD filessize  = 0;
1919   char* filesimage = read_string_table(pdb);
1920   if (filesimage) {
1921      filessize = *(const DWORD*)(filesimage + 8);
1922   } else {
1923      VG_(umsg)("LOAD_PDB_DEBUGINFO: pdb_dump: string table not found\n");
1924   }
1925
1926   /* Since we just use the FPO data without reformatting, at least
1927      do a basic sanity check on the struct layout. */
1928   vg_assert(sizeof(FPO_DATA) == 16);
1929   if (di->text_present) {
1930      /* only load FPO if there's text present (otherwise it's
1931         meaningless?) */
1932      unsigned sz = 0;
1933      di->fpo = pdb->read_file( pdb, 5, &sz );
1934
1935      // FIXME: seems like the size can be a non-integral number
1936      // of FPO_DATAs.  Force-align it (moronically).  Perhaps this
1937      // signifies that we're not looking at a valid FPO table ..
1938      // who knows.  Needs investigation.
1939      while (sz > 0 && (sz % sizeof(FPO_DATA)) != 0)
1940         sz--;
1941
1942      di->fpo_size = sz;
1943      if (0) VG_(printf)("FPO: got fpo_size %lu\n", (UWord)sz);
1944      vg_assert(0 == (di->fpo_size % sizeof(FPO_DATA)));
1945      di->fpo_base_avma = pe_avma;
1946   } else {
1947      vg_assert(di->fpo == NULL);
1948      vg_assert(di->fpo_size == 0);
1949   }
1950
1951   // BEGIN clean up FPO data
1952   if (di->fpo && di->fpo_size > 0) {
1953      Word i, j;
1954      Bool anyChanges;
1955      Int itersAvail = 10;
1956
1957      vg_assert(sizeof(di->fpo[0]) == 16);
1958      di->fpo_size /= sizeof(di->fpo[0]);
1959
1960      // BEGIN FPO-data tidying-up loop
1961      do {
1962
1963         vg_assert(itersAvail >= 0); /* safety check -- don't loop forever */
1964         itersAvail--;
1965
1966         anyChanges = False;
1967
1968         /* First get them in ascending order of start point */
1969         VG_(ssort)( di->fpo, (SizeT)di->fpo_size, (SizeT)sizeof(FPO_DATA),
1970                              cmp_FPO_DATA_for_canonicalisation );
1971         /* Get rid of any zero length entries */
1972         j = 0;
1973         for (i = 0; i < di->fpo_size; i++) {
1974            if (di->fpo[i].cbProcSize == 0) {
1975               anyChanges = True;
1976               continue;
1977            }
1978            di->fpo[j++] = di->fpo[i];
1979         }
1980         vg_assert(j >= 0 && j <= di->fpo_size);
1981         di->fpo_size = j;
1982
1983         /* Get rid of any dups */
1984         if (di->fpo_size > 1) {
1985            j = 1;
1986            for (i = 1; i < di->fpo_size; i++) {
1987               Bool dup
1988                  = di->fpo[j-1].ulOffStart == di->fpo[i].ulOffStart
1989                    && di->fpo[j-1].cbProcSize == di->fpo[i].cbProcSize;
1990               if (dup) {
1991                 anyChanges = True;
1992                 continue;
1993               }
1994               di->fpo[j++] = di->fpo[i];
1995            }
1996            vg_assert(j >= 0 && j <= di->fpo_size);
1997            di->fpo_size = j;
1998         }
1999
2000         /* Truncate any overlapping ranges */
2001         for (i = 1; i < di->fpo_size; i++) {
2002            vg_assert(di->fpo[i-1].ulOffStart <= di->fpo[i].ulOffStart);
2003            if (di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
2004                > di->fpo[i].ulOffStart) {
2005               anyChanges = True;
2006               di->fpo[i-1].cbProcSize
2007                  = di->fpo[i].ulOffStart - di->fpo[i-1].ulOffStart;
2008            }
2009         }
2010
2011      } while (anyChanges);
2012      // END FPO-data tidying-up loop
2013
2014      /* Should now be in ascending order, non overlapping, no zero ranges.
2015         Check this, get the min and max avmas, and bias the entries. */
2016      for (i = 0; i < di->fpo_size; i++) {
2017         vg_assert(di->fpo[i].cbProcSize > 0);
2018
2019         if (i > 0) {
2020            vg_assert(di->fpo[i-1].ulOffStart < di->fpo[i].ulOffStart);
2021            vg_assert(di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
2022                      <= di->fpo[i].ulOffStart);
2023         }
2024      }
2025
2026      /* Now bias the table.  This can't be done in the same pass as
2027         the sanity check, hence a second loop. */
2028      for (i = 0; i < di->fpo_size; i++) {
2029         di->fpo[i].ulOffStart += pe_avma;
2030         // make sure the biasing didn't royally screw up, by wrapping
2031         // the range around the end of the address space
2032         vg_assert(0xFFFFFFFF - di->fpo[i].ulOffStart /* "remaining space" */
2033                   >= di->fpo[i].cbProcSize);
2034      }
2035
2036      /* Dump any entries which point outside the text segment and
2037         compute the min/max avma "hint" addresses. */
2038      Addr min_avma = ~(Addr)0;
2039      Addr max_avma = (Addr)0;
2040      vg_assert(di->text_present);
2041      j = 0;
2042      for (i = 0; i < di->fpo_size; i++) {
2043         if ((Addr)(di->fpo[i].ulOffStart) >= di->text_avma
2044             && (Addr)(di->fpo[i].ulOffStart + di->fpo[i].cbProcSize)
2045                <= di->text_avma + di->text_size) {
2046            /* Update min/max limits as we go along. */
2047            if (di->fpo[i].ulOffStart < min_avma)
2048               min_avma = di->fpo[i].ulOffStart;
2049            if (di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1 > max_avma)
2050               max_avma = di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1;
2051            /* Keep */
2052            di->fpo[j++] = di->fpo[i];
2053            if (0)
2054            VG_(printf)("FPO: keep text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
2055                        di->text_avma, di->text_avma + di->text_size,
2056                        (Addr)di->fpo[i].ulOffStart,
2057                        (Addr)di->fpo[i].ulOffStart
2058                        + (Addr)di->fpo[i].cbProcSize - 1);
2059         } else {
2060            if (0)
2061            VG_(printf)("FPO: SKIP text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
2062                        di->text_avma, di->text_avma + di->text_size,
2063                        (Addr)di->fpo[i].ulOffStart,
2064                        (Addr)di->fpo[i].ulOffStart
2065                        + (Addr)di->fpo[i].cbProcSize - 1);
2066            /* out of range; ignore */
2067         }
2068      }
2069      vg_assert(j >= 0 && j <= di->fpo_size);
2070      di->fpo_size = j;
2071
2072      /* And record min/max */
2073      /* biasing shouldn't cause wraparound (?!) */
2074      if (di->fpo_size > 0) {
2075         vg_assert(min_avma <= max_avma); /* should always hold */
2076         di->fpo_minavma = min_avma;
2077         di->fpo_maxavma = max_avma;
2078      } else {
2079         di->fpo_minavma = 0;
2080         di->fpo_maxavma = 0;
2081      }
2082
2083      if (0) {
2084         VG_(printf)("FPO: min/max avma %#lx %#lx\n",
2085                     di->fpo_minavma, di->fpo_maxavma);
2086      }
2087
2088      n_fpos_read += (ULong)di->fpo_size;
2089   }
2090   // END clean up FPO data
2091
2092   pdb_convert_types_header( &types, types_image );
2093   switch ( types.version ) {
2094      case 19950410:      /* VC 4.0 */
2095      case 19951122:
2096      case 19961031:      /* VC 5.0 / 6.0 */
2097      case 20040203:      /* VC 7.0  FIXME??  */
2098         break;
2099      default:
2100         if (VG_(clo_verbosity) > 1)
2101            VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2102                      "Unknown .pdb type info version %ld\n", types.version );
2103   }
2104
2105   header_size = 0;
2106   pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2107   switch ( symbols.version ) {
2108      case 0:            /* VC 4.0 */
2109      case 19960307:     /* VC 5.0 */
2110      case 19970606:     /* VC 6.0 */
2111      case 19990903:     /* VC 7.0  FIXME?? */
2112         break;
2113      default:
2114         if (VG_(clo_verbosity) > 1)
2115            VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2116                      "Unknown .pdb symbol info version %ld\n",
2117                      symbols.version );
2118   }
2119
2120   /*
2121    * Read global symbol table
2122    */
2123   modimage = pdb->read_file( pdb, symbols.gsym_file, &len_modimage );
2124   if (modimage) {
2125      if (debug)
2126         VG_(umsg)("\n");
2127      if (VG_(clo_verbosity) > 1)
2128         VG_(umsg)("LOAD_PDB_DEBUGINFO: Reading global symbols\n" );
2129      DEBUG_SnarfCodeView( di, pe_avma, sectp_avma, modimage, 0, len_modimage );
2130      ML_(dinfo_free)( modimage );
2131   }
2132
2133   /*
2134    * Read per-module symbol / linenumber tables
2135    */
2136   file = symbols_image + header_size;
2137   while ( file - symbols_image < header_size + symbols.module_size ) {
2138      int file_nr, /* file_index, */ symbol_size, lineno_size;
2139      const char *file_name;
2140
2141      if ( symbols.version < 19970000 ) {
2142         const PDB_SYMBOL_FILE *sym_file = (const PDB_SYMBOL_FILE *) file;
2143         file_nr     = sym_file->file;
2144         file_name   = sym_file->filename;
2145         /* file_index  = sym_file->range.index; */ /* UNUSED */
2146         symbol_size = sym_file->symbol_size;
2147         lineno_size = sym_file->lineno_size;
2148      } else {
2149         const PDB_SYMBOL_FILE_EX *sym_file = (const PDB_SYMBOL_FILE_EX *) file;
2150         file_nr     = sym_file->file;
2151         file_name   = sym_file->filename;
2152         /* file_index  = sym_file->range.index; */ /* UNUSED */
2153         symbol_size = sym_file->symbol_size;
2154         lineno_size = sym_file->lineno_size;
2155      }
2156
2157      modimage = pdb->read_file( pdb, file_nr, 0 );
2158      if (modimage) {
2159         Int total_size;
2160         if (0) VG_(printf)("lineno_size %d symbol_size %d\n",
2161                            lineno_size, symbol_size );
2162
2163         total_size = pdb_get_file_size(pdb, file_nr);
2164
2165         if (symbol_size) {
2166            if (debug)
2167               VG_(umsg)("\n");
2168            if (VG_(clo_verbosity) > 1)
2169               VG_(umsg)("LOAD_PDB_DEBUGINFO: Reading symbols for %s\n",
2170                                        file_name );
2171            n_syms_read
2172               += DEBUG_SnarfCodeView( di, pe_avma, sectp_avma, modimage,
2173                                           sizeof(unsigned long),
2174                                           symbol_size );
2175         }
2176
2177         if (lineno_size) {
2178            if (debug)
2179               VG_(umsg)("\n");
2180            if (VG_(clo_verbosity) > 1)
2181               VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2182                         "Reading lines for %s\n", file_name );
2183            n_lines_read
2184               += DEBUG_SnarfLinetab( di, pe_avma, sectp_avma,
2185                                          modimage + symbol_size, lineno_size );
2186         }
2187
2188         /* anyway, lineno_size doesn't see to really be the size of
2189          * the line number information, and it's not clear yet when
2190          * to call for linetab2...
2191          */
2192         if (0) VG_(printf)("Reading lines for %s\n", file_name );
2193         n_line2s_read
2194            += codeview_dump_linetab2(
2195                  di, pe_avma, sectp_avma,
2196                      (HChar*)modimage + symbol_size + lineno_size,
2197                      total_size - (symbol_size + lineno_size),
2198                  /* if filesimage is NULL, pass that directly onwards
2199                     to codeview_dump_linetab2, so it knows not to
2200                     poke around in there. */
2201                  filesimage ? filesimage + 12 : NULL,
2202                  filessize, "        "
2203               );
2204
2205         ML_(dinfo_free)( modimage );
2206      }
2207
2208      file_name += VG_(strlen)(file_name) + 1;
2209      file = (const char *)(
2210                (unsigned long)(file_name
2211                                + VG_(strlen)(file_name) + 1 + 3) & ~3 );
2212   }
2213
2214   /*
2215    * Cleanup
2216    */
2217   if ( symbols_image ) ML_(dinfo_free)( symbols_image );
2218   if ( types_image ) ML_(dinfo_free)( types_image );
2219   if ( pdb->u.jg.toc ) ML_(dinfo_free)( pdb->u.jg.toc );
2220
2221   if (VG_(clo_verbosity) > 1) {
2222      VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2223                "    # symbols read = %llu\n", n_syms_read );
2224      VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2225                "    # lines   read = %llu\n", n_lines_read );
2226      VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2227                "    # line2s  read = %llu\n", n_line2s_read );
2228      VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2229                "    # fpos    read = %llu\n", n_fpos_read );
2230   }
2231}
2232
2233
2234/*------------------------------------------------------------*/
2235/*---                                                      ---*/
2236/*--- TOP LEVEL for PDB reading                            ---*/
2237/*---                                                      ---*/
2238/*------------------------------------------------------------*/
2239
2240/* Read line, symbol and unwind information from a PDB file.
2241*/
2242Bool ML_(read_pdb_debug_info)(
2243        DebugInfo* di,
2244        Addr       obj_avma,
2245        PtrdiffT   obj_bias,
2246        void*      pdbimage,
2247        SizeT      n_pdbimage,
2248        const HChar* pdbname,
2249        ULong      pdbmtime
2250     )
2251{
2252   Char*    pe_seg_avma;
2253   Int      i;
2254   Addr     mapped_avma, mapped_end_avma;
2255   unsigned signature;
2256   void*    hdr;
2257   struct pdb_reader     reader;
2258   IMAGE_DOS_HEADER*     dos_avma;
2259   IMAGE_NT_HEADERS*     ntheaders_avma;
2260   IMAGE_SECTION_HEADER* sectp_avma;
2261   IMAGE_SECTION_HEADER* pe_sechdr_avma;
2262
2263   if (VG_(clo_verbosity) > 1)
2264       VG_(umsg)("LOAD_PDB_DEBUGINFO: Processing PDB file %s\n", pdbname );
2265
2266   dos_avma = (IMAGE_DOS_HEADER *)obj_avma;
2267   if (dos_avma->e_magic != IMAGE_DOS_SIGNATURE)
2268      return False;
2269
2270   ntheaders_avma
2271      = (IMAGE_NT_HEADERS *)((Char*)dos_avma + dos_avma->e_lfanew);
2272   if (ntheaders_avma->Signature != IMAGE_NT_SIGNATURE)
2273      return False;
2274
2275   sectp_avma
2276      = (IMAGE_SECTION_HEADER *)(
2277           (Char*)ntheaders_avma
2278           + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2279           + ntheaders_avma->FileHeader.SizeOfOptionalHeader
2280        );
2281
2282   /* JRS: this seems like something of a hack. */
2283   di->soname = ML_(dinfo_strdup)("di.readpdb.rpdi.1", pdbname);
2284
2285   /* someone (ie WINE) is loading a Windows PE format object.  we
2286      need to use its details to determine which area of memory is
2287      executable... */
2288   pe_seg_avma
2289      = (Char*)ntheaders_avma
2290        + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2291        + ntheaders_avma->FileHeader.SizeOfOptionalHeader;
2292
2293   /* Iterate over PE headers and fill our section mapping table. */
2294   for ( i = 0;
2295         i < ntheaders_avma->FileHeader.NumberOfSections;
2296         i++, pe_seg_avma += sizeof(IMAGE_SECTION_HEADER) ) {
2297      pe_sechdr_avma = (IMAGE_SECTION_HEADER *)pe_seg_avma;
2298
2299      if (VG_(clo_verbosity) > 1) {
2300         /* Copy name, it can be 8 chars and not NUL-terminated */
2301         char name[9];
2302         VG_(memcpy)(name, pe_sechdr_avma->Name, 8);
2303         name[8] = '\0';
2304         VG_(umsg)("LOAD_PDB_DEBUGINFO:"
2305                   "   Scanning PE section %ps at avma %#lx svma %#lx\n",
2306                   name, obj_avma + pe_sechdr_avma->VirtualAddress,
2307                   pe_sechdr_avma->VirtualAddress);
2308      }
2309
2310      if (pe_sechdr_avma->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2311         continue;
2312
2313      mapped_avma     = (Addr)obj_avma + pe_sechdr_avma->VirtualAddress;
2314      mapped_end_avma = mapped_avma + pe_sechdr_avma->Misc.VirtualSize;
2315
2316      DebugInfoMapping map;
2317      map.avma = mapped_avma;
2318      map.size = pe_sechdr_avma->Misc.VirtualSize;
2319      map.foff = pe_sechdr_avma->PointerToRawData;
2320      map.ro   = False;
2321
2322      if (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_CODE) {
2323         /* Ignore uninitialised code sections - if you have
2324            incremental linking enabled in Visual Studio then you will
2325            get a uninitialised code section called .textbss before
2326            the real text section and valgrind will compute the wrong
2327            avma value and hence the wrong bias. */
2328         if (!(pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
2329            map.rx   = True;
2330            map.rw   = False;
2331            VG_(addToXA)(di->fsm.maps, &map);
2332            di->fsm.have_rx_map = True;
2333
2334            di->text_present = True;
2335            if (di->text_avma == 0) {
2336               di->text_svma = pe_sechdr_avma->VirtualAddress;
2337               di->text_avma = mapped_avma;
2338               di->text_size = pe_sechdr_avma->Misc.VirtualSize;
2339            } else {
2340               di->text_size = mapped_end_avma - di->text_avma;
2341            }
2342         }
2343      }
2344      else if (pe_sechdr_avma->Characteristics
2345               & IMAGE_SCN_CNT_INITIALIZED_DATA) {
2346         map.rx   = False;
2347         map.rw   = True;
2348         VG_(addToXA)(di->fsm.maps, &map);
2349         di->fsm.have_rw_map = True;
2350
2351         di->data_present = True;
2352         if (di->data_avma == 0) {
2353            di->data_avma = mapped_avma;
2354            di->data_size = pe_sechdr_avma->Misc.VirtualSize;
2355         } else {
2356            di->data_size = mapped_end_avma - di->data_avma;
2357         }
2358      }
2359      else if (pe_sechdr_avma->Characteristics
2360               & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
2361         di->bss_present = True;
2362         if (di->bss_avma == 0) {
2363            di->bss_avma = mapped_avma;
2364            di->bss_size = pe_sechdr_avma->Misc.VirtualSize;
2365         } else {
2366            di->bss_size = mapped_end_avma - di->bss_avma;
2367         }
2368      }
2369   }
2370
2371   if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
2372      vg_assert(di->fsm.filename);
2373      TRACE_SYMTAB("\n");
2374      TRACE_SYMTAB("------ start PE OBJECT with PDB INFO "
2375                   "---------------------\n");
2376      TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
2377      TRACE_SYMTAB("\n");
2378   }
2379
2380   di->text_bias = obj_bias;
2381
2382   if (VG_(clo_verbosity) > 1) {
2383      for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2384         const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2385         if (map->rx)
2386            VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2387                      "rx_map: avma %#lx size %7lu foff %llu\n",
2388                      map->avma, map->size, (Off64T)map->foff);
2389      }
2390      for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2391         const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2392         if (map->rw)
2393            VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2394                      "rw_map: avma %#lx size %7lu foff %llu\n",
2395                      map->avma, map->size, (Off64T)map->foff);
2396      }
2397
2398      VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2399                "  text: avma %#lx svma %#lx size %7lu bias %#lx\n",
2400                di->text_avma, di->text_svma,
2401                di->text_size, di->text_bias);
2402   }
2403
2404   /*
2405    * Read in TOC and well-known files
2406    */
2407   signature = 0;
2408   hdr = find_pdb_header( pdbimage, &signature );
2409   if (0==hdr)
2410      return False; /* JRS: significance? no pdb header? */
2411
2412   VG_(memset)(&reader, 0, sizeof(reader));
2413   reader.u.jg.header = hdr;
2414
2415   if (0==VG_(strncmp)((char const *)&signature, "DS\0\0", 4)) {
2416      struct PDB_DS_ROOT* root;
2417      pdb_ds_init( &reader, pdbimage, n_pdbimage );
2418      root = reader.read_file( &reader, 1, 0 );
2419      reader.u.ds.root = root;
2420      if (root) {
2421         pdb_check_root_version_and_timestamp(
2422            pdbname, pdbmtime, root->version, root->TimeDateStamp );
2423      }
2424      pdb_dump( &reader, di, obj_avma, obj_bias, sectp_avma );
2425      if (root) {
2426         ML_(dinfo_free)( root );
2427      }
2428   }
2429   else
2430   if (0==VG_(strncmp)((char const *)&signature, "JG\0\0", 4)) {
2431      struct PDB_JG_ROOT* root;
2432      pdb_jg_init( &reader, pdbimage, n_pdbimage );
2433      root = reader.read_file( &reader, 1, 0 );
2434      reader.u.jg.root = root;
2435      if (root) {
2436         pdb_check_root_version_and_timestamp(
2437            pdbname, pdbmtime, root->version, root->TimeDateStamp);
2438      }
2439      pdb_dump( &reader, di, obj_avma, obj_bias, sectp_avma );
2440      if (root) {
2441         ML_(dinfo_free)( root );
2442      }
2443   }
2444
2445   if (1) {
2446      TRACE_SYMTAB("\n------ Canonicalising the "
2447                   "acquired info ------\n");
2448      /* prepare read data for use */
2449      ML_(canonicaliseTables)( di );
2450      /* notify m_redir about it */
2451      TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
2452      VG_(redir_notify_new_DebugInfo)( di );
2453      /* Note that we succeeded */
2454      di->have_dinfo = True;
2455   } else {
2456      TRACE_SYMTAB("\n------ PE with PDB reading failed ------\n");
2457      /* Something went wrong (eg. bad ELF file).  Should we delete
2458         this DebugInfo?  No - it contains info on the rw/rx
2459         mappings, at least. */
2460   }
2461
2462   TRACE_SYMTAB("\n");
2463   TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
2464   TRACE_SYMTAB("------ end PE OBJECT with PDB INFO "
2465                "--------------------\n");
2466   TRACE_SYMTAB("\n");
2467
2468   return True;
2469}
2470
2471
2472/* Examine a PE file to see if it states the path of an associated PDB
2473   file; if so return that.  Caller must deallocate with
2474   ML_(dinfo_free).
2475*/
2476
2477HChar* ML_(find_name_of_pdb_file)( const HChar* pename )
2478{
2479   /* This is a giant kludge, of the kind "you did WTF?!?", but it
2480      works. */
2481   Bool   do_cleanup = False;
2482   HChar  tmpnameroot[50];     // large enough
2483   HChar  tmpname[VG_(mkstemp_fullname_bufsz)(sizeof tmpnameroot - 1)];
2484   Int    fd, r;
2485   HChar* res = NULL;
2486
2487   if (!pename)
2488      goto out;
2489
2490   fd = -1;
2491   VG_(memset)(tmpnameroot, 0, sizeof(tmpnameroot));
2492   VG_(sprintf)(tmpnameroot, "petmp%d", VG_(getpid)());
2493   VG_(memset)(tmpname, 0, sizeof(tmpname));
2494   fd = VG_(mkstemp)( tmpnameroot, tmpname );
2495   if (fd == -1) {
2496      VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2497                "Find PDB file: Can't create temporary file %s\n", tmpname);
2498      goto out;
2499   }
2500   do_cleanup = True;
2501
2502   /* Make up the command to run, essentially:
2503      sh -c "strings (pename) | egrep '\.pdb$|\.PDB$' > (tmpname)"
2504   */
2505   const HChar* sh      = "/bin/sh";
2506   const HChar* strings = "/usr/bin/strings";
2507   const HChar* egrep   = "/usr/bin/egrep";
2508
2509   /* (sh) -c "(strings) (pename) | (egrep) 'pdb' > (tmpname) */
2510   Int cmdlen = VG_(strlen)(strings) + VG_(strlen)(pename)
2511                + VG_(strlen)(egrep) + VG_(strlen)(tmpname)
2512                + 100/*misc*/;
2513   HChar* cmd = ML_(dinfo_zalloc)("di.readpe.fnopf.cmd", cmdlen);
2514   VG_(sprintf)(cmd, "%s -c \"%s '%s' | %s '\\.pdb$|\\.PDB$' >> %s\"",
2515                     sh, strings, pename, egrep, tmpname);
2516   vg_assert(cmd[cmdlen-1] == 0);
2517   if (0) VG_(printf)("QQQQQQQQ: %s\n", cmd);
2518
2519   r = VG_(system)( cmd );
2520   if (r) {
2521      VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2522                "Find PDB file: Command failed:\n   %s\n", cmd);
2523      goto out;
2524   }
2525
2526   /* Find out how big the file is, and get it aboard. */
2527   struct vg_stat stat_buf;
2528   VG_(memset)(&stat_buf, 0, sizeof(stat_buf));
2529
2530   SysRes sr = VG_(stat)(tmpname, &stat_buf);
2531   if (sr_isError(sr)) {
2532      VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: can't stat %s\n", tmpname);
2533      goto out;
2534   }
2535
2536   Int szB = (Int)stat_buf.size;
2537   if (szB == 0) {
2538      VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: %s is empty\n", tmpname);
2539      goto out;
2540   }
2541   /* 6 == strlen("X.pdb\n") */
2542   if (szB < 6 || szB > 1024/*let's say*/) {
2543      VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: %s has implausible size %d\n",
2544                tmpname, szB);
2545      goto out;
2546   }
2547
2548   HChar* pdbname = ML_(dinfo_zalloc)("di.readpe.fnopf.pdbname", szB + 1);
2549   pdbname[szB] = 0;
2550
2551   Int nread = VG_(read)(fd, pdbname, szB);
2552   if (nread != szB) {
2553      VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: read of %s failed\n", tmpname);
2554      goto out;
2555   }
2556   vg_assert(pdbname[szB] == 0);
2557
2558   /* Check we've got something remotely sane -- must have one dot and
2559      one \n in it, and the \n must be at the end */
2560   Bool saw_dot = False;
2561   Int  saw_n_crs = 0;
2562   Int  i;
2563   for (i = 0; pdbname[i]; i++) {
2564      if (pdbname[i] == '.')  saw_dot = True;
2565      if (pdbname[i] == '\n') saw_n_crs++;
2566   }
2567   if (!saw_dot || saw_n_crs != 1 || pdbname[szB-1] != '\n') {
2568      VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: can't make sense of: %s\n", pdbname);
2569      goto out;
2570   }
2571   /* Change the \n to a terminating zero, so we have a "normal" string */
2572   pdbname[szB-1] = 0;
2573
2574   if (0) VG_(printf)("QQQQQQQQ: got %s\n", pdbname);
2575
2576   res = pdbname;
2577   goto out;
2578
2579  out:
2580   if (do_cleanup) {
2581      VG_(close)(fd);
2582      VG_(unlink)( tmpname );
2583   }
2584   return res;
2585}
2586
2587#endif // defined(VGO_linux) || defined(VGO_darwin)
2588
2589/*--------------------------------------------------------------------*/
2590/*--- end                                                          ---*/
2591/*--------------------------------------------------------------------*/
2592