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