Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / coregrind / m_debuginfo / readpdb.c
blob5506dde2b367bad3be9847bcda61e8a03851ecd6
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, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
33 02111-1307, USA.
35 The GNU General Public License is contained in the file COPYING.
38 #if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
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"
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
59 /*------------------------------------------------------------*/
60 /*--- ---*/
61 /*--- Biasing ---*/
62 /*--- ---*/
63 /*------------------------------------------------------------*/
65 /* There are just two simple ways of biasing in use here.
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".
71 The second type of debug info (FPOs) contain VAs relative
72 directly to the image base, without the segment indirection.
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.
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.
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. */
90 /*------------------------------------------------------------*/
91 /*--- ---*/
92 /*--- PE/PDB definitions ---*/
93 /*--- ---*/
94 /*------------------------------------------------------------*/
96 typedef UInt DWORD;
97 typedef UShort WORD;
98 typedef UChar BYTE;
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/
107 * File formats definitions
109 #define OFFSET_OF(__c,__f) ((int)(((char*)&(((__c*)0)->__f))-((char*)0)))
110 #define WIN32_PATH_MAX 256
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;
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 */
142 /* Subsystem Values */
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
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;
161 typedef struct _IMAGE_DATA_DIRECTORY {
162 unsigned long VirtualAddress;
163 unsigned long Size;
164 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
166 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
168 typedef struct _IMAGE_OPTIONAL_HEADER {
170 /* Standard fields */
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;
182 /* NT additional fields */
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;
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;
215 #define IMAGE_SIZEOF_SHORT_NAME 8
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;
233 #define IMAGE_SIZEOF_SECTION_HEADER 40
235 #define IMAGE_FIRST_SECTION(ntheader) \
236 ((PIMAGE_SECTION_HEADER)((LPunsigned char)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \
237 ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader))
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 */
247 #define IMAGE_SCN_CNT_CODE 0x00000020
248 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
249 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
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
257 /* 0x00002000 - Reserved */
258 /* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */
259 #define IMAGE_SCN_MEM_FARDATA 0x00008000
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
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 */
276 #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
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
287 #pragma pack()
289 typedef struct _GUID /* 16 bytes */
291 unsigned int Data1;
292 unsigned short Data2;
293 unsigned short Data3;
294 unsigned char Data4[ 8 ];
295 } GUID;
297 /*========================================================================
298 * Process PDB file.
301 #pragma pack(1)
302 typedef struct _PDB_FILE
304 unsigned long size;
305 unsigned long unknown;
307 } PDB_FILE, *PPDB_FILE;
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
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 ];
324 struct PDB_DS_HEADER
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;
335 struct PDB_JG_TOC
337 unsigned int nFiles;
338 PDB_FILE file[ 1 ];
342 struct PDB_DS_TOC
344 unsigned int num_files;
345 unsigned int file_size[1];
348 struct PDB_JG_ROOT
350 unsigned int version;
351 unsigned int TimeDateStamp;
352 unsigned int age;
353 unsigned int cbNames;
354 char names[ 1 ];
357 struct PDB_DS_ROOT
359 unsigned int version;
360 unsigned int TimeDateStamp;
361 unsigned int age;
362 GUID guid;
363 unsigned int cbNames;
364 char names[1];
367 typedef struct _PDB_TYPES_OLD
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;
376 } PDB_TYPES_OLD, *PPDB_TYPES_OLD;
378 typedef struct _PDB_TYPES
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;
396 } PDB_TYPES, *PPDB_TYPES;
398 typedef struct _PDB_SYMBOL_RANGE
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;
408 } PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
410 typedef struct _PDB_SYMBOL_RANGE_EX
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;
422 } PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
424 typedef struct _PDB_SYMBOL_FILE
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 ];
437 } PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
439 typedef struct _PDB_SYMBOL_FILE_EX
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 ];
453 } PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
455 typedef struct _PDB_SYMBOL_SOURCE
457 unsigned short nModules;
458 unsigned short nSrcFiles;
459 unsigned short table[ 1 ];
461 } PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
463 typedef struct _PDB_SYMBOL_IMPORT
465 unsigned long unknown1;
466 unsigned long unknown2;
467 unsigned long TimeDateStamp;
468 unsigned long nRequests;
469 char filename[ 1 ];
471 } PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
473 typedef struct _PDB_SYMBOLS_OLD
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;
484 } PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
486 typedef struct _PDB_SYMBOLS
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 ];
501 } PDB_SYMBOLS, *PPDB_SYMBOLS;
502 #pragma pack()
504 /*========================================================================
505 * Process CodeView symbol information.
508 /* from wine-1.0/include/wine/mscvpdb.h */
510 struct p_string /* "Pascal string": prefixed by byte containing length */
512 unsigned char namelen;
513 char name[1];
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.
522 union codeview_symbol
524 struct
526 short int len;
527 short int id;
528 } generic;
530 struct
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;
540 struct
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;
550 struct
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;
560 struct
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;
574 struct
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;
588 struct
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;
605 struct
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;
622 struct
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;
639 struct
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;
649 struct
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;
659 struct
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;
668 struct
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;
677 struct
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;
686 struct
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;
696 struct
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;
706 struct
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;
716 struct
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;
726 struct
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;
738 struct
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;
750 struct
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;
760 struct
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;
770 struct
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;
781 struct
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;
792 struct
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;
803 struct
805 short int len;
806 short int id;
807 unsigned short type;
808 struct p_string p_name;
809 } udt_v1;
811 struct
813 short int len;
814 short int id;
815 unsigned type;
816 struct p_string p_name;
817 } udt_v2;
819 struct
821 short int len;
822 short int id;
823 unsigned int type;
824 char name[1]; /* terminated by '\0' */
825 } udt_v3;
827 struct
829 short int len;
830 short int id;
831 char signature[4];
832 struct p_string p_name;
833 } objname_v1;
835 struct
837 short int len;
838 short int id;
839 unsigned int unknown;
840 struct p_string p_name;
841 } compiland_v1;
843 struct
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;
852 struct
854 short int len;
855 short int id;
856 unsigned int unknown;
857 char name[1]; /* terminated by '\0' */
858 } compiland_v3;
860 struct
862 short int len;
863 short int id;
864 unsigned int offset;
865 unsigned short segment;
866 } ssearch_v1;
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
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
900 #define S_PROCREF_V1 0x0400
901 #define S_DATAREF_V1 0x0401
902 #define S_ALIGN_V1 0x0402
903 #define S_LPROCREF_V1 0x0403
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
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
944 /*------------------------------------------------------------*/
945 /*--- ---*/
946 /*--- pdb-reading: bits and pieces ---*/
947 /*--- ---*/
948 /*------------------------------------------------------------*/
950 struct pdb_reader
952 void* (*read_file)(const struct pdb_reader*, unsigned, unsigned *);
953 // JRS 2009-Apr-8: .uu_n_pdbimage is never used.
954 UChar* pdbimage; // image address
955 SizeT uu_n_pdbimage; // size
956 union {
957 struct {
958 struct PDB_JG_HEADER* header;
959 struct PDB_JG_TOC* toc;
960 struct PDB_JG_ROOT* root;
961 } jg;
962 struct {
963 struct PDB_DS_HEADER* header;
964 struct PDB_DS_TOC* toc;
965 struct PDB_DS_ROOT* root;
966 } ds;
967 } u;
971 static void* pdb_ds_read( const struct pdb_reader* pdb,
972 const unsigned* block_list,
973 unsigned size )
975 unsigned blocksize, nBlocks;
976 UChar* buffer;
977 UInt i;
979 if (!size) return NULL;
980 if (size > 512 * 1024 * 1024) {
981 VG_(umsg)("LOAD_PDB_DEBUGINFO: pdb_ds_read: implausible size "
982 "(%u); skipping -- possible invalid .pdb file?\n", size);
983 return NULL;
986 blocksize = pdb->u.ds.header->block_size;
987 nBlocks = (size + blocksize - 1) / blocksize;
988 buffer = ML_(dinfo_zalloc)("di.readpe.pdr.1", nBlocks * blocksize);
989 for (i = 0; i < nBlocks; i++)
990 VG_(memcpy)( buffer + i * blocksize,
991 pdb->pdbimage + block_list[i] * blocksize,
992 blocksize );
993 return buffer;
997 static void* pdb_jg_read( const struct pdb_reader* pdb,
998 const unsigned short* block_list,
999 int size )
1001 unsigned blocksize, nBlocks;
1002 UChar* buffer;
1003 UInt i;
1004 //VG_(printf)("pdb_read %p %p %d\n", pdb, block_list, size);
1005 if ( !size ) return NULL;
1007 blocksize = pdb->u.jg.header->blocksize;
1008 nBlocks = (size + blocksize-1) / blocksize;
1009 buffer = ML_(dinfo_zalloc)("di.readpe.pjr.1", nBlocks * blocksize);
1010 for ( i = 0; i < nBlocks; i++ )
1011 VG_(memcpy)( buffer + i*blocksize,
1012 pdb->pdbimage + block_list[i]*blocksize, blocksize );
1013 return buffer;
1017 static void* find_pdb_header( void* pdbimage,
1018 unsigned* signature )
1020 static const HChar pdbtxt[]= "Microsoft C/C++";
1021 HChar* txteof = VG_(strchr)(pdbimage, '\032');
1022 if (! txteof) {
1023 VG_(umsg)("LOAD_PDB_DEBUGINFO: \\032 header character not found. "
1024 " possible invalid/unsupported pdb file format?\n");
1025 return NULL;
1027 if (0!=VG_(strncmp)(pdbimage, pdbtxt, -1+ sizeof(pdbtxt))) {
1028 VG_(umsg)("LOAD_PDB_DEBUGINFO: %s header string not found. "
1029 " possible invalid/unsupported pdb file format?\n",
1030 pdbtxt);;
1031 return NULL;
1034 *signature = *(unsigned*)(1+ txteof);
1035 HChar *img_addr = pdbimage; // so we can do address arithmetic
1036 return ((~3& (3+ (4+ 1+ (txteof - img_addr)))) + img_addr);
1040 static void* pdb_ds_read_file( const struct pdb_reader* reader,
1041 unsigned file_number,
1042 unsigned* plength )
1044 unsigned i, *block_list;
1045 if (!reader->u.ds.toc || file_number >= reader->u.ds.toc->num_files)
1046 return NULL;
1047 if (reader->u.ds.toc->file_size[file_number] == 0
1048 || reader->u.ds.toc->file_size[file_number] == 0xFFFFFFFF)
1049 return NULL;
1051 block_list
1052 = reader->u.ds.toc->file_size + reader->u.ds.toc->num_files;
1053 for (i = 0; i < file_number; i++)
1054 block_list += (reader->u.ds.toc->file_size[i]
1055 + reader->u.ds.header->block_size - 1)
1057 reader->u.ds.header->block_size;
1058 if (plength)
1059 *plength = reader->u.ds.toc->file_size[file_number];
1060 return pdb_ds_read( reader, block_list,
1061 reader->u.ds.toc->file_size[file_number]);
1065 static void* pdb_jg_read_file( const struct pdb_reader* pdb,
1066 unsigned fileNr,
1067 unsigned *plength )
1069 //VG_(printf)("pdb_read_file %p %d\n", pdb, fileNr);
1070 unsigned blocksize = pdb->u.jg.header->blocksize;
1071 struct PDB_JG_TOC* toc = pdb->u.jg.toc;
1072 unsigned i;
1073 unsigned short* block_list;
1075 if ( !toc || fileNr >= toc->nFiles )
1076 return NULL;
1078 block_list
1079 = (unsigned short *) &toc->file[ toc->nFiles ];
1080 for ( i = 0; i < fileNr; i++ )
1081 block_list += (toc->file[i].size + blocksize-1) / blocksize;
1083 if (plength)
1084 *plength = toc->file[fileNr].size;
1085 return pdb_jg_read( pdb, block_list, toc->file[fileNr].size );
1089 static void pdb_ds_init( struct pdb_reader * reader,
1090 UChar* pdbimage,
1091 SizeT n_pdbimage )
1093 reader->read_file = pdb_ds_read_file;
1094 reader->pdbimage = pdbimage;
1095 reader->uu_n_pdbimage = n_pdbimage;
1096 reader->u.ds.toc
1097 = pdb_ds_read(
1098 reader,
1099 (unsigned*)(reader->u.ds.header->block_size
1100 * reader->u.ds.header->toc_page
1101 + reader->pdbimage),
1102 reader->u.ds.header->toc_size
1107 static void pdb_jg_init( struct pdb_reader* reader,
1108 void* pdbimage,
1109 unsigned n_pdbimage )
1111 reader->read_file = pdb_jg_read_file;
1112 reader->pdbimage = pdbimage;
1113 reader->uu_n_pdbimage = n_pdbimage;
1114 reader->u.jg.toc = pdb_jg_read(reader,
1115 reader->u.jg.header->toc_block,
1116 reader->u.jg.header->toc.size);
1120 static
1121 void pdb_check_root_version_and_timestamp( const HChar* pdbname,
1122 ULong pdbmtime,
1123 UInt version,
1124 UInt TimeDateStamp )
1126 switch ( version ) {
1127 case 19950623: /* VC 4.0 */
1128 case 19950814:
1129 case 19960307: /* VC 5.0 */
1130 case 19970604: /* VC 6.0 */
1131 case 20000404: /* VC 7.0 FIXME?? */
1132 break;
1133 default:
1134 if (VG_(clo_verbosity) > 1)
1135 VG_(umsg)("LOAD_PDB_DEBUGINFO: "
1136 "Unknown .pdb root block version %u\n", version );
1138 if ( TimeDateStamp != pdbmtime ) {
1139 if (VG_(clo_verbosity) > 1)
1140 VG_(umsg)("LOAD_PDB_DEBUGINFO: Wrong time stamp of .PDB file "
1141 "%s (0x%08x, 0x%08llx)\n",
1142 pdbname, TimeDateStamp, pdbmtime );
1147 static DWORD pdb_get_file_size( const struct pdb_reader* reader, unsigned idx )
1149 if (reader->read_file == pdb_jg_read_file)
1150 return reader->u.jg.toc->file[idx].size;
1151 else
1152 return reader->u.ds.toc->file_size[idx];
1156 static void pdb_convert_types_header( PDB_TYPES *types, char* image )
1158 VG_(memset)( types, 0, sizeof(PDB_TYPES) );
1159 if ( !image )
1160 return;
1161 if ( *(unsigned long *)image < 19960000 ) { /* FIXME: correct version? */
1162 /* Old version of the types record header */
1163 PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
1164 types->version = old->version;
1165 types->type_offset = sizeof(PDB_TYPES_OLD);
1166 types->type_size = old->type_size;
1167 types->first_index = old->first_index;
1168 types->last_index = old->last_index;
1169 types->file = old->file;
1170 } else {
1171 /* New version of the types record header */
1172 *types = *(PDB_TYPES *)image;
1177 static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
1178 int *header_size, char* image )
1180 VG_(memset)( symbols, 0, sizeof(PDB_SYMBOLS) );
1181 if ( !image )
1182 return;
1183 if ( *(unsigned long *)image != 0xffffffff ) {
1184 /* Old version of the symbols record header */
1185 PDB_SYMBOLS_OLD *old = (PDB_SYMBOLS_OLD *)image;
1186 symbols->version = 0;
1187 symbols->module_size = old->module_size;
1188 symbols->offset_size = old->offset_size;
1189 symbols->hash_size = old->hash_size;
1190 symbols->srcmodule_size = old->srcmodule_size;
1191 symbols->pdbimport_size = 0;
1192 symbols->hash1_file = old->hash1_file;
1193 symbols->hash2_file = old->hash2_file;
1194 symbols->gsym_file = old->gsym_file;
1195 *header_size = sizeof(PDB_SYMBOLS_OLD);
1196 } else {
1197 /* New version of the symbols record header */
1198 *symbols = *(PDB_SYMBOLS *)image;
1199 *header_size = sizeof(PDB_SYMBOLS);
1204 /*------------------------------------------------------------*/
1205 /*--- ---*/
1206 /*--- Main stuff: reading of symbol addresses ---*/
1207 /*--- ---*/
1208 /*------------------------------------------------------------*/
1210 static ULong DEBUG_SnarfCodeView(
1211 DebugInfo* di,
1212 PtrdiffT bias,
1213 const IMAGE_SECTION_HEADER* sectp,
1214 const void* root, /* FIXME: better name */
1215 Int offset,
1216 Int size
1219 Int i, length;
1220 DiSym vsym;
1221 const HChar* nmstr;
1222 HChar symname[4096 /*WIN32_PATH_MAX*/]; // FIXME: really ?
1224 Bool debug = di->trace_symtab;
1225 ULong n_syms_read = 0;
1227 if (debug)
1228 VG_(umsg)("BEGIN SnarfCodeView addr=%p offset=%d length=%d\n",
1229 root, offset, size );
1231 VG_(memset)(&vsym, 0, sizeof(vsym)); /* avoid holes */
1233 * Loop over the different types of records and whenever we
1234 * find something we are interested in, record it and move on.
1236 for ( i = offset; i < size; i += length )
1238 const union codeview_symbol *sym =
1239 (const union codeview_symbol *)((const char *)root + i);
1241 length = sym->generic.len + 2;
1243 //VG_(printf)("id=%x len=%d\n", sym->generic.id, length);
1244 switch ( sym->generic.id ) {
1246 default:
1247 if (0) {
1248 const UInt *isym = (const UInt *)sym;
1249 VG_(printf)("unknown id 0x%x len=0x%x at %p\n",
1250 (UInt)sym->generic.id, (UInt)sym->generic.len, sym);
1251 VG_(printf)(" %8x %8x %8x %8x\n",
1252 isym[1], isym[2], isym[3], isym[4]);
1253 VG_(printf)(" %8x %8x %8x %8x\n",
1254 isym[5], isym[6], isym[7], isym[8]);
1256 break;
1258 * Global and local data symbols. We don't associate these
1259 * with any given source file.
1261 case S_GDATA_V1:
1262 case S_LDATA_V1:
1263 case S_PUB_V1:
1264 VG_(memcpy)(symname, sym->data_v1.p_name.name,
1265 sym->data_v1.p_name.namelen);
1266 symname[sym->data_v1.p_name.namelen] = '\0';
1268 if (debug)
1269 VG_(umsg)(" Data %s\n", symname );
1271 if (0 /*VG_(needs).data_syms*/) {
1272 nmstr = ML_(addStr)(di, symname, sym->data_v1.p_name.namelen);
1273 vsym.avmas.main = bias + sectp[sym->data_v1.segment-1].VirtualAddress
1274 + sym->data_v1.offset;
1275 SET_TOCPTR_AVMA(vsym.avmas, 0);
1276 vsym.pri_name = nmstr;
1277 vsym.sec_names = NULL;
1278 vsym.size = sym->data_v1.p_name.namelen;
1279 // FIXME: .namelen is sizeof(.data) including .name[]
1280 vsym.isText = (sym->generic.id == S_PUB_V1);
1281 vsym.isIFunc = False;
1282 vsym.isGlobal = True;
1283 ML_(addSym)( di, &vsym );
1284 n_syms_read++;
1286 break;
1287 case S_GDATA_V2:
1288 case S_LDATA_V2:
1289 case S_PUB_V2: {
1290 Int const k = sym->data_v2.p_name.namelen;
1291 VG_(memcpy)(symname, sym->data_v2.p_name.name, k);
1292 symname[k] = '\0';
1294 if (debug)
1295 VG_(umsg)(" S_GDATA_V2/S_LDATA_V2/S_PUB_V2 %s\n", symname );
1297 if (sym->generic.id==S_PUB_V2 /*VG_(needs).data_syms*/) {
1298 nmstr = ML_(addStr)(di, symname, k);
1299 vsym.avmas.main = bias + sectp[sym->data_v2.segment-1].VirtualAddress
1300 + sym->data_v2.offset;
1301 SET_TOCPTR_AVMA(vsym.avmas, 0);
1302 vsym.pri_name = nmstr;
1303 vsym.sec_names = NULL;
1304 vsym.size = 4000;
1305 // FIXME: data_v2.len is sizeof(.data),
1306 // not size of function!
1307 vsym.isText = !!(IMAGE_SCN_CNT_CODE
1308 & sectp[sym->data_v2.segment-1].Characteristics);
1309 vsym.isIFunc = False;
1310 vsym.isGlobal = True;
1311 ML_(addSym)( di, &vsym );
1312 n_syms_read++;
1314 break;
1316 case S_PUB_V3:
1317 /* not completely sure of those two anyway */
1318 case S_PUB_FUNC1_V3:
1319 case S_PUB_FUNC2_V3: {
1320 Int k = sym->public_v3.len - (-1+ sizeof(sym->public_v3));
1321 if ((-1+ sizeof(symname)) < k)
1322 k = -1+ sizeof(symname);
1323 VG_(memcpy)(symname, sym->public_v3.name, k);
1324 symname[k] = '\0';
1326 if (debug)
1327 VG_(umsg)(" S_PUB_FUNC1_V3/S_PUB_FUNC2_V3/S_PUB_V3 %s\n",
1328 symname );
1330 if (1 /*sym->generic.id==S_PUB_FUNC1_V3
1331 || sym->generic.id==S_PUB_FUNC2_V3*/) {
1332 nmstr = ML_(addStr)(di, symname, k);
1333 vsym.avmas.main = bias + sectp[sym->public_v3.segment-1].VirtualAddress
1334 + sym->public_v3.offset;
1335 SET_TOCPTR_AVMA(vsym.avmas, 0);
1336 vsym.pri_name = nmstr;
1337 vsym.sec_names = NULL;
1338 vsym.size = 4000;
1339 // FIXME: public_v3.len is not length of the
1340 // .text of the function
1341 vsym.isText = !!(IMAGE_SCN_CNT_CODE
1342 & sectp[sym->data_v2.segment-1].Characteristics);
1343 vsym.isIFunc = False;
1344 vsym.isGlobal = True;
1345 ML_(addSym)( di, &vsym );
1346 n_syms_read++;
1348 break;
1352 * Sort of like a global function, but it just points
1353 * to a thunk, which is a stupid name for what amounts to
1354 * a PLT slot in the normal jargon that everyone else uses.
1356 case S_THUNK_V3:
1357 case S_THUNK_V1:
1358 /* valgrind ignores PLTs */ /* JRS: it does? */
1359 break;
1362 * Global and static functions.
1364 case S_GPROC_V1:
1365 case S_LPROC_V1:
1366 VG_(memcpy)(symname, sym->proc_v1.p_name.name,
1367 sym->proc_v1.p_name.namelen);
1368 symname[sym->proc_v1.p_name.namelen] = '\0';
1369 nmstr = ML_(addStr)(di, symname, sym->proc_v1.p_name.namelen);
1370 vsym.avmas.main = bias + sectp[sym->proc_v1.segment-1].VirtualAddress
1371 + sym->proc_v1.offset;
1372 SET_TOCPTR_AVMA(vsym.avmas, 0);
1373 vsym.pri_name = nmstr;
1374 vsym.sec_names = NULL;
1375 vsym.size = sym->proc_v1.proc_len;
1376 vsym.isText = True;
1377 vsym.isIFunc = False;
1378 vsym.isGlobal = sym->generic.id == S_GPROC_V1;
1379 if (debug)
1380 VG_(umsg)(" Adding function %s addr=%#lx length=%u\n",
1381 symname, vsym.avmas.main, vsym.size );
1382 ML_(addSym)( di, &vsym );
1383 n_syms_read++;
1384 break;
1386 case S_GPROC_V2:
1387 case S_LPROC_V2:
1388 VG_(memcpy)(symname, sym->proc_v2.p_name.name,
1389 sym->proc_v2.p_name.namelen);
1390 symname[sym->proc_v2.p_name.namelen] = '\0';
1391 nmstr = ML_(addStr)(di, symname, sym->proc_v2.p_name.namelen);
1392 vsym.avmas.main = bias + sectp[sym->proc_v2.segment-1].VirtualAddress
1393 + sym->proc_v2.offset;
1394 SET_TOCPTR_AVMA(vsym.avmas, 0);
1395 vsym.pri_name = nmstr;
1396 vsym.sec_names = NULL;
1397 vsym.size = sym->proc_v2.proc_len;
1398 vsym.isText = True;
1399 vsym.isIFunc = False;
1400 vsym.isGlobal = sym->generic.id == S_GPROC_V2;
1401 if (debug)
1402 VG_(umsg)(" Adding function %s addr=%#lx length=%u\n",
1403 symname, vsym.avmas.main, vsym.size );
1404 ML_(addSym)( di, &vsym );
1405 n_syms_read++;
1406 break;
1407 case S_LPROC_V3:
1408 case S_GPROC_V3: {
1409 if (debug)
1410 VG_(umsg)(" S_LPROC_V3/S_GPROC_V3 %s\n", sym->proc_v3.name );
1412 if (1) {
1413 nmstr = ML_(addStr)(di, sym->proc_v3.name,
1414 VG_(strlen)(sym->proc_v3.name));
1415 vsym.avmas.main = bias + sectp[sym->proc_v3.segment-1].VirtualAddress
1416 + sym->proc_v3.offset;
1417 SET_TOCPTR_AVMA(vsym.avmas, 0);
1418 vsym.pri_name = nmstr;
1419 vsym.sec_names = NULL;
1420 vsym.size = sym->proc_v3.proc_len;
1421 vsym.isText = 1;
1422 vsym.isIFunc = False;
1423 vsym.isGlobal = sym->generic.id == S_GPROC_V3;
1424 ML_(addSym)( di, &vsym );
1425 n_syms_read++;
1427 break;
1429 /* JRS: how is flow supposed to arrive at commented out code below? */
1430 //if (nest_block)
1432 // printf(">>> prev func '%s' still has nest_block %u count\n",
1433 // curr_func, nest_block);
1434 // nest_block = 0;
1436 //curr_func = strdup(sym->proc_v3.name);
1437 /* EPP unsigned int pparent; */
1438 /* EPP unsigned int pend; */
1439 /* EPP unsigned int next; */
1440 /* EPP unsigned int debug_start; */
1441 /* EPP unsigned int debug_end; */
1442 /* EPP unsigned char flags; */
1443 // break;
1447 * Function parameters and stack variables.
1449 case S_BPREL_XXXX_V3:
1450 case S_BPREL_V3:
1451 case S_BPREL_V2:
1452 case S_BPREL_V1:
1453 /* ignored */
1454 break;
1456 case S_LABEL_V3: // FIXME
1457 case S_LABEL_V1:
1458 break;
1460 case S_SSEARCH_V1:
1461 case S_ALIGN_V1:
1462 case S_MSTOOL_V3:
1463 case S_UDT_V3:
1464 case S_UDT_V2:
1465 case S_UDT_V1:
1466 case S_CONSTANT_V3:
1467 case S_CONSTANT_V1:
1468 case S_OBJNAME_V1:
1469 case S_END_V1:
1470 case S_COMPILAND_V3:
1471 case S_COMPILAND_V2:
1472 case S_COMPILAND_V1:
1473 case S_BLOCK_V3:
1474 case S_BLOCK_V1:
1475 case S_REGISTER_V3:
1476 case S_REGISTER_V2:
1477 case S_REGISTER_V1:
1478 /* ignored */
1479 break;
1482 * These are special, in that they are always followed by an
1483 * additional length-prefixed string which is *not* included
1484 * into the symbol length count. We need to skip it.
1486 case S_PROCREF_V1:
1487 case S_DATAREF_V1:
1488 case S_LPROCREF_V1: {
1489 const unsigned char *name = (const unsigned char *)sym + length;
1490 length += (*name + 1 + 3) & ~3;
1491 break;
1493 } /* switch ( sym->generic.id ) */
1495 } /* for ( i = offset; i < size; i += length ) */
1497 if (debug)
1498 VG_(umsg)("END SnarfCodeView addr=%p offset=%d length=%d\n",
1499 root, offset, size );
1500 return n_syms_read;
1504 /*------------------------------------------------------------*/
1505 /*--- ---*/
1506 /*--- Main stuff: reading of line number tables ---*/
1507 /*--- ---*/
1508 /*------------------------------------------------------------*/
1510 union any_size
1512 char const *c;
1513 short const *s;
1514 int const *i;
1515 unsigned int const *ui;
1518 struct startend
1520 unsigned int start;
1521 unsigned int end;
1524 static ULong DEBUG_SnarfLinetab(
1525 DebugInfo* di,
1526 PtrdiffT bias,
1527 const IMAGE_SECTION_HEADER* sectp,
1528 const void* linetab,
1529 Int size
1532 //VG_(printf)("DEBUG_SnarfLinetab %p %p %p %d\n", di, sectp, linetab, size);
1533 Int file_segcount;
1534 HChar filename[WIN32_PATH_MAX];
1535 const UInt * filetab;
1536 const UChar * fn;
1537 Int i;
1538 Int k;
1539 const UInt * lt_ptr;
1540 Int nfile;
1541 Int nseg;
1542 union any_size pnt;
1543 union any_size pnt2;
1544 const struct startend * start;
1545 Int this_seg;
1547 Bool debug = di->trace_symtab;
1548 ULong n_lines_read = 0;
1550 if (debug)
1551 VG_(umsg)("BEGIN SnarfLineTab linetab=%p size=%d\n", linetab, size);
1554 * Now get the important bits.
1556 pnt.c = linetab;
1557 nfile = *pnt.s++;
1558 nseg = *pnt.s++;
1560 filetab = pnt.ui;
1563 * Now count up the number of segments in the file.
1565 nseg = 0;
1566 for (i = 0; i < nfile; i++) {
1567 pnt2.c = (const HChar *)linetab + filetab[i];
1568 nseg += *pnt2.s;
1571 this_seg = 0;
1572 for (i = 0; i < nfile; i++) {
1573 const HChar *fnmstr;
1574 const HChar *dirstr;
1575 UInt fnmdirstr_ix;
1578 * Get the pointer into the segment information.
1580 pnt2.c = (const HChar *)linetab + filetab[i];
1581 file_segcount = *pnt2.s;
1583 pnt2.ui++;
1584 lt_ptr = pnt2.ui;
1585 start = (const struct startend *) (lt_ptr + file_segcount);
1588 * Now snarf the filename for all of the segments for this file.
1590 fn = (const UChar*) (start + file_segcount);
1591 /* fn now points at a Pascal-style string, that is, the first
1592 byte is the length, and the remaining up to 255 (presumably)
1593 are the contents. */
1594 vg_assert(WIN32_PATH_MAX >= 256);
1595 VG_(memset)(filename, 0, sizeof(filename));
1596 VG_(memcpy)(filename, fn + 1, *fn);
1597 vg_assert(filename[ sizeof(filename)-1 ] == 0);
1598 filename[(Int)*fn] = 0;
1599 fnmstr = VG_(strrchr)(filename, '\\');
1600 if (fnmstr == NULL)
1601 fnmstr = filename;
1602 else
1603 ++fnmstr;
1604 k = VG_(strlen)(fnmstr);
1605 dirstr = ML_(addStr)(di, filename, *fn - k);
1606 fnmstr = ML_(addStr)(di, fnmstr, k);
1607 fnmdirstr_ix = ML_(addFnDn) (di, fnmstr, dirstr);
1609 for (k = 0; k < file_segcount; k++, this_seg++) {
1610 Int linecount;
1611 Int segno;
1613 pnt2.c = (const HChar *)linetab + lt_ptr[k];
1615 segno = *pnt2.s++;
1616 linecount = *pnt2.s++;
1618 if ( linecount > 0 ) {
1619 UInt j;
1621 if (debug)
1622 VG_(umsg)(
1623 " Adding %d lines for file %s segment %d addr=%#x end=%#x\n",
1624 linecount, filename, segno, start[k].start, start[k].end );
1626 for ( j = 0; j < linecount; j++ ) {
1627 Addr startaddr = bias + sectp[segno-1].VirtualAddress
1628 + pnt2.ui[j];
1629 Addr endaddr = bias + sectp[segno-1].VirtualAddress
1630 + ((j < (linecount - 1))
1631 ? pnt2.ui[j+1]
1632 : start[k].end);
1633 if (debug)
1634 VG_(umsg)(
1635 " Adding line %d addr=%#lx end=%#lx\n",
1636 ((const unsigned short *)(pnt2.ui + linecount))[j],
1637 startaddr, endaddr );
1638 ML_(addLineInfo)(
1639 di,
1640 fnmdirstr_ix,
1641 startaddr, endaddr,
1642 ((const unsigned short *)(pnt2.ui + linecount))[j], j );
1643 n_lines_read++;
1649 if (debug)
1650 VG_(umsg)("END SnarfLineTab linetab=%p size=%d\n",
1651 linetab, size );
1653 return n_lines_read;
1658 /* there's a new line tab structure from MS Studio 2005 and after
1659 * it's made of:
1660 * DWORD 000000f4
1661 * DWORD lineblk_offset (counting bytes after this field)
1662 * an array of codeview_linetab2_file structures
1663 * an array (starting at <lineblk_offset>) of codeview_linetab2_block structures
1666 typedef struct codeview_linetab2_file
1668 DWORD offset; /* offset in string table for filename */
1669 WORD unk; /* always 0x0110... type of following
1670 information ??? */
1671 BYTE md5[16]; /* MD5 signature of file (signature on
1672 file's content or name ???) */
1673 WORD pad0; /* always 0 */
1674 } codeview_linetab2_file;
1676 typedef struct codeview_linetab2_block
1678 DWORD header; /* 0x000000f2 */
1679 DWORD size_of_block; /* next block is at # bytes after this field */
1680 DWORD start; /* start address of function with line numbers */
1681 DWORD seg; /* segment of function with line numbers */
1682 DWORD size; /* size of function with line numbers */
1683 DWORD file_offset; /* offset for accessing corresponding
1684 codeview_linetab2_file */
1685 DWORD nlines; /* number of lines in this block */
1686 DWORD size_lines; /* number of bytes following for line
1687 number information */
1688 struct {
1689 DWORD offset; /* offset (from <seg>:<start>) for line number */
1690 DWORD lineno; /* the line number (OR:ed with
1691 0x80000000 why ???) */
1692 } l[1]; /* actually array of <nlines> */
1693 } codeview_linetab2_block;
1695 static ULong codeview_dump_linetab2(
1696 DebugInfo* di,
1697 Addr bias,
1698 const IMAGE_SECTION_HEADER* sectp,
1699 const HChar* linetab,
1700 DWORD size,
1701 const HChar* strimage,
1702 DWORD strsize,
1703 const HChar* pfx
1706 DWORD offset;
1707 unsigned i;
1708 const codeview_linetab2_block* lbh;
1709 const codeview_linetab2_file* fd;
1711 Bool debug = di->trace_symtab;
1712 ULong n_line2s_read = 0;
1714 if (*(const DWORD*)linetab != 0x000000f4)
1715 return 0;
1716 offset = *((const DWORD*)linetab + 1);
1717 lbh = (const codeview_linetab2_block*)(linetab + 8 + offset);
1719 while ((const HChar*)lbh < linetab + size) {
1721 UInt filedirname_ix;
1722 Addr svma_s, svma_e;
1723 if (lbh->header != 0x000000f2) {
1724 /* FIXME: should also check that whole lbh fits in linetab + size */
1725 if (debug)
1726 VG_(printf)("%sblock end %x\n", pfx, lbh->header);
1727 break;
1729 if (debug)
1730 VG_(printf)("%sblock from %04x:%08x-%08x (size %u) (%u lines)\n",
1731 pfx, lbh->seg, lbh->start, lbh->start + lbh->size - 1,
1732 lbh->size, lbh->nlines);
1733 fd = (const codeview_linetab2_file*)(linetab + 8 + lbh->file_offset);
1734 if (debug)
1735 VG_(printf)(
1736 "%s md5=%02x%02x%02x%02x%02x%02x%02x%02x"
1737 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
1738 pfx, fd->md5[ 0], fd->md5[ 1], fd->md5[ 2], fd->md5[ 3],
1739 fd->md5[ 4], fd->md5[ 5], fd->md5[ 6], fd->md5[ 7],
1740 fd->md5[ 8], fd->md5[ 9], fd->md5[10], fd->md5[11],
1741 fd->md5[12], fd->md5[13], fd->md5[14], fd->md5[15] );
1742 /* FIXME: should check that string is within strimage + strsize */
1743 const HChar* filename = NULL; // in ML_(addStr) space
1744 const HChar* dirname = NULL; // in ML_(addStr) space
1745 if (strimage) {
1746 const HChar* strI = strimage + fd->offset;
1747 /* Copy |strI| into mutable storage, temporarily, so we can put a zero
1748 byte in place of the last pathname separator. */
1749 HChar* strM = ML_(dinfo_strdup)("di.readpe.cdl2.1", strI);
1750 HChar* fname = VG_(strrchr)(strM, '\\');
1751 if (fname == NULL) {
1752 filename = ML_(addStr)(di, strM, -1);
1753 dirname = NULL;
1754 } else {
1755 *fname++ = '\0';
1756 filename = ML_(addStr)(di, fname, -1);
1757 dirname = ML_(addStr)(di, strM, -1);
1759 ML_(dinfo_free)(strM);
1760 } else {
1761 filename = ML_(addStr)(di, "???", -1);
1762 dirname = NULL;
1765 if (debug)
1766 VG_(printf)("%s file=%s\n", pfx, filename);
1768 filedirname_ix = ML_(addFnDn) (di, filename, dirname);
1770 for (i = 0; i < lbh->nlines; i++) {
1771 if (debug)
1772 VG_(printf)("%s offset=%08x line=%u\n",
1773 pfx, lbh->l[i].offset, lbh->l[i].lineno ^ 0x80000000);
1776 if (lbh->nlines > 1) {
1777 for (i = 0; i < lbh->nlines-1; i++) {
1778 svma_s = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1779 + lbh->l[i].offset;
1780 svma_e = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1781 + lbh->l[i+1].offset-1;
1782 if (debug)
1783 VG_(printf)("%s line %u: %08lx to %08lx\n",
1784 pfx, lbh->l[i].lineno ^ 0x80000000, svma_s, svma_e);
1785 ML_(addLineInfo)( di,
1786 filedirname_ix,
1787 bias + svma_s,
1788 bias + svma_e + 1,
1789 lbh->l[i].lineno ^ 0x80000000, 0 );
1790 n_line2s_read++;
1792 svma_s = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1793 + lbh->l[ lbh->nlines-1].offset;
1794 svma_e = sectp[lbh->seg - 1].VirtualAddress + lbh->start
1795 + lbh->size - 1;
1796 if (debug)
1797 VG_(printf)("%s line %u: %08lx to %08lx\n",
1798 pfx, lbh->l[ lbh->nlines-1 ].lineno ^ 0x80000000,
1799 svma_s, svma_e);
1800 ML_(addLineInfo)( di,
1801 filedirname_ix,
1802 bias + svma_s,
1803 bias + svma_e + 1,
1804 lbh->l[lbh->nlines-1].lineno ^ 0x80000000, 0 );
1805 n_line2s_read++;
1808 lbh = (const codeview_linetab2_block*)
1809 ((const char*)lbh + 8 + lbh->size_of_block);
1811 return n_line2s_read;
1815 /*------------------------------------------------------------*/
1816 /*--- ---*/
1817 /*--- Main stuff: pdb_dump ---*/
1818 /*--- ---*/
1819 /*------------------------------------------------------------*/
1821 static Int cmp_FPO_DATA_for_canonicalisation ( const void* f1V,
1822 const void* f2V )
1824 /* Cause FPO data to be sorted first in ascending order of range
1825 starts, and for entries with the same range start, with the
1826 shorter range (length) first. */
1827 const FPO_DATA* f1 = f1V;
1828 const FPO_DATA* f2 = f2V;
1829 if (f1->ulOffStart < f2->ulOffStart) return -1;
1830 if (f1->ulOffStart > f2->ulOffStart) return 1;
1831 if (f1->cbProcSize < f2->cbProcSize) return -1;
1832 if (f1->cbProcSize > f2->cbProcSize) return 1;
1833 return 0; /* identical in both start and length */
1836 static unsigned get_stream_by_name(const struct pdb_reader* pdb, const char* name)
1838 const DWORD* pdw;
1839 const DWORD* ok_bits;
1840 DWORD cbstr, count;
1841 DWORD string_idx, stream_idx;
1842 unsigned i;
1843 const char* str;
1845 if (pdb->read_file == pdb_jg_read_file)
1847 str = pdb->u.jg.root->names;
1848 cbstr = pdb->u.jg.root->cbNames;
1850 else
1852 str = pdb->u.ds.root->names;
1853 cbstr = pdb->u.ds.root->cbNames;
1856 pdw = (const DWORD*)(str + cbstr);
1857 pdw++; /* number of ok entries */
1858 count = *pdw++;
1860 /* bitfield: first dword is len (in dword), then data */
1861 ok_bits = pdw;
1862 pdw += *ok_bits++ + 1;
1863 if (*pdw++ != 0)
1865 if (VG_(clo_verbosity) > 1)
1866 VG_(umsg)("LOAD_PDB_DEBUGINFO: "
1867 "get_stream_by_name: unexpected value\n");
1868 return -1;
1871 for (i = 0; i < count; i++)
1873 if (ok_bits[i / 32] & (1 << (i % 32)))
1875 string_idx = *pdw++;
1876 stream_idx = *pdw++;
1877 if (!VG_(strcmp)(name, &str[string_idx])) return stream_idx;
1880 return -1;
1884 static void *read_string_table(const struct pdb_reader* pdb)
1886 unsigned stream_idx;
1887 void* ret;
1889 stream_idx = get_stream_by_name(pdb, "/names");
1890 if (stream_idx == -1) return NULL;
1891 ret = pdb->read_file(pdb, stream_idx,0);
1892 if (ret && *(const DWORD*)ret == 0xeffeeffe) {
1893 return ret;
1895 if (VG_(clo_verbosity) > 1)
1896 VG_(umsg)("LOAD_PDB_DEBUGINFO: read_string_table: "
1897 "wrong header 0x%08x, expecting 0xeffeeffe\n",
1898 *(const DWORD*)ret);
1899 ML_(dinfo_free)( ret );
1900 return NULL;
1903 /* JRS fixme: compare with version in current Wine sources */
1904 static void pdb_dump( const struct pdb_reader* pdb,
1905 DebugInfo* di,
1906 Addr pe_avma,
1907 PtrdiffT pe_bias,
1908 const IMAGE_SECTION_HEADER* sectp_avma )
1910 Int header_size;
1912 PDB_TYPES types;
1913 PDB_SYMBOLS symbols;
1914 unsigned len_modimage;
1915 char *modimage;
1916 const char *file;
1918 Bool debug = di->trace_symtab;
1920 ULong n_fpos_read = 0, n_syms_read = 0,
1921 n_lines_read = 0, n_line2s_read = 0;
1923 // FIXME: symbols for bare indices 1,2,3,5 in .pdb file
1925 char* types_image = pdb->read_file( pdb, 2, 0 );
1926 char* symbols_image = pdb->read_file( pdb, 3, 0 );
1928 /* establish filesimage and filessize. These are only needed for
1929 reading linetab2 tables, as far as I can deduce from the Wine
1930 sources. */
1931 DWORD filessize = 0;
1932 char* filesimage = read_string_table(pdb);
1933 if (filesimage) {
1934 filessize = *(const DWORD*)(filesimage + 8);
1935 } else {
1936 VG_(umsg)("LOAD_PDB_DEBUGINFO: pdb_dump: string table not found\n");
1939 /* Since we just use the FPO data without reformatting, at least
1940 do a basic sanity check on the struct layout. */
1941 vg_assert(sizeof(FPO_DATA) == 16);
1942 if (di->text_present) {
1943 /* only load FPO if there's text present (otherwise it's
1944 meaningless?) */
1945 unsigned sz = 0;
1946 di->fpo = pdb->read_file( pdb, 5, &sz );
1948 // FIXME: seems like the size can be a non-integral number
1949 // of FPO_DATAs. Force-align it (moronically). Perhaps this
1950 // signifies that we're not looking at a valid FPO table ..
1951 // who knows. Needs investigation.
1952 while (sz > 0 && (sz % sizeof(FPO_DATA)) != 0)
1953 sz--;
1955 di->fpo_size = sz;
1956 if (0) VG_(printf)("FPO: got fpo_size %lu\n", (UWord)sz);
1957 vg_assert(0 == (di->fpo_size % sizeof(FPO_DATA)));
1958 di->fpo_base_avma = pe_avma;
1959 } else {
1960 vg_assert(di->fpo == NULL);
1961 vg_assert(di->fpo_size == 0);
1964 // BEGIN clean up FPO data
1965 if (di->fpo && di->fpo_size > 0) {
1966 Word i, j;
1967 Bool anyChanges;
1968 Int itersAvail = 10;
1970 vg_assert(sizeof(di->fpo[0]) == 16);
1971 di->fpo_size /= sizeof(di->fpo[0]);
1973 // BEGIN FPO-data tidying-up loop
1974 do {
1976 vg_assert(itersAvail >= 0); /* safety check -- don't loop forever */
1977 itersAvail--;
1979 anyChanges = False;
1981 /* First get them in ascending order of start point */
1982 VG_(ssort)( di->fpo, (SizeT)di->fpo_size, (SizeT)sizeof(FPO_DATA),
1983 cmp_FPO_DATA_for_canonicalisation );
1984 /* Get rid of any zero length entries */
1985 j = 0;
1986 for (i = 0; i < di->fpo_size; i++) {
1987 if (di->fpo[i].cbProcSize == 0) {
1988 anyChanges = True;
1989 continue;
1991 di->fpo[j++] = di->fpo[i];
1993 vg_assert(j >= 0 && j <= di->fpo_size);
1994 di->fpo_size = j;
1996 /* Get rid of any dups */
1997 if (di->fpo_size > 1) {
1998 j = 1;
1999 for (i = 1; i < di->fpo_size; i++) {
2000 Bool dup
2001 = di->fpo[j-1].ulOffStart == di->fpo[i].ulOffStart
2002 && di->fpo[j-1].cbProcSize == di->fpo[i].cbProcSize;
2003 if (dup) {
2004 anyChanges = True;
2005 continue;
2007 di->fpo[j++] = di->fpo[i];
2009 vg_assert(j >= 0 && j <= di->fpo_size);
2010 di->fpo_size = j;
2013 /* Truncate any overlapping ranges */
2014 for (i = 1; i < di->fpo_size; i++) {
2015 vg_assert(di->fpo[i-1].ulOffStart <= di->fpo[i].ulOffStart);
2016 if (di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
2017 > di->fpo[i].ulOffStart) {
2018 anyChanges = True;
2019 di->fpo[i-1].cbProcSize
2020 = di->fpo[i].ulOffStart - di->fpo[i-1].ulOffStart;
2024 } while (anyChanges);
2025 // END FPO-data tidying-up loop
2027 /* Should now be in ascending order, non overlapping, no zero ranges.
2028 Check this, get the min and max avmas, and bias the entries. */
2029 for (i = 0; i < di->fpo_size; i++) {
2030 vg_assert(di->fpo[i].cbProcSize > 0);
2032 if (i > 0) {
2033 vg_assert(di->fpo[i-1].ulOffStart < di->fpo[i].ulOffStart);
2034 vg_assert(di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
2035 <= di->fpo[i].ulOffStart);
2039 /* Now bias the table. This can't be done in the same pass as
2040 the sanity check, hence a second loop. */
2041 for (i = 0; i < di->fpo_size; i++) {
2042 di->fpo[i].ulOffStart += pe_avma;
2043 // make sure the biasing didn't royally screw up, by wrapping
2044 // the range around the end of the address space
2045 vg_assert(0xFFFFFFFF - di->fpo[i].ulOffStart /* "remaining space" */
2046 >= di->fpo[i].cbProcSize);
2049 /* Dump any entries which point outside the text segment and
2050 compute the min/max avma "hint" addresses. */
2051 Addr min_avma = ~(Addr)0;
2052 Addr max_avma = (Addr)0;
2053 vg_assert(di->text_present);
2054 j = 0;
2055 for (i = 0; i < di->fpo_size; i++) {
2056 if ((Addr)(di->fpo[i].ulOffStart) >= di->text_avma
2057 && (Addr)(di->fpo[i].ulOffStart + di->fpo[i].cbProcSize)
2058 <= di->text_avma + di->text_size) {
2059 /* Update min/max limits as we go along. */
2060 if (di->fpo[i].ulOffStart < min_avma)
2061 min_avma = di->fpo[i].ulOffStart;
2062 if (di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1 > max_avma)
2063 max_avma = di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1;
2064 /* Keep */
2065 di->fpo[j++] = di->fpo[i];
2066 if (0)
2067 VG_(printf)("FPO: keep text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
2068 di->text_avma, di->text_avma + di->text_size,
2069 (Addr)di->fpo[i].ulOffStart,
2070 (Addr)di->fpo[i].ulOffStart
2071 + (Addr)di->fpo[i].cbProcSize - 1);
2072 } else {
2073 if (0)
2074 VG_(printf)("FPO: SKIP text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
2075 di->text_avma, di->text_avma + di->text_size,
2076 (Addr)di->fpo[i].ulOffStart,
2077 (Addr)di->fpo[i].ulOffStart
2078 + (Addr)di->fpo[i].cbProcSize - 1);
2079 /* out of range; ignore */
2082 vg_assert(j >= 0 && j <= di->fpo_size);
2083 di->fpo_size = j;
2085 /* And record min/max */
2086 /* biasing shouldn't cause wraparound (?!) */
2087 if (di->fpo_size > 0) {
2088 vg_assert(min_avma <= max_avma); /* should always hold */
2089 di->fpo_minavma = min_avma;
2090 di->fpo_maxavma = max_avma;
2091 } else {
2092 di->fpo_minavma = 0;
2093 di->fpo_maxavma = 0;
2096 if (0) {
2097 VG_(printf)("FPO: min/max avma %#lx %#lx\n",
2098 di->fpo_minavma, di->fpo_maxavma);
2101 n_fpos_read += (ULong)di->fpo_size;
2103 // END clean up FPO data
2105 pdb_convert_types_header( &types, types_image );
2106 switch ( types.version ) {
2107 case 19950410: /* VC 4.0 */
2108 case 19951122:
2109 case 19961031: /* VC 5.0 / 6.0 */
2110 case 20040203: /* VC 7.0 FIXME?? */
2111 break;
2112 default:
2113 if (VG_(clo_verbosity) > 1)
2114 VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2115 "Unknown .pdb type info version %lu\n", types.version );
2118 header_size = 0;
2119 pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2120 switch ( symbols.version ) {
2121 case 0: /* VC 4.0 */
2122 case 19960307: /* VC 5.0 */
2123 case 19970606: /* VC 6.0 */
2124 case 19990903: /* VC 7.0 FIXME?? */
2125 break;
2126 default:
2127 if (VG_(clo_verbosity) > 1)
2128 VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2129 "Unknown .pdb symbol info version %lu\n",
2130 symbols.version );
2134 * Read global symbol table
2136 modimage = pdb->read_file( pdb, symbols.gsym_file, &len_modimage );
2137 if (modimage) {
2138 if (debug)
2139 VG_(umsg)("\n");
2140 if (VG_(clo_verbosity) > 1)
2141 VG_(umsg)("LOAD_PDB_DEBUGINFO: Reading global symbols\n" );
2142 DEBUG_SnarfCodeView( di, pe_avma, sectp_avma, modimage, 0, len_modimage );
2143 ML_(dinfo_free)( modimage );
2147 * Read per-module symbol / linenumber tables
2149 file = symbols_image + header_size;
2150 while ( file - symbols_image < header_size + symbols.module_size ) {
2151 int file_nr, /* file_index, */ symbol_size, lineno_size;
2152 const char *file_name;
2154 if ( symbols.version < 19970000 ) {
2155 const PDB_SYMBOL_FILE *sym_file = (const PDB_SYMBOL_FILE *) file;
2156 file_nr = sym_file->file;
2157 file_name = sym_file->filename;
2158 /* file_index = sym_file->range.index; */ /* UNUSED */
2159 symbol_size = sym_file->symbol_size;
2160 lineno_size = sym_file->lineno_size;
2161 } else {
2162 const PDB_SYMBOL_FILE_EX *sym_file = (const PDB_SYMBOL_FILE_EX *) file;
2163 file_nr = sym_file->file;
2164 file_name = sym_file->filename;
2165 /* file_index = sym_file->range.index; */ /* UNUSED */
2166 symbol_size = sym_file->symbol_size;
2167 lineno_size = sym_file->lineno_size;
2170 modimage = pdb->read_file( pdb, file_nr, 0 );
2171 if (modimage) {
2172 Int total_size;
2173 if (0) VG_(printf)("lineno_size %d symbol_size %d\n",
2174 lineno_size, symbol_size );
2176 total_size = pdb_get_file_size(pdb, file_nr);
2178 if (symbol_size) {
2179 if (debug)
2180 VG_(umsg)("\n");
2181 if (VG_(clo_verbosity) > 1)
2182 VG_(umsg)("LOAD_PDB_DEBUGINFO: Reading symbols for %s\n",
2183 file_name );
2184 n_syms_read
2185 += DEBUG_SnarfCodeView( di, pe_avma, sectp_avma, modimage,
2186 sizeof(unsigned long),
2187 symbol_size );
2190 if (lineno_size) {
2191 if (debug)
2192 VG_(umsg)("\n");
2193 if (VG_(clo_verbosity) > 1)
2194 VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2195 "Reading lines for %s\n", file_name );
2196 n_lines_read
2197 += DEBUG_SnarfLinetab( di, pe_avma, sectp_avma,
2198 modimage + symbol_size, lineno_size );
2201 /* anyway, lineno_size doesn't see to really be the size of
2202 * the line number information, and it's not clear yet when
2203 * to call for linetab2...
2205 if (0) VG_(printf)("Reading lines for %s\n", file_name );
2206 n_line2s_read
2207 += codeview_dump_linetab2(
2208 di, pe_avma, sectp_avma,
2209 (HChar*)modimage + symbol_size + lineno_size,
2210 total_size - (symbol_size + lineno_size),
2211 /* if filesimage is NULL, pass that directly onwards
2212 to codeview_dump_linetab2, so it knows not to
2213 poke around in there. */
2214 filesimage ? filesimage + 12 : NULL,
2215 filessize, " "
2218 ML_(dinfo_free)( modimage );
2221 file_name += VG_(strlen)(file_name) + 1;
2222 file = (const char *)(
2223 (unsigned long)(file_name
2224 + VG_(strlen)(file_name) + 1 + 3) & ~3 );
2228 * Cleanup
2230 if ( symbols_image ) ML_(dinfo_free)( symbols_image );
2231 if ( types_image ) ML_(dinfo_free)( types_image );
2232 if ( pdb->u.jg.toc ) ML_(dinfo_free)( pdb->u.jg.toc );
2234 if (VG_(clo_verbosity) > 1) {
2235 VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2236 " # symbols read = %llu\n", n_syms_read );
2237 VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2238 " # lines read = %llu\n", n_lines_read );
2239 VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2240 " # line2s read = %llu\n", n_line2s_read );
2241 VG_(dmsg)("LOAD_PDB_DEBUGINFO:"
2242 " # fpos read = %llu\n", n_fpos_read );
2247 /*------------------------------------------------------------*/
2248 /*--- ---*/
2249 /*--- TOP LEVEL for PDB reading ---*/
2250 /*--- ---*/
2251 /*------------------------------------------------------------*/
2253 /* Read line, symbol and unwind information from a PDB file.
2255 Bool ML_(read_pdb_debug_info)(
2256 DebugInfo* di,
2257 Addr obj_avma,
2258 PtrdiffT obj_bias,
2259 void* pdbimage,
2260 SizeT n_pdbimage,
2261 const HChar* pdbname,
2262 ULong pdbmtime
2265 Char* pe_seg_avma;
2266 Int i;
2267 Addr mapped_avma, mapped_end_avma;
2268 unsigned signature;
2269 void* hdr;
2270 struct pdb_reader reader;
2271 IMAGE_DOS_HEADER* dos_avma;
2272 IMAGE_NT_HEADERS* ntheaders_avma;
2273 IMAGE_SECTION_HEADER* sectp_avma;
2274 IMAGE_SECTION_HEADER* pe_sechdr_avma;
2276 if (VG_(clo_verbosity) > 1)
2277 VG_(umsg)("LOAD_PDB_DEBUGINFO: Processing PDB file %s\n", pdbname );
2279 dos_avma = (IMAGE_DOS_HEADER *)obj_avma;
2280 if (dos_avma->e_magic != IMAGE_DOS_SIGNATURE) {
2281 VG_(umsg)("LOAD_PDB_DEBUGINFO: IMAGE_DOS_SIGNATURE not found. "
2282 " possible invalid/unsupported pdb file format?\n");
2283 return False;
2286 ntheaders_avma
2287 = (IMAGE_NT_HEADERS *)((Char*)dos_avma + dos_avma->e_lfanew);
2288 if (ntheaders_avma->Signature != IMAGE_NT_SIGNATURE) {
2289 VG_(umsg)("LOAD_PDB_DEBUGINFO: IMAGE_NT_SIGNATURE not found. "
2290 " possible invalid/unsupported pdb file format?\n");
2291 return False;
2294 sectp_avma
2295 = (IMAGE_SECTION_HEADER *)(
2296 (Char*)ntheaders_avma
2297 + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2298 + ntheaders_avma->FileHeader.SizeOfOptionalHeader
2301 /* JRS: this seems like something of a hack. */
2302 di->soname = ML_(dinfo_strdup)("di.readpdb.rpdi.1", pdbname);
2304 /* someone (ie WINE) is loading a Windows PE format object. we
2305 need to use its details to determine which area of memory is
2306 executable... */
2307 pe_seg_avma
2308 = (Char*)ntheaders_avma
2309 + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2310 + ntheaders_avma->FileHeader.SizeOfOptionalHeader;
2312 /* Iterate over PE headers and fill our section mapping table. */
2313 for ( i = 0;
2314 i < ntheaders_avma->FileHeader.NumberOfSections;
2315 i++, pe_seg_avma += sizeof(IMAGE_SECTION_HEADER) ) {
2316 pe_sechdr_avma = (IMAGE_SECTION_HEADER *)pe_seg_avma;
2318 if (VG_(clo_verbosity) > 1) {
2319 /* Copy name, it can be 8 chars and not NUL-terminated */
2320 char name[9];
2321 VG_(memcpy)(name, pe_sechdr_avma->Name, 8);
2322 name[8] = '\0';
2323 VG_(umsg)("LOAD_PDB_DEBUGINFO:"
2324 " Scanning PE section %ps at avma %#lx svma %#lx\n",
2325 name, obj_avma + pe_sechdr_avma->VirtualAddress,
2326 pe_sechdr_avma->VirtualAddress);
2329 if (pe_sechdr_avma->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2330 continue;
2332 mapped_avma = (Addr)obj_avma + pe_sechdr_avma->VirtualAddress;
2333 mapped_end_avma = mapped_avma + pe_sechdr_avma->Misc.VirtualSize;
2335 DebugInfoMapping map;
2336 map.avma = mapped_avma;
2337 map.size = pe_sechdr_avma->Misc.VirtualSize;
2338 map.foff = pe_sechdr_avma->PointerToRawData;
2339 map.ro = False;
2341 if (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_CODE) {
2342 /* Ignore uninitialised code sections - if you have
2343 incremental linking enabled in Visual Studio then you will
2344 get a uninitialised code section called .textbss before
2345 the real text section and valgrind will compute the wrong
2346 avma value and hence the wrong bias. */
2347 if (!(pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
2348 map.rx = True;
2349 map.rw = False;
2350 VG_(addToXA)(di->fsm.maps, &map);
2351 di->fsm.have_rx_map = True;
2353 di->text_present = True;
2354 if (di->text_avma == 0) {
2355 di->text_svma = pe_sechdr_avma->VirtualAddress;
2356 di->text_avma = mapped_avma;
2357 di->text_size = pe_sechdr_avma->Misc.VirtualSize;
2358 } else {
2359 di->text_size = mapped_end_avma - di->text_avma;
2363 else if (pe_sechdr_avma->Characteristics
2364 & IMAGE_SCN_CNT_INITIALIZED_DATA) {
2365 map.rx = False;
2366 map.rw = True;
2367 VG_(addToXA)(di->fsm.maps, &map);
2368 di->fsm.have_rw_map = True;
2370 di->data_present = True;
2371 if (di->data_avma == 0) {
2372 di->data_avma = mapped_avma;
2373 di->data_size = pe_sechdr_avma->Misc.VirtualSize;
2374 } else {
2375 di->data_size = mapped_end_avma - di->data_avma;
2378 else if (pe_sechdr_avma->Characteristics
2379 & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
2380 di->bss_present = True;
2381 if (di->bss_avma == 0) {
2382 di->bss_avma = mapped_avma;
2383 di->bss_size = pe_sechdr_avma->Misc.VirtualSize;
2384 } else {
2385 di->bss_size = mapped_end_avma - di->bss_avma;
2390 if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
2391 vg_assert(di->fsm.filename);
2392 TRACE_SYMTAB("\n");
2393 TRACE_SYMTAB("------ start PE OBJECT with PDB INFO "
2394 "---------------------\n");
2395 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
2396 TRACE_SYMTAB("\n");
2399 di->text_bias = obj_bias;
2401 if (VG_(clo_verbosity) > 1) {
2402 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2403 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2404 if (map->rx)
2405 VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2406 "rx_map: avma %#lx size %7lu foff %lld\n",
2407 map->avma, map->size, (Long)map->foff);
2409 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
2410 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
2411 if (map->rw)
2412 VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2413 "rw_map: avma %#lx size %7lu foff %lld\n",
2414 map->avma, map->size, (Long)map->foff);
2417 VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2418 " text: avma %#lx svma %#lx size %7lu bias %#lx\n",
2419 di->text_avma, di->text_svma,
2420 di->text_size, (UWord)di->text_bias);
2424 * Read in TOC and well-known files
2426 signature = 0;
2427 hdr = find_pdb_header( pdbimage, &signature );
2428 if (0==hdr) {
2429 VG_(umsg)("LOAD_PDB_DEBUGINFO: find_pdb_header found no hdr. "
2430 " possible invalid/unsupported pdb file format?\n");
2431 return False; /* JRS: significance? no pdb header? */
2434 VG_(memset)(&reader, 0, sizeof(reader));
2435 reader.u.jg.header = hdr;
2437 if (0==VG_(strncmp)((char const *)&signature, "DS\0\0", 4)) {
2438 struct PDB_DS_ROOT* root;
2439 pdb_ds_init( &reader, pdbimage, n_pdbimage );
2440 root = reader.read_file( &reader, 1, 0 );
2441 reader.u.ds.root = root;
2442 if (root) {
2443 pdb_check_root_version_and_timestamp(
2444 pdbname, pdbmtime, root->version, root->TimeDateStamp );
2446 pdb_dump( &reader, di, obj_avma, obj_bias, sectp_avma );
2447 if (root) {
2448 ML_(dinfo_free)( root );
2451 else
2452 if (0==VG_(strncmp)((char const *)&signature, "JG\0\0", 4)) {
2453 struct PDB_JG_ROOT* root;
2454 pdb_jg_init( &reader, pdbimage, n_pdbimage );
2455 root = reader.read_file( &reader, 1, 0 );
2456 reader.u.jg.root = root;
2457 if (root) {
2458 pdb_check_root_version_and_timestamp(
2459 pdbname, pdbmtime, root->version, root->TimeDateStamp);
2461 pdb_dump( &reader, di, obj_avma, obj_bias, sectp_avma );
2462 if (root) {
2463 ML_(dinfo_free)( root );
2467 if (1) {
2468 TRACE_SYMTAB("\n------ Canonicalising the "
2469 "acquired info ------\n");
2470 /* prepare read data for use */
2471 ML_(canonicaliseTables)( di );
2472 /* notify m_redir about it */
2473 TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
2474 VG_(redir_notify_new_DebugInfo)( di );
2475 /* Note that we succeeded */
2476 di->have_dinfo = True;
2477 } else {
2478 TRACE_SYMTAB("\n------ PE with PDB reading failed ------\n");
2479 /* Something went wrong (eg. bad ELF file). Should we delete
2480 this DebugInfo? No - it contains info on the rw/rx
2481 mappings, at least. */
2484 TRACE_SYMTAB("\n");
2485 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
2486 TRACE_SYMTAB("------ end PE OBJECT with PDB INFO "
2487 "--------------------\n");
2488 TRACE_SYMTAB("\n");
2490 return True;
2494 /* Examine a PE file to see if it states the path of an associated PDB
2495 file; if so return that. Caller must deallocate with
2496 ML_(dinfo_free).
2499 HChar* ML_(find_name_of_pdb_file)( const HChar* pename )
2501 /* This is a giant kludge, of the kind "you did WTF?!?", but it
2502 works. */
2503 Bool do_cleanup = False;
2504 HChar tmpnameroot[50]; // large enough
2505 HChar tmpname[VG_(mkstemp_fullname_bufsz)(sizeof tmpnameroot - 1)];
2506 Int fd, r;
2507 HChar* res = NULL;
2509 if (!pename)
2510 goto out;
2512 fd = -1;
2513 VG_(memset)(tmpnameroot, 0, sizeof(tmpnameroot));
2514 VG_(sprintf)(tmpnameroot, "petmp%d", VG_(getpid)());
2515 VG_(memset)(tmpname, 0, sizeof(tmpname));
2516 fd = VG_(mkstemp)( tmpnameroot, tmpname );
2517 if (fd == -1) {
2518 VG_(umsg)("LOAD_PDB_DEBUGINFO: "
2519 "Find PDB file: Can't create temporary file %s\n", tmpname);
2520 goto out;
2522 do_cleanup = True;
2524 /* Make up the command to run, essentially:
2525 sh -c "strings (pename) | egrep '\.pdb$|\.PDB$' > (tmpname)"
2527 const HChar* sh = "/bin/sh";
2528 const HChar* strings = "strings";
2529 const HChar* egrep = "grep -E";
2531 /* (sh) -c "(strings) (pename) | (egrep) 'pdb' > (tmpname) */
2532 Int cmdlen = VG_(strlen)(strings) + VG_(strlen)(pename)
2533 + VG_(strlen)(egrep) + VG_(strlen)(tmpname)
2534 + 100/*misc*/;
2535 HChar* cmd = ML_(dinfo_zalloc)("di.readpe.fnopf.cmd", cmdlen);
2536 VG_(sprintf)(cmd, "%s -c \"%s '%s' | %s '\\.pdb$|\\.PDB$' >> %s\"",
2537 sh, strings, pename, egrep, tmpname);
2538 vg_assert(cmd[cmdlen-1] == 0);
2539 if (0) VG_(printf)("QQQQQQQQ: %s\n", cmd);
2541 r = VG_(system)( cmd );
2542 if (r) {
2543 VG_(dmsg)("LOAD_PDB_DEBUGINFO: "
2544 "Find PDB file: Command failed:\n %s\n", cmd);
2545 goto out;
2548 /* Find out how big the file is, and get it aboard. */
2549 struct vg_stat stat_buf;
2550 VG_(memset)(&stat_buf, 0, sizeof(stat_buf));
2552 SysRes sr = VG_(stat)(tmpname, &stat_buf);
2553 if (sr_isError(sr)) {
2554 VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: can't stat %s\n", tmpname);
2555 goto out;
2558 Int szB = (Int)stat_buf.size;
2559 if (szB == 0) {
2560 VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: %s is empty\n", tmpname);
2561 goto out;
2563 /* 6 == strlen("X.pdb\n") */
2564 if (szB < 6 || szB > 1024/*let's say*/) {
2565 VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: %s has implausible size %d\n",
2566 tmpname, szB);
2567 goto out;
2570 HChar* pdbname = ML_(dinfo_zalloc)("di.readpe.fnopf.pdbname", szB + 1);
2571 pdbname[szB] = 0;
2573 Int nread = VG_(read)(fd, pdbname, szB);
2574 if (nread != szB) {
2575 VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: read of %s failed\n", tmpname);
2576 goto out;
2578 vg_assert(pdbname[szB] == 0);
2580 /* Check we've got something remotely sane -- must have one dot and
2581 one \n in it, and the \n must be at the end */
2582 Bool saw_dot = False;
2583 Int saw_n_crs = 0;
2584 Int i;
2585 for (i = 0; pdbname[i]; i++) {
2586 if (pdbname[i] == '.') saw_dot = True;
2587 if (pdbname[i] == '\n') saw_n_crs++;
2589 if (!saw_dot || saw_n_crs != 1 || pdbname[szB-1] != '\n') {
2590 VG_(umsg)("LOAD_PDB_DEBUGINFO: Find PDB file: can't make sense of: %s\n", pdbname);
2591 goto out;
2593 /* Change the \n to a terminating zero, so we have a "normal" string */
2594 pdbname[szB-1] = 0;
2596 if (0) VG_(printf)("QQQQQQQQ: got %s\n", pdbname);
2598 res = pdbname;
2599 goto out;
2601 out:
2602 if (do_cleanup) {
2603 VG_(close)(fd);
2604 VG_(unlink)( tmpname );
2606 return res;
2609 #endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
2611 /*--------------------------------------------------------------------*/
2612 /*--- end ---*/
2613 /*--------------------------------------------------------------------*/