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-2008 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, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
35 The GNU General Public License is contained in the file COPYING.
38 #if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_l4re)
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_d3basics.h"
54 #include "priv_storage.h"
55 #include "priv_readpdb.h" // self
58 /*------------------------------------------------------------*/
62 /*------------------------------------------------------------*/
64 /* JRS 2009-Apr-13: Mostly this PDB reader is straightforward. But
65 the biasing is incomprehensible, and I don't claim to understand it
66 at all. There are four places where biasing is required:
68 - when reading symbol addresses (DEBUG_SnarfCodeView)
69 - when reading old-style line number tables (DEBUG_SnarfLinetab)
70 - when reading new-style line number tables (codeview_dump_linetab2)
71 - when reading FPO (stack-unwind) tables (pdb_dump)
73 To complicate matters further, Wine supplies us, via the
74 VG_USERREQ__LOAD_PDB_DEBUGINFO client request that initiates PDB
75 reading, a value 'unknown_purpose__reloc' which, if you read
76 'virtual.c' in the Wine sources, looks a lot like a text bias
77 value. Yet the code below ignores it.
79 To make future experimentation with biasing easier, here are four
80 macros which give the bias to use in each of the four cases. Be
81 warned, they can and do refer to local vars in the relevant
84 /* The BIAS_FOR_{SYMBOLS,LINETAB,LINETAB2} are as in JohnR's original
85 patch. BIAS_FOR_FPO was originally hardwired to zero, but that
86 doesn't make much sense. Here, we use text_bias as empirically
87 producing the most ranges that fall inside the text segments for a
88 multi-dll program. Of course, it could still be nonsense :-) */
89 #define BIAS_FOR_SYMBOLS (di->rx_map_avma)
90 #define BIAS_FOR_LINETAB (di->rx_map_avma)
91 #define BIAS_FOR_LINETAB2 (di->text_bias)
92 #define BIAS_FOR_FPO (di->text_bias)
93 /* Using di->text_bias for the FPOs causes 981 in range and 1 out of
94 range. Using rx_map_avma gives 953 in range and 29 out of range,
95 so di->text_bias looks like a better bet.:
96 $ grep FPO spew-B-text_bias | grep keep | wc
98 $ grep FPO spew-B-text_bias | grep SKIP | wc
100 $ grep FPO spew-B-rx_map_avma | grep keep | wc
102 $ grep FPO spew-B-rx_map_avma | grep SKIP | wc
106 /* This module leaks space; enable m_main's calling of
107 VG_(di_discard_ALL_debuginfo)() at shutdown and run with
108 --profile-heap=yes to see. The main culprit appears to be
109 di.readpe.pdr.1. I haven't bothered to chase it further. */
112 /*------------------------------------------------------------*/
114 /*--- PE/PDB definitions ---*/
116 /*------------------------------------------------------------*/
123 /* the following DOS and WINDOWS structures, defines and PE/PDB
124 * parsing code are copied or derived from the WINE
125 * project - http://www.winehq.com/
129 * File formats definitions
131 #define OFFSET_OF(__c,__f) ((int)(((char*)&(((__c*)0)->__f))-((char*)0)))
132 #define WIN32_PATH_MAX 256
135 typedef struct _IMAGE_DOS_HEADER {
136 unsigned short e_magic; /* 00: MZ Header signature */
137 unsigned short e_cblp; /* 02: Bytes on last page of file */
138 unsigned short e_cp; /* 04: Pages in file */
139 unsigned short e_crlc; /* 06: Relocations */
140 unsigned short e_cparhdr; /* 08: Size of header in paragraphs */
141 unsigned short e_minalloc; /* 0a: Minimum extra paragraphs needed */
142 unsigned short e_maxalloc; /* 0c: Maximum extra paragraphs needed */
143 unsigned short e_ss; /* 0e: Initial (relative) SS value */
144 unsigned short e_sp; /* 10: Initial SP value */
145 unsigned short e_csum; /* 12: Checksum */
146 unsigned short e_ip; /* 14: Initial IP value */
147 unsigned short e_cs; /* 16: Initial (relative) CS value */
148 unsigned short e_lfarlc; /* 18: File address of relocation table */
149 unsigned short e_ovno; /* 1a: Overlay number */
150 unsigned short e_res[4]; /* 1c: Reserved words */
151 unsigned short e_oemid; /* 24: OEM identifier (for e_oeminfo) */
152 unsigned short e_oeminfo; /* 26: OEM information; e_oemid specific */
153 unsigned short e_res2[10]; /* 28: Reserved words */
154 unsigned long e_lfanew; /* 3c: Offset to extended header */
155 } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
157 #define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
158 #define IMAGE_OS2_SIGNATURE 0x454E /* NE */
159 #define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
160 #define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */
161 #define IMAGE_VXD_SIGNATURE 0x454C /* LE */
162 #define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
164 /* Subsystem Values */
166 #define IMAGE_SUBSYSTEM_UNKNOWN 0
167 #define IMAGE_SUBSYSTEM_NATIVE 1
168 #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */
169 #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem*/
170 #define IMAGE_SUBSYSTEM_OS2_CUI 5
171 #define IMAGE_SUBSYSTEM_POSIX_CUI 7
173 typedef struct _IMAGE_FILE_HEADER {
174 unsigned short Machine;
175 unsigned short NumberOfSections;
176 unsigned long TimeDateStamp;
177 unsigned long PointerToSymbolTable;
178 unsigned long NumberOfSymbols;
179 unsigned short SizeOfOptionalHeader;
180 unsigned short Characteristics;
181 } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
183 typedef struct _IMAGE_DATA_DIRECTORY {
184 unsigned long VirtualAddress;
186 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
188 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
190 typedef struct _IMAGE_OPTIONAL_HEADER {
192 /* Standard fields */
194 unsigned short Magic; /* 0x10b or 0x107 */ /* 0x00 */
195 unsigned char MajorLinkerVersion;
196 unsigned char MinorLinkerVersion;
197 unsigned long SizeOfCode;
198 unsigned long SizeOfInitializedData;
199 unsigned long SizeOfUninitializedData;
200 unsigned long AddressOfEntryPoint; /* 0x10 */
201 unsigned long BaseOfCode;
202 unsigned long BaseOfData;
204 /* NT additional fields */
206 unsigned long ImageBase;
207 unsigned long SectionAlignment; /* 0x20 */
208 unsigned long FileAlignment;
209 unsigned short MajorOperatingSystemVersion;
210 unsigned short MinorOperatingSystemVersion;
211 unsigned short MajorImageVersion;
212 unsigned short MinorImageVersion;
213 unsigned short MajorSubsystemVersion; /* 0x30 */
214 unsigned short MinorSubsystemVersion;
215 unsigned long Win32VersionValue;
216 unsigned long SizeOfImage;
217 unsigned long SizeOfHeaders;
218 unsigned long CheckSum; /* 0x40 */
219 unsigned short Subsystem;
220 unsigned short DllCharacteristics;
221 unsigned long SizeOfStackReserve;
222 unsigned long SizeOfStackCommit;
223 unsigned long SizeOfHeapReserve; /* 0x50 */
224 unsigned long SizeOfHeapCommit;
225 unsigned long LoaderFlags;
226 unsigned long NumberOfRvaAndSizes;
227 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /* 0x60 */
229 } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
231 typedef struct _IMAGE_NT_HEADERS {
232 unsigned long Signature; /* "PE"\0\0 */ /* 0x00 */
233 IMAGE_FILE_HEADER FileHeader; /* 0x04 */
234 IMAGE_OPTIONAL_HEADER OptionalHeader; /* 0x18 */
235 } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
237 #define IMAGE_SIZEOF_SHORT_NAME 8
239 typedef struct _IMAGE_SECTION_HEADER {
240 unsigned char Name[IMAGE_SIZEOF_SHORT_NAME];
242 unsigned long PhysicalAddress;
243 unsigned long VirtualSize;
245 unsigned long VirtualAddress;
246 unsigned long SizeOfRawData;
247 unsigned long PointerToRawData;
248 unsigned long PointerToRelocations;
249 unsigned long PointerToLinenumbers;
250 unsigned short NumberOfRelocations;
251 unsigned short NumberOfLinenumbers;
252 unsigned long Characteristics;
253 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
255 #define IMAGE_SIZEOF_SECTION_HEADER 40
257 #define IMAGE_FIRST_SECTION(ntheader) \
258 ((PIMAGE_SECTION_HEADER)((LPunsigned char)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \
259 ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader))
261 /* These defines are for the Characteristics bitfield. */
262 /* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */
263 /* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */
264 /* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */
265 /* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */
266 /* #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 - Reserved */
267 /* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */
269 #define IMAGE_SCN_CNT_CODE 0x00000020
270 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
271 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
273 #define IMAGE_SCN_LNK_OTHER 0x00000100
274 #define IMAGE_SCN_LNK_INFO 0x00000200
275 /* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */
276 #define IMAGE_SCN_LNK_REMOVE 0x00000800
277 #define IMAGE_SCN_LNK_COMDAT 0x00001000
279 /* 0x00002000 - Reserved */
280 /* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */
281 #define IMAGE_SCN_MEM_FARDATA 0x00008000
283 /* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */
284 #define IMAGE_SCN_MEM_PURGEABLE 0x00020000
285 #define IMAGE_SCN_MEM_16BIT 0x00020000
286 #define IMAGE_SCN_MEM_LOCKED 0x00040000
287 #define IMAGE_SCN_MEM_PRELOAD 0x00080000
289 #define IMAGE_SCN_ALIGN_1BYTES 0x00100000
290 #define IMAGE_SCN_ALIGN_2BYTES 0x00200000
291 #define IMAGE_SCN_ALIGN_4BYTES 0x00300000
292 #define IMAGE_SCN_ALIGN_8BYTES 0x00400000
293 #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */
294 #define IMAGE_SCN_ALIGN_32BYTES 0x00600000
295 #define IMAGE_SCN_ALIGN_64BYTES 0x00700000
296 /* 0x00800000 - Unused */
298 #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
301 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
302 #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
303 #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
304 #define IMAGE_SCN_MEM_SHARED 0x10000000
305 #define IMAGE_SCN_MEM_EXECUTE 0x20000000
306 #define IMAGE_SCN_MEM_READ 0x40000000
307 #define IMAGE_SCN_MEM_WRITE 0x80000000
311 typedef struct _GUID /* 16 bytes */
314 unsigned short Data2;
315 unsigned short Data3;
316 unsigned char Data4[ 8 ];
319 /*========================================================================
324 typedef struct _PDB_FILE
327 unsigned long unknown;
329 } PDB_FILE, *PPDB_FILE;
331 // A .pdb file begins with a variable-length one-line text string
332 // that ends in "\r\n\032". This is followed by a 4-byte "signature"
333 // ("DS\0\0" for newer files, "JG\0\0" for older files), then
334 // aligned up to a 4-byte boundary, then the struct below:
337 //char ident[40]; // "Microsoft C/C++ program database 2.00\r\n\032"
338 //unsigned long signature; // "JG\0\0"
339 unsigned int blocksize; // 0x400 typical; also 0x800, 0x1000
340 unsigned short freelist;
341 unsigned short total_alloc;
343 unsigned short toc_block[ 1 ];
348 //char signature[32]; // "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0"
349 unsigned int block_size;
350 unsigned int unknown1;
351 unsigned int num_pages;
352 unsigned int toc_size;
353 unsigned int unknown2;
354 unsigned int toc_page;
366 unsigned int num_files;
367 unsigned int file_size[1];
372 unsigned int version;
373 unsigned int TimeDateStamp;
375 unsigned int cbNames;
381 unsigned int version;
382 unsigned int TimeDateStamp;
385 unsigned int cbNames;
389 typedef struct _PDB_TYPES_OLD
391 unsigned long version;
392 unsigned short first_index;
393 unsigned short last_index;
394 unsigned long type_size;
398 } PDB_TYPES_OLD, *PPDB_TYPES_OLD;
400 typedef struct _PDB_TYPES
402 unsigned long version;
403 unsigned long type_offset;
404 unsigned long first_index;
405 unsigned long last_index;
406 unsigned long type_size;
409 unsigned long hash_size;
410 unsigned long hash_base;
411 unsigned long hash_offset;
412 unsigned long hash_len;
413 unsigned long search_offset;
414 unsigned long search_len;
415 unsigned long unknown_offset;
416 unsigned long unknown_len;
418 } PDB_TYPES, *PPDB_TYPES;
420 typedef struct _PDB_SYMBOL_RANGE
422 unsigned short segment;
424 unsigned long offset;
426 unsigned long characteristics;
427 unsigned short index;
430 } PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
432 typedef struct _PDB_SYMBOL_RANGE_EX
434 unsigned short segment;
436 unsigned long offset;
438 unsigned long characteristics;
439 unsigned short index;
441 unsigned long timestamp;
442 unsigned long unknown;
444 } PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
446 typedef struct _PDB_SYMBOL_FILE
448 unsigned long unknown1;
449 PDB_SYMBOL_RANGE range;
452 unsigned long symbol_size;
453 unsigned long lineno_size;
454 unsigned long unknown2;
455 unsigned long nSrcFiles;
456 unsigned long attribute;
459 } PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
461 typedef struct _PDB_SYMBOL_FILE_EX
463 unsigned long unknown1;
464 PDB_SYMBOL_RANGE_EX range;
467 unsigned long symbol_size;
468 unsigned long lineno_size;
469 unsigned long unknown2;
470 unsigned long nSrcFiles;
471 unsigned long attribute;
472 unsigned long reserved[ 2 ];
475 } PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
477 typedef struct _PDB_SYMBOL_SOURCE
479 unsigned short nModules;
480 unsigned short nSrcFiles;
481 unsigned short table[ 1 ];
483 } PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
485 typedef struct _PDB_SYMBOL_IMPORT
487 unsigned long unknown1;
488 unsigned long unknown2;
489 unsigned long TimeDateStamp;
490 unsigned long nRequests;
493 } PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
495 typedef struct _PDB_SYMBOLS_OLD
497 unsigned short hash1_file;
498 unsigned short hash2_file;
499 unsigned short gsym_file;
501 unsigned long module_size;
502 unsigned long offset_size;
503 unsigned long hash_size;
504 unsigned long srcmodule_size;
506 } PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
508 typedef struct _PDB_SYMBOLS
510 unsigned long signature;
511 unsigned long version;
512 unsigned long unknown;
513 unsigned long hash1_file;
514 unsigned long hash2_file;
515 unsigned long gsym_file;
516 unsigned long module_size;
517 unsigned long offset_size;
518 unsigned long hash_size;
519 unsigned long srcmodule_size;
520 unsigned long pdbimport_size;
521 unsigned long resvd[ 5 ];
523 } PDB_SYMBOLS, *PPDB_SYMBOLS;
526 /*========================================================================
527 * Process CodeView symbol information.
530 /* from wine-1.0/include/wine/mscvpdb.h */
532 struct p_string /* "Pascal string": prefixed by byte containing length */
534 unsigned char namelen;
537 /* The other kind of "char name[1]" is a "C++ string" terminated by '\0'.
538 * "Name mangling" to encode type information often exceeds 255 bytes.
539 * Instead of using a 2-byte explicit length, they save one byte of space
540 * but incur a strlen(). This is justified by other code that wants
541 * a "C string" [terminated by '\0'] anyway.
544 union codeview_symbol
557 unsigned short segment;
558 unsigned short symtype;
559 struct p_string p_name;
566 unsigned int symtype;
568 unsigned short segment;
569 struct p_string p_name;
576 unsigned int symtype;
578 unsigned short segment;
579 char name[1]; /* terminated by '\0' */
586 unsigned int pparent;
590 unsigned short segment;
591 unsigned short thunk_len;
592 unsigned char thtype;
593 struct p_string p_name;
600 unsigned int pparent;
604 unsigned short segment;
605 unsigned short thunk_len;
606 unsigned char thtype;
607 char name[1]; /* terminated by '\0' */
614 unsigned int pparent;
617 unsigned int proc_len;
618 unsigned int debug_start;
619 unsigned int debug_end;
621 unsigned short segment;
622 unsigned short proctype;
624 struct p_string p_name;
631 unsigned int pparent;
634 unsigned int proc_len;
635 unsigned int debug_start;
636 unsigned int debug_end;
637 unsigned int proctype;
639 unsigned short segment;
641 struct p_string p_name;
648 unsigned int pparent;
651 unsigned int proc_len;
652 unsigned int debug_start;
653 unsigned int debug_end;
654 unsigned int proctype;
656 unsigned short segment;
658 char name[1]; /* terminated by '\0' */
665 unsigned int symtype;
667 unsigned short segment;
668 struct p_string p_name;
675 unsigned int symtype;
677 unsigned short segment;
678 char name[1]; /* terminated by '\0' */
683 short int len; /* Total length of this entry */
684 short int id; /* Always S_BPREL_V1 */
685 unsigned int offset; /* Stack offset relative to BP */
686 unsigned short symtype;
687 struct p_string p_name;
692 short int len; /* Total length of this entry */
693 short int id; /* Always S_BPREL_V2 */
694 unsigned int offset; /* Stack offset relative to EBP */
695 unsigned int symtype;
696 struct p_string p_name;
701 short int len; /* Total length of this entry */
702 short int id; /* Always S_BPREL_V3 */
703 int offset; /* Stack offset relative to BP */
704 unsigned int symtype;
705 char name[1]; /* terminated by '\0' */
710 short int len; /* Total length of this entry */
711 short int id; /* Always S_BPREL_V3 */
712 int offset; /* Stack offset relative to BP */
713 unsigned int symtype;
714 unsigned short unknown;
715 char name[1]; /* terminated by '\0' */
720 short int len; /* Total length of this entry */
721 short int id; /* Always S_REGISTER */
724 struct p_string p_name;
725 /* don't handle register tracking */
730 short int len; /* Total length of this entry */
731 short int id; /* Always S_REGISTER_V2 */
732 unsigned int type; /* check whether type & reg are correct */
734 struct p_string p_name;
735 /* don't handle register tracking */
740 short int len; /* Total length of this entry */
741 short int id; /* Always S_REGISTER_V3 */
742 unsigned int type; /* check whether type & reg are correct */
744 char name[1]; /* terminated by '\0' */
745 /* don't handle register tracking */
756 unsigned short segment;
757 struct p_string p_name;
768 unsigned short segment;
769 char name[1]; /* terminated by '\0' */
777 unsigned short segment;
779 struct p_string p_name;
787 unsigned short segment;
789 char name[1]; /* terminated by '\0' */
797 unsigned short cvalue; /* numeric leaf */
799 struct p_string p_name;
808 unsigned short cvalue; /* numeric leaf */
810 struct p_string p_name;
819 unsigned short cvalue;
821 char name[1]; /* terminated by '\0' */
830 struct p_string p_name;
838 struct p_string p_name;
846 char name[1]; /* terminated by '\0' */
854 struct p_string p_name;
861 unsigned int unknown;
862 struct p_string p_name;
869 unsigned unknown1[4];
870 unsigned short unknown2;
871 struct p_string p_name;
878 unsigned int unknown;
879 char name[1]; /* terminated by '\0' */
887 unsigned short segment;
891 #define S_COMPILAND_V1 0x0001
892 #define S_REGISTER_V1 0x0002
893 #define S_CONSTANT_V1 0x0003
894 #define S_UDT_V1 0x0004
895 #define S_SSEARCH_V1 0x0005
896 #define S_END_V1 0x0006
897 #define S_SKIP_V1 0x0007
898 #define S_CVRESERVE_V1 0x0008
899 #define S_OBJNAME_V1 0x0009
900 #define S_ENDARG_V1 0x000a
901 #define S_COBOLUDT_V1 0x000b
902 #define S_MANYREG_V1 0x000c
903 #define S_RETURN_V1 0x000d
904 #define S_ENTRYTHIS_V1 0x000e
906 #define S_BPREL_V1 0x0200
907 #define S_LDATA_V1 0x0201
908 #define S_GDATA_V1 0x0202
909 #define S_PUB_V1 0x0203
910 #define S_LPROC_V1 0x0204
911 #define S_GPROC_V1 0x0205
912 #define S_THUNK_V1 0x0206
913 #define S_BLOCK_V1 0x0207
914 #define S_WITH_V1 0x0208
915 #define S_LABEL_V1 0x0209
916 #define S_CEXMODEL_V1 0x020a
917 #define S_VFTPATH_V1 0x020b
918 #define S_REGREL_V1 0x020c
919 #define S_LTHREAD_V1 0x020d
920 #define S_GTHREAD_V1 0x020e
922 #define S_PROCREF_V1 0x0400
923 #define S_DATAREF_V1 0x0401
924 #define S_ALIGN_V1 0x0402
925 #define S_LPROCREF_V1 0x0403
927 #define S_REGISTER_V2 0x1001 /* Variants with new 32-bit type indices */
928 #define S_CONSTANT_V2 0x1002
929 #define S_UDT_V2 0x1003
930 #define S_COBOLUDT_V2 0x1004
931 #define S_MANYREG_V2 0x1005
932 #define S_BPREL_V2 0x1006
933 #define S_LDATA_V2 0x1007
934 #define S_GDATA_V2 0x1008
935 #define S_PUB_V2 0x1009
936 #define S_LPROC_V2 0x100a
937 #define S_GPROC_V2 0x100b
938 #define S_VFTTABLE_V2 0x100c
939 #define S_REGREL_V2 0x100d
940 #define S_LTHREAD_V2 0x100e
941 #define S_GTHREAD_V2 0x100f
943 #define S_XXXXXXXXX_32 0x1012 /* seems linked to a function, content unknown */
945 #define S_COMPILAND_V2 0x1013
947 #define S_COMPILAND_V3 0x1101
948 #define S_THUNK_V3 0x1102
949 #define S_BLOCK_V3 0x1103
950 #define S_LABEL_V3 0x1105
951 #define S_REGISTER_V3 0x1106
952 #define S_CONSTANT_V3 0x1107
953 #define S_UDT_V3 0x1108
954 #define S_BPREL_V3 0x110B
955 #define S_LDATA_V3 0x110C
956 #define S_GDATA_V3 0x110D
957 #define S_PUB_V3 0x110E
958 #define S_LPROC_V3 0x110F
959 #define S_GPROC_V3 0x1110
960 #define S_BPREL_XXXX_V3 0x1111 /* not really understood, but looks like bprel... */
961 #define S_MSTOOL_V3 0x1116 /* compiler command line options and build information */
962 #define S_PUB_FUNC1_V3 0x1125 /* didn't get the difference between the two */
963 #define S_PUB_FUNC2_V3 0x1127
966 /*------------------------------------------------------------*/
968 /*--- pdb-reading: bits and pieces ---*/
970 /*------------------------------------------------------------*/
974 void* (*read_file)(struct pdb_reader*, unsigned, unsigned *);
975 // JRS 2009-Apr-8: .uu_n_pdbimage is never used.
976 UChar* pdbimage; // image address
977 SizeT uu_n_pdbimage; // size
980 struct PDB_JG_HEADER* header;
981 struct PDB_JG_TOC* toc;
984 struct PDB_DS_HEADER* header;
985 struct PDB_DS_TOC* toc;
991 static void* pdb_ds_read( struct pdb_reader* pdb,
992 unsigned* block_list,
995 unsigned blocksize, nBlocks;
999 if (!size) return NULL;
1000 if (size > 512 * 1024 * 1024) {
1001 VG_(umsg)("Warning: pdb_ds_read: implausible size "
1002 "(%u); skipping -- possible invalid .pdb file?\n", size);
1006 blocksize = pdb->u.ds.header->block_size;
1007 nBlocks = (size + blocksize - 1) / blocksize;
1008 buffer = ML_(dinfo_zalloc)("di.readpe.pdr.1", nBlocks * blocksize);
1009 for (i = 0; i < nBlocks; i++)
1010 VG_(memcpy)( buffer + i * blocksize,
1011 pdb->pdbimage + block_list[i] * blocksize,
1017 static void* pdb_jg_read( struct pdb_reader* pdb,
1018 unsigned short* block_list,
1021 unsigned blocksize, nBlocks;
1024 //VG_(printf)("pdb_read %p %p %d\n", pdb, block_list, size);
1025 if ( !size ) return NULL;
1027 blocksize = pdb->u.jg.header->blocksize;
1028 nBlocks = (size + blocksize-1) / blocksize;
1029 buffer = ML_(dinfo_zalloc)("di.readpe.pjr.1", nBlocks * blocksize);
1030 for ( i = 0; i < nBlocks; i++ )
1031 VG_(memcpy)( buffer + i*blocksize,
1032 pdb->pdbimage + block_list[i]*blocksize, blocksize );
1037 static void* find_pdb_header( UChar* pdbimage,
1038 unsigned* signature )
1040 static char pdbtxt[]= "Microsoft C/C++";
1041 UChar* txteof = (UChar*)VG_(strchr)(pdbimage, '\032');
1044 if (0!=VG_(strncmp)(pdbimage, pdbtxt, -1+ sizeof(pdbtxt)))
1047 *signature = *(unsigned*)(1+ txteof);
1048 return (void*)((~3& (3+ (4+ 1+ (txteof - pdbimage)))) + pdbimage);
1052 static void* pdb_ds_read_file( struct pdb_reader* reader,
1053 unsigned file_number,
1056 unsigned i, *block_list;
1057 if (!reader->u.ds.toc || file_number >= reader->u.ds.toc->num_files)
1059 if (reader->u.ds.toc->file_size[file_number] == 0
1060 || reader->u.ds.toc->file_size[file_number] == 0xFFFFFFFF)
1064 = reader->u.ds.toc->file_size + reader->u.ds.toc->num_files;
1065 for (i = 0; i < file_number; i++)
1066 block_list += (reader->u.ds.toc->file_size[i]
1067 + reader->u.ds.header->block_size - 1)
1069 reader->u.ds.header->block_size;
1071 *plength = reader->u.ds.toc->file_size[file_number];
1072 return pdb_ds_read( reader, block_list,
1073 reader->u.ds.toc->file_size[file_number]);
1077 static void* pdb_jg_read_file( struct pdb_reader* pdb,
1081 //VG_(printf)("pdb_read_file %p %d\n", pdb, fileNr);
1082 unsigned blocksize = pdb->u.jg.header->blocksize;
1083 struct PDB_JG_TOC* toc = pdb->u.jg.toc;
1085 unsigned short* block_list;
1087 if ( !toc || fileNr >= toc->nFiles )
1091 = (unsigned short *) &toc->file[ toc->nFiles ];
1092 for ( i = 0; i < fileNr; i++ )
1093 block_list += (toc->file[i].size + blocksize-1) / blocksize;
1096 *plength = toc->file[fileNr].size;
1097 return pdb_jg_read( pdb, block_list, toc->file[fileNr].size );
1101 static void pdb_ds_init( struct pdb_reader * reader,
1105 reader->read_file = pdb_ds_read_file;
1106 reader->pdbimage = pdbimage;
1107 reader->uu_n_pdbimage = n_pdbimage;
1111 (unsigned*)(reader->u.ds.header->block_size
1112 * reader->u.ds.header->toc_page
1113 + reader->pdbimage),
1114 reader->u.ds.header->toc_size
1119 static void pdb_jg_init( struct pdb_reader* reader,
1121 unsigned n_pdbimage )
1123 reader->read_file = pdb_jg_read_file;
1124 reader->pdbimage = pdbimage;
1125 reader->uu_n_pdbimage = n_pdbimage;
1126 reader->u.jg.toc = pdb_jg_read(reader,
1127 reader->u.jg.header->toc_block,
1128 reader->u.jg.header->toc.size);
1135 void pdb_check_root_version_and_timestamp( char* pdbname,
1138 UInt TimeDateStamp )
1140 switch ( version ) {
1141 case 19950623: /* VC 4.0 */
1143 case 19960307: /* VC 5.0 */
1144 case 19970604: /* VC 6.0 */
1145 case 20000404: /* VC 7.0 FIXME?? */
1148 if (VG_(clo_verbosity) > 1)
1149 VG_(message)(Vg_UserMsg,
1150 "Unknown .pdb root block version %d\n", version );
1152 if ( TimeDateStamp != pdbmtime ) {
1153 if (VG_(clo_verbosity) > 1)
1154 VG_(message)(Vg_UserMsg,
1155 "Wrong time stamp of .PDB file %s (0x%08x, 0x%08llx)\n",
1156 pdbname, TimeDateStamp, pdbmtime );
1161 static DWORD pdb_get_file_size( struct pdb_reader* reader, unsigned idx )
1163 if (reader->read_file == pdb_jg_read_file)
1164 return reader->u.jg.toc->file[idx].size;
1166 return reader->u.ds.toc->file_size[idx];
1170 static void pdb_convert_types_header( PDB_TYPES *types, char* image )
1172 VG_(memset)( types, 0, sizeof(PDB_TYPES) );
1175 if ( *(unsigned long *)image < 19960000 ) { /* FIXME: correct version? */
1176 /* Old version of the types record header */
1177 PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
1178 types->version = old->version;
1179 types->type_offset = sizeof(PDB_TYPES_OLD);
1180 types->type_size = old->type_size;
1181 types->first_index = old->first_index;
1182 types->last_index = old->last_index;
1183 types->file = old->file;
1185 /* New version of the types record header */
1186 *types = *(PDB_TYPES *)image;
1191 static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols,
1192 int *header_size, char* image )
1194 VG_(memset)( symbols, 0, sizeof(PDB_SYMBOLS) );
1197 if ( *(unsigned long *)image != 0xffffffff ) {
1198 /* Old version of the symbols record header */
1199 PDB_SYMBOLS_OLD *old = (PDB_SYMBOLS_OLD *)image;
1200 symbols->version = 0;
1201 symbols->module_size = old->module_size;
1202 symbols->offset_size = old->offset_size;
1203 symbols->hash_size = old->hash_size;
1204 symbols->srcmodule_size = old->srcmodule_size;
1205 symbols->pdbimport_size = 0;
1206 symbols->hash1_file = old->hash1_file;
1207 symbols->hash2_file = old->hash2_file;
1208 symbols->gsym_file = old->gsym_file;
1209 *header_size = sizeof(PDB_SYMBOLS_OLD);
1211 /* New version of the symbols record header */
1212 *symbols = *(PDB_SYMBOLS *)image;
1213 *header_size = sizeof(PDB_SYMBOLS);
1218 /*------------------------------------------------------------*/
1220 /*--- Main stuff: reading of symbol addresses ---*/
1222 /*------------------------------------------------------------*/
1224 static ULong DEBUG_SnarfCodeView(
1226 IMAGE_SECTION_HEADER* sectp,
1227 void* root, /* FIXME: better name */
1235 Char symname[4096 /*WIN32_PATH_MAX*/];
1237 Bool debug = di->trace_symtab;
1238 Addr bias = BIAS_FOR_SYMBOLS;
1239 ULong n_syms_read = 0;
1242 VG_(message)(Vg_UserMsg,
1243 "BEGIN SnarfCodeView addr=%p offset=%d length=%d\n",
1244 root, offset, size );
1246 VG_(memset)(&vsym, 0, sizeof(vsym)); /* avoid holes */
1248 * Loop over the different types of records and whenever we
1249 * find something we are interested in, record it and move on.
1251 for ( i = offset; i < size; i += length )
1253 union codeview_symbol *sym = (union codeview_symbol *)((char *)root + i);
1255 length = sym->generic.len + 2;
1257 //VG_(printf)("id=%x len=%d\n", sym->generic.id, length);
1258 switch ( sym->generic.id ) {
1262 VG_(printf)("unknown id 0x%x len=0x%x at %p\n",
1263 sym->generic.id, sym->generic.len, sym);
1264 VG_(printf)(" %8x %8x %8x %8x\n",
1265 ((int *)sym)[1],((int *)sym)[2],
1266 ((int *)sym)[3],((int *)sym)[4]);
1267 VG_(printf)(" %8x %8x %8x %8x\n",
1268 ((int *)sym)[5],((int *)sym)[6],
1269 ((int *)sym)[7],((int *)sym)[8]);
1273 * Global and local data symbols. We don't associate these
1274 * with any given source file.
1279 VG_(memcpy)(symname, sym->data_v1.p_name.name,
1280 sym->data_v1.p_name.namelen);
1281 symname[sym->data_v1.p_name.namelen] = '\0';
1284 VG_(message)(Vg_UserMsg, " Data %s\n", symname );
1286 if (0 /*VG_(needs).data_syms*/) {
1287 nmstr = ML_(addStr)(di, symname, sym->data_v1.p_name.namelen);
1289 vsym.addr = bias + sectp[sym->data_v1.segment-1].VirtualAddress
1290 + sym->data_v1.offset;
1292 vsym.size = sym->data_v1.p_name.namelen;
1293 // FIXME: .namelen is sizeof(.data) including .name[]
1294 vsym.isText = (sym->generic.id == S_PUB_V1);
1295 vsym.isIFunc = False;
1296 ML_(addSym)( di, &vsym );
1303 Int const k = sym->data_v2.p_name.namelen;
1304 VG_(memcpy)(symname, sym->data_v2.p_name.name, k);
1308 VG_(message)(Vg_UserMsg,
1309 " S_GDATA_V2/S_LDATA_V2/S_PUB_V2 %s\n", symname );
1311 if (sym->generic.id==S_PUB_V2 /*VG_(needs).data_syms*/) {
1312 nmstr = ML_(addStr)(di, symname, k);
1314 vsym.addr = bias + sectp[sym->data_v2.segment-1].VirtualAddress
1315 + sym->data_v2.offset;
1318 // FIXME: data_v2.len is sizeof(.data),
1319 // not size of function!
1320 vsym.isText = !!(IMAGE_SCN_CNT_CODE
1321 & sectp[sym->data_v2.segment-1].Characteristics);
1322 vsym.isIFunc = False;
1323 ML_(addSym)( di, &vsym );
1329 /* not completely sure of those two anyway */
1330 case S_PUB_FUNC1_V3:
1331 case S_PUB_FUNC2_V3: {
1332 Int k = sym->public_v3.len - (-1+ sizeof(sym->public_v3));
1333 if ((-1+ sizeof(symname)) < k)
1334 k = -1+ sizeof(symname);
1335 VG_(memcpy)(symname, sym->public_v3.name, k);
1339 VG_(message)(Vg_UserMsg,
1340 " S_PUB_FUNC1_V3/S_PUB_FUNC2_V3/S_PUB_V3 %s\n",
1343 if (1 /*sym->generic.id==S_PUB_FUNC1_V3
1344 || sym->generic.id==S_PUB_FUNC2_V3*/) {
1345 nmstr = ML_(addStr)(di, symname, k);
1347 vsym.addr = bias + sectp[sym->public_v3.segment-1].VirtualAddress
1348 + sym->public_v3.offset;
1351 // FIXME: public_v3.len is not length of the
1352 // .text of the function
1353 vsym.isText = !!(IMAGE_SCN_CNT_CODE
1354 & sectp[sym->data_v2.segment-1].Characteristics);
1355 vsym.isIFunc = False;
1356 ML_(addSym)( di, &vsym );
1363 * Sort of like a global function, but it just points
1364 * to a thunk, which is a stupid name for what amounts to
1365 * a PLT slot in the normal jargon that everyone else uses.
1369 /* valgrind ignores PLTs */ /* JRS: it does? */
1373 * Global and static functions.
1377 VG_(memcpy)(symname, sym->proc_v1.p_name.name,
1378 sym->proc_v1.p_name.namelen);
1379 symname[sym->proc_v1.p_name.namelen] = '\0';
1380 nmstr = ML_(addStr)(di, symname, sym->proc_v1.p_name.namelen);
1382 vsym.addr = bias + sectp[sym->proc_v1.segment-1].VirtualAddress
1383 + sym->proc_v1.offset;
1385 vsym.size = sym->proc_v1.proc_len;
1387 vsym.isIFunc = False;
1389 VG_(message)(Vg_UserMsg,
1390 " Adding function %s addr=%#lx length=%d\n",
1391 symname, vsym.addr, vsym.size );
1392 ML_(addSym)( di, &vsym );
1398 VG_(memcpy)(symname, sym->proc_v2.p_name.name,
1399 sym->proc_v2.p_name.namelen);
1400 symname[sym->proc_v2.p_name.namelen] = '\0';
1401 nmstr = ML_(addStr)(di, symname, sym->proc_v2.p_name.namelen);
1403 vsym.addr = bias + sectp[sym->proc_v2.segment-1].VirtualAddress
1404 + sym->proc_v2.offset;
1406 vsym.size = sym->proc_v2.proc_len;
1408 vsym.isIFunc = False;
1410 VG_(message)(Vg_UserMsg,
1411 " Adding function %s addr=%#lx length=%d\n",
1412 symname, vsym.addr, vsym.size );
1413 ML_(addSym)( di, &vsym );
1419 VG_(message)(Vg_UserMsg,
1420 " S_LPROC_V3/S_GPROC_V3 %s\n", sym->proc_v3.name );
1423 nmstr = ML_(addStr)(di, sym->proc_v3.name,
1424 VG_(strlen)(sym->proc_v3.name));
1426 vsym.addr = bias + sectp[sym->proc_v3.segment-1].VirtualAddress
1427 + sym->proc_v3.offset;
1429 vsym.size = sym->proc_v3.proc_len;
1431 vsym.isIFunc = False;
1432 ML_(addSym)( di, &vsym );
1437 /* JRS: how is flow supposed to arrive at commented out code below? */
1440 // printf(">>> prev func '%s' still has nest_block %u count\n",
1441 // curr_func, nest_block);
1444 //curr_func = strdup(sym->proc_v3.name);
1445 /* EPP unsigned int pparent; */
1446 /* EPP unsigned int pend; */
1447 /* EPP unsigned int next; */
1448 /* EPP unsigned int debug_start; */
1449 /* EPP unsigned int debug_end; */
1450 /* EPP unsigned char flags; */
1455 * Function parameters and stack variables.
1457 case S_BPREL_XXXX_V3:
1464 case S_LABEL_V3: // FIXME
1478 case S_COMPILAND_V3:
1479 case S_COMPILAND_V2:
1480 case S_COMPILAND_V1:
1490 * These are special, in that they are always followed by an
1491 * additional length-prefixed string which is *not* included
1492 * into the symbol length count. We need to skip it.
1496 case S_LPROCREF_V1: {
1497 unsigned char *name = (unsigned char *)sym + length;
1498 length += (*name + 1 + 3) & ~3;
1501 } /* switch ( sym->generic.id ) */
1503 } /* for ( i = offset; i < size; i += length ) */
1506 VG_(message)(Vg_UserMsg,
1507 "END SnarfCodeView addr=%p offset=%d length=%d\n",
1508 root, offset, size );
1513 /*------------------------------------------------------------*/
1515 /*--- Main stuff: reading of line number tables ---*/
1517 /*------------------------------------------------------------*/
1524 unsigned int const *ui;
1533 static ULong DEBUG_SnarfLinetab(
1535 IMAGE_SECTION_HEADER* sectp,
1540 //VG_(printf)("DEBUG_SnarfLinetab %p %p %p %d\n", di, sectp, linetab, size);
1542 Char filename[WIN32_PATH_MAX];
1551 union any_size pnt2;
1552 struct startend * start;
1555 Bool debug = di->trace_symtab;
1556 Addr bias = BIAS_FOR_LINETAB;
1557 ULong n_lines_read = 0;
1560 VG_(message)(Vg_UserMsg,
1561 "BEGIN SnarfLineTab linetab=%p size=%d\n",
1565 * Now get the important bits.
1571 filetab = (unsigned int *) pnt.c;
1574 * Now count up the number of segments in the file.
1577 for (i = 0; i < nfile; i++) {
1578 pnt2.c = linetab + filetab[i];
1583 for (i = 0; i < nfile; i++) {
1588 * Get the pointer into the segment information.
1590 pnt2.c = linetab + filetab[i];
1591 file_segcount = *pnt2.s;
1594 lt_ptr = (unsigned int *) pnt2.c;
1595 start = (struct startend *) (lt_ptr + file_segcount);
1598 * Now snarf the filename for all of the segments for this file.
1600 fn = (UChar*) (start + file_segcount);
1601 /* fn now points at a Pascal-style string, that is, the first
1602 byte is the length, and the remaining up to 255 (presumably)
1603 are the contents. */
1604 vg_assert(WIN32_PATH_MAX >= 256);
1605 VG_(memset)(filename, 0, sizeof(filename));
1606 VG_(memcpy)(filename, fn + 1, *fn);
1607 vg_assert(filename[ sizeof(filename)-1 ] == 0);
1608 filename[(Int)*fn] = 0;
1609 fnmstr = VG_(strrchr)(filename, '\\');
1614 k = VG_(strlen)(fnmstr);
1615 dirstr = ML_(addStr)(di, filename, *fn - k);
1616 fnmstr = ML_(addStr)(di, fnmstr, k);
1618 for (k = 0; k < file_segcount; k++, this_seg++) {
1622 pnt2.c = linetab + lt_ptr[k];
1625 linecount = *pnt2.s++;
1627 if ( linecount > 0 ) {
1631 VG_(message)(Vg_UserMsg,
1632 " Adding %d lines for file %s segment %d addr=%#x end=%#x\n",
1633 linecount, filename, segno, start[k].start, start[k].end );
1635 for ( j = 0; j < linecount; j++ ) {
1636 Addr startaddr = bias + sectp[segno-1].VirtualAddress
1638 Addr endaddr = bias + sectp[segno-1].VirtualAddress
1639 + ((j < (linecount - 1))
1643 VG_(message)(Vg_UserMsg,
1644 " Adding line %d addr=%#lx end=%#lx\n",
1645 ((unsigned short *)(pnt2.ui + linecount))[j],
1646 startaddr, endaddr );
1648 di, fnmstr, dirstr, startaddr, endaddr,
1649 ((unsigned short *)(pnt2.ui + linecount))[j], j );
1657 VG_(message)(Vg_UserMsg,
1658 "END SnarfLineTab linetab=%p size=%d\n",
1661 return n_lines_read;
1666 /* there's a new line tab structure from MS Studio 2005 and after
1669 * DWORD lineblk_offset (counting bytes after this field)
1670 * an array of codeview_linetab2_file structures
1671 * an array (starting at <lineblk_offset>) of codeview_linetab2_block structures
1674 struct codeview_linetab2_file
1676 DWORD offset; /* offset in string table for filename */
1677 WORD unk; /* always 0x0110... type of following
1679 BYTE md5[16]; /* MD5 signature of file (signature on
1680 file's content or name ???) */
1681 WORD pad0; /* always 0 */
1684 struct codeview_linetab2_block
1686 DWORD header; /* 0x000000f2 */
1687 DWORD size_of_block; /* next block is at # bytes after this field */
1688 DWORD start; /* start address of function with line numbers */
1689 DWORD seg; /* segment of function with line numbers */
1690 DWORD size; /* size of function with line numbers */
1691 DWORD file_offset; /* offset for accessing corresponding
1692 codeview_linetab2_file */
1693 DWORD nlines; /* number of lines in this block */
1694 DWORD size_lines; /* number of bytes following for line
1695 number information */
1697 DWORD offset; /* offset (from <seg>:<start>) for line number */
1698 DWORD lineno; /* the line number (OR:ed with
1699 0x80000000 why ???) */
1700 } l[1]; /* actually array of <nlines> */
1703 static ULong codeview_dump_linetab2(
1714 struct codeview_linetab2_block* lbh;
1715 struct codeview_linetab2_file* fd;
1717 Bool debug = di->trace_symtab;
1718 Addr bias = BIAS_FOR_LINETAB2;
1719 ULong n_line2s_read = 0;
1721 if (*(const DWORD*)linetab != 0x000000f4)
1723 offset = *((DWORD*)linetab + 1);
1724 lbh = (struct codeview_linetab2_block*)(linetab + 8 + offset);
1726 while ((Char*)lbh < linetab + size) {
1728 HChar *filename, *dirname;
1729 Addr svma_s, svma_e;
1730 if (lbh->header != 0x000000f2) {
1731 /* FIXME: should also check that whole lbh fits in linetab + size */
1733 VG_(printf)("%sblock end %x\n", pfx, lbh->header);
1737 VG_(printf)("%sblock from %04x:%08x-%08x (size %u) (%u lines)\n",
1738 pfx, lbh->seg, lbh->start, lbh->start + lbh->size - 1,
1739 lbh->size, lbh->nlines);
1740 fd = (struct codeview_linetab2_file*)(linetab + 8 + lbh->file_offset);
1743 "%s md5=%02x%02x%02x%02x%02x%02x%02x%02x"
1744 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
1745 pfx, fd->md5[ 0], fd->md5[ 1], fd->md5[ 2], fd->md5[ 3],
1746 fd->md5[ 4], fd->md5[ 5], fd->md5[ 6], fd->md5[ 7],
1747 fd->md5[ 8], fd->md5[ 9], fd->md5[10], fd->md5[11],
1748 fd->md5[12], fd->md5[13], fd->md5[14], fd->md5[15] );
1749 /* FIXME: should check that string is within strimage + strsize */
1751 dirname = strimage + fd->offset;
1752 filename = VG_(strrchr)(dirname, '\\');
1753 if (filename == NULL) {
1754 filename = ML_(addStr)(di, dirname, -1);
1757 dirname = ML_(addStr)(di, dirname, VG_(strlen)(dirname)
1758 - VG_(strlen)(filename));
1759 filename = ML_(addStr)(di, filename+1, -1);
1762 filename = ML_(addStr)(di, "???", -1);
1767 VG_(printf)("%s file=%s\n", pfx, filename);
1769 for (i = 0; i < lbh->nlines; i++) {
1771 VG_(printf)("%s offset=%08x line=%d\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 = lbh->start + lbh->l[i].offset;
1778 svma_e = lbh->start + lbh->l[i+1].offset-1;
1780 VG_(printf)("%s line %d: %08lx to %08lx\n",
1781 pfx, lbh->l[i].lineno ^ 0x80000000, svma_s, svma_e);
1782 ML_(addLineInfo)( di, filename, dirname,
1785 lbh->l[i].lineno ^ 0x80000000, 0 );
1788 svma_s = lbh->start + lbh->l[ lbh->nlines-1].offset;
1789 svma_e = lbh->start + lbh->size - 1;
1791 VG_(printf)("%s line %d: %08lx to %08lx\n",
1792 pfx, lbh->l[ lbh->nlines-1 ].lineno ^ 0x80000000,
1794 ML_(addLineInfo)( di, filename, dirname,
1797 lbh->l[lbh->nlines-1].lineno ^ 0x80000000, 0 );
1801 lbh = (struct codeview_linetab2_block*)
1802 ((char*)lbh + 8 + lbh->size_of_block);
1804 return n_line2s_read;
1808 /*------------------------------------------------------------*/
1810 /*--- Main stuff: pdb_dump ---*/
1812 /*------------------------------------------------------------*/
1814 static Int cmp_FPO_DATA_for_canonicalisation ( void* f1V, void* f2V )
1816 /* Cause FPO data to be sorted first in ascending order of range
1817 starts, and for entries with the same range start, with the
1818 shorter range (length) first. */
1819 FPO_DATA* f1 = (FPO_DATA*)f1V;
1820 FPO_DATA* f2 = (FPO_DATA*)f2V;
1821 if (f1->ulOffStart < f2->ulOffStart) return -1;
1822 if (f1->ulOffStart > f2->ulOffStart) return 1;
1823 if (f1->cbProcSize < f2->cbProcSize) return -1;
1824 if (f1->cbProcSize > f2->cbProcSize) return 1;
1825 return 0; /* identical in both start and length */
1829 /* JRS fixme: compare with version in current Wine sources */
1830 static void pdb_dump( struct pdb_reader* pdb,
1833 Int unknown_purpose__reloc,
1834 IMAGE_SECTION_HEADER* sectp_avma )
1839 PDB_SYMBOLS symbols;
1840 unsigned len_modimage;
1844 Bool debug = di->trace_symtab;
1845 Addr bias_for_fpo = BIAS_FOR_FPO;
1847 ULong n_fpos_read = 0, n_syms_read = 0,
1848 n_lines_read = 0, n_line2s_read = 0;
1850 // FIXME: symbols for bare indices 1,2,3,5 in .pdb file
1852 char* types_image = pdb->read_file( pdb, 2, 0 );
1853 char* symbols_image = pdb->read_file( pdb, 3, 0 );
1855 /* establish filesimage and filessize. These are only needed for
1856 reading linetab2 tables, as far as I can deduce from the Wine
1858 char* filesimage = pdb->read_file( pdb, 12, 0); /* FIXME: really fixed ??? */
1861 if (*(const DWORD*)filesimage == 0xeffeeffe) {
1862 filessize = *(const DWORD*)(filesimage + 8);
1865 VG_(printf)("wrong header %x expecting 0xeffeeffe\n",
1866 *(const DWORD*)filesimage);
1867 ML_(dinfo_free)( (void*)filesimage);
1872 if (VG_(clo_verbosity) > 1) {
1873 VG_(message)(Vg_DebugMsg,
1875 VG_(message)(Vg_DebugMsg,
1876 " BIAS_FOR_SYMBOLS = %#08lx %s\n",
1877 (PtrdiffT)BIAS_FOR_SYMBOLS, VG_STRINGIFY(BIAS_FOR_SYMBOLS));
1878 VG_(message)(Vg_DebugMsg,
1879 " BIAS_FOR_LINETAB = %#08lx %s\n",
1880 (PtrdiffT)BIAS_FOR_LINETAB, VG_STRINGIFY(BIAS_FOR_LINETAB));
1881 VG_(message)(Vg_DebugMsg,
1882 " BIAS_FOR_LINETAB2 = %#08lx %s\n",
1883 (PtrdiffT)BIAS_FOR_LINETAB2, VG_STRINGIFY(BIAS_FOR_LINETAB2));
1884 VG_(message)(Vg_DebugMsg,
1885 " BIAS_FOR_FPO = %#08lx %s\n",
1886 (PtrdiffT)BIAS_FOR_FPO, VG_STRINGIFY(BIAS_FOR_FPO));
1887 VG_(message)(Vg_DebugMsg,
1888 " RELOC = %#08lx\n",
1889 (PtrdiffT)unknown_purpose__reloc);
1892 /* Since we just use the FPO data without reformatting, at least
1893 do a basic sanity check on the struct layout. */
1894 vg_assert(sizeof(FPO_DATA) == 16);
1895 if (di->text_present) {
1896 /* only load FPO if there's text present (otherwise it's
1899 di->fpo = pdb->read_file( pdb, 5, &sz );
1901 // FIXME: seems like the size can be a non-integral number
1902 // of FPO_DATAs. Force-align it (moronically). Perhaps this
1903 // signifies that we're not looking at a valid FPO table ..
1904 // who knows. Needs investigation.
1905 while (sz > 0 && (sz % sizeof(FPO_DATA)) != 0)
1909 if (0) VG_(printf)("FPO: got fpo_size %lu\n", (UWord)sz);
1910 vg_assert(0 == (di->fpo_size % sizeof(FPO_DATA)));
1912 vg_assert(di->fpo == NULL);
1913 vg_assert(di->fpo_size == 0);
1916 // BEGIN clean up FPO data
1917 if (di->fpo && di->fpo_size > 0) {
1920 Int itersAvail = 10;
1922 vg_assert(sizeof(di->fpo[0]) == 16);
1923 di->fpo_size /= sizeof(di->fpo[0]);
1925 // BEGIN FPO-data tidying-up loop
1928 vg_assert(itersAvail >= 0); /* safety check -- don't loop forever */
1933 /* First get them in ascending order of start point */
1934 VG_(ssort)( di->fpo, (SizeT)di->fpo_size, (SizeT)sizeof(FPO_DATA),
1935 cmp_FPO_DATA_for_canonicalisation );
1936 /* Get rid of any zero length entries */
1938 for (i = 0; i < di->fpo_size; i++) {
1939 if (di->fpo[i].cbProcSize == 0) {
1943 di->fpo[j++] = di->fpo[i];
1945 vg_assert(j >= 0 && j <= di->fpo_size);
1948 /* Get rid of any dups */
1949 if (di->fpo_size > 1) {
1951 for (i = 1; i < di->fpo_size; i++) {
1953 = di->fpo[j-1].ulOffStart == di->fpo[i].ulOffStart
1954 && di->fpo[j-1].cbProcSize == di->fpo[i].cbProcSize;
1959 di->fpo[j++] = di->fpo[i];
1961 vg_assert(j >= 0 && j <= di->fpo_size);
1965 /* Truncate any overlapping ranges */
1966 for (i = 1; i < di->fpo_size; i++) {
1967 vg_assert(di->fpo[i-1].ulOffStart <= di->fpo[i].ulOffStart);
1968 if (di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
1969 > di->fpo[i].ulOffStart) {
1971 di->fpo[i-1].cbProcSize
1972 = di->fpo[i].ulOffStart - di->fpo[i-1].ulOffStart;
1976 } while (anyChanges);
1977 // END FPO-data tidying-up loop
1979 /* Should now be in ascending order, non overlapping, no zero ranges.
1980 Check this, get the min and max avmas, and bias the entries. */
1981 for (i = 0; i < di->fpo_size; i++) {
1982 vg_assert(di->fpo[i].cbProcSize > 0);
1985 vg_assert(di->fpo[i-1].ulOffStart < di->fpo[i].ulOffStart);
1986 vg_assert(di->fpo[i-1].ulOffStart + di->fpo[i-1].cbProcSize
1987 <= di->fpo[i].ulOffStart);
1991 /* Now bias the table. This can't be done in the same pass as
1992 the sanity check, hence a second loop. */
1993 for (i = 0; i < di->fpo_size; i++) {
1994 di->fpo[i].ulOffStart += bias_for_fpo;
1995 // make sure the biasing didn't royally screw up, by wrapping
1996 // the range around the end of the address space
1997 vg_assert(0xFFFFFFFF - di->fpo[i].ulOffStart /* "remaining space" */
1998 >= di->fpo[i].cbProcSize);
2001 /* Dump any entries which point outside the text segment and
2002 compute the min/max avma "hint" addresses. */
2003 Addr min_avma = ~(Addr)0;
2004 Addr max_avma = (Addr)0;
2005 vg_assert(di->text_present);
2007 for (i = 0; i < di->fpo_size; i++) {
2008 if ((Addr)(di->fpo[i].ulOffStart) >= di->text_avma
2009 && (Addr)(di->fpo[i].ulOffStart + di->fpo[i].cbProcSize)
2010 <= di->text_avma + di->text_size) {
2011 /* Update min/max limits as we go along. */
2012 if (di->fpo[i].ulOffStart < min_avma)
2013 min_avma = di->fpo[i].ulOffStart;
2014 if (di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1 > max_avma)
2015 max_avma = di->fpo[i].ulOffStart + di->fpo[i].cbProcSize - 1;
2017 di->fpo[j++] = di->fpo[i];
2019 VG_(printf)("FPO: keep text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
2020 di->text_avma, di->text_avma + di->text_size,
2021 (Addr)di->fpo[i].ulOffStart,
2022 (Addr)di->fpo[i].ulOffStart
2023 + (Addr)di->fpo[i].cbProcSize - 1);
2026 VG_(printf)("FPO: SKIP text=[0x%lx,0x%lx) 0x%lx 0x%lx\n",
2027 di->text_avma, di->text_avma + di->text_size,
2028 (Addr)di->fpo[i].ulOffStart,
2029 (Addr)di->fpo[i].ulOffStart
2030 + (Addr)di->fpo[i].cbProcSize - 1);
2031 /* out of range; ignore */
2034 vg_assert(j >= 0 && j <= di->fpo_size);
2037 /* And record min/max */
2038 /* biasing shouldn't cause wraparound (?!) */
2039 if (di->fpo_size > 0) {
2040 vg_assert(min_avma <= max_avma); /* should always hold */
2041 di->fpo_minavma = min_avma;
2042 di->fpo_maxavma = max_avma;
2044 di->fpo_minavma = 0;
2045 di->fpo_maxavma = 0;
2049 VG_(printf)("FPO: min/max avma %#lx %#lx\n",
2050 di->fpo_minavma, di->fpo_maxavma);
2053 n_fpos_read += (ULong)di->fpo_size;
2055 // END clean up FPO data
2057 pdb_convert_types_header( &types, types_image );
2058 switch ( types.version ) {
2059 case 19950410: /* VC 4.0 */
2061 case 19961031: /* VC 5.0 / 6.0 */
2062 case 20040203: /* VC 7.0 FIXME?? */
2065 if (VG_(clo_verbosity) > 1)
2066 VG_(message)(Vg_UserMsg,
2067 "Unknown .pdb type info version %ld\n",
2072 pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
2073 switch ( symbols.version ) {
2074 case 0: /* VC 4.0 */
2075 case 19960307: /* VC 5.0 */
2076 case 19970606: /* VC 6.0 */
2077 case 19990903: /* VC 7.0 FIXME?? */
2080 if (VG_(clo_verbosity) > 1)
2081 VG_(message)(Vg_UserMsg,
2082 "Unknown .pdb symbol info version %ld\n",
2087 * Read global symbol table
2089 modimage = pdb->read_file( pdb, symbols.gsym_file, &len_modimage );
2093 if (VG_(clo_verbosity) > 1)
2094 VG_(message)(Vg_UserMsg, "Reading global symbols\n" );
2095 DEBUG_SnarfCodeView( di, sectp_avma, modimage, 0, len_modimage );
2096 ML_(dinfo_free)( (void*)modimage );
2100 * Read per-module symbol / linenumber tables
2102 file = symbols_image + header_size;
2103 while ( file - symbols_image < header_size + symbols.module_size ) {
2104 int file_nr, /* file_index, */ symbol_size, lineno_size;
2107 if ( symbols.version < 19970000 ) {
2108 PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
2109 file_nr = sym_file->file;
2110 file_name = sym_file->filename;
2111 /* file_index = sym_file->range.index; */ /* UNUSED */
2112 symbol_size = sym_file->symbol_size;
2113 lineno_size = sym_file->lineno_size;
2115 PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
2116 file_nr = sym_file->file;
2117 file_name = sym_file->filename;
2118 /* file_index = sym_file->range.index; */ /* UNUSED */
2119 symbol_size = sym_file->symbol_size;
2120 lineno_size = sym_file->lineno_size;
2123 modimage = pdb->read_file( pdb, file_nr, 0 );
2126 if (0) VG_(printf)("lineno_size %d symbol_size %d\n",
2127 lineno_size, symbol_size );
2129 total_size = pdb_get_file_size(pdb, file_nr);
2134 if (VG_(clo_verbosity) > 1)
2135 VG_(message)(Vg_UserMsg, "Reading symbols for %s\n",
2138 += DEBUG_SnarfCodeView( di, sectp_avma, modimage,
2139 sizeof(unsigned long),
2146 if (VG_(clo_verbosity) > 1)
2147 VG_(message)(Vg_UserMsg, "Reading lines for %s\n", file_name );
2149 += DEBUG_SnarfLinetab( di, sectp_avma,
2150 modimage + symbol_size, lineno_size );
2153 /* anyway, lineno_size doesn't see to really be the size of
2154 * the line number information, and it's not clear yet when
2155 * to call for linetab2...
2158 += codeview_dump_linetab2(
2159 di, (char*)modimage + symbol_size + lineno_size,
2160 total_size - (symbol_size + lineno_size),
2161 /* if filesimage is NULL, pass that directly onwards
2162 to codeview_dump_linetab2, so it knows not to
2163 poke around in there. */
2164 filesimage ? filesimage + 12 : NULL,
2168 ML_(dinfo_free)( (void*)modimage );
2171 file_name += VG_(strlen)(file_name) + 1;
2173 (unsigned long)(file_name
2174 + VG_(strlen)(file_name) + 1 + 3) & ~3 );
2180 if ( symbols_image ) ML_(dinfo_free)( symbols_image );
2181 if ( types_image ) ML_(dinfo_free)( types_image );
2182 if ( pdb->u.jg.toc ) ML_(dinfo_free)( pdb->u.jg.toc );
2184 if (VG_(clo_verbosity) > 1) {
2185 VG_(message)(Vg_DebugMsg,
2186 " # symbols read = %llu\n", n_syms_read );
2187 VG_(message)(Vg_DebugMsg,
2188 " # lines read = %llu\n", n_lines_read );
2189 VG_(message)(Vg_DebugMsg,
2190 " # line2s read = %llu\n", n_line2s_read );
2191 VG_(message)(Vg_DebugMsg,
2192 " # fpos read = %llu\n", n_fpos_read );
2197 /*------------------------------------------------------------*/
2199 /*--- TOP LEVEL for PDB reading ---*/
2201 /*------------------------------------------------------------*/
2203 /* Read line, symbol and unwind information from a PDB file.
2205 Bool ML_(read_pdb_debug_info)(
2208 PtrdiffT unknown_purpose__reloc,
2217 Addr mapped_avma, mapped_end_avma;
2220 struct pdb_reader reader;
2221 IMAGE_DOS_HEADER* dos_avma;
2222 IMAGE_NT_HEADERS* ntheaders_avma;
2223 IMAGE_SECTION_HEADER* sectp_avma;
2224 IMAGE_SECTION_HEADER* pe_sechdr_avma;
2226 if (VG_(clo_verbosity) > 1)
2227 VG_(message)(Vg_UserMsg, "Processing PDB file %s\n", pdbname );
2229 dos_avma = (IMAGE_DOS_HEADER *)obj_avma;
2230 if (dos_avma->e_magic != IMAGE_DOS_SIGNATURE)
2234 = (IMAGE_NT_HEADERS *)((Char*)dos_avma + dos_avma->e_lfanew);
2235 if (ntheaders_avma->Signature != IMAGE_NT_SIGNATURE)
2239 = (IMAGE_SECTION_HEADER *)(
2240 (Char*)ntheaders_avma
2241 + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2242 + ntheaders_avma->FileHeader.SizeOfOptionalHeader
2245 /* JRS: this seems like something of a hack. */
2246 di->soname = ML_(dinfo_strdup)("di.readpdb.rpdi.1", pdbname);
2248 /* someone (ie WINE) is loading a Windows PE format object. we
2249 need to use its details to determine which area of memory is
2252 = (Char*)ntheaders_avma
2253 + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader)
2254 + ntheaders_avma->FileHeader.SizeOfOptionalHeader;
2256 di->rx_map_avma = (Addr)obj_avma;
2258 /* Iterate over PE(?) headers. Try to establish the text_bias,
2259 that's all we really care about. */
2261 i < ntheaders_avma->FileHeader.NumberOfSections;
2262 i++, pe_seg_avma += sizeof(IMAGE_SECTION_HEADER) ) {
2263 pe_sechdr_avma = (IMAGE_SECTION_HEADER *)pe_seg_avma;
2265 if (VG_(clo_verbosity) > 1)
2266 VG_(message)(Vg_UserMsg,
2267 " Scanning PE section %s at avma %p svma %#lx\n",
2268 pe_sechdr_avma->Name, pe_seg_avma,
2269 pe_sechdr_avma->VirtualAddress);
2271 if (pe_sechdr_avma->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2274 mapped_avma = (Addr)obj_avma + pe_sechdr_avma->VirtualAddress;
2275 mapped_end_avma = mapped_avma + pe_sechdr_avma->Misc.VirtualSize;
2276 if (VG_(clo_verbosity) > 1)
2277 VG_(message)(Vg_DebugMsg,
2278 " ::: mapped_avma is %#lx\n", mapped_avma);
2280 if (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_CODE) {
2281 /* Ignore uninitialised code sections - if you have
2282 incremental linking enabled in Visual Studio then you will
2283 get a uninitialised code section called .textbss before
2284 the real text section and valgrind will compute the wrong
2285 avma value and hence the wrong bias. */
2286 if (!(pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
2287 di->have_rx_map = True;
2288 if (di->rx_map_avma == 0) {
2289 di->rx_map_avma = mapped_avma;
2291 if (di->rx_map_size==0) {
2292 di->rx_map_foff = pe_sechdr_avma->PointerToRawData;
2294 di->text_present = True;
2295 if (di->text_avma==0) {
2296 di->text_avma = mapped_avma;
2298 di->text_size += pe_sechdr_avma->Misc.VirtualSize;
2299 di->rx_map_size += pe_sechdr_avma->Misc.VirtualSize;
2302 else if (pe_sechdr_avma->Characteristics
2303 & IMAGE_SCN_CNT_INITIALIZED_DATA) {
2304 di->have_rw_map = True;
2305 if (di->rw_map_avma == 0) {
2306 di->rw_map_avma = mapped_avma;
2308 if (di->rw_map_size==0) {
2309 di->rw_map_foff = pe_sechdr_avma->PointerToRawData;
2311 di->data_present = True;
2312 if (di->data_avma==0) {
2313 di->data_avma = mapped_avma;
2315 di->rw_map_size += pe_sechdr_avma->Misc.VirtualSize;
2316 di->data_size += pe_sechdr_avma->Misc.VirtualSize;
2318 else if (pe_sechdr_avma->Characteristics
2319 & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
2320 di->bss_present = True;
2321 di->bss_avma = mapped_avma;
2322 di->bss_size = pe_sechdr_avma->Misc.VirtualSize;
2325 mapped_avma = VG_PGROUNDDN(mapped_avma);
2326 mapped_end_avma = VG_PGROUNDUP(mapped_end_avma);
2328 /* Urr. These tests are bogus; ->rx_map_avma is not necessarily
2329 the start of the text section. */
2330 if ((1 /*VG_(needs).data_syms*/
2331 || (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_CODE))
2332 && mapped_avma >= di->rx_map_avma
2333 && mapped_avma <= (di->rx_map_avma+di->text_size)
2334 && mapped_end_avma > (di->rx_map_avma+di->text_size)) {
2335 UInt newsz = mapped_end_avma - di->rx_map_avma;
2336 if (newsz > di->text_size) {
2337 /* extending the mapping is always needed for PE files
2339 di->text_size = newsz;
2340 di->rx_map_size = newsz;
2345 if (di->have_rx_map && di->have_rw_map && !di->have_dinfo) {
2346 vg_assert(di->filename);
2348 TRACE_SYMTAB("------ start PE OBJECT with PDB INFO "
2349 "---------------------\n");
2350 TRACE_SYMTAB("------ name = %s\n", di->filename);
2354 if (di->text_present) {
2355 di->text_bias = di->text_avma - di->text_svma;
2360 if (VG_(clo_verbosity) > 1) {
2361 VG_(message)(Vg_DebugMsg,
2362 "rx_map: avma %#lx size %7lu foff %llu\n",
2363 di->rx_map_avma, di->rx_map_size, (Off64T)di->rx_map_foff);
2364 VG_(message)(Vg_DebugMsg,
2365 "rw_map: avma %#lx size %7lu foff %llu\n",
2366 di->rw_map_avma, di->rw_map_size, (Off64T)di->rw_map_foff);
2368 VG_(message)(Vg_DebugMsg,
2369 " text: avma %#lx svma %#lx size %7lu bias %#lx\n",
2370 di->text_avma, di->text_svma, di->text_size, di->text_bias);
2374 * Read in TOC and well-known files
2377 hdr = find_pdb_header( pdbimage, &signature );
2379 return False; /* JRS: significance? no pdb header? */
2381 VG_(memset)(&reader, 0, sizeof(reader));
2382 reader.u.jg.header = hdr;
2384 if (0==VG_(strncmp)((char const *)&signature, "DS\0\0", 4)) {
2385 struct PDB_DS_ROOT* root;
2386 pdb_ds_init( &reader, pdbimage, n_pdbimage );
2387 root = reader.read_file( &reader, 1, 0 );
2389 pdb_check_root_version_and_timestamp(
2390 pdbname, pdbmtime, root->version, root->TimeDateStamp );
2391 ML_(dinfo_free)( root );
2393 pdb_dump( &reader, di, obj_avma, unknown_purpose__reloc, sectp_avma );
2396 if (0==VG_(strncmp)((char const *)&signature, "JG\0\0", 4)) {
2397 struct PDB_JG_ROOT* root;
2398 pdb_jg_init( &reader, pdbimage, n_pdbimage );
2399 root = reader.read_file( &reader, 1, 0 );
2401 pdb_check_root_version_and_timestamp(
2402 pdbname, pdbmtime, root->version, root->TimeDateStamp);
2403 ML_(dinfo_free)( root );
2405 pdb_dump( &reader, di, obj_avma, unknown_purpose__reloc, sectp_avma );
2409 TRACE_SYMTAB("\n------ Canonicalising the "
2410 "acquired info ------\n");
2411 /* prepare read data for use */
2412 ML_(canonicaliseTables)( di );
2413 /* notify m_redir about it */
2414 TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
2415 VG_(redir_notify_new_DebugInfo)( di );
2416 /* Note that we succeeded */
2417 di->have_dinfo = True;
2419 TRACE_SYMTAB("\n------ PE with PDB reading failed ------\n");
2420 /* Something went wrong (eg. bad ELF file). Should we delete
2421 this DebugInfo? No - it contains info on the rw/rx
2422 mappings, at least. */
2426 TRACE_SYMTAB("------ name = %s\n", di->filename);
2427 TRACE_SYMTAB("------ end PE OBJECT with PDB INFO "
2428 "--------------------\n");
2435 /* Examine a PE file to see if it states the path of an associated PDB
2436 file; if so return that. Caller must deallocate with
2440 HChar* ML_(find_name_of_pdb_file)( HChar* pename )
2442 /* This is a giant kludge, of the kind "you did WTF?!?", but it
2444 Bool do_cleanup = False;
2445 HChar tmpname[100], tmpnameroot[50];
2453 VG_(memset)(tmpnameroot, 0, sizeof(tmpnameroot));
2454 VG_(sprintf)(tmpnameroot, "petmp%d", VG_(getpid)());
2455 VG_(memset)(tmpname, 0, sizeof(tmpname));
2456 fd = VG_(mkstemp)( tmpnameroot, tmpname );
2458 VG_(message)(Vg_UserMsg,
2459 "Find PDB file: Can't create /tmp file %s\n", tmpname);
2464 /* Make up the command to run, essentially:
2465 sh -c "strings (pename) | egrep '\.pdb|\.PDB' > (tmpname)"
2467 HChar* sh = "/bin/sh";
2468 HChar* strings = "/usr/bin/strings";
2469 HChar* egrep = "/usr/bin/egrep";
2471 /* (sh) -c "(strings) (pename) | (egrep) 'pdb' > (tmpname) */
2472 Int cmdlen = VG_(strlen)(strings) + VG_(strlen)(pename)
2473 + VG_(strlen)(egrep) + VG_(strlen)(tmpname)
2475 HChar* cmd = ML_(dinfo_zalloc)("di.readpe.fnopf.cmd", cmdlen);
2477 VG_(sprintf)(cmd, "%s -c \"%s '%s' | %s '\\.pdb|\\.PDB' >> %s\"",
2478 sh, strings, pename, egrep, tmpname);
2479 vg_assert(cmd[cmdlen-1] == 0);
2480 if (0) VG_(printf)("QQQQQQQQ: %s\n", cmd);
2482 r = VG_(system)( cmd );
2484 VG_(message)(Vg_DebugMsg,
2485 "Find PDB file: Command failed:\n %s\n", cmd);
2489 /* Find out how big the file is, and get it aboard. */
2490 struct vg_stat stat_buf;
2491 VG_(memset)(&stat_buf, 0, sizeof(stat_buf));
2493 SysRes sr = VG_(stat)(tmpname, &stat_buf);
2494 if (sr_isError(sr)) {
2495 VG_(umsg)("Find PDB file: can't stat %s\n", tmpname);
2499 Int szB = (Int)stat_buf.size;
2501 VG_(umsg)("Find PDB file: %s is empty\n", tmpname);
2504 /* 6 == strlen("X.pdb\n") */
2505 if (szB < 6 || szB > 1024/*let's say*/) {
2506 VG_(umsg)("Find PDB file: %s has implausible size %d\n",
2511 HChar* pdbname = ML_(dinfo_zalloc)("di.readpe.fnopf.pdbname", szB + 1);
2515 Int nread = VG_(read)(fd, pdbname, szB);
2517 VG_(umsg)("Find PDB file: read of %s failed\n", tmpname);
2520 vg_assert(pdbname[szB] == 0);
2522 /* Check we've got something remotely sane -- must have one dot and
2523 one \n in it, and the \n must be at the end */
2524 Bool saw_dot = False;
2527 for (i = 0; pdbname[i]; i++) {
2528 if (pdbname[i] == '.') saw_dot = True;
2529 if (pdbname[i] == '\n') saw_n_crs++;
2531 if (!saw_dot || saw_n_crs != 1 || pdbname[szB-1] != '\n') {
2532 VG_(umsg)("Find PDB file: can't make sense of: %s\n", pdbname);
2535 /* Change the \n to a terminating zero, so we have a "normal" string */
2538 if (0) VG_(printf)("QQQQQQQQ: got %s\n", pdbname);
2546 VG_(unlink)( tmpname );
2551 #endif // defined(VGO_linux) || defined(VGO_darwin)
2553 /*--------------------------------------------------------------------*/
2555 /*--------------------------------------------------------------------*/