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