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