2 /*--------------------------------------------------------------------*/
3 /*--- Reading of syms & debug info from PDB-format files. ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
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
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 /*------------------------------------------------------------*/
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 /*------------------------------------------------------------*/
90 /*--- PE/PDB definitions ---*/
92 /*------------------------------------------------------------*/
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
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
;
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 */
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
];
218 unsigned long PhysicalAddress
;
219 unsigned long VirtualSize
;
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
287 typedef struct _GUID
/* 16 bytes */
290 unsigned short Data2
;
291 unsigned short Data3
;
292 unsigned char Data4
[ 8 ];
295 /*========================================================================
300 typedef struct _PDB_FILE
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:
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
;
319 unsigned short toc_block
[ 1 ];
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
;
342 unsigned int num_files
;
343 unsigned int file_size
[1];
348 unsigned int version
;
349 unsigned int TimeDateStamp
;
351 unsigned int cbNames
;
357 unsigned int version
;
358 unsigned int TimeDateStamp
;
361 unsigned int cbNames
;
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
;
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
;
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
;
400 unsigned long offset
;
402 unsigned long characteristics
;
403 unsigned short index
;
406 } PDB_SYMBOL_RANGE
, *PPDB_SYMBOL_RANGE
;
408 typedef struct _PDB_SYMBOL_RANGE_EX
410 unsigned short segment
;
412 unsigned long offset
;
414 unsigned long characteristics
;
415 unsigned short index
;
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
;
428 unsigned long symbol_size
;
429 unsigned long lineno_size
;
430 unsigned long unknown2
;
431 unsigned long nSrcFiles
;
432 unsigned long attribute
;
435 } PDB_SYMBOL_FILE
, *PPDB_SYMBOL_FILE
;
437 typedef struct _PDB_SYMBOL_FILE_EX
439 unsigned long unknown1
;
440 PDB_SYMBOL_RANGE_EX range
;
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 ];
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
;
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
;
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
;
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
;
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
533 unsigned short segment
;
534 unsigned short symtype
;
535 struct p_string p_name
;
542 unsigned int symtype
;
544 unsigned short segment
;
545 struct p_string p_name
;
552 unsigned int symtype
;
554 unsigned short segment
;
555 char name
[1]; /* terminated by '\0' */
562 unsigned int pparent
;
566 unsigned short segment
;
567 unsigned short thunk_len
;
568 unsigned char thtype
;
569 struct p_string p_name
;
576 unsigned int pparent
;
580 unsigned short segment
;
581 unsigned short thunk_len
;
582 unsigned char thtype
;
583 char name
[1]; /* terminated by '\0' */
590 unsigned int pparent
;
593 unsigned int proc_len
;
594 unsigned int debug_start
;
595 unsigned int debug_end
;
597 unsigned short segment
;
598 unsigned short proctype
;
600 struct p_string p_name
;
607 unsigned int pparent
;
610 unsigned int proc_len
;
611 unsigned int debug_start
;
612 unsigned int debug_end
;
613 unsigned int proctype
;
615 unsigned short segment
;
617 struct p_string p_name
;
624 unsigned int pparent
;
627 unsigned int proc_len
;
628 unsigned int debug_start
;
629 unsigned int debug_end
;
630 unsigned int proctype
;
632 unsigned short segment
;
634 char name
[1]; /* terminated by '\0' */
641 unsigned int symtype
;
643 unsigned short segment
;
644 struct p_string p_name
;
651 unsigned int symtype
;
653 unsigned short segment
;
654 char name
[1]; /* terminated by '\0' */
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
;
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
;
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' */
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' */
696 short int len
; /* Total length of this entry */
697 short int id
; /* Always S_REGISTER */
700 struct p_string p_name
;
701 /* don't handle register tracking */
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 */
710 struct p_string p_name
;
711 /* don't handle register tracking */
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 */
720 char name
[1]; /* terminated by '\0' */
721 /* don't handle register tracking */
732 unsigned short segment
;
733 struct p_string p_name
;
744 unsigned short segment
;
745 char name
[1]; /* terminated by '\0' */
753 unsigned short segment
;
755 struct p_string p_name
;
763 unsigned short segment
;
765 char name
[1]; /* terminated by '\0' */
773 unsigned short cvalue
; /* numeric leaf */
775 struct p_string p_name
;
784 unsigned short cvalue
; /* numeric leaf */
786 struct p_string p_name
;
795 unsigned short cvalue
;
797 char name
[1]; /* terminated by '\0' */
806 struct p_string p_name
;
814 struct p_string p_name
;
822 char name
[1]; /* terminated by '\0' */
830 struct p_string p_name
;
837 unsigned int unknown
;
838 struct p_string p_name
;
845 unsigned unknown1
[4];
846 unsigned short unknown2
;
847 struct p_string p_name
;
854 unsigned int unknown
;
855 char name
[1]; /* terminated by '\0' */
863 unsigned short segment
;
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
919 #define S_XXXXXXXXX_32 0x1012 /* seems linked to a function, content unknown */
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 /*------------------------------------------------------------*/
944 /*--- pdb-reading: bits and pieces ---*/
946 /*------------------------------------------------------------*/
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
956 struct PDB_JG_HEADER
* header
;
957 struct PDB_JG_TOC
* toc
;
958 struct PDB_JG_ROOT
* root
;
961 struct PDB_DS_HEADER
* header
;
962 struct PDB_DS_TOC
* toc
;
963 struct PDB_DS_ROOT
* root
;
969 static void* pdb_ds_read( const struct pdb_reader
* pdb
,
970 const unsigned* block_list
,
973 unsigned blocksize
, nBlocks
;
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
);
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
,
995 static void* pdb_jg_read( const struct pdb_reader
* pdb
,
996 const unsigned short* block_list
,
999 unsigned blocksize
, nBlocks
;
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
);
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');
1021 VG_(umsg
)("LOAD_PDB_DEBUGINFO: \\032 header character not found. "
1022 " possible invalid/unsupported pdb file format?\n");
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",
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
,
1042 unsigned i
, *block_list
;
1043 if (!reader
->u
.ds
.toc
|| file_number
>= reader
->u
.ds
.toc
->num_files
)
1045 if (reader
->u
.ds
.toc
->file_size
[file_number
] == 0
1046 || reader
->u
.ds
.toc
->file_size
[file_number
] == 0xFFFFFFFF)
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
;
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
,
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
;
1071 unsigned short* block_list
;
1073 if ( !toc
|| fileNr
>= toc
->nFiles
)
1077 = (unsigned short *) &toc
->file
[ toc
->nFiles
];
1078 for ( i
= 0; i
< fileNr
; i
++ )
1079 block_list
+= (toc
->file
[i
].size
+ blocksize
-1) / blocksize
;
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
,
1091 reader
->read_file
= pdb_ds_read_file
;
1092 reader
->pdbimage
= pdbimage
;
1093 reader
->uu_n_pdbimage
= n_pdbimage
;
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
,
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
);
1119 void pdb_check_root_version_and_timestamp( const HChar
* pdbname
,
1122 UInt TimeDateStamp
)
1124 switch ( version
) {
1125 case 19950623: /* VC 4.0 */
1127 case 19960307: /* VC 5.0 */
1128 case 19970604: /* VC 6.0 */
1129 case 20000404: /* VC 7.0 FIXME?? */
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
;
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
) );
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
;
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
) );
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
);
1195 /* New version of the symbols record header */
1196 *symbols
= *(PDB_SYMBOLS
*)image
;
1197 *header_size
= sizeof(PDB_SYMBOLS
);
1202 /*------------------------------------------------------------*/
1204 /*--- Main stuff: reading of symbol addresses ---*/
1206 /*------------------------------------------------------------*/
1208 static ULong
DEBUG_SnarfCodeView(
1211 const IMAGE_SECTION_HEADER
* sectp
,
1212 const void* root
, /* FIXME: better name */
1220 HChar symname
[4096 /*WIN32_PATH_MAX*/]; // FIXME: really ?
1222 Bool debug
= di
->trace_symtab
;
1223 ULong n_syms_read
= 0;
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
) {
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]);
1256 * Global and local data symbols. We don't associate these
1257 * with any given source file.
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';
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
);
1288 Int
const k
= sym
->data_v2
.p_name
.namelen
;
1289 VG_(memcpy
)(symname
, sym
->data_v2
.p_name
.name
, k
);
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
;
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
);
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
);
1325 VG_(umsg
)(" S_PUB_FUNC1_V3/S_PUB_FUNC2_V3/S_PUB_V3 %s\n",
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
;
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
);
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.
1356 /* valgrind ignores PLTs */ /* JRS: it does? */
1360 * Global and static functions.
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
;
1375 vsym
.isIFunc
= False
;
1376 vsym
.isGlobal
= sym
->generic
.id
== S_GPROC_V1
;
1378 VG_(umsg
)(" Adding function %s addr=%#lx length=%u\n",
1379 symname
, vsym
.avmas
.main
, vsym
.size
);
1380 ML_(addSym
)( di
, &vsym
);
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
;
1397 vsym
.isIFunc
= False
;
1398 vsym
.isGlobal
= sym
->generic
.id
== S_GPROC_V2
;
1400 VG_(umsg
)(" Adding function %s addr=%#lx length=%u\n",
1401 symname
, vsym
.avmas
.main
, vsym
.size
);
1402 ML_(addSym
)( di
, &vsym
);
1408 VG_(umsg
)(" S_LPROC_V3/S_GPROC_V3 %s\n", sym
->proc_v3
.name
);
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
;
1420 vsym
.isIFunc
= False
;
1421 vsym
.isGlobal
= sym
->generic
.id
== S_GPROC_V3
;
1422 ML_(addSym
)( di
, &vsym
);
1427 /* JRS: how is flow supposed to arrive at commented out code below? */
1430 // printf(">>> prev func '%s' still has nest_block %u count\n",
1431 // curr_func, nest_block);
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; */
1445 * Function parameters and stack variables.
1447 case S_BPREL_XXXX_V3
:
1454 case S_LABEL_V3
: // FIXME
1468 case S_COMPILAND_V3
:
1469 case S_COMPILAND_V2
:
1470 case S_COMPILAND_V1
:
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.
1486 case S_LPROCREF_V1
: {
1487 const unsigned char *name
= (const unsigned char *)sym
+ length
;
1488 length
+= (*name
+ 1 + 3) & ~3;
1491 } /* switch ( sym->generic.id ) */
1493 } /* for ( i = offset; i < size; i += length ) */
1496 VG_(umsg
)("END SnarfCodeView addr=%p offset=%d length=%d\n",
1497 root
, offset
, size
);
1502 /*------------------------------------------------------------*/
1504 /*--- Main stuff: reading of line number tables ---*/
1506 /*------------------------------------------------------------*/
1513 unsigned int const *ui
;
1522 static ULong
DEBUG_SnarfLinetab(
1525 const IMAGE_SECTION_HEADER
* sectp
,
1526 const void* linetab
,
1530 //VG_(printf)("DEBUG_SnarfLinetab %p %p %p %d\n", di, sectp, linetab, size);
1532 HChar filename
[WIN32_PATH_MAX
];
1533 const UInt
* filetab
;
1537 const UInt
* lt_ptr
;
1541 union any_size pnt2
;
1542 const struct startend
* start
;
1545 Bool debug
= di
->trace_symtab
;
1546 ULong n_lines_read
= 0;
1549 VG_(umsg
)("BEGIN SnarfLineTab linetab=%p size=%d\n", linetab
, size
);
1553 * Now get the important bits.
1562 * Now count up the number of segments in the file.
1565 for (i
= 0; i
< nfile
; i
++) {
1566 pnt2
.c
= (const HChar
*)linetab
+ filetab
[i
];
1571 for (i
= 0; i
< nfile
; i
++) {
1572 const HChar
*fnmstr
;
1573 const HChar
*dirstr
;
1577 * Get the pointer into the segment information.
1579 pnt2
.c
= (const HChar
*)linetab
+ filetab
[i
];
1580 file_segcount
= *pnt2
.s
;
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
, '\\');
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
++) {
1612 pnt2
.c
= (const HChar
*)linetab
+ lt_ptr
[k
];
1615 linecount
= *pnt2
.s
++;
1617 if ( linecount
> 0 ) {
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
1628 Addr endaddr
= bias
+ sectp
[segno
-1].VirtualAddress
1629 + ((j
< (linecount
- 1))
1634 " Adding line %d addr=%#lx end=%#lx\n",
1635 ((const unsigned short *)(pnt2
.ui
+ linecount
))[j
],
1636 startaddr
, endaddr
);
1641 ((const unsigned short *)(pnt2
.ui
+ linecount
))[j
], j
);
1649 VG_(umsg
)("END SnarfLineTab linetab=%p size=%d\n",
1652 return n_lines_read
;
1657 /* there's a new line tab structure from MS Studio 2005 and after
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
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 */
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(
1697 const IMAGE_SECTION_HEADER
* sectp
,
1698 const HChar
* linetab
,
1700 const HChar
* strimage
,
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)
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 */
1725 VG_(printf
)("%sblock end %x\n", pfx
, lbh
->header
);
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
);
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
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);
1755 filename
= ML_(addStr
)(di
, fname
, -1);
1756 dirname
= ML_(addStr
)(di
, strM
, -1);
1758 ML_(dinfo_free
)(strM
);
1760 filename
= ML_(addStr
)(di
, "???", -1);
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
++) {
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
1779 svma_e
= sectp
[lbh
->seg
- 1].VirtualAddress
+ lbh
->start
1780 + lbh
->l
[i
+1].offset
-1;
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
,
1788 lbh
->l
[i
].lineno
^ 0x80000000, 0 );
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
1796 VG_(printf
)("%s line %u: %08lx to %08lx\n",
1797 pfx
, lbh
->l
[ lbh
->nlines
-1 ].lineno
^ 0x80000000,
1799 ML_(addLineInfo
)( di
,
1803 lbh
->l
[lbh
->nlines
-1].lineno
^ 0x80000000, 0 );
1807 lbh
= (const codeview_linetab2_block
*)
1808 ((const char*)lbh
+ 8 + lbh
->size_of_block
);
1810 return n_line2s_read
;
1814 /*------------------------------------------------------------*/
1816 /*--- Main stuff: pdb_dump ---*/
1818 /*------------------------------------------------------------*/
1820 static Int
cmp_FPO_DATA_for_canonicalisation ( const void* f1V
,
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
)
1838 const DWORD
* ok_bits
;
1840 DWORD string_idx
, stream_idx
;
1844 if (pdb
->read_file
== pdb_jg_read_file
)
1846 str
= pdb
->u
.jg
.root
->names
;
1847 cbstr
= pdb
->u
.jg
.root
->cbNames
;
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 */
1859 /* bitfield: first dword is len (in dword), then data */
1861 pdw
+= *ok_bits
++ + 1;
1864 if (VG_(clo_verbosity
) > 1)
1865 VG_(umsg
)("LOAD_PDB_DEBUGINFO: "
1866 "get_stream_by_name: unexpected value\n");
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
;
1883 static void *read_string_table(const struct pdb_reader
* pdb
)
1885 unsigned stream_idx
;
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) {
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
);
1902 /* JRS fixme: compare with version in current Wine sources */
1903 static void pdb_dump( const struct pdb_reader
* pdb
,
1907 const IMAGE_SECTION_HEADER
* sectp_avma
)
1912 PDB_SYMBOLS symbols
;
1913 unsigned len_modimage
;
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
1930 DWORD filessize
= 0;
1931 char* filesimage
= read_string_table(pdb
);
1933 filessize
= *(const DWORD
*)(filesimage
+ 8);
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
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)
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
;
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) {
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
1975 vg_assert(itersAvail
>= 0); /* safety check -- don't loop forever */
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 */
1985 for (i
= 0; i
< di
->fpo_size
; i
++) {
1986 if (di
->fpo
[i
].cbProcSize
== 0) {
1990 di
->fpo
[j
++] = di
->fpo
[i
];
1992 vg_assert(j
>= 0 && j
<= di
->fpo_size
);
1995 /* Get rid of any dups */
1996 if (di
->fpo_size
> 1) {
1998 for (i
= 1; i
< di
->fpo_size
; i
++) {
2000 = di
->fpo
[j
-1].ulOffStart
== di
->fpo
[i
].ulOffStart
2001 && di
->fpo
[j
-1].cbProcSize
== di
->fpo
[i
].cbProcSize
;
2006 di
->fpo
[j
++] = di
->fpo
[i
];
2008 vg_assert(j
>= 0 && j
<= di
->fpo_size
);
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
) {
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);
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
);
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;
2064 di
->fpo
[j
++] = di
->fpo
[i
];
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);
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
);
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
;
2091 di
->fpo_minavma
= 0;
2092 di
->fpo_maxavma
= 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 */
2108 case 19961031: /* VC 5.0 / 6.0 */
2109 case 20040203: /* VC 7.0 FIXME?? */
2112 if (VG_(clo_verbosity
) > 1)
2113 VG_(umsg
)("LOAD_PDB_DEBUGINFO: "
2114 "Unknown .pdb type info version %lu\n", types
.version
);
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?? */
2126 if (VG_(clo_verbosity
) > 1)
2127 VG_(umsg
)("LOAD_PDB_DEBUGINFO: "
2128 "Unknown .pdb symbol info version %lu\n",
2133 * Read global symbol table
2135 modimage
= pdb
->read_file( pdb
, symbols
.gsym_file
, &len_modimage
);
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
;
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 );
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
);
2180 if (VG_(clo_verbosity
) > 1)
2181 VG_(umsg
)("LOAD_PDB_DEBUGINFO: Reading symbols for %s\n",
2184 += DEBUG_SnarfCodeView( di
, pe_avma
, sectp_avma
, modimage
,
2185 sizeof(unsigned long),
2192 if (VG_(clo_verbosity
) > 1)
2193 VG_(umsg
)("LOAD_PDB_DEBUGINFO: "
2194 "Reading lines for %s\n", file_name
);
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
);
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
,
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 );
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 /*------------------------------------------------------------*/
2248 /*--- TOP LEVEL for PDB reading ---*/
2250 /*------------------------------------------------------------*/
2252 /* Read line, symbol and unwind information from a PDB file.
2254 Bool
ML_(read_pdb_debug_info
)(
2260 const HChar
* pdbname
,
2266 Addr mapped_avma
, mapped_end_avma
;
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");
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");
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
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. */
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 */
2320 VG_(memcpy
)(name
, pe_sechdr_avma
->Name
, 8);
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
)
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
;
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
)) {
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
;
2358 di
->text_size
= mapped_end_avma
- di
->text_avma
;
2362 else if (pe_sechdr_avma
->Characteristics
2363 & IMAGE_SCN_CNT_INITIALIZED_DATA
) {
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
;
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
;
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
);
2392 TRACE_SYMTAB("------ start PE OBJECT with PDB INFO "
2393 "---------------------\n");
2394 TRACE_SYMTAB("------ name = %s\n", di
->fsm
.filename
);
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
);
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
);
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
2426 hdr
= find_pdb_header( pdbimage
, &signature
);
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
;
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
);
2447 ML_(dinfo_free
)( root
);
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
;
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
);
2462 ML_(dinfo_free
)( root
);
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
;
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. */
2484 TRACE_SYMTAB("------ name = %s\n", di
->fsm
.filename
);
2485 TRACE_SYMTAB("------ end PE OBJECT with PDB INFO "
2486 "--------------------\n");
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
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
2502 Bool do_cleanup
= False
;
2503 HChar tmpnameroot
[50]; // large enough
2504 HChar tmpname
[VG_(mkstemp_fullname_bufsz
)(sizeof tmpnameroot
- 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
);
2517 VG_(umsg
)("LOAD_PDB_DEBUGINFO: "
2518 "Find PDB file: Can't create temporary file %s\n", tmpname
);
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
)
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
);
2542 VG_(dmsg
)("LOAD_PDB_DEBUGINFO: "
2543 "Find PDB file: Command failed:\n %s\n", cmd
);
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
);
2557 Int szB
= (Int
)stat_buf
.size
;
2559 VG_(umsg
)("LOAD_PDB_DEBUGINFO: Find PDB file: %s is empty\n", tmpname
);
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",
2569 HChar
* pdbname
= ML_(dinfo_zalloc
)("di.readpe.fnopf.pdbname", szB
+ 1);
2572 Int nread
= VG_(read
)(fd
, pdbname
, szB
);
2574 VG_(umsg
)("LOAD_PDB_DEBUGINFO: Find PDB file: read of %s failed\n", tmpname
);
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
;
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
);
2592 /* Change the \n to a terminating zero, so we have a "normal" string */
2595 if (0) VG_(printf
)("QQQQQQQQ: got %s\n", pdbname
);
2603 VG_(unlink
)( tmpname
);
2608 #endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
2610 /*--------------------------------------------------------------------*/
2612 /*--------------------------------------------------------------------*/