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