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