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