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