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