• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
118 typedef  UInt   DWORD;
119 typedef  UShort WORD;
120 typedef  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)
135 typedef 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 
173 typedef 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 
183 typedef 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 
190 typedef 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 
231 typedef 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 
239 typedef 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 
311 typedef 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)
324 typedef 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:
335 struct 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 
346 struct 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 
357 struct PDB_JG_TOC
358 {
359     unsigned int  nFiles;
360     PDB_FILE file[ 1 ];
361 
362 };
363 
364 struct PDB_DS_TOC
365 {
366     unsigned int num_files;
367     unsigned int file_size[1];
368 };
369 
370 struct 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 
379 struct 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 
389 typedef 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 
400 typedef 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 
420 typedef 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 
432 typedef 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 
446 typedef 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 
461 typedef 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 
477 typedef 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 
485 typedef 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 
495 typedef 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 
508 typedef 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 
532 struct 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 
544 union 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 
972 struct 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 
pdb_ds_read(struct pdb_reader * pdb,unsigned * block_list,unsigned size)991 static 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 
pdb_jg_read(struct pdb_reader * pdb,unsigned short * block_list,int size)1017 static 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 
find_pdb_header(UChar * pdbimage,unsigned * signature)1037 static 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 
pdb_ds_read_file(struct pdb_reader * reader,unsigned file_number,unsigned * plength)1052 static 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 
pdb_jg_read_file(struct pdb_reader * pdb,unsigned fileNr,unsigned * plength)1077 static 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 
pdb_ds_init(struct pdb_reader * reader,UChar * pdbimage,SizeT n_pdbimage)1101 static 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 
pdb_jg_init(struct pdb_reader * reader,char * pdbimage,unsigned n_pdbimage)1119 static 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 
1134 static
pdb_check_root_version_and_timestamp(char * pdbname,ULong pdbmtime,unsigned version,UInt TimeDateStamp)1135 void 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 
pdb_get_file_size(struct pdb_reader * reader,unsigned idx)1161 static 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 
pdb_convert_types_header(PDB_TYPES * types,char * image)1170 static 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 
pdb_convert_symbols_header(PDB_SYMBOLS * symbols,int * header_size,char * image)1191 static 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 
DEBUG_SnarfCodeView(DebugInfo * di,IMAGE_SECTION_HEADER * sectp,void * root,Int offset,Int size)1224 static 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 
1519 union any_size
1520 {
1521           char const *c;
1522          short const *s;
1523            int const *i;
1524   unsigned int const *ui;
1525 };
1526 
1527 struct startend
1528 {
1529   unsigned int          start;
1530   unsigned int          end;
1531 };
1532 
DEBUG_SnarfLinetab(DebugInfo * di,IMAGE_SECTION_HEADER * sectp,Char * linetab,Int size)1533 static 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 
1674 struct 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 
1684 struct 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 
codeview_dump_linetab2(DebugInfo * di,Char * linetab,DWORD size,Char * strimage,DWORD strsize,Char * pfx)1703 static 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 
cmp_FPO_DATA_for_canonicalisation(void * f1V,void * f2V)1814 static 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 */
pdb_dump(struct pdb_reader * pdb,DebugInfo * di,Addr pe_avma,Int unknown_purpose__reloc,IMAGE_SECTION_HEADER * sectp_avma)1830 static 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 */
ML_(read_pdb_debug_info)2205 Bool 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 
ML_(find_name_of_pdb_file)2441 HChar* 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