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