├── cvdump ├── type7.cpp ├── cvdump.exe ├── output.h ├── cvdump.rc ├── utils.cpp ├── output.cpp ├── debsym.h ├── auto.dep ├── cvdump.nativeproj ├── makefile.mak ├── cvtdef.h ├── cvdump.h ├── dumptyp6.cpp └── symrec.h ├── pdbtest ├── makefile ├── pdbtest.cpp └── pdbtest.mak ├── PDB ├── include │ ├── pdbguid.h │ ├── gsicommon.h │ ├── srccommon.h │ ├── enum.h │ ├── SysPage.h │ ├── output.h │ ├── mrcommon.h │ ├── trace.h │ ├── crtwrap.h │ ├── modcommon.h │ ├── poolcpy.h │ ├── szcanon.h │ ├── pdbver.h │ ├── StrConvBuf.h │ ├── cvhelper.h │ ├── pdbimpl.h │ ├── assert_.h │ ├── ptr.h │ ├── mdalign.h │ ├── pdbtypdefs.h │ ├── objfile.h │ ├── crtfubar.h │ ├── syncro.h │ ├── mts.h │ ├── utf8.h │ ├── cvlines.h │ ├── critsec.h │ ├── pdbheap.h │ ├── iset.h │ ├── pdbcommon.h │ ├── two.h │ ├── misc.h │ ├── pool.h │ ├── srcimpl.h │ ├── indbuf.h │ ├── mapfile.h │ ├── msf.h │ ├── xheap.h │ └── dbicommon.h └── dbi │ ├── def.dat │ ├── dbipch.cpp │ ├── heap.cpp │ ├── udtrefs.h │ ├── dbicommon.cpp │ ├── udtrefs.cpp │ ├── dbiimpl.h │ ├── stream.cpp │ ├── stream.h │ ├── pdbmain.cpp │ ├── modcommon.cpp │ ├── mli.h │ ├── util.h │ ├── src.cpp │ ├── locator.h │ └── pdbcommon.cpp ├── pdbdump ├── pdbdump.rc └── makefile.old ├── docs └── ExternalResources.md ├── LICENSE ├── langapi └── shared │ └── crc32.h └── README.md /cvdump/type7.cpp: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /pdbtest/makefile: -------------------------------------------------------------------------------- 1 | !include pdbtest.mak 2 | -------------------------------------------------------------------------------- /cvdump/cvdump.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbhyudayaSharma/microsoft-pdb/master/cvdump/cvdump.exe -------------------------------------------------------------------------------- /PDB/include/pdbguid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include // definition for UUID 3 | BOOL FUuidCreate(UUID *); 4 | -------------------------------------------------------------------------------- /PDB/dbi/def.dat: -------------------------------------------------------------------------------- 1 | #ifdef _X86_ 2 | ??0SymTiIter@@QAE@PAUSYMTYPE@@@Z 3 | #else 4 | ??0SymTiIter@@QAA@PAUSYMTYPE@@@Z // no thiscall on non-X86 5 | #endif 6 | -------------------------------------------------------------------------------- /PDB/dbi/dbipch.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // dbipch.cpp: PCH file 3 | #include "pdbimpl.h" 4 | #include "dbiimpl.h" 5 | -------------------------------------------------------------------------------- /PDB/include/gsicommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // These should migrate to the real GSI interfaces 3 | 4 | struct _GSI : public GSI { 5 | virtual BOOL getEnumSyms(EnumSyms **, PB) pure; 6 | }; -------------------------------------------------------------------------------- /PDB/include/srccommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class SrcCommon : public Src { 4 | public: 5 | virtual bool Add(IN PCSrcHeader psrcheader, IN const void * pvData); 6 | virtual bool QueryByName(IN SZ_CONST szFile, OUT PSrcHeaderOut psrcheaderOut) const; 7 | }; -------------------------------------------------------------------------------- /PDB/dbi/heap.cpp: -------------------------------------------------------------------------------- 1 | #include "pdbimpl.h" 2 | #include "dbiimpl.h" 3 | 4 | #pragma warning(disable:4073) 5 | #pragma init_seg(lib) 6 | 7 | #if defined(PDB_SERVER) || defined(MSOBJ_DLL) || defined(STANDALONE_HEAP) 8 | 9 | Heap Heap::theHeap; 10 | HANDLE Heap::hheap; 11 | 12 | #endif // defined(PDB_SERVER) || defined(MSOBJ_DLL) || defined(STANDALONE_HEAP) 13 | 14 | namespace pdb_internal { 15 | SysPage cbSysPage; 16 | } 17 | -------------------------------------------------------------------------------- /PDB/include/enum.h: -------------------------------------------------------------------------------- 1 | #ifndef __ENUM_INCLUDED__ 2 | #define __ENUM_INCLUDED__ 3 | 4 | // Expected enumerator usage: 5 | // XS xs; 6 | // EnumXS exs(xs); 7 | // while (exs.next()) 8 | // exs.get(&x); 9 | // exs.reset(); 10 | // while (exs.next()) 11 | // exs.get(&x) 12 | 13 | class Enum { 14 | public: 15 | virtual ~Enum() { } 16 | virtual void reset() { } 17 | virtual BOOL next() { 18 | return TRUE; 19 | } 20 | }; 21 | 22 | #endif // !__ENUM_INCLUDED__ 23 | -------------------------------------------------------------------------------- /PDB/include/SysPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if !defined(_SysPage_h) 3 | #define _SysPage_h 4 | namespace pdb_internal { 5 | class SysPage { 6 | DWORD m_cbPage; 7 | public: 8 | operator DWORD() { 9 | return m_cbPage; 10 | } 11 | SysPage() { 12 | SYSTEM_INFO si; 13 | ::GetSystemInfo(&si); 14 | m_cbPage = si.dwPageSize; 15 | } 16 | }; 17 | extern SysPage cbSysPage; 18 | } 19 | 20 | #endif // _SysPage_h 21 | -------------------------------------------------------------------------------- /PDB/include/output.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Incremental Linker 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | void OutputInit(); 12 | 13 | int StdOutFlush(); 14 | int __cdecl StdOutPrintf(const wchar_t *, ...); 15 | int StdOutPutc(wchar_t); 16 | int StdOutPuts(const wchar_t *); 17 | int StdOutVprintf(const wchar_t *, va_list); 18 | -------------------------------------------------------------------------------- /cvdump/output.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | void OutputInit(); 12 | 13 | int StdOutFlush(); 14 | int __cdecl StdOutPrintf(const wchar_t *, ...); 15 | int StdOutPutc(wchar_t); 16 | int StdOutPuts(const wchar_t *); 17 | int StdOutVprintf(const wchar_t *, va_list); 18 | -------------------------------------------------------------------------------- /PDB/include/mrcommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | enum { 5 | sigMagic = ' SRD', 6 | sigFileStream = ' srd', 7 | cbitsName = 256, 8 | cbMapInit = 4096, 9 | cbFileInfoInit = 4096, 10 | sgnLess = -1, 11 | sgnEqual = 0, 12 | sgnGreater = 1, 13 | cchMrePathMax = _MAX_PATH + 40, 14 | cbStreamPage = 4096, 15 | }; 16 | 17 | bool 18 | __forceinline 19 | FNonNullSz(const wchar_t * sz) { 20 | return (sz != NULL) && ((*sz) != L'\0'); 21 | } 22 | 23 | bool 24 | __forceinline 25 | FNonNullSz(const char * sz) { 26 | return (sz != NULL) && ((*sz) != '\0'); 27 | } 28 | -------------------------------------------------------------------------------- /pdbdump/pdbdump.rc: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | #include "verstamp.h" 12 | 13 | #define VER_FILETYPE VFT_APP 14 | #define VER_FILESUBTYPE VFT2_UNKNOWN 15 | #define VER_FILEDESCRIPTION_STR L"Microsoft\256 PDB File Dumper" 16 | #define VER_INTERNALNAME_STR "PDBDUMP.EXE" 17 | 18 | #include 19 | -------------------------------------------------------------------------------- /PDB/dbi/udtrefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __UDTREFS_INCLUDED__ 3 | #define __UDTREFS_INCLUDED__ 4 | 5 | #ifndef __ISET_INCLUDED__ 6 | #include "..\include\iset.h" 7 | #endif 8 | 9 | class UDTRefs { 10 | public: 11 | UDTRefs(unsigned int cti_, bool fGrowRefSets =false); 12 | ~UDTRefs(); 13 | BOOL fNoteRef(TI ti); 14 | BOOL tiNext(TI *pti); 15 | 16 | private: 17 | unsigned int cti; 18 | unsigned int ucur; 19 | ISet isetRefs; 20 | ISet isetProcessed; 21 | bool fGrowRefSets; 22 | 23 | inline unsigned int normalize(TI ti); 24 | inline TI denormalize(unsigned int u); 25 | 26 | }; 27 | 28 | #endif -------------------------------------------------------------------------------- /PDB/include/trace.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __TRACE_INCLUDED__ 3 | #define __TRACE_INCLUDED__ 4 | 5 | #if defined(_DEBUG) 6 | 7 | #if defined(_UNICODE) || defined(UNICODE) 8 | #define trace(args) traceW_ args 9 | #else 10 | #define trace(args) trace_ args 11 | #endif 12 | 13 | #define traceOnly(x) x 14 | 15 | #else 16 | #define trace(args) 0 17 | #define traceOnly(x) 18 | #endif 19 | 20 | enum TR { 21 | trMap, 22 | trSave, 23 | trStreams, 24 | trStreamImage, 25 | trStreamImageSummary, 26 | trMax 27 | }; 28 | BOOL trace_(TR tr, const char* szFmt, ...); 29 | BOOL traceW_(TR tr, const wchar_t* szFmt, ...); 30 | 31 | #endif // !__TRACE_INCLUDED__ 32 | -------------------------------------------------------------------------------- /PDB/include/crtwrap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef _M_IX86 6 | 7 | FILE *PDB_wfsopen(const wchar_t *wszPath, const wchar_t *wszMode, int shflag); 8 | wchar_t *PDB_wfullpath(__out_ecount(maxlen) wchar_t *wszFullpath, const wchar_t *wszPath, size_t maxlen); 9 | 10 | #else // !_M_IX86 11 | 12 | #define PDB_wfsopen _wfsopen 13 | #define PDB_wfullpath _wfullpath 14 | 15 | #endif // !_M_IX86 16 | 17 | #ifdef _CRT_ALTERNATIVE_INLINES 18 | 19 | errno_t __cdecl PDB_wdupenv_s(_Deref_out_opt_z_ wchar_t **pwszDest, size_t * pcchDest, const wchar_t *wszVarName); 20 | 21 | #else 22 | 23 | #define PDB_wdupenv_s _wdupenv_s 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /cvdump/cvdump.rc: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | #include "windows.h" 12 | 13 | #include "verstamp.h" 14 | 15 | #define VER_FILETYPE VFT_APP 16 | #define VER_FILESUBTYPE VFT2_UNKNOWN 17 | #define VER_FILEDESCRIPTION_STR L"Microsoft\256 Debugging Information Dumper" 18 | #define VER_INTERNALNAME_STR "CVDUMP.EXE" 19 | 20 | #include 21 | -------------------------------------------------------------------------------- /PDB/include/modcommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ModCommon : public Mod { 4 | public: 5 | BOOL AddLines(SZ_CONST szSrc, ISECT isect, OFF offCon, CB cbCon, OFF doff, LINE lineStart, PB pbCoff, CB cbCoff); 6 | BOOL QueryPdbFile(_Out_z_cap_(_MAX_PATH) OUT char szFile[_MAX_PATH], OUT CB* pcb); // mts safe 7 | BOOL QueryCBName(OUT CB* pcb); 8 | BOOL QueryName(_Out_z_cap_(_MAX_PATH) OUT char szName[_MAX_PATH], OUT CB* pcb); 9 | BOOL QueryCBFile(OUT CB* pcb); 10 | BOOL QueryFile(_Out_z_cap_(_MAX_PATH) OUT char szFile[_MAX_PATH], OUT CB* pcb); 11 | BOOL QuerySrcFile(_Out_z_cap_(_MAX_PATH) OUT char szFile[_MAX_PATH], OUT CB* pcb); // mts safe 12 | }; 13 | -------------------------------------------------------------------------------- /PDB/include/poolcpy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __POOL_COPY__ 3 | #define __POOL_COPY__ 4 | 5 | #include "szst.h" 6 | #include "pool.h" 7 | 8 | // Return a 0-terminated string copied from the 0-terminated string, 9 | // or 0 if memory allocation failure. 10 | // 11 | inline SZ szCopyPool(SZ_CONST szFrom, POOL<4>& pool) 12 | { 13 | size_t cch = strlen(szFrom); 14 | SZ sz = new (pool) char[cch + 1]; 15 | if (sz) 16 | memcpy(sz, szFrom, cch + 1); 17 | return sz; 18 | } 19 | 20 | inline SZ szCopyPool(SZ_CONST szFrom, POOL<8>& pool) 21 | { 22 | size_t cch = strlen(szFrom); 23 | SZ sz = new (pool) char[cch + 1]; 24 | if (sz) 25 | memcpy(sz, szFrom, cch + 1); 26 | return sz; 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /PDB/include/szcanon.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // SzCanon.h 3 | // 4 | // Copyright (C) 1995, Microsoft Corporation 5 | // 6 | // Purpose: Perform filename canonicalizations 7 | // 8 | // Revision History: 9 | // 10 | // [] 09/01/95 Dans Created 11 | // 12 | //----------------------------------------------------------------------------- 13 | 14 | #pragma once 15 | 16 | #include 17 | 18 | class CCanonFile { 19 | public: 20 | 21 | static wchar_t * 22 | SzCanonFilename( __inout_z wchar_t *szFilename); 23 | 24 | static wchar_t * 25 | SzFullCanonFilename(__in_z const wchar_t *szFile, __ecount(cch) wchar_t *szCanonFile, size_t cch); 26 | }; 27 | -------------------------------------------------------------------------------- /PDB/include/pdbver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #define _VERSION_H_INCL 5 | 6 | #include "verstamp.h" 7 | 8 | /////////////////////////////////////////// 9 | // 10 | // Set up the defines for use in common.ver 11 | // 12 | 13 | // defines for the VS_VERSION block 14 | 15 | #define VER_FILESUBTYPE VFT2_UNKNOWN 16 | #define VER_FILEDESCRIPTION_STR "Microsoft\256 Program Database" 17 | 18 | #ifdef PDB_CORE 19 | #define VER_FILETYPE VFT_DLL 20 | #define VER_INTERNALNAME_STR "MSPDBCORE.DLL" 21 | #else 22 | #ifdef PDB_SRVEXE 23 | #define VER_FILETYPE VFT_APP 24 | #define VER_INTERNALNAME_STR "MSPDBSRV.EXE" 25 | #else 26 | #define VER_FILETYPE VFT_DLL 27 | #define VER_INTERNALNAME_STR "MSPDB" RMJ_AS_FILENAME_STRING RMM_AS_FILENAME_STRING ".DLL" 28 | #endif 29 | #endif 30 | -------------------------------------------------------------------------------- /PDB/dbi/dbicommon.cpp: -------------------------------------------------------------------------------- 1 | #include "pdbimpl.h" 2 | #include "dbicommon.h" 3 | 4 | BOOL DBICommon::OpenMod(SZ_CONST szModule, SZ_CONST szObjFile, OUT Mod** ppmod) 5 | { 6 | USES_STACKBUFFER(0x400); 7 | 8 | // szModule, szObjFile are in MBCS, convert to Unicode 9 | wchar_t* szMod = GetSZUnicodeFromSZMBCS(szModule); 10 | wchar_t* szObj = szObjFile != NULL ? GetSZUnicodeFromSZMBCS(szObjFile) : NULL; 11 | 12 | if ( szMod == NULL || ( szObjFile != NULL && szObj == NULL ) ) 13 | return FALSE; 14 | 15 | return OpenModW(szMod, szObj, ppmod); 16 | } 17 | 18 | BOOL DBICommon::QueryTypeServerByPdb(const char* szPdb, OUT ITSM* piTsm ) 19 | { 20 | USES_STACKBUFFER(0x400); 21 | 22 | // Filename in MBCS, convert it to UTF8 23 | wchar_t * wszPdb = GetSZUnicodeFromSZMBCS(szPdb); 24 | if ( wszPdb == NULL ) 25 | return FALSE; 26 | 27 | BOOL fResult = QueryTypeServerByPdbW(wszPdb, piTsm); 28 | return fResult; 29 | } -------------------------------------------------------------------------------- /docs/ExternalResources.md: -------------------------------------------------------------------------------- 1 | #External Resources 2 | 3 | This document contains some external resources with information about the PDB format and related topics. 4 | Note that the following documents are not maintained or guaranteed by Microsoft, they are just provided 5 | as links for your convenience. 6 | 7 | # PDB Format 8 | - [Breakpad Symbol Files](https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md) 9 | - [Reimplementation of Breakpad Windows dump_syms tool](https://github.com/luser/dump_syms) 10 | - [Parsing library for PDB file format](https://code.google.com/p/pdbparser/w/list) 11 | - [RFC: CodeView debug info emission in Clang/LLVM](http://lists.llvm.org/pipermail/cfe-dev/2015-October/045780.html) 12 | - [Microsoft Symbol and Type Information](http://pierrelib.pagesperso-orange.fr/exec_formats/MS_Symbol_Type_v1.0.pdf) 13 | 14 | ##PE Format 15 | - [Microsoft PE and Coff Specification](https://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx) 16 | - [PE Format by corkami](https://code.google.com/p/corkami/wiki/PE) 17 | 18 | ##Calling Conventions and Name Mangling 19 | - [Calling conventions for different C++ compilers and operating systems](http://www.agner.org/optimize/calling_conventions.pdf) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Microsoft Corporation. All rights reserved. 2 | 3 | This code is licensed under the MIT License (MIT). 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /PDB/include/StrConvBuf.h: -------------------------------------------------------------------------------- 1 | // StrConvBuf.h - advanced functions to convert strings between utf8, unicode, mbcs, etc. 2 | // that use Buffers instead of raw pointers. 3 | // useful for when working in a loop where _alloca() is bad or you want to easily 4 | // manage the memory being used, i.e. have it go away automatically. 5 | // 6 | #pragma once 7 | #include "szst.h" // we use some of the underlying support here too. 8 | 9 | // 10 | // Use a buffer so that we can avoid use of _alloca() where appropriate, 11 | // as in loops or places where we want ease of use with respect to the 12 | // lifetime of the WSZ generated. 13 | // 14 | // NB: this should be done also for UTF-8 and MBCS targets as necessary. 15 | // 16 | inline wchar_t * _GetSZUnicodeFromSZUTF8(SZ_CONST szUtf8, Buffer & bufwsz) { 17 | size_t cchUnicode = utflen(szUtf8); 18 | size_t cbUnicode = sizeof(wchar_t) * cchUnicode; 19 | if ( static_cast(bufwsz.Size()) < cbUnicode ) { 20 | if ( !bufwsz.Reserve(static_cast(cbUnicode - bufwsz.Size())) ) { 21 | return NULL; 22 | } 23 | } 24 | return _GetSZUnicodeFromSZUTF8( 25 | szUtf8, 26 | reinterpret_cast(bufwsz.Start()), 27 | cchUnicode 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /PDB/dbi/udtrefs.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // UDTRefs bit maps 3 | 4 | #include "pdbimpl.h" 5 | #include "dbiimpl.h" 6 | #include 7 | 8 | 9 | UDTRefs::UDTRefs(unsigned int cti_, bool fGrowRefSets_) : 10 | cti(cti_), ucur(0), fGrowRefSets(fGrowRefSets_) 11 | { 12 | } 13 | 14 | UDTRefs::~UDTRefs() 15 | { 16 | } 17 | 18 | unsigned int UDTRefs::normalize(TI ti) 19 | { 20 | assert(!CV_IS_PRIMITIVE(ti)); 21 | unsigned int retval = ti - CV_FIRST_NONPRIM; 22 | assert(retval <= cti); 23 | return retval; 24 | } 25 | 26 | TI UDTRefs::denormalize(unsigned int u) 27 | { 28 | return u + CV_FIRST_NONPRIM; 29 | } 30 | 31 | BOOL UDTRefs::fNoteRef(TI ti) 32 | { 33 | if (fGrowRefSets && ti - CV_FIRST_NONPRIM > cti ) { 34 | cti = ti - CV_FIRST_NONPRIM; 35 | } 36 | return isetRefs.add(normalize(ti)); 37 | } 38 | 39 | BOOL UDTRefs::tiNext(TI *pti) 40 | { 41 | if (cti) { 42 | unsigned int u = ucur; 43 | do { 44 | if (isetRefs.contains(u) && !isetProcessed.contains(u)) { 45 | *pti = denormalize(u); 46 | ucur = (u + 1) % cti; 47 | return isetProcessed.add(u); 48 | } 49 | u = (u + 1) % cti; 50 | } while (u != ucur); 51 | } 52 | 53 | *pti = tiNil; 54 | return TRUE; 55 | } 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /cvdump/utils.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | #include "cvdump.h" 12 | 13 | #define STRICT 14 | #define WIN32_LEAN_AND_MEAN 15 | #include "windows.h" 16 | 17 | #define BYTELN 8 18 | #define WORDLN 16 19 | typedef unsigned short WORD; 20 | 21 | 22 | void InvalidObject() 23 | { 24 | Fatal(L"Invalid file"); 25 | } 26 | 27 | 28 | WORD Gets() 29 | { 30 | WORD b; // A byte of input 31 | 32 | if (((_read(exefile, &b, 1)) != 1) || cbRec < 1) { 33 | InvalidObject(); 34 | } 35 | 36 | --cbRec; 37 | 38 | return (b & 0xff); 39 | } 40 | 41 | 42 | void GetBytes(void *pv, size_t n) 43 | { 44 | if ((size_t) _read(exefile, pv, (unsigned int) n) != n) { 45 | InvalidObject(); 46 | } 47 | 48 | cbRec -= n; 49 | } 50 | 51 | 52 | WORD WGets() 53 | { 54 | WORD w; /* Word of input */ 55 | 56 | w = Gets(); /* Get low-order byte */ 57 | return (w | (Gets() << BYTELN)); /* Return word */ 58 | } 59 | 60 | 61 | 62 | DWORD LGets() 63 | { 64 | DWORD ul; 65 | 66 | ul = (DWORD) WGets(); 67 | 68 | return (ul | ((DWORD) WGets() << WORDLN)); 69 | } 70 | -------------------------------------------------------------------------------- /pdbdump/makefile.old: -------------------------------------------------------------------------------- 1 | !if "$(DEBUG)" == "" 2 | DEBUG = 1 3 | !endif 4 | 5 | inc = -I"$(LANGAPI)\include" -I"$(LANGAPI)\shared" -I..\..\..\include 6 | CFLAGS = -nologo -c -W3 -Zi -Fd"$(odir)/" -Fp"$(odir)/pdbdump.pch" -D_CRT_SECURE_NO_DEPRECATE -D_SECURE_SCL=0 -GS -Zc:wchar_t- 7 | 8 | !if "$(DEBUG)" == "1" 9 | CFLAGS = $(CFLAGS) -Od -D_DEBUG -MTd -FR$(odir)\ $(inc) 10 | odir = debug 11 | !else 12 | CFLAGS = $(CFLAGS) -O2 -DNDEBUG -MT $(inc) 13 | odir = release 14 | !endif 15 | 16 | !ifdef CPU 17 | !if "$(CPU)" != "x86" && "$(CPU)" != "X86" 18 | odir = $(odir)_$(CPU) 19 | !endif 20 | !endif 21 | 22 | MSPDB=mspdbcore.lib 23 | 24 | .rc{$(odir)}.res: 25 | rc $(inc) -Fo$(odir)/$(nul 2>&1 39 | 40 | $(odir)/pdbdump.obj : \ 41 | $(LANGAPI)\include\pdb.h $(LANGAPI)\include\vcver.h \ 42 | ..\..\..\include\msf.h $(LANGAPI)\include\cvr.h \ 43 | $(LANGAPI)\include\.\..\include\vcver.h \ 44 | $(LANGAPI)\include\cvinfo.h 45 | 46 | $(odir)/pdbdump.res: \ 47 | $(LANGAPI)\include\version.h $(LANGAPI)\include\verstamp.h \ 48 | $(LANGAPI)\include\common.ver 49 | 50 | $(odir)/utf8.obj: \ 51 | ..\..\..\misc\utf8.c 52 | cl $(CFLAGS) -Fo$(odir)/ ..\..\..\misc\utf8.c 53 | -------------------------------------------------------------------------------- /PDB/include/cvhelper.h: -------------------------------------------------------------------------------- 1 | #ifndef _CVHELPER_H_ 2 | #define _CVHELPER_H_ 3 | 4 | // MP is used to buffer the incoming public info for a module 5 | 6 | struct MP { 7 | 8 | typedef const char* SZ_CONST; 9 | 10 | PUBSYM32 * m_pPubSym; 11 | 12 | // use a local copy for almost all cases, 13 | // go for the heap version only on extra long symbols. 14 | // 15 | struct BigEnough_PubSym : public PUBSYM32 { 16 | BYTE rgbExtra[2049]; 17 | } m_pubsym; 18 | 19 | MP(SZ_CONST utfszPublic, ISECT isect_, OFF off_, CV_pubsymflag_t cvpsf =0) 20 | { 21 | size_t cbName = strlen(utfszPublic); // UTF8 has same length as ASCII 22 | size_t cbRec = cbAlign(offsetof(PUBSYM32,name) + cbName + 1); 23 | 24 | if (cbRec < sizeof(m_pubsym)) { 25 | m_pPubSym = &m_pubsym; 26 | } 27 | else { 28 | m_pPubSym = reinterpret_cast(new BYTE[cbRec]); 29 | } 30 | 31 | m_pPubSym->reclen = (unsigned short) (cbRec - sizeof(m_pPubSym->reclen)); 32 | m_pPubSym->rectyp = S_PUB32; 33 | m_pPubSym->off = off_; 34 | m_pPubSym->seg = isect_; 35 | m_pPubSym->pubsymflags.grfFlags = cvpsf; 36 | memcpy(SZ(m_pPubSym->name), utfszPublic, cbName + 1); 37 | 38 | memset(m_pPubSym->name + cbName, 0, dcbAlign(offsetof(DATASYM32,name) + cbName + 1)); 39 | } 40 | 41 | ~MP() 42 | { 43 | if (m_pPubSym != &m_pubsym) { 44 | delete [] reinterpret_cast(m_pPubSym); 45 | } 46 | } 47 | 48 | PSYM operator &() 49 | { 50 | return reinterpret_cast(m_pPubSym); 51 | } 52 | }; 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /PDB/include/pdbimpl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define __PDBIMPL_INCLUDED__ 4 | 5 | #include "prefast.h" 6 | 7 | namespace pdb_internal { } 8 | 9 | using namespace pdb_internal; 10 | 11 | #define STRICT 12 | #define WIN32_LEAN_AND_MEAN 13 | #include "windows.h" 14 | 15 | #define INCR_COMPILE 16 | 17 | #ifndef PDB_MT 18 | //#define PDB_TYPESERVER // uncomment this to get rid of looking up types 19 | // from additional type servers 20 | #endif 21 | 22 | #include "SysPage.h" 23 | #include 24 | 25 | #define MR_ENGINE_IMPL 26 | #include // includes PDB and MR definitions 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "pdbtypdefs.h" 35 | #include "assert_.h" 36 | 37 | #include "trace.h" 38 | 39 | #define UTF8_IMP 40 | #include "utf8.h" 41 | 42 | #define precondition(x) assert(x) 43 | #define postcondition(x) assert(x) 44 | #define notReached() assert(0) 45 | 46 | inline bool implies(int a, int b) { 47 | // a implies b: if a is true, b must be true 48 | return a <= b; 49 | } 50 | 51 | #if defined(INSTRUMENTED) 52 | #define instrumentation(x) x 53 | #else 54 | #define instrumentation(x) 55 | #endif 56 | 57 | #include "crtwrap.h" 58 | 59 | #include "mdalign.h" 60 | #include "pdbheap.h" 61 | #include "buffer.h" 62 | #include "pool.h" 63 | #include "safestk.h" 64 | #include "szst.h" 65 | 66 | #include "ptr.h" 67 | #include "mts.h" 68 | 69 | #if defined(_WIN64) 70 | const size_t s_cbMaxAlloc = 0xFFFFFFFFFFFFFFFFUI64 - 0xF; 71 | #else 72 | const size_t s_cbMaxAlloc = 0xFFFFFFFF - 0x7; 73 | #endif 74 | -------------------------------------------------------------------------------- /PDB/include/assert_.h: -------------------------------------------------------------------------------- 1 | // assert_.h - assert specific to the pdb project 2 | #if defined(__cplusplus) 3 | 4 | extern "C" void failAssertion(const char* szFile, int line); 5 | extern "C" void failExpect(const char* szFile, int line); 6 | extern "C" void failAssertionFunc(const char* szFile, const char * szFunc, int line, const char* szCond); 7 | extern "C" void failExpectFunc(const char* szFile, const char * szFunc, int line, const char* szCond); 8 | 9 | #else // i.e not C++ 10 | 11 | void failAssertion(const char* szFile, int line); 12 | void failExpect(const char* szFile, int line); 13 | void failAssertionFunc(const char* szFile, const char * szFunc, int line, const char* szCond); 14 | void failExpectFunc(const char* szFile, const char * szFunc, int line, const char* szCond); 15 | 16 | #endif 17 | 18 | #if defined(_DEBUG) 19 | 20 | #define assert(x) if (!(x)) { failAssertionFunc(__FILE__, __FUNCTION__, __LINE__, #x); } else 21 | #define expect(x) if (!(x)) { failExpectFunc(__FILE__ , __FUNCTION__, __LINE__, #x); } else 22 | #define expectFailed(x) failExpectFunc(__FILE__ , __FUNCTION__, __LINE__, x) 23 | #define rangeCheck(val, valMin, valMax) \ 24 | ( (!((val >= valMin) && (val < valMax))) ? (failExpectFunc(__FILE__, __FUNCTION__, __LINE__, "(rangeCheck(" #val ", " #valMin ", " #valMax "))"), val) : val) 25 | #define assume(x) assert(x) 26 | 27 | #define verify(x) assert(x) 28 | #define dassert(x) assert(x) 29 | extern BOOL rgbEnableDiagnostic[20]; 30 | #define dprintf(args) printf args 31 | #define debug(x) x 32 | 33 | #else 34 | #define assert(x) ((void)0) 35 | #define verify(x) (x,0) 36 | #define dassert(x) 37 | #define expect(x) 38 | #define dprintf(args) 39 | #define debug(x) 40 | #define rangeCheck(val, valMin, valMax) (val) 41 | #define assume(x) __assume(x) 42 | #endif 43 | 44 | // compile time assert 45 | #if !defined(cassert) 46 | #define cassert(x) extern char dummyAssert[ (x) ] 47 | #endif 48 | -------------------------------------------------------------------------------- /PDB/include/ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef __PTR_INCLUDED__ 2 | #define __PTR_INCLUDED__ 3 | 4 | // UNDONE: this should move to ref.h and replace COMRefPtr as well in Orcas 5 | template class Trait > class AutoPtr { 6 | public: 7 | AutoPtr(T* pt_ = NULL) { 8 | pt = pt_; 9 | if (pt != NULL) { 10 | Trait::AddRef(pt); 11 | } 12 | } 13 | AutoPtr(AutoPtr const& t) { 14 | pt = t.pt; 15 | if (pt != NULL) { 16 | Trait::CopyAddRef(pt); 17 | } 18 | } 19 | 20 | ~AutoPtr() { 21 | release(); 22 | } 23 | 24 | AutoPtr& operator=(T * pt_) { 25 | if (pt_ != NULL) { 26 | Trait::AddRef(pt); 27 | } 28 | release(); 29 | pt = pt_; 30 | return *this; 31 | } 32 | AutoPtr& operator=(AutoPtr const& t) { 33 | if (pt_ != NULL) { 34 | Trait::CopyAddRef(pt); 35 | } 36 | release(); 37 | pt = t.pt; 38 | return *this; 39 | } 40 | 41 | 42 | T ** operator&() { 43 | release(); 44 | return &pt; 45 | } 46 | T* operator->() const { return pt; } 47 | operator T*() const { return pt; } 48 | private: 49 | // close 50 | void release() { 51 | if (pt) { 52 | Trait::Release(pt); 53 | } 54 | pt = NULL; 55 | } 56 | T* pt; 57 | }; 58 | 59 | template 60 | class AutoCloseTrait { 61 | public: 62 | static void AddRef(T * pt) {}; 63 | static void Release(T * pt) { pt->close(); } 64 | }; 65 | 66 | template 67 | class AutoReleaseTrait { 68 | public: 69 | static void AddRef(T * pt) {}; 70 | static void Release(T * pt) { pt->release(); } 71 | }; 72 | 73 | template class AutoClosePtr : public AutoPtr {}; 74 | template class AutoReleasePtr : public AutoPtr {}; 75 | #endif // !__PTR_INCLUDED__ 76 | -------------------------------------------------------------------------------- /PDB/include/mdalign.h: -------------------------------------------------------------------------------- 1 | // mdalign.h - Machine Dependent Alignment functions 2 | #pragma once 3 | #ifndef __MDALIGN_INLCUDED__ 4 | #define __MDALIGN_INCLUDED__ 5 | 6 | typedef unsigned __int32 _file_align_t; 7 | 8 | #if defined(_M_IA64) || defined(_M_ALPHA64) || defined(_M_AMD64) || defined(_M_ARM64) 9 | typedef __int64 _md_int_t; 10 | #else 11 | typedef __int32 _md_int_t; 12 | #endif 13 | 14 | // returns the delta 15 | inline CB dcbAlign(size_t cb) 16 | { 17 | return CB((-_md_int_t(cb)) & (sizeof(_file_align_t) - 1)); 18 | } 19 | 20 | inline size_t cbAlign(size_t cb) 21 | { 22 | return ((cb + sizeof(_file_align_t) - 1)) & ~(sizeof(_file_align_t) - 1); 23 | } 24 | 25 | inline PB pbAlign(PB pb) 26 | { 27 | return PB((_md_int_t(pb) + sizeof(_file_align_t) - 1) & ~(_md_int_t(sizeof(_file_align_t) - 1))); 28 | } 29 | 30 | inline BOOL fAlign(_md_int_t i) 31 | { 32 | return BOOL( !(i & (sizeof(_file_align_t) - 1)) ); 33 | } 34 | 35 | inline BOOL fAlign(void* pv) 36 | { 37 | return fAlign(_md_int_t(pv)); 38 | } 39 | 40 | inline unsigned cbInsertAlign(PB pb, unsigned len) 41 | { 42 | unsigned align = (4 - len) & 3; 43 | unsigned alignT = align; 44 | char cPad = (char)(LF_PAD0 + align); 45 | 46 | while (align--) { 47 | *pb++ = cPad--; 48 | } 49 | return alignT; 50 | } 51 | 52 | // Align via the native pointer size, not to be used for aligned data on 53 | // disk, as it will be different for different platforms. 54 | // 55 | inline CB dcbAlignNative(size_t cb) 56 | { 57 | return CB((-_md_int_t(cb)) & (sizeof(_md_int_t) - 1)); 58 | } 59 | 60 | inline size_t cbAlignNative(size_t cb) 61 | { 62 | return ((cb + sizeof(_md_int_t) - 1)) & ~(sizeof(_md_int_t) - 1); 63 | } 64 | 65 | inline PB pbAlignNative(PB pb) 66 | { 67 | return PB((_md_int_t(pb) + sizeof(_md_int_t) - 1) & ~(_md_int_t(sizeof(_md_int_t) - 1))); 68 | } 69 | 70 | inline BOOL fAlignNative(_md_int_t i) 71 | { 72 | return BOOL( !(i & (sizeof(_md_int_t) - 1)) ); 73 | } 74 | 75 | inline BOOL fAlignNative(void* pv) 76 | { 77 | return fAlign(_md_int_t(pv)); 78 | } 79 | 80 | #endif // !__MDALIGN_INCLUDED__ 81 | -------------------------------------------------------------------------------- /cvdump/output.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | #include "cvdump.h" 12 | 13 | #define STRICT 14 | #define WIN32_LEAN_AND_MEAN 15 | #include "windows.h" 16 | 17 | 18 | bool fStdOutConsole; 19 | 20 | 21 | bool FIsConsole(FILE *fd) 22 | { 23 | int fh = _fileno(fd); 24 | 25 | HANDLE hFile = (HANDLE) _get_osfhandle(fh); 26 | 27 | DWORD dwType = GetFileType(hFile); 28 | 29 | dwType &= ~FILE_TYPE_REMOTE; 30 | 31 | if (dwType != FILE_TYPE_CHAR) { 32 | return false; 33 | } 34 | 35 | DWORD dwMode; 36 | 37 | if (!GetConsoleMode(hFile, &dwMode)) { 38 | return false; 39 | } 40 | 41 | return true; 42 | } 43 | 44 | 45 | void OutputInit() 46 | { 47 | if (FIsConsole(stdout)) { 48 | fStdOutConsole = true; 49 | } 50 | } 51 | 52 | 53 | int StdOutFlush() 54 | { 55 | if (fStdOutConsole) { 56 | return 0; 57 | } 58 | 59 | return fflush(stdout); 60 | } 61 | 62 | 63 | int __cdecl StdOutPrintf(const wchar_t *szFormat, ...) 64 | { 65 | va_list valist; 66 | 67 | va_start(valist, szFormat); 68 | 69 | int ret = StdOutVprintf(szFormat, valist); 70 | 71 | va_end(valist); 72 | 73 | return ret; 74 | } 75 | 76 | 77 | int StdOutPutc(wchar_t ch) 78 | { 79 | if (fStdOutConsole) { 80 | return _putwch(ch); 81 | } 82 | 83 | return fputwc(ch, stdout); 84 | } 85 | 86 | 87 | int StdOutPuts(const wchar_t *sz) 88 | { 89 | if (fStdOutConsole) { 90 | return _cputws(sz); 91 | } 92 | 93 | return fputws(sz, stdout); 94 | } 95 | 96 | 97 | int StdOutVprintf(const wchar_t *szFormat, va_list valist) 98 | { 99 | if (fStdOutConsole) { 100 | return _vcwprintf(szFormat, valist); 101 | } 102 | 103 | return vfwprintf(stdout, szFormat, valist); 104 | } 105 | -------------------------------------------------------------------------------- /PDB/dbi/dbiimpl.h: -------------------------------------------------------------------------------- 1 | // PDB Debug Information (DBI) API Implementation 2 | 3 | #ifndef __DBIIMPL_INCLUDED__ 4 | #define __DBIIMPL_INCLUDED__ 5 | 6 | #ifndef __PDBIMPL_INCLUDED__ 7 | #include "pdbimpl.h" 8 | #endif 9 | 10 | #include "map.h" 11 | 12 | #ifndef __MSF_INCLUDED__ 13 | #define MSF_IMP 14 | #include "..\include\msf.h" 15 | #endif 16 | #ifndef __CVR_INCLUDED__ 17 | #define CVR_IMP 18 | #include 19 | #endif 20 | 21 | #include "nmt.h" 22 | 23 | 24 | struct HDR; 25 | struct REC; 26 | #ifdef PDB_DEFUNCT_V8 27 | struct C8REC; 28 | #endif 29 | struct CHN; 30 | struct DBI1; 31 | struct MODI; // module information 32 | struct TPI1; 33 | struct Mod1; 34 | struct GSI1; 35 | struct PSGSI1; 36 | class TM; // abstract type map 37 | class TMTS; // type map for modules which use a different TypeServer 38 | class TMR; // type map for module with type records 39 | class TMPCT; // type map for a PCT module 40 | struct OTM; // DBI1 helper to find some currently Open TM 41 | class Strm; 42 | typedef REC *PREC; 43 | #ifdef PDB_DEFUNCT_V8 44 | typedef C8REC UNALIGNED * PC8REC; 45 | #endif 46 | typedef CHN *PCHN; 47 | typedef SYMTYPE* PSYM; 48 | typedef TYPTYPE* PTYPE; 49 | typedef USHORT CBREC; 50 | typedef USHORT IFILE; 51 | typedef long ICH; 52 | 53 | #ifndef __MLI_INCLUDED__ 54 | #include "mli.h" 55 | #endif 56 | 57 | #define isectNil ((ISECT)-1) 58 | 59 | const TI tiMin = 0x1000; 60 | 61 | // Reserve 28-bits worth of type indices. 256 Meg entries should be plenty for anybody! 62 | const TI tiMax = 0x0fffffff; 63 | 64 | const TI16 ti16Max = 0xfff0; 65 | const CB cbRecMax = 0xff00; 66 | const SN snPDB = 1; 67 | const SN snTpi = 2; 68 | const SN snDbi = 3; 69 | const SN snIpi = 4; 70 | const SN snSpecialMax = 5; 71 | 72 | 73 | #include "ref.h" 74 | #include "nmtni.h" 75 | #include "pdbcommon.h" 76 | #include "pdb1.h" 77 | #include "stream.h" 78 | #if CC_LAZYSYMS 79 | #include "objfile.h" 80 | #endif 81 | #include 82 | #include "dbicommon.h" 83 | #include "dbi.h" 84 | #include "modcommon.h" 85 | #include "mod.h" 86 | #include "gsi.h" 87 | #include "udtrefs.h" 88 | #include "tm.h" 89 | #include "tpi.h" 90 | #include "util.h" 91 | #include "misc.h" 92 | 93 | #endif // !__DBI_INCLUDED__ 94 | -------------------------------------------------------------------------------- /cvdump/debsym.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | /* 12 | * SYMBOLS segment definitions 13 | */ 14 | 15 | /* Record types */ 16 | 17 | #define S_BLOCK 0 /* Block start - obsolete */ 18 | #define S_PROC 1 /* Procedure start - obsolete */ 19 | #define S_END 2 /* Block, procedure, or "with" end */ 20 | #define S_BPREL 4 /* BP-relative */ 21 | #define S_LOCAL 5 /* Module-local symbol */ 22 | #define S_LABEL 11 /* Code label - obsolete */ 23 | #define S_WITH 12 /* "With" start - obsolete */ 24 | #define S_REG 13 /* Register variable */ 25 | #define S_CONST 14 /* Constant symbol */ 26 | #define S_ENTRY 15 /* entry symbol */ 27 | #define S_NOOP 16 /* noop - used for incremental padding */ 28 | #define S_CODSEG 17 /* effective code segment */ 29 | #define S_TYPEDEF 18 /* Used to specify a typedef */ 30 | #define S_GLOBAL 19 /* Used to specify global data */ 31 | #define S_GLOBPROC 20 /* Used to specify global procedure */ 32 | #define S_LOCPROC 21 /* Used to specify local procedure */ 33 | #define S_CHGMODEL 22 /* Change execution model - obsolete */ 34 | #define S_PUBLIC 23 /* Symbol in $$PUBLICS section */ 35 | #define S_THUNK 24 /* Thunk start */ 36 | #define S_SEARCH 25 /* Start Search */ 37 | #define S_CV4BLOCK 26 /* New version of S_BLOCK */ 38 | #define S_CV4WITH 27 /* New version of S_WITH */ 39 | #define S_CV4LABEL 28 /* New version of S_LABEL */ 40 | #define S_CV4CHGMODEL 29 /* New version of S_CHGMODEL */ 41 | #define S_COMPILEFLAG 30 // Some info about the compiler 42 | 43 | /* Code return type */ 44 | 45 | #define S_NEAR 0 /* NEAR code flag */ 46 | #define S_FAR 4 /* FAR code flag */ 47 | -------------------------------------------------------------------------------- /PDB/include/pdbtypdefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //standard typedefs used by pdb and its associated components 3 | 4 | typedef unsigned short ushort; 5 | typedef unsigned long ulong; 6 | typedef char* ST; // length prefixed string 7 | typedef const char* ST_CONST; // const length prefixed string 8 | typedef char* SZ; // zero terminated string 9 | typedef const char* SZ_CONST; // const string 10 | typedef wchar_t* USZ; // zero terminated string 11 | typedef const wchar_t* USZ_CONST; // const string 12 | typedef BYTE* PB; // pointer to some bytes 13 | typedef long CB; // count of bytes 14 | typedef long OFF; // offset 15 | typedef OFF* POFF; // pointer to offset 16 | typedef wchar_t * WSZ; // Wide string 17 | typedef const wchar_t * WSZ_CONST; // Const wide string 18 | 19 | // define types that hold machine dependent pointer types as 20 | // integers or longs. Needs to be used in place of CB/OFF whereever 21 | // a pointer is also stored. 22 | // 23 | #if defined(_M_IA64) || defined(_M_ALPHA64) || defined(_M_AMD64) || defined(_M_ARM64) 24 | typedef unsigned __int64 uint_ptr_t; 25 | typedef __int64 int_ptr_t; 26 | typedef unsigned __int64 ulong_ptr_t; 27 | typedef __int64 long_ptr_t; 28 | #else 29 | typedef unsigned int uint_ptr_t; 30 | typedef int int_ptr_t; 31 | typedef unsigned long ulong_ptr_t; 32 | typedef long long_ptr_t; 33 | #endif 34 | 35 | typedef uint_ptr_t * puint_ptr_t; 36 | typedef int_ptr_t * pint_ptr_t; 37 | typedef ulong_ptr_t * pulong_ptr_t; 38 | typedef long_ptr_t * plong_ptr_t; 39 | 40 | typedef USHORT IFILE; // file index 41 | typedef USHORT IMOD; // module index 42 | typedef USHORT ISECT; // section index 43 | typedef USHORT LINE; // line number 44 | typedef ULONG LINE32; // long line number 45 | typedef USHORT HASH; // short hash 46 | typedef ULONG LHASH; // long hash 47 | 48 | // TFS #498256 -- We used to define a local buffer with length _MAX_PATH 49 | // and use it as dest buffer to call _wmakepath(). When the combined length 50 | // of drive, path, filename, and extension is larger than _MAX_PATH, Watson 51 | // would be invoked and mspdbsrv.exe would then crash. So we define a large 52 | // enough size for the dest buffer to prevent Watson from being invoked and 53 | // mspdbsrv.exe from crashing. 54 | #define PDB_MAX_FILENAME (_MAX_DRIVE + _MAX_PATH + _MAX_FNAME + _MAX_EXT + 1) 55 | -------------------------------------------------------------------------------- /PDB/include/objfile.h: -------------------------------------------------------------------------------- 1 | // 2 | // class ObjectFile 3 | // 4 | // Readonly access to an object file 5 | // (or container object, e.g., library ) 6 | // 7 | #if CC_LAZYSYMS 8 | 9 | class ObjectFile 10 | { 11 | public: 12 | ObjectFile( SZ_CONST _szModule, SZ_CONST _szObjFile, SZ_CONST _szFullPath ); 13 | ~ObjectFile(); 14 | BOOL Open(); 15 | BOOL Section( size_t i, OUT PB& pb, OUT CB& cb ); 16 | DWORD Timestamp(); 17 | PB pbObjView( DWORD fo=0 ) { assert( (CB)fo < cbObj ); return pbObj+fo; } 18 | 19 | static void Flush(); // close and unmap files 20 | 21 | private: 22 | SZ_CONST szModule; 23 | SZ_CONST szObjFile; 24 | SZ_CONST szFullPath; 25 | DWORD dwSize; 26 | LPVOID pvMapView; 27 | HANDLE hFile; 28 | PB pbObj; 29 | CB cbObj; 30 | BOOL cacheHit; 31 | 32 | BOOL LocateObj(); // locate the object in the container 33 | BOOL OpenFile( SZ_CONST ); // map the file contents 34 | PB pbMapView( DWORD fo=0 ) 35 | { return (PB)pvMapView+fo; } 36 | 37 | const IMAGE_ARCHIVE_MEMBER_HEADER& hdrMapView( DWORD fo ) 38 | { return *(IMAGE_ARCHIVE_MEMBER_HEADER*)pbMapView(fo); } 39 | 40 | DWORD foMember( DWORD foHdr ) 41 | { return foHdr + sizeof( IMAGE_ARCHIVE_MEMBER_HEADER ); } 42 | 43 | const IMAGE_FILE_HEADER& ihdrMapView() 44 | { assert(pbObj); return *(IMAGE_FILE_HEADER*)pbObj; } 45 | 46 | BOOL shdrMapView( size_t i, const IMAGE_SECTION_HEADER*& ); 47 | 48 | BOOL ExtractMember(); 49 | SZ_CONST ExpandName( char szName[], SZ_CONST longnames ); 50 | BOOL NextMember( DWORD& fo ); 51 | BOOL MemberSize( const IMAGE_ARCHIVE_MEMBER_HEADER& hdr, OUT CB& cb ); 52 | 53 | struct LibMap { 54 | LPVOID pvMapView; 55 | HANDLE hFile; 56 | DWORD dwSize; 57 | char szObjFile[_MAX_PATH]; 58 | 59 | LibMap( SZ_CONST _szObjFile, LPVOID _pvMapView, HANDLE _hFile, DWORD _dwSize ) 60 | : pvMapView( _pvMapView ), hFile( _hFile ), dwSize( _dwSize ) 61 | { 62 | assert( _szObjFile ); 63 | strcpy( szObjFile, _szObjFile ); 64 | } 65 | BOOL operator==( SZ_CONST sz ) 66 | { 67 | return strcmp( sz, szObjFile ) == 0; 68 | } 69 | }; 70 | 71 | static ArrayBuf cache; // cached library files 72 | static BOOL Lookup( SZ_CONST sz, OUT LPVOID& pvMapView, OUT HANDLE& hFile, OUT DWORD& dwSize ); 73 | static void Insert( SZ_CONST sz, LPVOID pvMapView, HANDLE hFile, DWORD dwSize ); 74 | }; 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /PDB/include/crtfubar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Fix up the CRT's FUBAR'ed _[w]sopen madness; we still have to link/run for/on 4 | // down-level OS versions of the CRT DLL 5 | 6 | // Produce prototypes matching the CRT but with different names (C linkage too!) 7 | 8 | extern "C" { 9 | int _ACRTIMP __cdecl _pdb_sopen(const char *, int, int, int); 10 | int _ACRTIMP __cdecl _pdb_wsopen(const wchar_t *, int, int, int); 11 | int _ACRTIMP __cdecl _pdb_open(const char *, int, int); 12 | int _ACRTIMP __cdecl _pdb_wopen(const wchar_t *, int, int); 13 | } 14 | 15 | // Redirect the ones we use to the ones above 16 | 17 | #define _sopen _pdb_sopen 18 | #define _wsopen _pdb_wsopen 19 | #define _open _pdb_open 20 | #define _wopen _pdb_wopen 21 | 22 | // Now, through a bit of linker magic, redirect the ones above to the real CRT ones 23 | // that should have been accessible anyway. 24 | 25 | #if defined(_M_IX86) 26 | #if defined(_DLL) 27 | #pragma comment(linker, "/alternatename:__imp___pdb_sopen=__imp___sopen") 28 | #pragma comment(linker, "/alternatename:__imp___pdb_wsopen=__imp___wsopen") 29 | #pragma comment(linker, "/alternatename:__imp___pdb_open=__imp___open") 30 | #pragma comment(linker, "/alternatename:__imp___pdb_wopen=__imp___wopen") 31 | #else 32 | #pragma comment(linker, "/alternatename:__pdb_sopen=__sopen") 33 | #pragma comment(linker, "/alternatename:__pdb_wsopen=__wsopen") 34 | #pragma comment(linker, "/alternatename:__pdb_open=__open") 35 | #pragma comment(linker, "/alternatename:__pdb_wopen=__wopen") 36 | #endif 37 | #else 38 | #if defined(_DLL) 39 | #pragma comment(linker, "/alternatename:__imp__pdb_sopen=__imp__sopen") 40 | #pragma comment(linker, "/alternatename:__imp__pdb_wsopen=__imp__wsopen") 41 | #pragma comment(linker, "/alternatename:__imp__pdb_open=__imp__open") 42 | #pragma comment(linker, "/alternatename:__imp__pdb_wopen=__imp__wopen") 43 | #else 44 | #pragma comment(linker, "/alternatename:_pdb_sopen=_sopen") 45 | #pragma comment(linker, "/alternatename:_pdb_wsopen=_wsopen") 46 | #pragma comment(linker, "/alternatename:_pdb_open=_open") 47 | #pragma comment(linker, "/alternatename:_pdb_wopen=_wopen") 48 | #if defined(_M_IA64) 49 | #pragma comment(linker, "/alternatename:._pdb_sopen=._sopen") 50 | #pragma comment(linker, "/alternatename:._pdb_wsopen=._wsopen") 51 | #pragma comment(linker, "/alternatename:._pdb_open=._open") 52 | #pragma comment(linker, "/alternatename:._pdb_wopen=._wopen") 53 | #endif 54 | #endif 55 | #endif 56 | -------------------------------------------------------------------------------- /PDB/dbi/stream.cpp: -------------------------------------------------------------------------------- 1 | #include "pdbimpl.h" 2 | #include "dbiimpl.h" 3 | 4 | #ifndef PDB_MT 5 | BOOL PDB1::OpenStreamEx(SZ_CONST sz, SZ_CONST szMode, OUT Stream** ppstream) { 6 | // MTS NOTE: NMTNI is MTS, no need to protect 7 | NI ni; 8 | return nmt.addNiForSz(sz, &ni) && !!(*ppstream = new Strm(this, (SN)ni)); 9 | } 10 | 11 | #else 12 | 13 | 14 | BOOL PDB1::OpenStreamEx(SZ_CONST sz, SZ_CONST szMode, OUT Stream** ppstream) { 15 | PDBLOG_FUNC(); 16 | PDBLOG_FUNCARG(sz); 17 | PDBLOG_FUNCARG(szMode); 18 | 19 | // MTS NOTE: NMTNI is MTS, no need to protect 20 | BOOL fExclusive = strchr(szMode, 'x') != 0; 21 | NI ni; 22 | if (!nmt.addNiForSz(sz, &ni)) { 23 | return FALSE; 24 | } 25 | 26 | MTS_PROTECT_T(Mutex, m_mutexStreamOpenClose); 27 | 28 | Strm * pstrm; 29 | if (m_mpOpenedStream.map(ni, &pstrm)) { 30 | while (pstrm->GetRefcount() != 0) { 31 | if (!fExclusive && !pstrm->fExclusive()) { 32 | break; 33 | } 34 | if (!pstrm->ReleaseAndAcquire( m_mutexStreamOpenClose )) { 35 | setLastError(EC_ACCESS_DENIED); 36 | return FALSE; 37 | } 38 | } 39 | assert(pstrm->GetRefcount() == 0 || (!pstrm->fExclusive() && !fExclusive)); 40 | } else { 41 | pstrm = new (this) Strm(this, (SN)ni, m_mutexStreamOpenClose); 42 | if (pstrm == NULL || !m_mpOpenedStream.add(ni, pstrm)) { 43 | setOOMError(); 44 | return FALSE; 45 | } 46 | } 47 | 48 | *ppstream = pstrm; 49 | 50 | pstrm->IncRefcount(); 51 | pstrm->fExclusive() = fExclusive; 52 | 53 | return TRUE; 54 | } 55 | #endif 56 | 57 | BOOL PDB1::GetEnumStreamNameMap(OUT Enum** ppenum) { 58 | // MTS NOTE: NMTNI is MTS, no need to protect 59 | // MTS NOTE: EnumNMTNI can't be share with multiple thread! 60 | return !!(*ppenum = (Enum *)new EnumNMTNI(nmt)); 61 | } 62 | 63 | // Return the next free SN as an NI. Called by PDB1::nmt.niForSz() when first 64 | // establishing a name index for a new stream name. 65 | BOOL PDB1::niForNextFreeSn(void* pv, OUT NI* pni) { 66 | PDB1* ppdb1 = (PDB1*)pv; 67 | SN sn = ppdb1->pmsf->GetFreeSn(); 68 | if (sn != snNil) { 69 | *pni = (NI)sn; 70 | #ifdef PDB_MT 71 | // MTS NOTE: the MSF is MTS and it automatically replace the stream 72 | return TRUE; 73 | #else 74 | // Alas, necessary to create an empty stream to "claim it", otherwise 75 | // the next call to MSFGetFreeSn() will return same sn again. 76 | return ppdb1->pmsf->ReplaceStream(sn, 0, 0); 77 | #endif 78 | } 79 | return FALSE; 80 | } 81 | 82 | extern const char szStreamNameMap[] = "/names"; 83 | 84 | -------------------------------------------------------------------------------- /PDB/include/syncro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Event { 4 | public : 5 | Event( BOOL fManualReset = FALSE ) : m_hEvent( NULL ) { 6 | verify( Init(fManualReset) ); 7 | } 8 | ~Event( ) { 9 | if ( m_hEvent ) { 10 | CloseHandle( m_hEvent ); 11 | } 12 | } 13 | BOOL Set() { 14 | return SetEvent( m_hEvent ); 15 | } 16 | BOOL Reset() { 17 | return ResetEvent( m_hEvent ); 18 | } 19 | BOOL Wait( DWORD dwmsMaxWait ) { 20 | DWORD dwRet = WaitForSingleObject( m_hEvent, dwmsMaxWait ); 21 | return dwRet == WAIT_OBJECT_0; 22 | } 23 | HANDLE GetHandle() { 24 | return m_hEvent; 25 | } 26 | protected: 27 | HANDLE m_hEvent; 28 | BOOL Init( BOOL fManualReset ) { 29 | m_hEvent = CreateEventW(NULL, fManualReset, FALSE, NULL); 30 | return m_hEvent != NULL; 31 | } 32 | }; 33 | 34 | class Mutex { 35 | public: 36 | Mutex() : m_hMutex( 0 ), m_tidOwner( 0 ) { 37 | verify( Init() ); 38 | } 39 | ~Mutex( ) { 40 | if ( m_hMutex ) { 41 | CloseHandle( m_hMutex ); 42 | } 43 | } 44 | BOOL Enter() { 45 | DWORD dwRet = WaitForSingleObject( m_hMutex, INFINITE ); 46 | if ( dwRet == WAIT_OBJECT_0 ) { 47 | m_tidOwner = GetCurrentThreadId(); 48 | } 49 | return dwRet == WAIT_OBJECT_0; 50 | } 51 | BOOL Leave() { 52 | BOOL fResult; 53 | if ( fResult = ReleaseMutex( m_hMutex ) ) { 54 | m_tidOwner = 0; 55 | } 56 | return fResult; 57 | } 58 | HANDLE GetHandle() { 59 | return m_hMutex; 60 | } 61 | protected: 62 | HANDLE m_hMutex; 63 | DWORD m_tidOwner; 64 | BOOL Init() { 65 | m_hMutex = CreateMutexW( NULL, FALSE, NULL ); 66 | return m_hMutex != NULL; 67 | } 68 | }; 69 | 70 | class Semaphore { 71 | public: 72 | Semaphore( DWORD nMaxThreads ) : m_hSemaphore( 0 ), m_nMaxThreads( nMaxThreads ) { 73 | m_hSemaphore = CreateSemaphoreA(NULL, 0, nMaxThreads, NULL); 74 | } 75 | ~Semaphore() { 76 | CloseHandle(m_hSemaphore); 77 | } 78 | BOOL SetCount( DWORD count ) { 79 | return ReleaseSemaphore(m_hSemaphore, count, NULL); 80 | } 81 | BOOL Acquire( DWORD dwmsMaxWait ) { 82 | DWORD dwRet = WaitForSingleObject( m_hSemaphore, dwmsMaxWait ); 83 | return dwRet == WAIT_OBJECT_0; 84 | } 85 | BOOL Release() { 86 | return ReleaseSemaphore(m_hSemaphore, 1, NULL); 87 | } 88 | BOOL ReleaseAll() { 89 | return ReleaseSemaphore(m_hSemaphore, m_nMaxThreads, NULL); 90 | } 91 | HANDLE GetHandle() { 92 | return m_hSemaphore; 93 | } 94 | private: 95 | HANDLE m_hSemaphore; 96 | DWORD m_nMaxThreads; 97 | }; 98 | -------------------------------------------------------------------------------- /PDB/include/mts.h: -------------------------------------------------------------------------------- 1 | #ifndef __MTS_H__ 2 | #define __MTS_H__ 3 | 4 | #include "assert_.h" 5 | 6 | #if !defined(_DEBUG) || !defined(PDB_MT) 7 | #define MTS_ASSERT_SINGLETHREAD() 8 | #define USE_ASSURE_SINGLETHREAD() 9 | #else 10 | #define MTS_ASSERT_SINGLETHREAD() AutoAssureSingleThread _autost##n(_ast) 11 | #define USE_ASSURE_SINGLETHREAD() AssureSingleThread _ast 12 | 13 | class AssureSingleThread { 14 | public: 15 | AssureSingleThread() : tid(0) {}; 16 | private: 17 | LONG tid; 18 | friend class AutoAssureSingleThread; 19 | }; 20 | 21 | class AutoAssureSingleThread { 22 | public: 23 | AutoAssureSingleThread(AssureSingleThread& ast) : m_ptid(&ast.tid) { 24 | LONG tid = InterlockedExchange(m_ptid, (LONG)GetCurrentThreadId()); 25 | fIgnore = (tid == GetCurrentThreadId()); // re-entrent 26 | assert(tid == NULL || fIgnore); 27 | }; 28 | ~AutoAssureSingleThread() { 29 | LONG tid = InterlockedExchange(m_ptid, (fIgnore? (LONG)GetCurrentThreadId() : 0)); 30 | assert(tid == GetCurrentThreadId()); 31 | } 32 | private: 33 | LONG * m_ptid; 34 | bool fIgnore; 35 | }; 36 | #endif // _DEBUG 37 | 38 | // PDB_MT ONLY 39 | #ifndef PDB_MT 40 | 41 | #define MTS_PROTECT_T(T, lock) 42 | #define MTS_PROTECTNOLOG(lock) 43 | #define MTS_PROTECT(lock) 44 | #define MTS_PROTECT_COND(lock, f) 45 | 46 | #define MTS_ENTER(lock) 47 | #define MTS_LEAVE(lock) 48 | 49 | #define MTS_ASSERT(lock) 50 | 51 | #include "pdblog.h" 52 | #include "critsec.h" 53 | 54 | #else 55 | 56 | #define _MTS_STRINGIZING(x) #x 57 | #define MTS_STRINGIZING(x) _MTS_STRINGIZING(x) 58 | #define _MTS_MESSAGE(a, b, x) "TODO: " a "(" MTS_STRINGIZING(b) "): " x 59 | 60 | #define _MTS_PROTECT2(T, lock, n) AutoLockTemplate autolock##n(&lock); 61 | #define _MTS_PROTECT(T, lock, n) _MTS_PROTECT2(T, lock, n) 62 | 63 | #define _MTS_PROTECT2_COND(T, lock, f, n) AutoLockWithConditionTemplate autolock##n(&lock, f); 64 | #define _MTS_PROTECT_COND(T, lock, f, n) _MTS_PROTECT2_COND(T, lock, f, n) 65 | 66 | #define MTS_MESSAGE(x) _MTS_MESSAGE(__FILE__, __LINE__, x) 67 | 68 | #ifdef PDB_LOGGING 69 | #define MTS_PROTECTNOLOG(lock) _MTS_PROTECT(CriticalSectionNoLog, lock, __COUNTER__) 70 | #endif 71 | 72 | #define MTS_ENTER(lock) verify(lock.Enter()) 73 | #define MTS_LEAVE(lock) verify(lock.Leave()) 74 | 75 | #include "pdblog.h" 76 | #include "critsec.h" 77 | #include "syncro.h" 78 | 79 | #define MTS_PROTECT_T(T, lock) _MTS_PROTECT(T, lock, __COUNTER__) 80 | #define MTS_PROTECT(lock) MTS_PROTECT_T(CriticalSection, lock) 81 | #define MTS_ASSERT(lock) assert(lock.FAcquired()) 82 | 83 | #define MTS_PROTECT_T_COND(T, lock, f) _MTS_PROTECT_COND(T, lock, f, __COUNTER__) 84 | #define MTS_PROTECT_COND(lock, f) MTS_PROTECT_T_COND(CriticalSection, lock, f) 85 | 86 | #endif // PDB_MT 87 | #endif 88 | -------------------------------------------------------------------------------- /PDB/dbi/stream.h: -------------------------------------------------------------------------------- 1 | class Strm : public Stream { 2 | public: 3 | #ifdef PDB_MT 4 | Strm(PDB1* ppdb1, SN sn, Mutex& mutex ) : m_refcount(0), m_mutexOpenClose( mutex ) { 5 | #else 6 | Strm(PDB1* ppdb1, SN sn) { 7 | #endif 8 | PDBLOG_FUNC(); 9 | m_ppdb1 = ppdb1; 10 | m_sn = sn; 11 | } 12 | CB QueryCb() { 13 | PDBLOG_FUNC(); 14 | return m_ppdb1->pmsf->GetCbStream(m_sn); 15 | } 16 | BOOL Read(OFF off, void* pvBuf, CB* pcbBuf) { 17 | PDBLOG_FUNC(); 18 | return m_ppdb1->pmsf->ReadStream(m_sn, off, pvBuf, pcbBuf); 19 | } 20 | BOOL Read2(OFF off, void* pvBuf, CB cbBuf) { 21 | CB cbT = cbBuf; 22 | return m_ppdb1->pmsf->ReadStream(m_sn, off, pvBuf, &cbT) && cbT == cbBuf; 23 | } 24 | BOOL Write(OFF off, void* pvBuf, CB cbBuf) { 25 | PDBLOG_FUNC(); 26 | return m_ppdb1->pmsf->WriteStream(m_sn, off, pvBuf, cbBuf); 27 | } 28 | BOOL Replace(void* pvBuf, CB cbBuf) { 29 | PDBLOG_FUNC(); 30 | return m_ppdb1->pmsf->ReplaceStream(m_sn, pvBuf, cbBuf); 31 | } 32 | BOOL Append(void* pvBuf, CB cbBuf) { 33 | PDBLOG_FUNC(); 34 | return m_ppdb1->pmsf->AppendStream(m_sn, pvBuf, cbBuf); 35 | } 36 | BOOL Truncate(CB cb) { 37 | PDBLOG_FUNC(); 38 | return m_ppdb1->pmsf->TruncateStream(m_sn, cb); 39 | } 40 | BOOL Delete() { 41 | PDBLOG_FUNC(); 42 | #ifdef PDB_MT 43 | MTS_PROTECT_T( Mutex, m_mutexOpenClose ); 44 | #endif 45 | BOOL fRet = m_ppdb1->pmsf->DeleteStream(m_sn); 46 | fRet &= m_ppdb1->RemoveStreamName(m_sn); 47 | return fRet; 48 | } 49 | BOOL Release() { 50 | PDBLOG_FUNC(); 51 | #ifdef PDB_MT 52 | MTS_PROTECT_T( Mutex, m_mutexOpenClose ); 53 | assert(m_refcount != 0); 54 | if (DecRefcount() == 0) { 55 | m_evRelease.Set(); 56 | } 57 | #else 58 | m_ppdb1->pmsf->CloseStream(m_sn); 59 | delete this; 60 | #endif 61 | return TRUE; 62 | } 63 | #ifdef PDB_MT 64 | ULONG IncRefcount() { 65 | return ++m_refcount; 66 | } 67 | ULONG DecRefcount() { 68 | return --m_refcount; 69 | } 70 | ULONG GetRefcount() { 71 | return m_refcount; 72 | } 73 | BOOL& fExclusive() { 74 | return m_fExclusive; 75 | } 76 | BOOL ReleaseAndAcquire(Mutex & mutex) { 77 | if ( SignalObjectAndWait( mutex.GetHandle(), m_evRelease.GetHandle(), INFINITE, FALSE ) == WAIT_OBJECT_0 ) { 78 | return mutex.Enter(); 79 | } 80 | else { 81 | assert( FALSE ); 82 | return FALSE; 83 | } 84 | } 85 | #endif 86 | private: 87 | PDB1* m_ppdb1; 88 | SN m_sn; 89 | #ifdef PDB_MT 90 | BOOL m_fExclusive; 91 | DWORD m_refcount; 92 | Mutex& m_mutexOpenClose; 93 | Event m_evRelease; 94 | 95 | friend class PDB1; 96 | #endif 97 | }; 98 | -------------------------------------------------------------------------------- /PDB/dbi/pdbmain.cpp: -------------------------------------------------------------------------------- 1 | #include "pdbimpl.h" 2 | #include "dbiimpl.h" 3 | 4 | #ifdef _M_IX86 5 | void InitPfnWow64FsRedirection(); 6 | #endif // _M_IX86 7 | 8 | #if 0 9 | 10 | enum PRTY 11 | { 12 | prtyMin = THREAD_PRIORITY_LOWEST, 13 | prtyMost = THREAD_PRIORITY_HIGHEST 14 | }; 15 | 16 | #endif 17 | 18 | 19 | #ifdef _M_IX86 20 | 21 | BOOL WINAPI DllMain(HINSTANCE h, ULONG ulReason, PVOID pvReserved) 22 | { 23 | #if 0 24 | static int dPrty = 0; 25 | static bool fDoSetPrty; 26 | #endif 27 | 28 | switch ( ulReason ) { 29 | case DLL_PROCESS_ATTACH: 30 | #ifdef _M_IX86 31 | InitPfnWow64FsRedirection(); 32 | #endif // _M_IX86 33 | 34 | #if 0 35 | { 36 | LPCTSTR szMsDev = _tgetenv(_TEXT("_MSDEV_BLD_ENV_")); 37 | 38 | if (szMsDev != NULL) { 39 | // check for the reg key first, it overrides the value, 40 | // but not the existence of the env var 41 | 42 | bool fRegKeyPresent = false; 43 | HKEY hkey; 44 | 45 | if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, 46 | _TEXT("Software\\Microsoft\\DevStudio"), 47 | 0, 48 | KEY_READ, 49 | &hkey)) { 50 | DWORD dwValType; 51 | DWORD cbVal = sizeof(int); 52 | 53 | if (ERROR_SUCCESS == RegQueryValueEx(hkey, 54 | _TEXT("ToolPriorityDelta"), 55 | 0, 56 | &dwValType, 57 | PB(&dPrty), 58 | &cbVal)) { 59 | fRegKeyPresent = dwValType == REG_DWORD; 60 | } 61 | 62 | RegCloseKey(hkey); 63 | } 64 | 65 | SYSTEM_INFO si; 66 | 67 | ::GetSystemInfo(&si); 68 | 69 | fDoSetPrty = ((si.dwNumberOfProcessors > 1) || fRegKeyPresent) && 70 | (dPrty >= prtyMin) && 71 | (dPrty <= prtyMost); 72 | } 73 | } 74 | 75 | // Fall through and get the initial thread... 76 | 77 | case DLL_THREAD_ATTACH : 78 | if (fDoSetPrty) { 79 | HANDLE hThread = ::GetCurrentThread(); 80 | 81 | ::SetThreadPriority(hThread, dPrty); 82 | 83 | debug(_TCHAR szMsg[128]); 84 | debug(_stprintf(szMsg, _TEXT("MSPdb::PriorityDelta(%d)\r\n"), dPrty)); 85 | debug(::OutputDebugString(szMsg)); 86 | } 87 | break; 88 | #endif 89 | } 90 | 91 | return true; 92 | } 93 | 94 | #endif -------------------------------------------------------------------------------- /PDB/include/utf8.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 1991-1999, Microsoft Corporation All rights reserved. 4 | 5 | Module Name: 6 | 7 | utf.h 8 | 9 | Abstract: 10 | 11 | This file contains the header information for the UTF module of NLS. 12 | 13 | Revision History: 14 | 15 | 02-06-96 JulieB Created. 16 | 17 | --*/ 18 | // 19 | // Constant Declarations. 20 | // 21 | 22 | #ifndef _UTF8_H_ 23 | #define _UTF8_H_ 24 | 25 | #define ASCII 0x007f 26 | 27 | #define UTF8_2_MAX 0x07ff // max UTF8 2-byte sequence (32 * 64 = 2048) 28 | #define UTF8_1ST_OF_2 0xc0 // 110x xxxx 29 | #define UTF8_1ST_OF_3 0xe0 // 1110 xxxx 30 | #define UTF8_1ST_OF_4 0xf0 // 1111 xxxx 31 | #define UTF8_TRAIL 0x80 // 10xx xxxx 32 | 33 | #define HIGHER_6_BIT(u) ((u) >> 12) 34 | #define MIDDLE_6_BIT(u) (((u) & 0x0fc0) >> 6) 35 | #define LOWER_6_BIT(u) ((u) & 0x003f) 36 | 37 | #define BIT7(a) ((a) & 0x80) 38 | #define BIT6(a) ((a) & 0x40) 39 | 40 | #define HIGH_SURROGATE_START 0xd800 41 | #define HIGH_SURROGATE_END 0xdbff 42 | #define LOW_SURROGATE_START 0xdc00 43 | #define LOW_SURROGATE_END 0xdfff 44 | 45 | 46 | #define UCH_SURROGATE_FIRST 0xD800 // First surrogate 47 | #define UCH_HI_SURROGATE_FIRST 0xD800 // First High Surrogate 48 | #define UCH_PV_HI_SURROGATE_FIRST 0xDB80 // 49 | #define UCH_PV_HI_SURROGATE_LAST 0xDBFF // 50 | #define UCH_HI_SURROGATE_LAST 0xDBFF // Last High Surrogate 51 | #define UCH_LO_SURROGATE_FIRST 0xDC00 // 52 | #define UCH_LO_SURROGATE_LAST 0xDFFF // 53 | #define UCH_SURROGATE_LAST 0xDFFF // Last surrogate 54 | 55 | #define IN_RANGE(v, r1, r2) ((r1) <= (v) && (v) <= (r2)) 56 | #define UCH_REPLACE 0xFFFD // REPLACEMENT CHARACTER 57 | 58 | #define IsSurrogate(ch) IN_RANGE(ch, UCH_SURROGATE_FIRST, UCH_SURROGATE_LAST) 59 | #define IsHighSurrogate(ch) IN_RANGE(ch, UCH_HI_SURROGATE_FIRST, UCH_HI_SURROGATE_LAST) 60 | #define IsLowSurrogate(ch) IN_RANGE(ch, UCH_LO_SURROGATE_FIRST, UCH_LO_SURROGATE_LAST) 61 | 62 | #ifdef __cplusplus 63 | extern "C" { 64 | #endif 65 | 66 | size_t UTF8ToUnicode(LPCSTR lpSrcStr, __out_ecount_opt(cchDest) LPWSTR lpDestStr, size_t cchDest); 67 | size_t UTF8ToUnicodeCch(LPCSTR lpSrcStr, size_t cchSrc, __out_ecount_opt(cchDest) LPWSTR lpDestStr, size_t cchDest); 68 | size_t UnicodeToUTF8(LPCWSTR lpSrcStr, __out_ecount_opt(cchDest) LPSTR lpDestStr, size_t cchDest); 69 | size_t UnicodeToUTF8Cch(LPCWSTR lpSrcStr, size_t cchSrc, __out_ecount_opt(cchDest) LPSTR lpDestStr, size_t cchDest); 70 | size_t UnicodeLengthOfUTF8 (PCSTR pUTF8); 71 | size_t UTF8LengthOfUnicode (PCWSTR pUni); 72 | size_t UnicodeLengthOfUTF8Cb (PCSTR pUTF8, size_t cbUTF); 73 | size_t UTF8LengthOfUnicodeCch (PCWSTR pUni, size_t cchUni); 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /PDB/dbi/modcommon.cpp: -------------------------------------------------------------------------------- 1 | #include "pdbimpl.h" 2 | #include "modcommon.h" 3 | 4 | BOOL ModCommon::QueryPdbFile(OUT char szFile[_MAX_PATH], OUT CB* pcb) 5 | { 6 | wchar_t wszFile[PDB_MAX_PATH]; 7 | BOOL fResult = QueryPdbFileW(wszFile, pcb); 8 | if (fResult) { 9 | //convert it to MBCS 10 | SafeStackAllocator<0x400> allocator; 11 | SZ mbsFile = (szFile == NULL) ? allocator.Alloc(_MAX_PATH) : szFile; 12 | if (_GetSZMBCSFromSZUnicode(wszFile, mbsFile, _MAX_PATH) == NULL) { 13 | return FALSE; 14 | } 15 | *pcb = static_cast(strlen(mbsFile) + 1); 16 | } 17 | 18 | return fResult; 19 | } 20 | BOOL ModCommon::QueryCBName(OUT CB* pcb) 21 | { 22 | return QueryName(NULL, pcb); 23 | } 24 | 25 | BOOL ModCommon::QueryName(OUT char szName[_MAX_PATH], OUT CB* pcb) 26 | { 27 | wchar_t wszName[PDB_MAX_PATH]; 28 | BOOL fResult = QueryNameW(wszName, pcb); 29 | if (fResult) { 30 | // convert it to MBCS 31 | SafeStackAllocator<0x400> allocator; 32 | SZ mbsz = (szName == NULL) ? allocator.Alloc(_MAX_PATH) : szName; 33 | if (_GetSZMBCSFromSZUnicode(wszName, mbsz, _MAX_PATH) == NULL) { 34 | return FALSE; 35 | } 36 | 37 | *pcb = static_cast(strlen(mbsz) + 1); 38 | } 39 | return fResult; 40 | } 41 | 42 | BOOL ModCommon::QueryCBFile(OUT CB* pcb) 43 | { 44 | return QueryFile(NULL, pcb); 45 | } 46 | 47 | BOOL ModCommon::QueryFile(OUT char szFile[_MAX_PATH], OUT CB* pcb) 48 | { 49 | wchar_t wszFile[PDB_MAX_PATH]; 50 | BOOL fResult = QueryFileW(wszFile, pcb); 51 | if (fResult) { 52 | // convert it to MBCS 53 | SafeStackAllocator<0x400> allocator; 54 | SZ mbsz = (szFile == NULL) ? allocator.Alloc(_MAX_PATH) : szFile; 55 | if (_GetSZMBCSFromSZUnicode(wszFile, mbsz, _MAX_PATH) == NULL) 56 | return FALSE; 57 | 58 | *pcb = static_cast(strlen(mbsz) + 1); 59 | } 60 | return fResult; 61 | } 62 | 63 | BOOL ModCommon::QuerySrcFile(OUT char szFile[_MAX_PATH], OUT CB* pcb) 64 | { 65 | wchar_t wszFile[_MAX_PATH]; 66 | BOOL fResult = QuerySrcFileW(wszFile, pcb ); 67 | if (fResult) { 68 | // convert it to MBCS 69 | SafeStackAllocator<0x400> allocator; 70 | SZ mbsFile = (szFile == NULL) ? allocator.Alloc(_MAX_PATH) : szFile; 71 | if (_GetSZMBCSFromSZUnicode(wszFile, mbsFile, _MAX_PATH) == NULL) { 72 | return FALSE; 73 | } 74 | *pcb = static_cast(strlen(mbsFile) + 1); 75 | } 76 | 77 | return fResult; 78 | } 79 | 80 | BOOL ModCommon::AddLines(SZ_CONST szSrc, ISECT isect, OFF offCon, CB cbCon, OFF doff, LINE lineStart, PB pbCoff, CB cbCoff) 81 | { 82 | dassert(szSrc); 83 | dassert(pbCoff); 84 | // assert(IS_SZ_FORMAT_PDB(ppdb1)); 85 | 86 | wchar_t wcsSrc[_MAX_PATH]; 87 | if (_GetSZUnicodeFromSZMBCS(szSrc, wcsSrc, _MAX_PATH) == NULL) 88 | return FALSE; 89 | 90 | return AddLinesW(wcsSrc, isect, offCon, cbCon, doff, lineStart, pbCoff, cbCoff); 91 | } 92 | 93 | -------------------------------------------------------------------------------- /PDB/include/cvlines.h: -------------------------------------------------------------------------------- 1 | #ifndef _CVLINES_H_ 2 | #define _CVLINES_H_ 3 | 4 | #pragma warning(push) 5 | #pragma warning(disable:4200) 6 | 7 | class LineBuffer 8 | { 9 | private: 10 | struct FSB { WORD cFile; WORD cSeg; DWORD baseSrcFile[]; }; 11 | 12 | public: 13 | LineBuffer( bool fDeletePb = false ) : m_pb( NULL ), m_cb( 0 ), m_fDeletePb( fDeletePb ) 14 | {} 15 | ~LineBuffer() { 16 | if ( m_fDeletePb && m_pb != NULL ) { 17 | delete [] m_pb; 18 | m_pb = NULL; 19 | } 20 | } 21 | struct SPB { WORD cSeg; WORD pad; DWORD baseSrcLn[]; }; 22 | struct SE { DWORD start, end; }; 23 | struct SPO { WORD Seg; WORD cPair; DWORD offset[]; }; 24 | 25 | DWORD cFile(){ 26 | return ((FSB*)pb())->cFile; 27 | } 28 | DWORD cSeg(){ 29 | return ((FSB*)pb())->cSeg; 30 | } 31 | DWORD* baseSrcFile(){ 32 | return ((FSB*)pb())->baseSrcFile; 33 | } 34 | SE* startEnd() { 35 | return (SE*)(baseSrcFile()+cFile()); 36 | } 37 | WORD* iSegs() { 38 | return (WORD*)(startEnd()+cSeg()); 39 | } 40 | bool handlesSeg( DWORD iSect ) { 41 | WORD* pSegs = iSegs(); 42 | for ( WORD i = 0; i < cSeg(); ++i ) { 43 | if ( pSegs[ i ] == iSect ) { 44 | return true; 45 | } 46 | } 47 | return false; 48 | } 49 | 50 | SPB* file( DWORD i ) { 51 | return (SPB*)(pb() + baseSrcFile()[i]); 52 | } 53 | SE* segStartEnd( DWORD i ) { 54 | return (SE*)&file( i )->baseSrcLn[file(i)->cSeg]; 55 | } 56 | SE* segStartEnd( SPB* pspb ) { 57 | return (SE*)&pspb->baseSrcLn[pspb->cSeg]; 58 | } 59 | const char* fileName( DWORD i, DWORD* pcb ) { 60 | if ( pcb ) 61 | *pcb = static_cast(strlen((char*)(&segStartEnd( i )[file(i)->cSeg]))); 62 | return (char*)(&segStartEnd( i )[file(i)->cSeg]); 63 | } 64 | 65 | SPO* fileSeg( DWORD i, DWORD s ) { 66 | return (SPO*)(pb() + file(i)->baseSrcLn[s]); 67 | } 68 | SPO* fileSeg( SPB* pspb, DWORD s ) { 69 | return (SPO*)(pb() + pspb->baseSrcLn[s]); 70 | } 71 | USHORT* linenumbers( SPO* pspo ) { 72 | return (USHORT*)&pspo->offset[ pspo->cPair ]; 73 | } 74 | USHORT* linenumbers( DWORD i, DWORD s ) { 75 | return linenumbers( fileSeg( i, s ) ); 76 | } 77 | 78 | bool fInit( PB pb, CB cb ) { 79 | m_pb = pb; 80 | m_cb = cb; 81 | return true; 82 | } 83 | bool isEmpty() { 84 | return cb() == 0; 85 | } 86 | private: 87 | bool m_fDeletePb; 88 | PB pb() { return m_pb; } 89 | CB cb() { return m_cb; } 90 | PB m_pb; 91 | CB m_cb; 92 | }; 93 | 94 | #pragma warning(pop) 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /PDB/dbi/mli.h: -------------------------------------------------------------------------------- 1 | // module line info internal interfaces 2 | 3 | #ifndef __MLI_INCLUDED__ 4 | #define __MLI_INCLUDED__ 5 | 6 | #include "cvlines.h" 7 | 8 | struct SrcFile; 9 | typedef SrcFile* pSrcFile; 10 | struct SectInfo; 11 | typedef SectInfo* pSectInfo; 12 | struct Lines; 13 | typedef Lines *pLines; 14 | 15 | struct FileNameMapCmd 16 | { 17 | virtual const char* map( const char* szFileName ) = 0; 18 | }; 19 | 20 | struct MLI { 21 | MLI() : cfiles(0), pSrcFiles(0), csect(0), pSectInfos(0) { } 22 | 23 | BOOL AddLines(SZ_CONST szSrc, ISECT isect, OFF offCon, CB cbCon, OFF doff, 24 | LINE32 lineStart, IMAGE_LINENUMBER *plnumCoff, CB cb); 25 | pSrcFile AddSrcFile(SZ_CONST szfilename); 26 | BOOL Emit(Buffer& buffer); 27 | BOOL CollectSections(); 28 | BOOL Dump(const Buffer& buffer) const; 29 | #ifdef PDB_DEFUNCT_V8 30 | bool FindSecByAddr( ISECT isect, OFF off, OFF* poffMax ); 31 | bool Merge( MLI* pmliNew, FileNameMapCmd* pfnMapCmd ); // called on old MLI, passing new in 32 | #endif 33 | 34 | 35 | #ifndef __NO_MOD__ 36 | BOOL EmitFileInfo(Mod1* pmod1); 37 | #ifdef PDB_DEFUNCT_V8 38 | void EmitSecContribs(Mod1* pmod1); 39 | Mod1* pmod1; 40 | #endif 41 | #endif 42 | 43 | BOOL Construct(PB pbStart); 44 | BOOL ConvertSrcFileNames(); 45 | BOOL UpdateSectionList(); 46 | BOOL EmitWithSZName(Buffer& buffer); 47 | 48 | POOL_AlignNative pool; // native aligned pool 49 | 50 | USHORT cfiles; 51 | pSrcFile pSrcFiles; 52 | 53 | USHORT csect; 54 | pSectInfo pSectInfos; 55 | }; 56 | 57 | struct SrcFile { 58 | SrcFile(SZ_CONST szFile_) : pNext(0), cbName(szFile_ ? strlen(szFile_) : 0), 59 | size(0), szFile(szFile_), csect(0), pSectInfos(0) { } 60 | pSectInfo AddSectInfo(ISECT isect, OFF offMin, OFF offMax, POOL_AlignNative & pool); 61 | OFF Size(); 62 | BOOL Emit(Buffer& buffer, OFF off) const; 63 | #ifdef PDB_DEFUNCT_V8 64 | bool FindSecByAddr( ISECT isect, OFF off, OFF* poffMax ); 65 | bool MergeSrc( MLI* pmliNew, FileNameMapCmd* pfnMapCmd ); 66 | #endif 67 | OFF Construct(PB pbStart, OFF off, POOL_AlignNative& pool); 68 | BOOL ConvertFileName(POOL_AlignNative& pool); 69 | 70 | pSrcFile pNext; 71 | pSectInfo pSectInfos; 72 | SZ_CONST szFile; 73 | size_t cbName; 74 | OFF size; 75 | USHORT csect; 76 | }; 77 | 78 | struct SectInfo { 79 | SectInfo(ISECT isect_, OFF offMin_, OFF offMax_) 80 | : pNext(0), isect(isect_), cPair(0), pHead(0), ppTail(&pHead), size(0), offMin(offMin_), offMax(offMax_) { } 81 | BOOL AddLineNumbers(int linenumber, int offset, POOL_AlignNative& pool); 82 | BOOL Emit(Buffer& buffer) const; 83 | #ifdef PDB_DEFUNCT_V8 84 | bool MergeLines( pSectInfo pSectInfo, OFF offMin, OFF offMax, POOL_AlignNative& pool ); 85 | #endif 86 | OFF Construct(PB pbStart, OFF off, POOL_AlignNative &pool); 87 | 88 | pSectInfo pNext; 89 | USHORT isect; 90 | USHORT cPair; 91 | pLines pHead; 92 | pLines* ppTail; 93 | OFF size; 94 | OFF offMin; 95 | OFF offMax; 96 | }; 97 | 98 | struct Lines { 99 | Lines(OFF off_, ULONG line_) : pNext(0), off(off_), line(line_) { } 100 | 101 | pLines pNext; 102 | OFF off; 103 | ULONG line; 104 | }; 105 | 106 | #endif // !__MLI_INCLUDED__ 107 | -------------------------------------------------------------------------------- /PDB/dbi/util.h: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Inline utility functions. 3 | 4 | inline BOOL DBI1::packRefToGS (PSYM psym, IMOD imod, OFF off, OFF *poff) 5 | { 6 | assert(pgsiGS); 7 | assert(fWrite); 8 | return pgsiGS->packRefSym(psym, imod, off, poff); 9 | } 10 | 11 | inline BOOL DBI1::removeGlobalRefsForMod(IMOD imod) 12 | { 13 | assert(fWrite); 14 | assert(imod != 0); 15 | return pgsiGS->removeGlobalRefsForMod(imod); 16 | } 17 | 18 | inline BOOL DBI1::packRefToGSForMiniPDB(const char *sz, WORD imod, DWORD isectCoff, bool fLocal, bool fData, bool fUDT, bool fLabel, bool fConst) 19 | { 20 | assert(pgsiGS); 21 | assert(fWrite); 22 | assert(imod != 0); 23 | return pgsiGS->packRefForMiniPDB(sz, imod, isectCoff, fLocal, fData, fUDT, fLabel, fConst); 24 | } 25 | 26 | inline BOOL DBI1::packTokenRefToGS(PSYM psym, IMOD imod, OFF off, OFF *poff) 27 | { 28 | assert(pgsiGS); 29 | assert(fWrite); 30 | return pgsiGS->packTokenRefSym(psym, imod, off, poff); 31 | } 32 | 33 | inline BOOL DBI1::packSymToGS (PSYM psym, OFF *poff) 34 | { 35 | assert(pgsiGS); 36 | assert(fWrite); 37 | return pgsiGS->packSym(psym, poff); 38 | } 39 | 40 | inline BOOL DBI1::packSymToPS (PSYM psym) 41 | { 42 | assert(pgsiPS); 43 | assert(fWrite); 44 | return pgsiPS->packSym(psym); 45 | } 46 | 47 | inline BOOL DBI1::packSymSPD (PSYM psym, OFF * poff, SPD & spd) 48 | { 49 | assert(pgsiGS); 50 | assert(fWrite); 51 | return pgsiGS->packSymSPD(psym, poff, spd); 52 | } 53 | 54 | inline BOOL DBI1::decRefCntGS (OFF off) 55 | { 56 | assert(pgsiGS); 57 | assert(fWrite); 58 | return pgsiGS->decRefCnt(off); 59 | } 60 | 61 | 62 | inline BOOL DBI1::fAddSym(PSYM psymIn, OUT PSYM* psymOut) 63 | { 64 | assert(fWrite); 65 | // MTS_ASSERT(m_csForSymRecs); // don't need because of fWrite 66 | expect(fAlign(cbForSym(psymIn))); 67 | if (!bufSymRecs.Append((PB)psymIn, cbForSym(psymIn), (PB*)psymOut)) { 68 | ppdb1->setOOMError(); 69 | return FALSE; 70 | } 71 | return TRUE; 72 | } 73 | 74 | inline SZ DBI1::szObjFile(IMOD imod) 75 | { 76 | MTS_PROTECT(m_csForMods); 77 | dassert(pmodiForImod(imod)); 78 | SZ sz = pmodiForImod(imod)->szObjFile(); 79 | return fWrite ? szCopy(sz) : sz; 80 | } 81 | 82 | inline SZ DBI1::szModule(IMOD imod) 83 | { 84 | MTS_PROTECT(m_csForMods); 85 | dassert(pmodiForImod(imod)); 86 | SZ sz = pmodiForImod(imod)->szModule(); 87 | return fWrite ? szCopy(sz) : sz; 88 | } 89 | 90 | inline CB DBI1::cbSyms(IMOD imod) 91 | { 92 | MTS_PROTECT(m_csForMods); 93 | dassert(pmodiForImod(imod)); 94 | return pmodiForImod(imod)->cbSyms; 95 | } 96 | 97 | inline CB DBI1::cbLines(IMOD imod) 98 | { 99 | MTS_PROTECT(m_csForMods); 100 | dassert(pmodiForImod(imod)); 101 | return pmodiForImod(imod)->cbLines; 102 | } 103 | 104 | inline CB DBI1::cbC13Lines(IMOD imod) 105 | { 106 | MTS_PROTECT(m_csForMods); 107 | dassert(pmodiForImod(imod)); 108 | return pmodiForImod(imod)->cbC13Lines; 109 | } 110 | 111 | inline SN DBI1::Sn(IMOD imod) 112 | { 113 | MTS_PROTECT(m_csForMods); 114 | dassert(pmodiForImod(imod)); 115 | return pmodiForImod(imod)->sn; 116 | } 117 | 118 | inline BOOL Mod1::addFileInfo(IFILE ifile, SZ_CONST szFile) 119 | { 120 | return pdbi1->addFileInfo(imod, ifile, (SZ)szFile); 121 | } 122 | -------------------------------------------------------------------------------- /PDB/include/critsec.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "assert_.h" 4 | 5 | class CriticalSectionNop 6 | { 7 | public: 8 | CriticalSectionNop(DWORD = 0) {} 9 | ~CriticalSectionNop() {} 10 | BOOL Enter() { return TRUE; } 11 | void Leave() {} 12 | 13 | BOOL TryEnter() { return FALSE; } 14 | BOOL FLocked() { return FALSE; } 15 | BOOL FAcquired() { return TRUE; } 16 | }; 17 | 18 | 19 | 20 | class CriticalSectionNoLog 21 | { 22 | public: 23 | enum { 24 | scPreAlloc = 0x80000000, 25 | }; 26 | 27 | CriticalSectionNoLog(DWORD dwSpinCount = 0) { 28 | verify(Init(dwSpinCount)); 29 | } 30 | ~CriticalSectionNoLog() { 31 | DeleteCriticalSection(&m_sec); 32 | } 33 | BOOL Enter() { 34 | EnterCriticalSection(&m_sec); 35 | return TRUE; 36 | } 37 | void Leave() { 38 | LeaveCriticalSection(&m_sec); 39 | } 40 | 41 | BOOL TryEnter() { 42 | return TryEnterCriticalSection(&m_sec); 43 | } 44 | 45 | BOOL FLocked() { 46 | return m_sec.LockCount != 0; 47 | } 48 | 49 | BOOL FAcquired() { 50 | return m_sec.OwningThread == reinterpret_cast(static_cast(GetCurrentThreadId())); 51 | } 52 | 53 | protected: 54 | CRITICAL_SECTION m_sec; 55 | 56 | BOOL Init(DWORD dwSpinCount) { 57 | return InitializeCriticalSectionAndSpinCount(&m_sec, dwSpinCount); 58 | } 59 | }; 60 | 61 | #if 0 62 | class CriticalSectionWithLog : public CriticalSectionNoLog 63 | { 64 | public: 65 | enum { 66 | scPreAlloc = 0x80000000, 67 | }; 68 | 69 | CriticalSectionWithLog(DWORD dwSpinCount = 0) : CriticalSectionNoLog(dwSpinCount) { 70 | PDBLOG(LOG_CTOR); 71 | } 72 | ~CriticalSectionWithLog() { 73 | PDBLOG(LOG_DTOR); 74 | } 75 | BOOL Enter() { 76 | CriticalSectionNoLog::Enter(); 77 | PDBLOG(LOG_LOCK); 78 | return TRUE; 79 | } 80 | void Leave() { 81 | PDBLOG(LOG_RELEASE); 82 | CriticalSectionNoLog::Leave(); 83 | } 84 | 85 | BOOL TryEnter() { 86 | BOOL ret = CriticalSectionNoLog::TryEnter(); 87 | PDBLOG(ret? LOG_LOCK : LOG_LOCK_FAILED); 88 | return ret; 89 | } 90 | 91 | BOOL FLocked() { 92 | return CriticalSectionNoLog::FLocked(); 93 | } 94 | 95 | BOOL FAcquired() { 96 | return CriticalSectionNoLog::FAcquired(); 97 | } 98 | }; 99 | 100 | typedef CriticalSectionWithLog CriticalSection; 101 | 102 | #else 103 | 104 | typedef CriticalSectionNoLog CriticalSection; 105 | 106 | #endif 107 | 108 | template 109 | class AutoLockTemplate 110 | { 111 | public: 112 | AutoLockTemplate(T *pCS) { 113 | m_pCS = pCS; 114 | m_pCS->Enter(); 115 | } 116 | ~AutoLockTemplate() { 117 | m_pCS->Leave(); 118 | } 119 | 120 | protected: 121 | T *m_pCS; 122 | }; 123 | 124 | typedef AutoLockTemplate AutoLock; 125 | 126 | template 127 | class AutoLockWithConditionTemplate 128 | { 129 | public: 130 | AutoLockWithConditionTemplate(T *pCS, bool f) { 131 | m_f = f; 132 | 133 | if (f) { 134 | m_pCS = pCS; 135 | m_pCS->Enter(); 136 | } 137 | } 138 | ~AutoLockWithConditionTemplate() { 139 | if (m_f) { 140 | m_pCS->Leave(); 141 | } 142 | } 143 | 144 | protected: 145 | T *m_pCS; 146 | bool m_f; 147 | }; 148 | -------------------------------------------------------------------------------- /cvdump/auto.dep: -------------------------------------------------------------------------------- 1 | #-------------------------------------------------------------------- 2 | # AUTOMATICALLY GENERATED BY MKDEP 3 | # 4 | # To regenerate dependencies, check out this file and then type 5 | # nmake /f pdb.mak auto.dep 6 | #-------------------------------------------------------------------- 7 | 8 | $(ODIR)\cvdump.obj : \ 9 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 10 | $(LANGAPI)/include/vcver.h \ 11 | $(LANGAPI)/include/cvinfo.h \ 12 | $(LANGAPI)/include/cvconst.h output.h \ 13 | $(LANGAPI)/include/pdb.h cvtdef.h \ 14 | $(LANGAPI)/include/version.h 15 | 16 | $(ODIR)\dumppdb.obj : \ 17 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 18 | $(LANGAPI)/include/vcver.h \ 19 | $(LANGAPI)/include/cvinfo.h \ 20 | $(LANGAPI)/include/cvconst.h output.h \ 21 | $(LANGAPI)/include/pdb.h cvtdef.h \ 22 | ../../../include/utf8.h ../../../include/mdalign.h \ 23 | $(LANGAPI)/shared/safestk.h \ 24 | ../../../include/szst.h $(LANGAPI)/shared/map_t.h \ 25 | $(LANGAPI)/shared/array_t.h \ 26 | $(LANGAPI)/shared/shared.h \ 27 | $(LANGAPI)/shared/buffer_t.h \ 28 | $(LANGAPI)/include/vcbudefs.h \ 29 | $(LANGAPI)/shared/two.h \ 30 | $(LANGAPI)/shared/iset_t.h \ 31 | $(LANGAPI)/shared/enum_t.h \ 32 | $(LANGAPI)/shared/crc32.h 33 | 34 | $(ODIR)\dumpsym6.obj : \ 35 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 36 | $(LANGAPI)/include/vcver.h \ 37 | $(LANGAPI)/include/cvinfo.h \ 38 | $(LANGAPI)/include/cvconst.h output.h \ 39 | $(LANGAPI)/include/pdb.h cvtdef.h debsym.h \ 40 | symrec.h 41 | 42 | $(ODIR)\dumpsym7.obj : \ 43 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 44 | $(LANGAPI)/include/vcver.h \ 45 | $(LANGAPI)/include/cvinfo.h \ 46 | $(LANGAPI)/include/cvconst.h output.h \ 47 | $(LANGAPI)/include/pdb.h cvtdef.h \ 48 | ../../../include/utf8.h 49 | 50 | $(ODIR)\dumptyp6.obj : \ 51 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 52 | $(LANGAPI)/include/vcver.h \ 53 | $(LANGAPI)/include/cvinfo.h \ 54 | $(LANGAPI)/include/cvconst.h output.h \ 55 | $(LANGAPI)/include/pdb.h cvtdef.h 56 | 57 | $(ODIR)\dumptyp7.obj : \ 58 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 59 | $(LANGAPI)/include/vcver.h \ 60 | $(LANGAPI)/include/cvinfo.h \ 61 | $(LANGAPI)/include/cvconst.h output.h \ 62 | $(LANGAPI)/include/pdb.h cvtdef.h 63 | 64 | $(ODIR)\output.obj : \ 65 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 66 | $(LANGAPI)/include/vcver.h \ 67 | $(LANGAPI)/include/cvinfo.h \ 68 | $(LANGAPI)/include/cvconst.h output.h \ 69 | $(LANGAPI)/include/pdb.h cvtdef.h 70 | 71 | $(ODIR)\type6.obj : \ 72 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 73 | $(LANGAPI)/include/vcver.h \ 74 | $(LANGAPI)/include/cvinfo.h \ 75 | $(LANGAPI)/include/cvconst.h output.h \ 76 | $(LANGAPI)/include/pdb.h cvtdef.h debsym.h \ 77 | typeinfo.h 78 | 79 | $(ODIR)\type7.obj : \ 80 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 81 | $(LANGAPI)/include/vcver.h \ 82 | $(LANGAPI)/include/cvinfo.h \ 83 | $(LANGAPI)/include/cvconst.h output.h \ 84 | $(LANGAPI)/include/pdb.h cvtdef.h 85 | 86 | $(ODIR)\utils.obj : \ 87 | cvdump.h $(LANGAPI)/include/cvexefmt.h \ 88 | $(LANGAPI)/include/vcver.h \ 89 | $(LANGAPI)/include/cvinfo.h \ 90 | $(LANGAPI)/include/cvconst.h output.h \ 91 | $(LANGAPI)/include/pdb.h cvtdef.h 92 | 93 | $(ODIR)\cvdump.res : \ 94 | $(LANGAPI)/include/verstamp.h \ 95 | $(LANGAPI)/include/version.h \ 96 | $(LANGAPI)/include/bld_version.h \ 97 | $(LANGAPI)/include/common.ver 98 | 99 | -------------------------------------------------------------------------------- /PDB/include/pdbheap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if !defined(__HEAP_INCLUDED__) 3 | #define __HEAP_INCLUDED__ 4 | 5 | #if !defined(STRICT) 6 | #define STRICT 7 | #endif 8 | #if !defined(WIN32_LEAN_AND_MEAN) 9 | #define WIN32_LEAN_AND_MEAN 10 | #endif 11 | 12 | #include 13 | #include 14 | 15 | #ifdef HeapDump 16 | #include 17 | #endif 18 | 19 | #if defined(CRT_LEAKS) 20 | #include 21 | #include 22 | #endif 23 | 24 | #if defined(PDB_SERVER) || defined(MSOBJ_DLL) || defined(STANDALONE_HEAP) 25 | #define INLINE inline 26 | 27 | class Heap { 28 | Heap() 29 | { 30 | #if !defined(CRT_LEAKS) 31 | hheap = HeapCreate(0, 0, 0); 32 | assert(hheap); 33 | #else 34 | _CrtSetDbgFlag((_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); 35 | #endif 36 | } 37 | 38 | static Heap theHeap; 39 | 40 | public: 41 | ~Heap() 42 | { 43 | #if defined(CRT_LEAKS) 44 | _CrtDumpMemoryLeaks(); 45 | #else 46 | verify (HeapDestroy(hheap)); 47 | #endif 48 | } 49 | static HANDLE hheap; 50 | }; 51 | 52 | INLINE void* __cdecl operator new (size_t size) 53 | { 54 | #ifdef HeapDump 55 | printf("Allocation size = %d\n", size); 56 | #endif 57 | #if defined(CRT_LEAKS) 58 | return malloc(size); 59 | #else 60 | if (Heap::hheap == NULL) { 61 | return NULL; 62 | } 63 | 64 | void* pv = nullptr; 65 | 66 | do { 67 | pv = HeapAlloc(Heap::hheap, 0, size); 68 | } while(!pv && _callnewh(size)); 69 | 70 | return pv; 71 | #endif 72 | } 73 | 74 | _Ret_bytecap_(_Size) INLINE void* __cdecl operator new[] (size_t _Size) 75 | { 76 | #ifdef HeapDump 77 | printf("Allocation size = %d\n", _Size); 78 | #endif 79 | #if defined(CRT_LEAKS) 80 | return malloc(size); 81 | #else 82 | if (Heap::hheap == NULL) { 83 | return NULL; 84 | } 85 | 86 | void* pv = nullptr; 87 | 88 | do { 89 | pv = HeapAlloc(Heap::hheap, 0, _Size); 90 | } while(!pv && _callnewh(_Size)); 91 | 92 | return pv; 93 | #endif 94 | } 95 | 96 | INLINE void __cdecl operator delete (void *pv) 97 | { 98 | // operator delete allows NULL parameter... must not pass to OS 99 | if (!pv) 100 | return; 101 | #if defined(CRT_LEAKS) 102 | free(pv); 103 | #else 104 | if (Heap::hheap != NULL) { 105 | verify (HeapFree(Heap::hheap, 0, pv)); 106 | } 107 | #endif 108 | } 109 | 110 | INLINE void __cdecl operator delete[] (void *pv) 111 | { 112 | // operator delete allows NULL parameter... must not pass to OS 113 | if (!pv) 114 | return; 115 | #if defined(CRT_LEAKS) 116 | free(pv); 117 | #else 118 | if (Heap::hheap != NULL) { 119 | verify (HeapFree(Heap::hheap, 0, pv)); 120 | } 121 | #endif 122 | } 123 | 124 | #else // if not (defined(PDB_SERVER) || defined(MSOBJ_DLL) || defined(STANDALONE_HEAP)) 125 | 126 | void __cdecl operator delete(void *); 127 | void *__cdecl operator new(size_t); 128 | void * __cdecl operator new[](size_t cb); 129 | void __cdecl operator delete[](void * pv); 130 | 131 | #endif 132 | 133 | enum FILL { zeroed = 0 }; 134 | inline void* __cdecl operator new(size_t size, FILL) { 135 | BYTE* pb = new BYTE[size]; 136 | if (pb) 137 | memset(pb, 0, size); 138 | return pb; 139 | } 140 | 141 | inline void* __cdecl operator new[](size_t size, FILL) { 142 | BYTE* pb = new BYTE[size]; 143 | if (pb) 144 | memset(pb, 0, size); 145 | return pb; 146 | } 147 | 148 | 149 | #endif /* __HEAP_INCLUDED__ */ 150 | -------------------------------------------------------------------------------- /PDB/include/iset.h: -------------------------------------------------------------------------------- 1 | #ifndef __ISET_INCLUDED__ 2 | #define __ISET_INCLUDED__ 3 | 4 | #ifndef __ARRAY_INCLUDED__ 5 | #include "array.h" 6 | #endif 7 | 8 | #ifndef __TWO_INCLUDED__ 9 | #include "two.h" 10 | #endif 11 | 12 | namespace pdb_internal { 13 | 14 | class ISet { // dense set of small integers, implemented using a bit array 15 | public: 16 | ISet() { 17 | } 18 | ISet(unsigned size) 19 | : rgw(size ? words(size - 1) : 0) 20 | { 21 | rgw.fill(0); 22 | } 23 | ~ISet() { 24 | } 25 | void reset() { 26 | rgw.reset(); 27 | } 28 | BOOL __fastcall contains(unsigned i) const { 29 | return (i < size()) && (word(i) & bitmask(i)); 30 | } 31 | BOOL __fastcall add(unsigned i) { 32 | if (!ensureRoomFor(i)) 33 | return FALSE; 34 | word(i) |= bitmask(i); 35 | return TRUE; 36 | } 37 | unsigned __fastcall size() const { 38 | return rgw.size() << lgBPW; 39 | } 40 | BOOL __fastcall remove(unsigned i) { 41 | if (i < size()) 42 | word(i) &= ~bitmask(i); 43 | return TRUE; 44 | } 45 | unsigned cardinality() const { 46 | unsigned n = 0; 47 | for (unsigned i = 0; i < rgw.size(); i++) 48 | n += bitcount(rgw[i]); 49 | return n; 50 | } 51 | friend BOOL intersect(const ISet& s1, const ISet& s2, ISet& iset) { 52 | iset.reset(); 53 | if (iset.rgw.setSize(min(s1.rgw.size(), s2.rgw.size()))) { 54 | for (unsigned i = 0; i < iset.rgw.size(); i++) 55 | iset.rgw[i] = s1.rgw[i] & s2.rgw[i]; 56 | return TRUE; 57 | } 58 | else { 59 | return FALSE; 60 | } 61 | } 62 | BOOL save(Buffer* pbuf) { 63 | return rgw.save(pbuf); 64 | } 65 | #if 0 66 | BOOL reload(PB* ppb) { 67 | return rgw.reload(ppb); 68 | } 69 | #endif 70 | BOOL reload(PB* ppb, CB cbReloadBuf) { 71 | return rgw.reload(ppb, cbReloadBuf); 72 | } 73 | void swap(ISet& is) { 74 | rgw.swap(is.rgw); 75 | } 76 | CB cbSave() const { 77 | return rgw.cbSave(); 78 | } 79 | 80 | void clear() { 81 | rgw.clear(); 82 | } 83 | 84 | private: 85 | 86 | #if 0 // defined(_M_IA64) 87 | // we cannot do this because of the serialization/reload semantics 88 | // in Array<>. It saves/restores the number of base elements at the head 89 | // of the buffer and that has to be consistent across 32- and 64-bit 90 | // platforms for shareability of the PDB files. 91 | // 92 | typedef unsigned __int64 native_word; 93 | enum { BPW = 64, lgBPW = 6 }; 94 | #else 95 | typedef ulong native_word; 96 | enum { BPW = 32, lgBPW = 5 }; 97 | #endif 98 | Array rgw; 99 | 100 | 101 | ISet(const ISet&); 102 | unsigned __fastcall index(unsigned i) const { 103 | return i >> lgBPW; 104 | } 105 | unsigned __fastcall words(unsigned i) const { 106 | return index(i) + 1; 107 | } 108 | unsigned __fastcall bit(unsigned i) const { 109 | return i & (BPW-1); 110 | } 111 | native_word & __fastcall word(unsigned i) { 112 | return rgw[index(i)]; 113 | } 114 | const native_word & __fastcall word(unsigned i) const { 115 | return rgw[index(i)]; 116 | } 117 | native_word bitmask(unsigned i) const { 118 | return 1 << bit(i); 119 | } 120 | BOOL ensureRoomFor(unsigned i) { 121 | const native_word zero = 0; 122 | while (words(i) > (unsigned)rgw.size()) 123 | if (!rgw.append(zero)) 124 | return FALSE; 125 | return TRUE; 126 | } 127 | }; 128 | 129 | } // namespace pdb_internal 130 | 131 | #endif // !__ISET_INCLUDED__ 132 | -------------------------------------------------------------------------------- /PDB/include/pdbcommon.h: -------------------------------------------------------------------------------- 1 | #include "pdb.h" 2 | #include "pdblog.h" 3 | #include 4 | 5 | class PDBCommon : public PDB { 6 | public: 7 | enum { 8 | impvVC2 = PDBImpvVC2, 9 | impvVC4 = PDBImpvVC4, 10 | impvVC50 = PDBImpvVC50, 11 | impvVC98 = PDBImpvVC98, 12 | impvVC70Dep = PDBImpvVC70Dep, // deprecated 7.0 verison 13 | impvVC70 = PDBImpvVC70, 14 | impvVC110 = PDBImpvVC110, 15 | impvVC140 = PDBImpvVC140, 16 | 17 | // TODO -- need to update this to impvVC140 when we are ready 18 | impv = impvVC70, 19 | }; 20 | 21 | enum { 22 | featNoTypeMerge = 0x4D544F4E, // "NOTM" 23 | featMinimalDbgInfo = 0x494E494D, // "MINI" 24 | }; 25 | 26 | static BOOL ExportValidateInterface(INTV intv_) 27 | { 28 | // Current interface is assumed to be backward 29 | // compatible with alternate interface intvAlt; 30 | // so we validate both 31 | return 32 | intv == intv_ || 33 | intvVC80 == intv_ || 34 | intvVC70 == intv_ || 35 | intvVC70Dep == intv_ 36 | ; 37 | } 38 | 39 | static BOOL ExportValidateImplementation(IMPV impv_) 40 | { 41 | // We could make the implementation versions 42 | // downword compatible, but like in case of 43 | // VC70, it might not always be possible 44 | return (PDBImpv == impv_); 45 | } 46 | 47 | static INTV QueryInterfaceVersionStatic() 48 | { 49 | return intv; 50 | } 51 | 52 | static IMPV QueryImplementationVersionStatic() 53 | { 54 | return impv; 55 | } 56 | static BOOL 57 | OpenValidate5( 58 | const wchar_t *wszExecutable, 59 | const wchar_t *wszSearchPath, 60 | void *pvClient, 61 | PfnPDBQueryCallback pfnQueryCallback, 62 | OUT EC *pec, 63 | __out_ecount_opt(cchErrMax) wchar_t *wszError, 64 | size_t cchErrMax, 65 | OUT PDB **pppdb); 66 | 67 | static BOOL 68 | Open2W( 69 | const wchar_t *wszPDB, 70 | const char *szMode, 71 | OUT EC *pec, 72 | _Out_opt_cap_(cchErrMax) OUT wchar_t *wszError, 73 | size_t cchErrMax, 74 | OUT PDB **pppdb); 75 | 76 | BOOL ValidateInterface() 77 | { 78 | return ExportValidateInterface(intv); 79 | } 80 | BOOL CopyTo(const char *szDst, DWORD dwCopyFilter, DWORD dwReserved); 81 | BOOL CopyToW(const wchar_t *wszDst, DWORD dwCopyFilter, DWORD dwReserved); 82 | BOOL OpenStream(SZ_CONST sz, OUT Stream **ppstream); 83 | BOOL OpenStreamW(const wchar_t * szStream, OUT Stream** ppstream); 84 | EC QueryLastError(_Out_opt_cap_(cbErrMax) char szError[cbErrMax]); 85 | 86 | #ifdef PDB_TYPESERVER 87 | // used by DBI1::fOpenPdb 88 | wchar_t *getExeNameW() { return (wszExeName[0] != L'\0') ? wszExeName : NULL; } 89 | 90 | // used by PDBCommon::OpenValidate5() 91 | void setExeNameW(const wchar_t *wsz) { 92 | if (wsz != NULL) { 93 | wcsncpy_s(wszExeName, _countof(wszExeName), wsz, _TRUNCATE); 94 | } 95 | else { 96 | wszExeName[0] = L'\0'; 97 | } 98 | } 99 | protected: 100 | PDBCommon() { 101 | wszExeName[0] = L'\0'; 102 | } 103 | 104 | private: 105 | wchar_t wszExeName[_MAX_PATH]; 106 | #endif 107 | }; 108 | 109 | inline void setError(OUT EC *pec, EC ec, __out_ecount_opt(cchErrMax) wchar_t *wszError, size_t cchErrMax, const wchar_t *wsz) 110 | { 111 | PDBLOG_FUNC(); 112 | if (pec != NULL) { 113 | *pec = ec; 114 | } 115 | 116 | if (wszError != NULL && cchErrMax > 0) { 117 | wcsncpy_s(wszError, cchErrMax, wsz, _TRUNCATE); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /PDB/include/two.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __TWO_INCLUDED__ 3 | #define __TWO_INCLUDED__ 4 | 5 | // return largest i such that 2^i <= u 6 | inline int lg(unsigned u) { 7 | debug(unsigned u0 = u;) 8 | precondition(u > 0); 9 | 10 | int n = 0; 11 | #define t(j) if (u >= (1 << (j))) { u >>= (j); n += (j); } 12 | t(16); t(8); t(4); t(2); t(1); 13 | #undef t 14 | 15 | postcondition(u == 1); 16 | postcondition((1U << n) <= u0); 17 | postcondition(n == 31 || u0 < (1U << (n+1))); 18 | return n; 19 | } 20 | 21 | // return smallest n such that n = 2^i and u <= n 22 | inline unsigned nextPowerOfTwo(unsigned u) { 23 | precondition(u > 0); 24 | 25 | int lgu = lg(u); 26 | int lguRoundedUp = lg(u + (1 << lgu) - 1); 27 | unsigned n = 1 << lguRoundedUp; 28 | 29 | postcondition(n/2 < u && u <= n); 30 | return n; 31 | // examples: 32 | // u lgu lgRU n 33 | // 1 0 0 1 34 | // 4 2 2 4 35 | // 5 2 3 8 36 | // 7 2 3 8 37 | // 8 3 3 8 38 | } 39 | 40 | inline unsigned nextMultiple(unsigned u, unsigned m) { 41 | return (u + m - 1) / m * m; 42 | } 43 | 44 | inline int nextMultiple(int i, unsigned m) { 45 | return (i + m - 1) / m * m; 46 | } 47 | 48 | // Return number of set bits in the word. 49 | #if defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM64) 50 | 51 | const unsigned __int64 _5_64 = 0x5555555555555555ui64; 52 | const unsigned __int64 _3_64 = 0x3333333333333333ui64; 53 | const unsigned __int64 _F1_64 = 0x0f0f0f0f0f0f0f0fui64; 54 | const unsigned __int64 _F2_64 = 0x00ff00ff00ff00ffui64; 55 | const unsigned __int64 _F4_64 = 0x0000ffff0000ffffui64; 56 | const unsigned __int64 _F8_64 = 0x00000000ffffffffui64; 57 | 58 | inline unsigned bitcount64( unsigned __int64 w ) { 59 | // In-place adder tree: perform 32 1-bit adds, 16 2-bit adds, 8 4-bit adds, 60 | // 4 8-bit adds, 2 16-bit adds, and 1 32-bit add. 61 | // From Dr. Dobb's Nov. 2000 letters, from Phil Bagwell, on reducing 62 | // the cost by removing some of the masks that can be "forgotten" due 63 | // to the max # of bits set (64) that will fit in a byte. 64 | // 65 | w -= (w >> 1) & _5_64; 66 | w = ((w >> 2) & _3_64) + (w & _3_64); 67 | w = ((w >> 4) & _F1_64) + (w & _F1_64); 68 | w += w >> 8; 69 | w += w >> 16; 70 | w += w >> 32; 71 | return unsigned(w & 0xff); 72 | 73 | #if 0 74 | w = ((w >> 1) & _5_64) + (w & _5_64); 75 | w = ((w >> 2) & _3_64) + (w & _3_64); 76 | w = ((w >> 4) & _F1_64) + (w & _F1_64); 77 | w = ((w >> 8) & _F2_64) + (w & _F2_64); 78 | w = ((w >>16) & _F4_64) + (w & _F4_64); 79 | w = ((w >>32) & _F8_64) + (w & _F8_64); 80 | return unsigned(w); 81 | #endif 82 | } 83 | 84 | #endif 85 | 86 | const unsigned int _5_32 = 0x55555555; 87 | const unsigned int _3_32 = 0x33333333; 88 | const unsigned int _F1_32 = 0x0f0f0f0f; 89 | const unsigned int _F2_32 = 0x00ff00ff; 90 | const unsigned int _F4_32 = 0x0000ffff; 91 | 92 | inline unsigned bitcount(unsigned u) { 93 | // In-place adder tree: perform 16 1-bit adds, 8 2-bit adds, 4 4-bit adds, 94 | // 2 8=bit adds, and 1 16-bit add. 95 | // From Dr. Dobb's Nov. 2000 letters, from Phil Bagwell, on reducing 96 | // the cost by removing some of the masks that can be "forgotten" due 97 | // to the max # of bits set (32) that will fit in a byte. 98 | // 99 | u -= (u >> 1) & _5_32; 100 | u = ((u >> 2) & _3_32) + (u & _3_32); 101 | u = ((u >> 4) & _F1_32) + (u & _F1_32); 102 | u += u >> 8; 103 | u += u >> 16; 104 | return u & 0xff; 105 | 106 | #if 0 107 | u = ((u >> 1) & _5_32) + (u & _5_32); 108 | u = ((u >> 2) & _3_32) + (u & _3_32); 109 | u = ((u >> 4) & _F1_32) + (u & _F1_32); 110 | u = ((u >> 8) & _F2_32) + (u & _F2_32); 111 | u = ((u >>16) & _F4_32) + (u & _F4_32); 112 | return u; 113 | #endif 114 | } 115 | 116 | #endif // !__TWO_INCLUDED__ 117 | -------------------------------------------------------------------------------- /langapi/shared/crc32.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CRC32__ 3 | #define __CRC32__ 4 | 5 | 6 | namespace PDBCRC32 { 7 | 8 | inline DWORD SigForPbCb(PB pb, size_t cb, SIG sig) { 9 | 10 | static const DWORD rgcrc[] = { 11 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 12 | 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 13 | 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 14 | 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 15 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 16 | 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 17 | 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 18 | 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 19 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 20 | 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 21 | 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 22 | 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 23 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 24 | 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 25 | 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 26 | 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 27 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 28 | 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 29 | 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 30 | 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 31 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 32 | 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 33 | 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 34 | 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 35 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 36 | 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 37 | 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 38 | 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 39 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 40 | 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 41 | 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 42 | 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 43 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 44 | 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 45 | 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 46 | 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 47 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 48 | 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 49 | 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 50 | 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 51 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 52 | 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 53 | 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 54 | }; 55 | 56 | while (cb-- > 0) 57 | { 58 | sig = (sig >> 8) ^ rgcrc[(sig & 0xff) ^ *pb++]; 59 | } 60 | return sig; 61 | } 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /cvdump/cvdump.nativeproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | cvdump 14 | PROGRAM 15 | stdcall 16 | false 17 | 3 18 | false 19 | ..\common;$(LangAPI)\include;$(LangAPI)\shared;..\..\..\include;$(UserIncludes) 20 | console 21 | Enabled 22 | true 23 | true 24 | false 25 | wmain 26 | $(ClAdditionalOptions) /GF /DPDB_LIBRARY 27 | $(ClAdditionalOptions) /D_DEFINE_FAILASSERTION_ 28 | 29 | 30 | 31 | 32 | 33 | $(ClDefines);DBG=0;NDEBUG 34 | Full 35 | Speed 36 | 37 | 38 | 39 | 40 | $(ClDefines);DBG=1;_DEBUG 41 | Disabled 42 | true 43 | true 44 | true 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | $(VCToolsRootPath)\PDB\lic\lic.nativeproj 68 | 69 | 70 | $(VCToolsRootPath)\PDB\objfile\lic\lic.nativeproj 71 | 72 | 73 | $(VCToolsRootPath)\PDB\dia2\lic\lic.nativeproj 74 | 75 | 76 | 77 | 78 | 79 | $(RCAdditionalOptions) -r -i$(LangAPI)/include 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /PDB/include/misc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __MISC_INCLUDED__ 3 | #define __MISC_INCLUDED__ 4 | 5 | #include "pdbtypdefs.h" 6 | 7 | #if (defined(_M_ALPHA) || defined(_M_IA64) || defined(_M_AMD64)) 8 | // for fAlign 9 | #include "cvinfo.h" // for LF_PAD0 used in mdalign.h 10 | #include "mdalign.h" 11 | #endif 12 | 13 | 14 | template struct Hasher { 15 | static inline LHASH lhashPbCb(PB pb, size_t cb, ULONG ulMod) { 16 | ULONG ulHash = 0; 17 | 18 | // hash leading dwords using Duff's Device 19 | size_t cl = cb >> 2; 20 | PUL pul = PUL(pb); 21 | PUL pulMac = pul + cl; 22 | size_t dcul = cl & 7; 23 | 24 | switch (dcul) { 25 | do { 26 | dcul = 8; 27 | ulHash ^= pul[7]; 28 | case 7: ulHash ^= pul[6]; 29 | case 6: ulHash ^= pul[5]; 30 | case 5: ulHash ^= pul[4]; 31 | case 4: ulHash ^= pul[3]; 32 | case 3: ulHash ^= pul[2]; 33 | case 2: ulHash ^= pul[1]; 34 | case 1: ulHash ^= pul[0]; 35 | case 0: ; 36 | } while ((pul += dcul) < pulMac); 37 | } 38 | 39 | pb = PB(pul); 40 | 41 | // hash possible odd word 42 | if (cb & 2) { 43 | ulHash ^= *(PUS)pb; 44 | pb = PB(PUS(pb) + 1); 45 | } 46 | 47 | // hash possible odd byte 48 | if (cb & 1) { 49 | ulHash ^= *(pb++); 50 | } 51 | 52 | const ULONG toLowerMask = 0x20202020; 53 | ulHash |= toLowerMask; 54 | ulHash ^= (ulHash >> 11); 55 | 56 | return (ulHash ^ (ulHash >> 16)) % ulMod; 57 | } 58 | static inline HASH hashPbCb(PB pb, size_t cb, ULONG ulMod) { 59 | return HASH(lhashPbCb(pb, cb, ulMod)); 60 | } 61 | }; 62 | 63 | // Hash the buffer. Text in the buffer is hashed in a case insensitive way. 64 | // 65 | // On alignment sensitive machines, unaligned buffers are handed over to 66 | // Hasher::hashPbCb();. 67 | // 68 | inline HASH HashPbCb(PB pb, size_t cb, ULONG ulMod) 69 | { 70 | #if (defined(_M_ALPHA) || defined(_M_IA64) || defined(_M_AMD64)) 71 | if (!fAlign(pb)) 72 | return Hasher::hashPbCb(pb, cb, ulMod); 73 | #endif 74 | return Hasher::hashPbCb(pb, cb, ulMod); 75 | } 76 | 77 | inline LHASH LHashPbCb(PB pb, size_t cb, ULONG ulMod) 78 | { 79 | #if (defined(_M_ALPHA) || defined(_M_IA64) || defined(_M_AMD64)) 80 | if (!fAlign(pb)) 81 | return Hasher::lhashPbCb(pb, cb, ulMod); 82 | #endif 83 | return Hasher::lhashPbCb(pb, cb, ulMod); 84 | } 85 | 86 | inline HASH __fastcall hashSz(_In_z_ SZ sz) { 87 | return HashPbCb(PB(sz), strlen(sz), (ULONG)-1); 88 | } 89 | 90 | // copied from the FE 91 | template class HasherV2 { 92 | private: 93 | static inline ULONG HashULONG(ULONG u) 94 | { 95 | // From Numerical Recipes in C, second edition, pg 284. 96 | return u * 1664525L + 1013904223L; 97 | } 98 | public: 99 | static inline LHASH lhashPbCb(PB pb, size_t cb, ULONG ulMod) { 100 | ULONG hash = 0xb170a1bf; 101 | 102 | // Hash 4 characters/one ULONG at a time. 103 | while (cb >= 4) { 104 | cb -= 4; 105 | hash += *(PUL)pb; 106 | hash += (hash << 10); 107 | hash ^= (hash >> 6); 108 | pb += 4; 109 | } 110 | 111 | // Hash the rest 1 by 1. 112 | while (cb > 0) { 113 | cb -= 1; 114 | hash += *(unsigned char*)pb; 115 | hash += (hash << 10); 116 | hash ^= (hash >> 6); 117 | pb += 1; 118 | } 119 | 120 | return HashULONG(hash) % ulMod; 121 | } 122 | }; 123 | 124 | inline LHASH LHashPbCbV2(PB pb, size_t cb, ULONG ulMod) 125 | { 126 | #if (defined(_M_ALPHA) || defined(_M_IA64) || defined(_M_AMD64)) 127 | if (!fAlign(pb)) 128 | return HasherV2::lhashPbCb(pb, cb, ulMod); 129 | #endif 130 | return HasherV2::lhashPbCb(pb, cb, ulMod); 131 | } 132 | 133 | #endif // !__MISC_INCLUDED__ 134 | -------------------------------------------------------------------------------- /cvdump/makefile.mak: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Microsoft (R) Debugging Information Dumper 3 | # 4 | # Copyright (c) Microsoft Corporation. All rights reserved. 5 | # 6 | # File Comments: 7 | # 8 | ######################################################################## 9 | 10 | CINC = /I$(LANGAPI)\include /I$(LANGAPI)\shared /I..\..\..\include 11 | CFLAGS = /c /errorReport:send /FC /Fd$(ODIR)\cvdump.pdb /GF /Gy /Gz $(CINC) /W3 /Zc:wchar_t- /Zi $(EXTRA_CFLAGS) 12 | LFLAGS = /debug /dynamicbase /functionpadmin /largeaddressaware /map 13 | 14 | MSPDB = mspdb.lib 15 | 16 | !if "$(CPU)" == "" 17 | CPU = $(PROCESSOR_ARCHITECTURE) 18 | !endif 19 | 20 | !ifdef RELEASE 21 | ODIR = $(CPU)\release 22 | CFLAGS = $(CFLAGS) /DDBG=0 /DNDEBUG /MT /O2 23 | LFLAGS = $(LFLAGS) /debugtype:cv,fixup /incremental:no /opt:icf /opt:ref /release 24 | CRTLIB = msvcrt.lib 25 | !else 26 | ODIR = $(CPU)\debug 27 | CFLAGS = $(CFLAGS) /DDBG=1 /D_DEBUG /MTd /Od /RTCc /RTCs /RTCu 28 | CRTLIB = msvcrtd.lib 29 | !endif 30 | 31 | !if "$(CPU)" == "x86" 32 | CFLAGS = $(CFLAGS) /hotpatch 33 | LFLAGS = $(LFLAGS) /nxcompat /safeseh 34 | !endif 35 | 36 | .c{$(ODIR)}.obj:: 37 | $(CC) $(CFLAGS) /Fo$(ODIR)\ $< 38 | 39 | {../../../misc}.c{$(ODIR)}.obj:: 40 | $(CC) $(CFLAGS) /Fo$(ODIR)\ $< 41 | 42 | .cpp{$(ODIR)}.obj:: 43 | $(CC) $(CFLAGS) /Fo$(ODIR)\ $< 44 | 45 | .rc{$(ODIR)}.res: 46 | if exist $@ del $@ 47 | rc -r -i$(LANGAPI)/include -Fo$@ $< 48 | 49 | OBJS = \ 50 | $(ODIR)\cvdump.obj \ 51 | $(ODIR)\dumppdb.obj \ 52 | $(ODIR)\dumpsym6.obj \ 53 | $(ODIR)\dumpsym7.obj \ 54 | $(ODIR)\dumptyp6.obj \ 55 | $(ODIR)\dumptyp7.obj \ 56 | $(ODIR)\output.obj \ 57 | $(ODIR)\type6.obj \ 58 | $(ODIR)\type7.obj \ 59 | $(ODIR)\utils.obj \ 60 | $(ODIR)\utf8.obj \ 61 | $(ODIR)\cvdump.res 62 | 63 | 64 | all: $(ODIR)\cvdump.exe 65 | 66 | 67 | $(ODIR): 68 | @-mkdir $(ODIR) 69 | 70 | 71 | $(ODIR)\cvdump.exe: $(ODIR) $(OBJS) 72 | link /errorreport:send @<<$(ODIR)\link.rsp 73 | $(LFLAGS) 74 | -out:$@ 75 | $(OBJS: = ^ 76 | ) 77 | $(MSPDB) 78 | ole32.lib 79 | oleaut32.lib 80 | <nul $(STDERR_NULL) 87 | copy << auto.dep 88 | #-------------------------------------------------------------------- 89 | # AUTOMATICALLY GENERATED BY MKDEP 90 | # 91 | # To regenerate dependencies, check out this file and then type 92 | # nmake /f pdb.mak auto.dep 93 | #-------------------------------------------------------------------- 94 | 95 | << 96 | mkdep -v $(CINC) -P $$(ODIR)\ -s .obj -n *.cpp > auto.tmp 97 | mkdep -v $(CINC) -P $$(ODIR)\ -s .res -n *.rc >> auto.tmp 98 | # note well that the sed command below needs a TAB in the first 99 | # substitution (TABs become spaces) otherwise, the subsequent 100 | # substitution does not work correctly. 101 | sed > auto.dep 103 | @-del auto.tmp 104 | !if exist(auto.dep) 105 | !include "auto.dep" 106 | !else 107 | cvdump.h: $(LANGAPI)\include\cvexefmt.h $(LANGAPI)\include\cvinfo.h output.h $(LANGAPI)\include\pdb.h cvtdef.h 108 | 109 | $(ODIR)\cvdump.obj: cvdump.h $(LANGAPI)\include\version.h 110 | 111 | $(ODIR)\dumpoledb.obj: cvdump.h $(LANGAPI)\include\dbgoledb.h $(LANGAPI)\include\dbgoledbdecl.h 112 | 113 | $(ODIR)\dumppdb.obj: cvdump.h ..\..\..\include\szst.h ..\..\..\include\utf8.h 114 | 115 | $(ODIR)\dumpsym6.obj: cvdump.h debsym.h symrec.h 116 | 117 | $(ODIR)\dumpsym7.obj: cvdump.h ..\..\..\include\utf8.h 118 | 119 | $(ODIR)\dumptyp6.obj: cvdump.h 120 | 121 | $(ODIR)\dumptyp7.obj: cvdump.h 122 | 123 | $(ODIR)\output.obj: cvdump.h 124 | 125 | $(ODIR)\type6.obj: cvdump.h debsym.h typeinfo.h 126 | 127 | $(ODIR)\type7.obj: cvdump.h 128 | 129 | $(ODIR)\utils.obj: cvdump.h 130 | !endif 131 | -------------------------------------------------------------------------------- /PDB/include/pool.h: -------------------------------------------------------------------------------- 1 | // Pool memory allocator 2 | #pragma once 3 | #ifndef __POOL_INCLUDED__ 4 | #define __POOL_INCLUDED__ 5 | 6 | #include "pdbimpl.h" 7 | 8 | #include "mdalign.h" 9 | 10 | #include "SysPage.h" 11 | 12 | #pragma warning(disable:4200) 13 | 14 | // A 'hard' typedef for use as the placement new operand to avoid conflicts 15 | // with the C++14 sized deallocator. 16 | enum class blkpool_t : size_t {}; 17 | 18 | struct BLK { // block in an allocation pool 19 | size_t cbFree; 20 | BYTE* pFree; 21 | BLK* pNext; 22 | BYTE buf[]; 23 | 24 | BLK(size_t cb) { 25 | cbFree = cb; 26 | pFree = buf; 27 | pNext = 0; 28 | } 29 | void* alloc(size_t cb) { 30 | assert(cbAlign(cb) == cb); 31 | // The only place that calls BLK::alloc() already aligns memory 32 | // properly, so don't bother doing it again. 33 | // cb = cbAlign(cb); // Round up for alignment 34 | if (cb <= cbFree) { 35 | cbFree -= cb; 36 | BYTE* p = pFree; 37 | pFree += cb; 38 | return p; 39 | } 40 | return 0; 41 | } 42 | void flush() { 43 | cbFree = 0; 44 | } 45 | CB cb() { 46 | return CB(pFree - buf); // REVIEW:WIN64 CAST 47 | } 48 | }; 49 | 50 | inline size_t cbRoundUp(size_t cb, size_t cbMult) { 51 | return (cb + cbMult-1) & ~(cbMult-1); 52 | } 53 | 54 | inline void* __cdecl operator new(size_t size, blkpool_t cb) { 55 | return new char[size + static_cast(cb)]; 56 | } 57 | 58 | template 59 | struct POOL { // allocation pool 60 | BLK* pHead; 61 | BLK* pTail; 62 | size_t cbTotal; 63 | 64 | POOL() { 65 | assert(bitcount(cbAlignVal) == 1); 66 | init(); 67 | } 68 | ~POOL() { 69 | uninit(); 70 | } 71 | size_t cbAlign(size_t cb) { 72 | return ((cb + cbAlignVal - 1)) & ~(cbAlignVal - 1); 73 | } 74 | void* alloc(size_t cbT) { 75 | size_t cb = cbRoundUp(cbT, cbAlignVal); // Round up for alignment 76 | if (cb < cbT) { 77 | // overflow 78 | return NULL; 79 | } 80 | void* p = pTail->alloc(cb); 81 | if (!p) { 82 | size_t cbBlkAlloc = cbRoundUp(cb + cbSysPage, cbSysPage); 83 | if (cbBlkAlloc < cb) { 84 | return NULL; 85 | } 86 | if (pTail->pNext = new (static_cast(cbBlkAlloc)) BLK(cbBlkAlloc)) { 87 | pTail = pTail->pNext; 88 | p = pTail->alloc(cb); 89 | } 90 | } 91 | if (p) { 92 | cbTotal += cb; 93 | } 94 | return p; 95 | } 96 | void discard(CB cb) { 97 | cbTotal -= cbRoundUp(cb, cbAlignVal); 98 | } 99 | void blkFlush() { 100 | dassert(pTail); 101 | pTail->flush(); 102 | } 103 | size_t cb() { 104 | return cbTotal; 105 | } 106 | 107 | void xferPool(POOL& poolSrc) { 108 | // we need to uninit us first and copy the data from the 109 | // source pool, then init the source pool w/o an uninit() 110 | uninit(); 111 | 112 | pHead = poolSrc.pHead; 113 | pTail = poolSrc.pTail; 114 | cbTotal = poolSrc.cbTotal; 115 | 116 | poolSrc.init(); 117 | } 118 | 119 | private: 120 | void init() { 121 | pHead = new (static_cast(0)) BLK(static_cast(0)); 122 | pTail = pHead; 123 | cbTotal = 0; 124 | } 125 | void uninit() { 126 | BLK* pNext; 127 | for (BLK* pblk = pHead; pblk; pblk = pNext) { 128 | pNext = pblk->pNext; 129 | delete pblk; 130 | } 131 | } 132 | 133 | POOL(const POOL&) { 134 | assert(0); 135 | } // error to copy a pool 136 | }; 137 | 138 | typedef POOL<4> POOL_Align4; // for things we have to align to 4. 139 | typedef POOL POOL_AlignNative; // for things we align natively (ptrs). 140 | 141 | template 142 | inline void * __cdecl operator new(size_t size, POOL & pool) { 143 | return pool.alloc(size); 144 | } 145 | template 146 | inline void * __cdecl operator new[](size_t size, POOL & pool) { 147 | return pool.alloc(size); 148 | } 149 | 150 | #endif // !__POOL_INCLUDED__ 151 | -------------------------------------------------------------------------------- /PDB/include/srcimpl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "map.h" 4 | #include "szcanon.h" 5 | #include 6 | #include "srccommon.h" 7 | 8 | struct SHO : public SrcHeaderOut { 9 | SHO() { 10 | memset(this, 0, sizeof(SHO)); 11 | } 12 | 13 | SHO(NameMap * pnamemap, const SrcHeaderW & srchdr) { 14 | CreateWithUnicodeNames( pnamemap, srchdr ); 15 | } 16 | 17 | private: 18 | void CreateWithUnicodeNames(NameMap *pnamemap, const SrcHeaderW& srchdr) 19 | { 20 | memset(this, 0, sizeof(SHO)); 21 | 22 | cb = sizeof SrcHeaderOut; 23 | ver = srcverOne; 24 | sig = srchdr.sig; 25 | cbSource = srchdr.cbSource; 26 | srccompress = srchdr.srccompress; 27 | grFlags = srchdr.grFlags; 28 | 29 | const wchar_t *wsz = srchdr.szNames; 30 | pnamemap->getNiW(wsz, &niFile); 31 | wsz += wcslen(wsz) + 1; 32 | pnamemap->getNiW(wsz, &niObj); 33 | wsz += wcslen(wsz) + 1; 34 | 35 | wchar_t wszT[_MAX_PATH * 2]; 36 | assert(wcslen(wsz) < _countof(wszT)); 37 | wcsncpy_s (wszT, _countof(wszT), wsz, _TRUNCATE); 38 | 39 | CCanonFile::SzCanonFilename(wszT); 40 | pnamemap->getNiW(wszT, &niVirt); 41 | 42 | assert(ptrdiff_t(srchdr.cb) >= (PB(wsz) + wcslen(wsz)*sizeof(*wsz) + 1) - PB(&srchdr)); 43 | } 44 | 45 | public: 46 | bool 47 | operator==(const SHO & sho) const { 48 | return memcmp(this, &sho, sizeof(SHO)) == 0; 49 | } 50 | 51 | 52 | }; 53 | 54 | #ifdef PDB_MT 55 | typedef Map MapNiSrcHdr; 56 | typedef EnumMap EnumMapNiSrcHdr; 57 | #else 58 | typedef Map MapNiSrcHdr; 59 | typedef EnumMap EnumMapNiSrcHdr; 60 | #endif 61 | 62 | class SrcImpl : public SrcCommon { 63 | 64 | friend class PDB1; 65 | 66 | public: 67 | // implement the public Src interface 68 | 69 | virtual bool 70 | Close(); 71 | 72 | virtual bool 73 | Remove(IN SZ_CONST szFile); 74 | 75 | virtual bool 76 | GetData(IN PCSrcHeaderOut pcsrcheader, OUT void * pvData) const; 77 | 78 | virtual bool 79 | GetEnum(OUT EnumSrc ** ppenum) const; 80 | 81 | virtual bool 82 | GetHeaderBlock(SrcHeaderBlock &shb) const; 83 | 84 | virtual bool RemoveW(__in_z wchar_t *wcsFile); 85 | virtual bool QueryByNameW(__in_z wchar_t *wcsFile, OUT PSrcHeaderOut psrcheaderOut) const; 86 | virtual bool AddW(PCSrcHeaderW psrcheader, const void * pvData); 87 | 88 | // private members/types 89 | private: 90 | static const wchar_t c_szSrcHeader[]; 91 | static const wchar_t c_szSrcFilesPrefix[12]; 92 | 93 | enum { 94 | // NB: depdendence on values of c_szSrcFilesPrefix and the name 95 | // the compiler uses to tag the injected code! 96 | cchInjPrefix = sizeof("*:12345"), 97 | cchStreamNameMax = _MAX_PATH + _countof(c_szSrcFilesPrefix) + cchInjPrefix, 98 | }; 99 | 100 | typedef SrcHeaderBlock Hdr; 101 | 102 | // private methods 103 | private: 104 | #ifdef PDB_MT 105 | SrcImpl(PDB * ppdb, BOOL (*pfnClose)(PDB *)); 106 | #else 107 | SrcImpl(PDB * ppdb); 108 | #endif 109 | ~SrcImpl(); 110 | 111 | bool 112 | internalInit(bool fWrite); 113 | 114 | bool 115 | internalClose(); 116 | 117 | static bool 118 | fBuildStreamName(WSZ_CONST szFile, _Out_opt_z_cap_(cchStreamNameMax) wchar_t szStrmName[cchStreamNameMax]); 119 | 120 | // private members 121 | private: 122 | bool m_fInit; 123 | bool m_fWritten; 124 | PDB * m_ppdb; 125 | Stream * m_pstrmHdr; // also used as a flag for fWrite. 126 | NameMap * m_pnamemap; 127 | MapNiSrcHdr m_mpnisrchdr; 128 | Hdr m_hdr; 129 | #ifdef PDB_MT 130 | mutable CriticalSection m_cs; 131 | BOOL (*m_pfnClose)(PDB *); 132 | #endif 133 | }; 134 | 135 | 136 | class EnumSrcImpl : public EnumSrc { 137 | 138 | friend SrcImpl; 139 | 140 | public: 141 | virtual void release(); 142 | virtual void reset(); 143 | virtual BOOL next(); 144 | virtual void get(OUT PCSrcHeaderOut * ppcsrcheader); 145 | 146 | private: 147 | EnumSrcImpl(const MapNiSrcHdr &); 148 | 149 | EnumMapNiSrcHdr m_enum; 150 | #ifdef PDB_MT 151 | // store one private copy for MT 152 | SHO m_sho; 153 | #endif 154 | }; 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # microsoft-pdb 2 | This repo contains information from Microsoft about the PDB (Program Database) 3 | [Symbol File](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363368(v=vs.85).aspx) format. 4 | 5 | [WILL NOT currently build. There is a cvdump.exe till the repo is completed. pdb.h is in the langapi folder] 6 | 7 | The intent here is to provide code that will show all the binary level formats and simple tools that can use the pdb. 8 | 9 | Simply put... We will make best efforts to roll this foward with the new compilers and tools that we ship every release. We will continue to innovate and change binary API's and ABI's for all the Microsoft platforms and we will try to include the community by keeping this PDB repo in synch with the latest retail products (compilers, linkers, debuggers) just shipped. 10 | 11 | By publishing this source code, we are by passing the publically documented API we provided for only reading a PDB - that was DIA 12 | https://msdn.microsoft.com/en-us/library/x93ctkx8.aspx 13 | 14 | With this information we are now building the information for other compilers (and tools) to efficiently write a PDB. 15 | 16 | The PDB format has not been officially documented, presenting a challenge for other compilers and 17 | toolsets (such as Clang/LLVM) that want to work with Windows or the Visual Studio debugger. We want 18 | to help the Open Source compilers to get onto the Windows platform. 19 | 20 | The majority of content on this repo is presented as actual source files from the VC++ compiler 21 | toolset. Source code is the ultimate documentation :-) We hope that you will find it helpful. If you 22 | find that you need other information to successfully complete your project, please enter an 23 | [Issue](https://github.com/microsoft/microsoft-pdb/issues) letting us know what information you need. 24 | 25 | ## Start here 26 | The file pdb.h (on in langapi), provides the API surface for mscorpdb.dll, which we ship with every compiler and toolset. 27 | 28 | Important points: 29 | - Mscorpdb.dll is what our linker and compiler uses to create PDB files. 30 | - Mscorpdb.dll implements the “stream” abstractions. 31 | 32 | Also there is another file that we ship that should allow you to determine whether you have correctly produced an “empty” PDB which contains the minimal encoding to let another tool open and correctly parse that “empty” file. “Empty” really meaning a properl 33 | y formated file where the sections contain the correct information to indicate zero records or symbols are present 34 | A tool that I thought we also ship that would easily verify your “empty” PDB file is dia2dump.exe 35 | 36 | So in summary, by using the externally defined function entry points in pdb.h you can call into mscorpdb.dll. 37 | 38 | ## What is a PDB 39 | PDBs are files with multiple ‘streams’ of information in them. You can almost assume each stream as an individual file, except that storing them as individual files is wasteful and inconvenient, hence this multiple streams approach. PDB streams are not NTFS streams though. They can be implemented as NTFS streams, but since they are to be made available on Win9X as well, they use a home brewed implementation. The implementation allows a primitive form of two-phase commit protocol. The writers of PDB files write what ever they want to in PDBs, but it won’t be committed until an explicit commit is issued. This allows the clients quite a bit of flexibility - say for example, a compiler can keep on writing information, and just not commit it, if it encounters an error in users’ source code. 40 | 41 | Each stream is identified with a unique stream number and an optional name. In a nutshell here’s how the PDB looks like - 42 | 43 | | Stream No. | Contents | Short Description 44 | |-----------------|---------------------------------|------------------- 45 | | 1 | Pdb (header) | Version information, and information to connect this PDB to the EXE 46 | | 2 | Tpi (Type manager) | All the types used in the executable. 47 | | 3 | Dbi (Debug information) | Holds section contributions, and list of ‘Mods’ 48 | | 4 | NameMap | Holds a hashed string table 49 | | 4 - ( n+ 4) | n Mod’s (Module information) | Each Mod stream holds symbols and line numbers for one compiland 50 | | n + 4 | Global symbol hash | An index that allows searching in global symbols by name 51 | | n + 5 | Public symbol hash | An index that allows searching in public symbols by addresses 52 | | n + 6 | Symbol records | Actual symbol records of global and public symbols 53 | | n + 7 | Type hash | Hash used by the TPI stream. 54 | -------------------------------------------------------------------------------- /PDB/include/indbuf.h: -------------------------------------------------------------------------------- 1 | // 2 | // DO NOT USE THIS FILE IN THE PDB CODE. 3 | // 4 | #pragma once 5 | #if 0 6 | #ifndef __INDBUF_INCLUDED__ 7 | #define __INDBUF_INCLUDED__ 8 | 9 | #include "buffer.h" 10 | 11 | // 12 | // IndexBuf 13 | // Maintain a raw buffer of non-fixed sized elements and an index 14 | // to those elements. 15 | // 16 | class IndexBuf { 17 | public: 18 | IndexBuf( BOOL fGrow ) // == true if this will grow by appending 19 | : m_index( 0, 0, fGrow ), m_raw( 0, 0, fGrow ), m_size( 0 ) 20 | {} 21 | PB At( UINT i ); // return pointer to the ith element 22 | UINT Length(); // number of elements in this buffer 23 | BOOL Add( PB pb ); // add a new elem at this point (in buffer) 24 | BOOL Reserve( CB cbIn, OUT PB* ppbOut = 0 ); 25 | void Clear(); 26 | CB RawSize() { return m_raw.Size(); } 27 | PB RawStart() { return m_raw.Start(); } 28 | Buffer& RawBuffer() { return m_raw; } // for new operation 29 | virtual BOOL scan() = 0; // subclass provides index building 30 | protected: 31 | // the index buffer contains a list of CB[0..m_size]. 32 | // m_raw.Start()+m_index[i] is the location of the ith element 33 | Buffer m_index; // index to elements stored in raw bytes 34 | Buffer m_raw; // raw bytes in buffer 35 | UINT m_size; // number of elements 36 | }; 37 | 38 | inline UINT IndexBuf::Length() 39 | { 40 | assert( m_index.Size()/sizeof(CB) == m_size ); 41 | return m_size; 42 | } 43 | 44 | inline PB IndexBuf::At( UINT i ) 45 | { 46 | assert( i < Length() ); 47 | return m_raw.Start()+((CB*)m_index.Start())[i]; 48 | } 49 | 50 | inline BOOL IndexBuf::Add( PB pb ) 51 | { 52 | assert( pb >= m_raw.Start() && pb < m_raw.End() ); 53 | assert( fAlign( pb ) ); 54 | CB cb = CB(pb-m_raw.Start()); // REVIEW:WIN64 CAST 55 | BOOL b = m_index.Append( (PB)&cb, sizeof(cb) ); 56 | if ( b ) m_size++; 57 | return b; 58 | } 59 | 60 | inline BOOL IndexBuf::Reserve( CB cbIn, OUT PB* ppbOut ) 61 | { 62 | return m_raw.Reserve( cbIn, ppbOut ); 63 | } 64 | 65 | inline void IndexBuf::Clear() 66 | { 67 | m_raw.Clear(); 68 | m_index.Clear(); 69 | m_size = 0; 70 | } 71 | 72 | template 73 | class InBuf: public IndexBuf 74 | { 75 | public: 76 | BOOL append( T* pT ) { expect(fAlign(pT)); return Add( (PB)pT ); } 77 | T* operator[]( UINT i ) { return (T*)At( i ); } 78 | BOOL scan() { // find all T*'s in the list 79 | m_size = 0; 80 | m_index.Truncate(0); 81 | for( PB pb = m_raw.Start(); pb < m_raw.End(); pb = ((T*)pb)->pbEnd() ) { 82 | expect(fAlign(pb)); 83 | if ( !Add( pb ) ) return FALSE; 84 | assert( At( m_size-1 ) == pb ); 85 | } 86 | return TRUE; 87 | } 88 | InBuf( BOOL fGrow=TRUE ) : IndexBuf( fGrow ) {} 89 | }; 90 | 91 | template 92 | class ArrayBuf: public Buffer 93 | { 94 | public: 95 | size_t length() const { return Size() / sizeof(T); } 96 | T* At( size_t i ) const 97 | { 98 | assert( i <= length() ); // allow 1 past end of buffer 99 | return (T*)Start()+i; 100 | } 101 | const T& operator[]( size_t i ) const 102 | { 103 | return *At(i); 104 | } 105 | T& operator[]( size_t i ) 106 | { 107 | return *At(i); 108 | } 109 | BOOL append( const T& t ) 110 | { 111 | return Append( (PB)&t, sizeof(T) ); 112 | } 113 | }; 114 | 115 | template 116 | class ArrayPtrBuf: public ArrayBuf 117 | { 118 | public: 119 | void destroy() // only works if T is a pointer type 120 | { 121 | for ( size_t i = 0; i < length(); ++i ) 122 | delete *At(i); 123 | Reset(); 124 | } 125 | 126 | typedef T** _Nodeptr; 127 | 128 | class iterator // based on STL forward iterator 129 | { 130 | public: 131 | iterator() 132 | {} 133 | iterator(_Nodeptr _P) 134 | : _Ptr(_P) {} 135 | T& operator*() const 136 | {return **_Ptr; } 137 | T* operator->() const 138 | {return (&**this); } 139 | iterator& operator++() 140 | {++_Ptr; 141 | return (*this); } 142 | iterator operator++(int) 143 | {iterator _Tmp = *this; 144 | ++*this; 145 | return (_Tmp); } 146 | bool operator==(const iterator& _X) const 147 | {return (_Ptr == _X._Ptr); } 148 | bool operator!=(const iterator& _X) const 149 | {return (!(*this == _X)); } 150 | _Nodeptr _Mynode() const 151 | {return (_Ptr); } 152 | private: 153 | _Nodeptr _Ptr; 154 | }; 155 | 156 | iterator begin() { return iterator( At(0) ); } 157 | iterator end() { return iterator( At( length() ) ); } 158 | iterator begin() const { return iterator( At(0) ); } 159 | iterator end() const { return At( length() ); } 160 | bool empty() { return begin() == end(); } 161 | }; 162 | 163 | #endif 164 | #endif 165 | -------------------------------------------------------------------------------- /cvdump/cvtdef.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | // these typedefs define the pointers to the cvinfo.h structures 12 | 13 | typedef TYPTYPE *TYPPTR; 14 | typedef lfEasy *plfEasy; 15 | typedef lfModifier *plfModifier; 16 | typedef lfPointer *plfPointer; 17 | typedef lfArray *plfArray; 18 | typedef lfClass *plfClass; 19 | typedef lfStructure *plfStructure; 20 | typedef lfUnion *plfUnion; 21 | typedef lfEnum *plfEnum; 22 | typedef lfProc *plfProc; 23 | typedef lfMFunc *plfMFunc; 24 | typedef lfVTShape *plfVTShape; 25 | typedef lfVftable *plfVftable; 26 | typedef lfCobol0 *plfCobol0; 27 | typedef lfCobol1 *plfCobol1; 28 | typedef lfBArray *plfBArray; 29 | typedef lfLabel *plfLabel; 30 | typedef lfSkip *plfSkip; 31 | typedef lfArgList *plfArgList; 32 | typedef lfDerived *plfDerived; 33 | typedef lfPreComp *plfPreComp; 34 | typedef lfAlias *plfAlias; 35 | typedef lfEndPreComp *plfEndPreComp; 36 | typedef lfDefArg *plfDefArg; 37 | typedef lfList *plfList; 38 | typedef lfFieldList *plfFieldList; 39 | typedef mlMethod *pmlMethod; 40 | typedef lfMethodList *plfMethodList; 41 | typedef lfBitfield *plfBitfield; 42 | typedef lfChar *plfChar; 43 | typedef lfShort *plfShort; 44 | typedef lfUShort *plfUShort; 45 | typedef lfLong *plfLong; 46 | typedef lfULong *plfULong; 47 | typedef lfReal32 *plfReal32; 48 | typedef lfReal64 *plfReal64; 49 | typedef lfReal80 *plfReal80; 50 | typedef lfReal128 *plfReal128; 51 | typedef lfIndex *plfIndex; 52 | typedef lfBClass *plfBClass; 53 | typedef lfVBClass *plfVBClass; 54 | typedef lfFriendCls *plfFriendCls; 55 | typedef lfFriendFcn *plfFriendFcn; 56 | typedef lfMember *plfMember; 57 | typedef lfSTMember *plfSTMember; 58 | typedef lfVFuncTab *plfVFuncTab; 59 | typedef lfMethod *plfMethod; 60 | typedef lfOneMethod *plfOneMethod; 61 | typedef lfEnumerate *plfEnumerate; 62 | typedef lfNestType *plfNestType; 63 | typedef lfTypeServer *plfTypeServer; 64 | typedef SYMTYPE *SYMPTR; 65 | typedef CFLAGSYM *CFLAGPTR; 66 | typedef CONSTSYM *CONSTPTR; 67 | typedef OBJNAMESYM *OBJNAMEPTR; 68 | typedef REGSYM *REGPTR; 69 | typedef UDTSYM *UDTPTR; 70 | typedef SEARCHSYM *SEARCHPTR; 71 | typedef BLOCKSYM16 *BLOCKPTR16; 72 | typedef DATASYM16 *DATAPTR16; 73 | typedef PUBSYM16 *PUBPTR16; 74 | typedef LABELSYM16 *LABELPTR16; 75 | typedef BPRELSYM16 *BPRELPTR16; 76 | typedef PROCSYM16 *PROCPTR16; 77 | typedef THUNKSYM16 *THUNKPTR16; 78 | typedef CEXMSYM16 *CEXMPTR16; 79 | typedef WITHSYM16 *WITHPTR16; 80 | typedef BLOCKSYM32 *BLOCKPTR32; 81 | typedef DATASYM32 *DATAPTR32; 82 | typedef PUBSYM32 *PUBPTR32; 83 | typedef LABELSYM32 *LABELPTR32; 84 | typedef BPRELSYM32 *BPRELPTR32; 85 | typedef PROCSYM32 *PROCPTR32; 86 | typedef THUNKSYM32 *THUNKPTR32; 87 | typedef WITHSYM32 *WITHPTR32; 88 | typedef BLOCKSYM *BLOCKPTR; 89 | typedef PROCSYM *PROCPTR; 90 | typedef THUNKSYM *THUNKPTR; 91 | typedef WITHSYM *WITHPTR; 92 | 93 | typedef lfModifier_16t *plfModifier_16t; 94 | typedef lfPointer_16t *plfPointer_16t; 95 | typedef lfArray_16t *plfArray_16t; 96 | typedef lfClass_16t *plfClass_16t; 97 | typedef lfStructure_16t *plfStructure_16t; 98 | typedef lfUnion_16t *plfUnion_16t; 99 | typedef lfEnum_16t *plfEnum_16t; 100 | typedef lfProc_16t *plfProc_16t; 101 | typedef lfMFunc_16t *plfMFunc_16t; 102 | typedef lfCobol0_16t *plfCobol0_16t; 103 | typedef lfBArray_16t *plfBArray_16t; 104 | typedef lfSkip_16t *plfSkip_16t; 105 | typedef lfArgList_16t *plfArgList_16t; 106 | typedef lfDerived_16t *plfDerived_16t; 107 | typedef lfPreComp_16t *plfPreComp_16t; 108 | typedef lfDefArg_16t *plfDefArg_16t; 109 | typedef lfFieldList_16t *plfFieldList_16t; 110 | typedef mlMethod_16t *pmlMethod_16t; 111 | typedef lfMethodList_16t*plfMethodList_16t; 112 | typedef lfBitfield_16t *plfBitfield_16t; 113 | typedef lfIndex_16t *plfIndex_16t; 114 | typedef lfBClass_16t *plfBClass_16t; 115 | typedef lfVBClass_16t *plfVBClass_16t; 116 | typedef lfFriendCls_16t *plfFriendCls_16t; 117 | typedef lfFriendFcn_16t *plfFriendFcn_16t; 118 | typedef lfMember_16t *plfMember_16t; 119 | typedef lfSTMember_16t *plfSTMember_16t; 120 | typedef lfVFuncTab_16t *plfVFuncTab_16t; 121 | typedef lfMethod_16t *plfMethod_16t; 122 | typedef lfOneMethod_16t *plfOneMethod_16t; 123 | typedef lfNestType_16t *plfNestType_16t; 124 | typedef lfNestTypeEx *plfNestTypeEx; 125 | typedef lfMemberModify *plfMemberModify; 126 | typedef CONSTSYM_16t *CONSTPTR_16t; 127 | typedef REGSYM_16t *REGPTR_16t; 128 | typedef UDTSYM_16t *UDTPTR_16t; 129 | typedef DATASYM32_16t *DATAPTR32_16t; 130 | typedef PUBSYM32_16t *PUBPTR32_16t; 131 | typedef BPRELSYM32_16t *BPRELPTR32_16t; 132 | typedef PROCSYM32_16t *PROCPTR32_16t; 133 | -------------------------------------------------------------------------------- /PDB/include/mapfile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if !defined verify 3 | #ifdef _DEBUG 4 | #define verify(x) assert((x)) 5 | #else 6 | #define verify(x) (x) 7 | #endif 8 | #endif // verify 9 | 10 | #if defined(MAPPEDMEM_LOGGING) 11 | 12 | #define LogMsg(szFmt, arg1, arg2) \ 13 | printf("Function: %s: " szFmt, __FUNCTION__, arg1, arg2), fflush(stdout) 14 | 15 | #endif 16 | 17 | 18 | 19 | 20 | // define MAPPED_IO to get mapped file I/O in makefile 21 | 22 | class MemoryMappedFile 23 | { 24 | enum 25 | { 26 | cbMinFileSize = 0x4000, // Minimum file size is 16KB 27 | cbDefFileSize = 0x400000, // default file size 4MB 28 | cbGrowth = 0x400000, // increase file size by 4MB 29 | }; 30 | 31 | protected: 32 | 33 | #ifdef _DEBUG 34 | wchar_t m_wszFileName[260]; 35 | unsigned __int64 ComputeChecksum(); 36 | #endif 37 | union { void *m_pv; BYTE *m_pb; }; 38 | 39 | HANDLE m_hFile; 40 | ULARGE_INTEGER m_ulLen; // user's know of this length 41 | ULARGE_INTEGER m_ulPos; 42 | BOOL m_fWrite; 43 | BOOL m_fRemote; // Is this a remote file? 44 | 45 | BOOL fInvalidate() 46 | { 47 | if (m_pb != NULL && UnmapViewOfFile(m_pv)) { 48 | #if defined(MAPPEDMEM_LOGGING) 49 | LogMsg("UnmapViewOfFile failed, error = 0x%08x, base = 0x%p\n", GetLastError(), m_pv); 50 | #endif 51 | m_pv = NULL; 52 | } 53 | 54 | if (m_hFile != INVALID_HANDLE_VALUE && CloseHandle(m_hFile)) 55 | m_hFile = INVALID_HANDLE_VALUE; 56 | 57 | return (m_pv == NULL && m_hFile == INVALID_HANDLE_VALUE); 58 | } 59 | 60 | BOOL SetFileSize(ULARGE_INTEGER ulNewSize); 61 | BOOL fMapFileToMemory(); 62 | 63 | public : 64 | 65 | // Standard construction / destruction 66 | MemoryMappedFile() { } 67 | 68 | ~MemoryMappedFile(); 69 | 70 | BOOL Init(const _TCHAR *szFilename, BOOL fWrite, BOOL& fCreated); 71 | BOOL Detach(HANDLE *pHandle); // Detach from the m_hFile 72 | 73 | bool operator !() 74 | { 75 | return (m_hFile == INVALID_HANDLE_VALUE) || (m_pb == NULL); 76 | } 77 | 78 | ULONG Read(void *buffer, ULONG count) 79 | { 80 | ULONG read = 0; 81 | 82 | if (m_pv == NULL) { 83 | assert( FALSE ); 84 | return read; 85 | } 86 | 87 | // make sure we are not reading beyond EOF 88 | if (m_ulPos.QuadPart < m_ulLen.QuadPart) { 89 | 90 | read = __min(count, ULONG(m_ulLen.QuadPart - m_ulPos.QuadPart)); 91 | assert(m_ulPos.QuadPart + read <= m_ulLen.QuadPart); 92 | 93 | DWORD dwExcept; 94 | DWORD cmsSleep = 0; 95 | 96 | do { 97 | __try { 98 | dwExcept = 0; 99 | memmove(buffer, m_pb + m_ulPos.QuadPart, read); 100 | } 101 | __except ( dwExcept = GetExceptionCode(), 102 | (dwExcept == EXCEPTION_ACCESS_VIOLATION || 103 | dwExcept == EXCEPTION_IN_PAGE_ERROR) ) 104 | { 105 | ::Sleep(cmsSleep); 106 | cmsSleep += 200; 107 | } 108 | } while (dwExcept == EXCEPTION_IN_PAGE_ERROR && cmsSleep <= 5000); 109 | 110 | if (dwExcept) { 111 | assert(FALSE); 112 | return 0; 113 | } 114 | 115 | m_ulPos.QuadPart += read; 116 | } 117 | 118 | return read; 119 | } 120 | 121 | ULONG Write(const void *buffer, ULONG count) 122 | { 123 | assert(m_ulPos.QuadPart + count <= m_ulLen.QuadPart); // Assert for now, later we can extend the file 124 | 125 | if (!m_fWrite) 126 | return 0; 127 | 128 | if (m_pv == NULL) { 129 | assert( FALSE ); 130 | return 0; 131 | } 132 | 133 | DWORD dwExcept; 134 | DWORD cmsSleep = 0; 135 | 136 | do { 137 | __try { 138 | dwExcept = 0; 139 | memmove(m_pb + m_ulPos.QuadPart, buffer, count); 140 | } 141 | __except ( dwExcept = GetExceptionCode(), 142 | (dwExcept == EXCEPTION_ACCESS_VIOLATION || 143 | dwExcept == EXCEPTION_IN_PAGE_ERROR) ) 144 | { 145 | ::Sleep(cmsSleep); 146 | cmsSleep += 200; 147 | } 148 | } while (dwExcept == EXCEPTION_IN_PAGE_ERROR && cmsSleep <= 5000); 149 | 150 | if (dwExcept) { 151 | assert(FALSE); 152 | return 0; 153 | } 154 | 155 | m_ulPos.QuadPart += count; 156 | return count; 157 | } 158 | 159 | ULARGE_INTEGER Seek(LARGE_INTEGER offset, DWORD dwOrigin) 160 | { 161 | ULARGE_INTEGER whence; 162 | 163 | switch(dwOrigin) 164 | { 165 | case SEEK_SET: whence.QuadPart = 0; break; 166 | case SEEK_CUR: whence = m_ulPos; break; 167 | case SEEK_END: whence = m_ulLen; break; 168 | default: 169 | whence.QuadPart = -1; 170 | return whence; 171 | } 172 | 173 | whence.QuadPart += offset.QuadPart; 174 | 175 | // Seek beyond the EOF?? 176 | if ((whence.QuadPart >= m_ulLen.QuadPart) && !fSetSize(whence)) { 177 | whence.QuadPart = -1; 178 | return whence; 179 | } 180 | 181 | return (m_ulPos = whence); 182 | } 183 | 184 | BOOL fSetSize(ULARGE_INTEGER ulNewSize); 185 | BOOL fFlush(); 186 | }; 187 | -------------------------------------------------------------------------------- /PDB/include/msf.h: -------------------------------------------------------------------------------- 1 | // msf.h: see "The Multistream File API" for more information 2 | 3 | #ifndef __MSF_INCLUDED__ 4 | #define __MSF_INCLUDED__ 5 | 6 | #ifndef TRUE 7 | 8 | #define TRUE 1 9 | #define FALSE 0 10 | typedef int BOOL; 11 | 12 | #if !defined(verify) 13 | #ifdef _DEBUG 14 | #define verify(x) assert(x) 15 | #else 16 | #define verify(x) (x) 17 | #endif 18 | #endif 19 | 20 | #endif 21 | 22 | // compile time assert 23 | #if !defined(cassert) 24 | #define cassert(x) extern char dummyAssert[ (x) ] 25 | #endif 26 | 27 | #if !defined(pure) 28 | #define pure =0 29 | #endif 30 | 31 | #define MsfInterface struct 32 | 33 | MsfInterface MSF; 34 | 35 | // type of callback arg to MSFGetRawBytes 36 | typedef BOOL (__cdecl *PFNfReadMSFRawBytes)(const void *, long); 37 | 38 | typedef void * PV; 39 | typedef unsigned short SN; // stream number 40 | typedef unsigned long UNSN; // unified stream number 41 | typedef long CB; // size (count of bytes) 42 | typedef long OFF; // offset 43 | 44 | #define cbNil ((long)-1) 45 | #define snNil ((SN)-1) 46 | #define unsnNil UNSN(-1) 47 | 48 | typedef long MSF_EC; 49 | enum MSFErrorCodes { 50 | MSF_EC_OK, 51 | MSF_EC_OUT_OF_MEMORY, 52 | MSF_EC_NOT_FOUND, 53 | MSF_EC_FILE_SYSTEM, 54 | MSF_EC_FORMAT, 55 | MSF_EC_ACCESS_DENIED, 56 | MSF_EC_CORRUPT, 57 | MSF_EC_MAX 58 | }; 59 | 60 | enum { 61 | MSFBaseIntv = 19960101, 62 | MSFOleIntv = 19960307 63 | }; 64 | 65 | typedef unsigned long MSF_FLAG; 66 | enum { 67 | msffCreate = 0x0001, 68 | msffOle = 0x0002, 69 | msffAccess = 0x0004, 70 | }; 71 | 72 | #ifdef __cplusplus 73 | 74 | const CB cbPgDef = 0x0400; 75 | const CB cbMsfPageDefault = cbPgDef; 76 | 77 | struct IStream; 78 | 79 | // define the abstract MSF class 80 | // 81 | MsfInterface MSF { // multistream file 82 | 83 | enum { intvBase = MSFBaseIntv, intvOle = MSFOleIntv }; 84 | enum CompressionType { 85 | ctFileSystem, 86 | ctInternal, 87 | }; 88 | 89 | static MSF* Open( 90 | const wchar_t *wszFilename, 91 | BOOL fWrite, 92 | MSF_EC* pec, 93 | CB cbPage=cbPgDef, 94 | MSF_FLAG msff = msffCreate|msffOle 95 | ); 96 | 97 | static MSF* Open( 98 | IStream* pIStream, 99 | BOOL fWrite, 100 | MSF_EC *pec, 101 | CB cbPage=cbPgDef 102 | ); 103 | 104 | virtual long QueryInterfaceVersion() pure; 105 | virtual long QueryImplementationVersion() pure; 106 | 107 | virtual CB GetCbPage() pure; 108 | virtual CB GetCbStream(SN sn) pure; 109 | virtual SN GetFreeSn() pure; 110 | virtual BOOL ReadStream(SN sn, PV pvBuf, CB cbBuf) pure; 111 | virtual BOOL ReadStream(SN sn, OFF off, PV pvBuf, CB* pcbBuf) pure; 112 | virtual BOOL WriteStream(SN sn, OFF off, PV pvBuf, CB cbBuf) pure; 113 | virtual BOOL ReplaceStream(SN sn, PV pvBuf, CB cbBuf) pure; 114 | virtual BOOL AppendStream(SN sn, PV pvBuf, CB cbBuf) pure; 115 | virtual BOOL TruncateStream(SN sn, CB cb) pure; 116 | virtual BOOL DeleteStream(SN sn) pure; 117 | virtual BOOL Commit(MSF_EC *pec = NULL) pure; 118 | virtual BOOL Close() pure; 119 | virtual BOOL GetRawBytes(PFNfReadMSFRawBytes fSnarfRawBytes) pure; 120 | virtual UNSN SnMax() const pure; 121 | virtual BOOL FSupportsSharing() const pure; 122 | virtual BOOL CloseStream(UNSN sn) pure; 123 | virtual bool FIsBigMsf() const pure; 124 | virtual bool FSetCompression(CompressionType ct, bool fCompress) const pure; 125 | virtual bool FGetCompression(CompressionType ct, bool & fCompress) const pure; 126 | virtual BOOL NonTransactionalEraseStream(SN sn) pure; 127 | 128 | #ifdef PDB_MT 129 | private: 130 | typedef unsigned __int64 QWORD; 131 | 132 | typedef struct { 133 | QWORD qwVolumeSerialNumber; 134 | BYTE rgb[16]; 135 | } FILE_ID; 136 | 137 | struct MSF_REC { 138 | MSF * pmsf; 139 | BOOL fWrite; 140 | DWORD refcount; 141 | bool operator==(MSF_REC& b) { 142 | return (pmsf == b.pmsf) && (fWrite == b.fWrite); 143 | } 144 | }; 145 | 146 | static BOOL GetFileID(const wchar_t * wszFilename, FILE_ID * id); 147 | static BOOL GetFileID(HANDLE hfile, FILE_ID * id); 148 | static Map > s_mpOpenedMSF; 149 | static CriticalSection s_csForMSFOpen; 150 | 151 | friend class MSF_HB; 152 | #endif 153 | }; 154 | 155 | #endif 156 | 157 | #if defined(__cplusplus) 158 | extern "C" { 159 | #endif 160 | 161 | // MSFOpenW -- open MSF; return MSF* or NULL if error. 162 | // MSFOpenExW -- open MSF with specific page size; return MSF* or NULL if error. 163 | // MSFGetCbPage -- return page size 164 | // MSFGetCbStream -- return size of stream or -1 if stream does not exist 165 | // MSFReadStream -- read stream into pvBuf; return TRUE if successful 166 | // MSFClose -- close MSF; return TRUE if successful 167 | 168 | #ifdef MSF_IMP 169 | #ifdef PDB_LIBRARY 170 | #define MSF_EXPORT2 171 | #else 172 | #define MSF_EXPORT2 __declspec(dllexport) 173 | #endif 174 | #else 175 | #define MSF_EXPORT2 __declspec(dllimport) 176 | #endif 177 | 178 | #define MSF_EXPORT 179 | 180 | MSF_EXPORT2 MSF * __cdecl MSFOpenW(const wchar_t *wszFilename, BOOL fWrite, MSF_EC* pec); 181 | MSF_EXPORT2 MSF * __cdecl MSFOpenExW(const wchar_t *wszFilename, BOOL fWrite, MSF_EC* pec, CB cbPage); 182 | 183 | #if defined(__cplusplus) 184 | }; 185 | #endif 186 | 187 | #endif // __MSF_INCLUDED__ 188 | -------------------------------------------------------------------------------- /PDB/include/xheap.h: -------------------------------------------------------------------------------- 1 | // xheap.h -- exogenous heap manager -- manages a heap in some other medium 2 | // 3 | // Most commonly used to manage a heap in a stream on disk, 4 | // without itself requiring disk I/O. 5 | 6 | #pragma once 7 | #ifndef __XHEAP_INCLUDED__ 8 | #define __XHEAP_INCLUDED__ 9 | 10 | #ifndef __ARRAY_INCLUDED__ 11 | #include "array.h" 12 | #endif 13 | 14 | class XHeap { 15 | struct Regn { 16 | OFF off; 17 | unsigned size; 18 | Regn() { 19 | off = 0; 20 | size = 0; 21 | } 22 | Regn(OFF off_, unsigned size_) { 23 | off = off_; 24 | size = size_; 25 | } 26 | OFF end() { 27 | return off + size; 28 | } 29 | static BOOL hasSize(Regn* pregn, void* pvSize) { 30 | return pregn->size >= *(unsigned*)pvSize; 31 | } 32 | static BOOL isOffLE(Regn* pregn, void* pvRegn) { 33 | return ((Regn*)pvRegn)->off <= pregn->off; 34 | } 35 | }; 36 | Array rgregnFree; 37 | unsigned iregnRover; 38 | OFF offMac; 39 | public: 40 | XHeap() { 41 | iregnRover = 0; 42 | offMac = 0; 43 | } 44 | void reset() { 45 | rgregnFree.reset(); 46 | iregnRover = 0; 47 | offMac = 0; 48 | 49 | } 50 | OFF alloc(unsigned size) { 51 | precondition(invariants()); 52 | precondition(size > 0); 53 | 54 | OFF off; 55 | 56 | #ifdef _MIPS_ 57 | size = cbAlign(size); 58 | #endif 59 | if (rgregnFree.findFirstEltSuchThat_Rover(&Regn::hasSize, &size, &iregnRover)) { 60 | Regn* pregn = &rgregnFree[iregnRover]; 61 | assert(pregn->size >= size); 62 | off = pregn->off; 63 | pregn->off += size; 64 | if ((pregn->size -= size) == 0) 65 | rgregnFree.deleteAt(iregnRover); 66 | } 67 | else { 68 | // No suitable free block found. Return storage at the end of the stream. 69 | off = offMac; 70 | offMac += size; 71 | } 72 | 73 | postcondition(invariants()); 74 | return off; 75 | } 76 | 77 | BOOL free(OFF off, unsigned size) { 78 | precondition(invariants()); 79 | precondition(off >= 0 && size > 0); 80 | 81 | #ifdef _MIPS_ 82 | size = cbAlign(size); 83 | #endif 84 | Regn regn(off, size); 85 | unsigned iregn = rgregnFree.binarySearch(&Regn::isOffLE, ®n); 86 | 87 | Regn* pregnPrev = (iregn > 0) ? &rgregnFree[iregn-1] : 0; 88 | Regn* pregnNext = (iregn < rgregnFree.size()) ? &rgregnFree[iregn] : 0; 89 | BOOL fAdjPrev = (pregnPrev && pregnPrev->end() == regn.off); 90 | BOOL fAdjNext = (pregnNext && regn.end() == pregnNext->off); 91 | 92 | if (fAdjPrev) { 93 | if (fAdjNext) { 94 | // merge all three blocks into previous block 95 | pregnPrev->size += regn.size + pregnNext->size; 96 | rgregnFree.deleteAt(iregn); 97 | } else { 98 | // merge this block into previous 99 | pregnPrev->size += regn.size; 100 | } 101 | } else { 102 | if (fAdjNext) { 103 | // merge this block into next 104 | pregnNext->off = regn.off; 105 | pregnNext->size += regn.size; 106 | } else { 107 | // insert a new block here 108 | if (!rgregnFree.insertAt(iregn, regn)) 109 | return FALSE; 110 | } 111 | } 112 | 113 | // Restart the rover index prior to this free block. 114 | if (iregn < iregnRover) 115 | iregnRover = (iregn > 0) ? iregn - 1 : 0; 116 | 117 | postcondition(invariants()); 118 | return TRUE; 119 | } 120 | 121 | BOOL save(Buffer* pbuf) { 122 | precondition(invariants()); 123 | 124 | return pbuf->Append((PB)&iregnRover, sizeof(iregnRover)) && 125 | pbuf->Append((PB)&offMac, sizeof(offMac)) && 126 | rgregnFree.save(pbuf); 127 | } 128 | BOOL reload(PB* ppb) { 129 | iregnRover = *((unsigned*&)*ppb)++; 130 | offMac = *((OFF*&)*ppb)++; 131 | BOOL OK = rgregnFree.reload(ppb); 132 | 133 | postcondition(invariants()); 134 | return OK; 135 | } 136 | 137 | BOOL invariants() { 138 | unsigned size = rgregnFree.size(); 139 | 140 | #ifdef _MIPS_ 141 | // all free regions should be in aligned-sized chunks 142 | for (unsigned i = 0; i < size; i++) 143 | if (rgregnFree[i].size != (ulong)cbAlign(rgregnFree[i].size)) 144 | return FALSE; 145 | 146 | 147 | // regions should be in sorted order 148 | for (i = 1; i < size; i++) 149 | #else 150 | for (unsigned i = 1; i < size; i++) 151 | #endif 152 | if (rgregnFree[i-1].off >= rgregnFree[i].off || 153 | rgregnFree[i-1].end() >= rgregnFree[i].off) 154 | return FALSE; 155 | 156 | 157 | // the last region should preceed offMac 158 | if (size > 0 && rgregnFree[size-1].end() > offMac) 159 | return FALSE; 160 | 161 | return TRUE; 162 | } 163 | #ifdef _DEBUG 164 | friend class EnumXHeap; 165 | #endif 166 | }; 167 | 168 | #ifdef _DEBUG 169 | class EnumXHeap : public Enum { // Enumerates the used regions of an XHeap 170 | private: 171 | unsigned current; 172 | unsigned size; 173 | unsigned rgnSize; 174 | OFF rgnOff; 175 | OFF nextOff; 176 | XHeap * xheap; 177 | 178 | public: 179 | EnumXHeap( XHeap *xheap_ ) { 180 | current = unsigned(-1); 181 | rgnOff = 0; 182 | nextOff = 0; 183 | rgnSize = 0; 184 | xheap = xheap_; 185 | size = xheap->rgregnFree.size(); 186 | } 187 | 188 | void release() { 189 | delete this; 190 | } 191 | 192 | void reset() { 193 | current = unsigned(-1); 194 | rgnOff = 0; 195 | nextOff = 0; 196 | } 197 | 198 | BOOL next() { 199 | ++current; 200 | if (current > size) 201 | return FALSE; 202 | if ( current == 0 && size > 0 && xheap->rgregnFree[0].off == 0) { 203 | // First block is free 204 | nextOff = xheap->rgregnFree[0].size; 205 | current++; 206 | } 207 | rgnOff = nextOff; // Advance our pointer 208 | if (current < size) { 209 | nextOff = xheap->rgregnFree[current].off + 210 | xheap->rgregnFree[current].size; 211 | rgnSize = xheap->rgregnFree[current].off - rgnOff; 212 | assert(rgnOff + rgnSize == (unsigned)xheap->rgregnFree[current].off ); 213 | } 214 | else // last blob of data (can be empty) 215 | rgnSize = xheap->offMac - rgnOff; 216 | assert( !current || (current && rgnSize >= 0) ); 217 | return rgnSize > 0; // Returns false when the region is empty 218 | } 219 | 220 | void get( OUT OFF *poff, OUT unsigned *psize ) { 221 | if (poff) 222 | *poff = rgnOff; 223 | if (psize) 224 | *psize = rgnSize; 225 | } 226 | }; 227 | 228 | #endif 229 | 230 | #endif // !__XHEAP_INCLUDED__ 231 | -------------------------------------------------------------------------------- /pdbtest/pdbtest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include // From \langapi\include 6 | #include 7 | #include 8 | #include 9 | 10 | #define FALSE 0 11 | #define TRUE 1 12 | 13 | int CbNumLeaf (void *pleaf, TI ti); 14 | BOOL FUDTInAnyMod(PB pbName); 15 | void ReadAllMods(DBI *pdbi); 16 | BOOL verifyGlobals(DBI* pdbi); 17 | void verifyAllSyms(DBI* pdbi); 18 | BOOL verifySymbols(Mod* pmod); 19 | void verifySymbol(PSYM psym) ; 20 | 21 | int Errors=0; 22 | GSI *pgsi; 23 | TPI *ptpi; 24 | 25 | void main(int argc, char **argv) 26 | { 27 | if (argc < 2 ) 28 | { 29 | printf("Usage: pdbtest file.pdb\n"); 30 | exit(0); 31 | } 32 | 33 | PDB *pdb; 34 | EC ec; 35 | char szError[cbErrMax]; 36 | 37 | if (!PDB::Open(argv[1], "r", (SIG)0, &ec, szError, &pdb)) { 38 | printf("Couldn't open %s :E%d %s", argv[1], ec, szError); 39 | exit(1); 40 | } 41 | 42 | DBI *pdbi; 43 | 44 | if (!pdb->OpenDBI("xxx", "r", &pdbi)) { 45 | printf("Couldn't open DBI\n"); 46 | exit(1); 47 | } 48 | 49 | ReadAllMods(pdbi); 50 | 51 | if (!pdbi->OpenGlobals(&pgsi)) { 52 | printf("Couldn't open globals\n"); 53 | exit(1); 54 | } 55 | 56 | if (!pdb->OpenTpi("r", &ptpi)) { 57 | printf("Couldn't open types info\n"); 58 | exit(1); 59 | } 60 | 61 | TI tiMin = ptpi->QueryTiMin(); 62 | TI tiMac = ptpi->QueryTiMac(); 63 | 64 | 65 | TI ti; 66 | 67 | for (ti = tiMin ; ti < tiMac ; ti++) 68 | { 69 | PB pb; 70 | 71 | ptpi->QueryPbCVRecordForTi(ti, &pb); 72 | 73 | lfClass *plfClass = (lfClass*)(pb+2); 74 | lfUnion *plfUnion = (lfUnion*)(pb+2); 75 | 76 | unsigned char *pdata = NULL; 77 | char *szType; 78 | 79 | switch (plfClass->leaf) 80 | { 81 | case LF_CLASS: 82 | if (plfClass->property.fwdref) 83 | pdata = &plfClass->data[0]; 84 | szType = "class"; 85 | break; 86 | 87 | case LF_STRUCTURE: 88 | if (plfClass->property.fwdref) 89 | pdata = &plfClass->data[0]; 90 | szType = "struct"; 91 | break; 92 | case LF_UNION: 93 | if (plfUnion->property.fwdref) 94 | pdata = &plfUnion->data[0]; 95 | szType = "union"; 96 | break; 97 | } 98 | 99 | if (pdata) { 100 | char buf[256]; 101 | pdata += CbNumLeaf((void*)pdata, ti); 102 | memcpy(buf, pdata+1, pdata[0]); 103 | buf[pdata[0]] = 0; 104 | 105 | UDTSYM *pbSym = NULL; 106 | 107 | while (pbSym = (UDTSYM*)pgsi->HashSym(buf, (PB)pbSym)) { 108 | if (pbSym->rectyp != S_UDT) 109 | continue; 110 | 111 | if (!memcmp((void*)&pbSym->name[0], (void*)pdata, pdata[0])) 112 | break; 113 | } 114 | 115 | if (!pbSym && !FUDTInAnyMod(pdata)) { 116 | printf("0x%04x %s '%s' UDT not found\n", ti, szType, buf); 117 | Errors++; 118 | } 119 | } 120 | } 121 | 122 | 123 | verifyAllSyms( pdbi ); 124 | 125 | pgsi->Close(); 126 | ptpi->Close(); 127 | pdbi->Close(); 128 | pdb->Close(); 129 | 130 | if(!Errors) printf("No errors were found.\n"); 131 | else printf("%d errors were found in %s.\n", Errors, argv[1] ); 132 | exit(Errors); 133 | } 134 | 135 | int CbNumLeaf (void *pleaf, TI ti) 136 | { 137 | unsigned short val; 138 | 139 | if ((val = ((lfEasy*)pleaf)->leaf) < LF_NUMERIC) { 140 | // No leaf can have an index less than LF_NUMERIC (0x8000) 141 | // so word is the value... 142 | return 2; 143 | } 144 | 145 | switch (val) { 146 | case LF_CHAR: 147 | return 3; 148 | 149 | case LF_USHORT: 150 | case LF_SHORT: 151 | return 4; 152 | 153 | case LF_LONG: 154 | case LF_ULONG: 155 | return 6; 156 | 157 | case LF_QUADWORD: 158 | case LF_UQUADWORD: 159 | return 10; 160 | 161 | default: 162 | printf("Error! 0x%04x bogus type encountered, aborting...\n", ti); 163 | exit(1); 164 | } 165 | return 0; 166 | } 167 | 168 | struct ML 169 | { 170 | ML *pNext; 171 | PB pbSym; 172 | CB cbSym; 173 | }; 174 | 175 | ML *pmlHead; 176 | 177 | void ReadAllMods(DBI *pdbi) 178 | { 179 | Mod *pmod = NULL; 180 | Mod *pmodNext = NULL; 181 | while (pdbi->QueryNextMod(pmod, &pmodNext) && pmodNext) 182 | { 183 | pmod = pmodNext; 184 | CB cb; 185 | if (!pmod->QuerySymbols(NULL, &cb)) 186 | continue; 187 | 188 | // empty symbols 189 | if (!cb) 190 | continue; 191 | 192 | ML *pml = new ML; 193 | pml->pbSym = (PB)malloc(cb); 194 | pml->cbSym = cb; 195 | 196 | if (!pmod->QuerySymbols(pml->pbSym, &cb)) 197 | continue; 198 | 199 | pml->pNext = pmlHead; 200 | pmlHead = pml; 201 | } 202 | } 203 | 204 | BOOL FUDTInAnyMod(PB pbName) 205 | { 206 | for (ML *pml = pmlHead; pml; pml = pml->pNext) 207 | { 208 | PB pb = pml->pbSym + sizeof(ULONG); 209 | CB cb = pml->cbSym - sizeof(ULONG); 210 | 211 | while (cb > 0) 212 | { 213 | UDTSYM *pbSym = (UDTSYM*)pb; 214 | CB cbRec = pbSym->reclen + sizeof(pbSym->reclen); 215 | cb -= cbRec; 216 | pb += cbRec; 217 | 218 | if (pbSym->rectyp != S_UDT) 219 | continue; 220 | 221 | if (!memcmp((void*)&pbSym->name[0], (void*)pbName, pbName[0])) 222 | return TRUE; 223 | } 224 | } 225 | 226 | return FALSE; 227 | } 228 | 229 | BOOL verifyGlobals(DBI* pdbi) { 230 | printf("Verifying globals.\n"); 231 | PB pbSym = 0; 232 | GSI* pgsi; 233 | if (!pdbi->OpenGlobals(&pgsi)) 234 | return FALSE; 235 | while (pbSym = pgsi->NextSym(pbSym)) 236 | verifySymbol((PSYM)pbSym); 237 | return TRUE; 238 | } 239 | 240 | void verifyAllSyms(DBI* pdbi) { 241 | verifyGlobals( pdbi ); 242 | printf("Verifying modules.\n"); 243 | Mod* pmod = 0; 244 | while (pdbi->QueryNextMod(pmod, &pmod) && pmod) { 245 | verifySymbols(pmod); 246 | } 247 | } 248 | 249 | BOOL verifySymbols(Mod* pmod) { 250 | CB cb; 251 | if (!pmod->QuerySymbols(0, &cb)) 252 | return FALSE; 253 | PB pb = new BYTE[cb]; 254 | if (!pb) 255 | return FALSE; 256 | if (!pmod->QuerySymbols(pb, &cb)) 257 | return FALSE; 258 | 259 | PSYM psymMac = (PSYM)(pb + cb); 260 | for (PSYM psym = (PSYM)(pb + sizeof(ULONG)); psym < psymMac; psym = (PSYM)pbEndSym(psym)) 261 | verifySymbol(psym); 262 | delete [] pb; 263 | return TRUE; 264 | } 265 | 266 | void verifySymbol(PSYM psym) 267 | { 268 | SymTiIter tii(psym); 269 | if (tii.next()) 270 | { 271 | TI ti=tii.rti(); 272 | if (ti < ptpi->QueryTiMin()) { 273 | return; 274 | } 275 | 276 | PB pb; 277 | if (!ptpi->QueryPbCVRecordForTi(ti, &pb)) 278 | { 279 | if(Errors==100) printf("More than 100 errors, output turned off...\n"); 280 | Errors++; 281 | if(Errors>100) return; /// Stop the ouput after 100 errors. 282 | printf("Error: cannot find type index: 0x%x\n", ti ); 283 | return; 284 | } 285 | } 286 | } 287 | 288 | -------------------------------------------------------------------------------- /pdbtest/pdbtest.mak: -------------------------------------------------------------------------------- 1 | # Microsoft Visual C++ Generated NMAKE File, Format Version 30003 2 | # ** DO NOT EDIT ** 3 | 4 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 5 | 6 | !IF "$(CFG)" == "" 7 | CFG=Win32 Debug 8 | !MESSAGE No configuration specified. Defaulting to Win32 Debug. 9 | !ENDIF 10 | 11 | !IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" 12 | !MESSAGE Invalid configuration "$(CFG)" specified. 13 | !MESSAGE You can specify a configuration when running NMAKE on this makefile 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "pdbtest.mak" CFG="Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | !ERROR An invalid configuration is specified. 24 | !ENDIF 25 | 26 | ################################################################################ 27 | # Begin Project 28 | # PROP Target_Last_Scanned "Win32 Debug" 29 | RSC=rc.exe 30 | CPP=cl.exe 31 | F90=fl32.exe 32 | 33 | !IF "$(CFG)" == "Win32 Release" 34 | 35 | # PROP BASE Use_MFC 0 36 | # PROP BASE Use_Debug_Libraries 0 37 | # PROP BASE Output_Dir WinRel 38 | # PROP BASE Intermediate_Dir WinRel 39 | # PROP Use_MFC 0 40 | # PROP Use_Debug_Libraries 0 41 | # PROP Output_Dir WinRel 42 | # PROP Intermediate_Dir WinRel 43 | OUTDIR=.\WinRel 44 | INTDIR=.\WinRel 45 | 46 | ALL : ".\WinRel\pdbtest.exe" ".\WinRel\pdbtest.bsc" 47 | 48 | "$(OUTDIR)" : 49 | if not exist "$(OUTDIR)/nul" mkdir "$(OUTDIR)" 50 | 51 | # ADD BASE F90 /I "WinRel/" 52 | # ADD F90 /I "WinRel/" 53 | F90_OBJS=.\WinRel/ 54 | # ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c 55 | # ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c 56 | CPP_PROJ=/nologo /ML /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ 57 | /FR"$(INTDIR)/" /Fp"$(INTDIR)/pdbtest.pch" /Fo"$(INTDIR)/" /c 58 | CPP_OBJS=.\WinRel/ 59 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 60 | # ADD RSC /l 0x409 /d "NDEBUG" 61 | BSC32=bscmake.exe 62 | # ADD BASE BSC32 /nologo 63 | # ADD BSC32 /nologo 64 | BSC32_FLAGS=/nologo /Iu /o"$(OUTDIR)/pdbtest.bsc" 65 | BSC32_SBRS= \ 66 | ".\WinRel\pdbtest.sbr" 67 | 68 | ".\WinRel\pdbtest.bsc" : "$(OUTDIR)" $(BSC32_SBRS) 69 | $(BSC32) @<< 70 | $(BSC32_FLAGS) $(BSC32_SBRS) 71 | << 72 | 73 | LINK32=link.exe 74 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386 75 | # ADD LINK32 mspdb.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386 76 | LINK32_FLAGS=mspdb.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ 77 | comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\ 78 | /subsystem:console /incremental:no /pdb:"$(OUTDIR)/pdbtest.pdb" /machine:I386\ 79 | /out:"$(OUTDIR)/pdbtest.exe" 80 | DEF_FILE= 81 | LINK32_OBJS= \ 82 | ".\WinRel\pdbtest.obj" 83 | 84 | ".\WinRel\pdbtest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) 85 | $(LINK32) @<< 86 | $(LINK32_FLAGS) $(LINK32_OBJS) 87 | << 88 | 89 | !ELSEIF "$(CFG)" == "Win32 Debug" 90 | 91 | # PROP BASE Use_MFC 0 92 | # PROP BASE Use_Debug_Libraries 1 93 | # PROP BASE Output_Dir WinDebug 94 | # PROP BASE Intermediate_Dir WinDebug 95 | # PROP Use_MFC 0 96 | # PROP Use_Debug_Libraries 1 97 | # PROP Output_Dir WinDebug 98 | # PROP Intermediate_Dir WinDebug 99 | OUTDIR=.\WinDebug 100 | INTDIR=.\WinDebug 101 | 102 | ALL : ".\WinDebug\pdbtest.exe" ".\WinDebug\pdbtest.bsc" 103 | 104 | "$(OUTDIR)" : 105 | if not exist "$(OUTDIR)/nul" mkdir "$(OUTDIR)" 106 | 107 | # ADD BASE F90 /I "WinDebug/" 108 | # ADD F90 /I "WinDebug/" 109 | F90_OBJS=.\WinDebug/ 110 | # ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c 111 | # ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c 112 | CPP_PROJ=/nologo /MLd /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ 113 | /FR"$(INTDIR)/" /Fp"$(INTDIR)/pdbtest.pch" /Fo"$(INTDIR)/"\ 114 | /Fd"$(OUTDIR)/pdbtest.pdb" /c 115 | CPP_OBJS=.\WinDebug/ 116 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 117 | # ADD RSC /l 0x409 /d "_DEBUG" 118 | BSC32=bscmake.exe 119 | # ADD BASE BSC32 /nologo 120 | # ADD BSC32 /nologo 121 | BSC32_FLAGS=/nologo /Iu /o"$(OUTDIR)/pdbtest.bsc" 122 | BSC32_SBRS= \ 123 | ".\WinDebug\pdbtest.sbr" 124 | 125 | ".\WinDebug\pdbtest.bsc" : "$(OUTDIR)" $(BSC32_SBRS) 126 | $(BSC32) @<< 127 | $(BSC32_FLAGS) $(BSC32_SBRS) 128 | << 129 | 130 | LINK32=link.exe 131 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 132 | # ADD LINK32 mspdb.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 133 | LINK32_FLAGS=mspdb.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ 134 | comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\ 135 | /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/pdbtest.pdb" /debug\ 136 | /machine:I386 /out:"$(OUTDIR)/pdbtest.exe" 137 | DEF_FILE= 138 | LINK32_OBJS= \ 139 | ".\WinDebug\pdbtest.obj" 140 | 141 | ".\WinDebug\pdbtest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) 142 | $(LINK32) @<< 143 | $(LINK32_FLAGS) $(LINK32_OBJS) 144 | << 145 | 146 | !ENDIF 147 | 148 | .c{$(CPP_OBJS)}.obj: 149 | $(CPP) $(CPP_PROJ) $< 150 | 151 | .cpp{$(CPP_OBJS)}.obj: 152 | $(CPP) $(CPP_PROJ) $< 153 | 154 | .cxx{$(CPP_OBJS)}.obj: 155 | $(CPP) $(CPP_PROJ) $< 156 | 157 | F90_PROJ=/I "WinRel/" /Fo"WinRel/" 158 | 159 | .for{$(F90_OBJS)}.obj: 160 | $(F90) $(F90_PROJ) $< 161 | 162 | .f{$(F90_OBJS)}.obj: 163 | $(F90) $(F90_PROJ) $< 164 | 165 | .f90{$(F90_OBJS)}.obj: 166 | $(F90) $(F90_PROJ) $< 167 | 168 | ################################################################################ 169 | # Begin Target 170 | 171 | # Name "Win32 Release" 172 | # Name "Win32 Debug" 173 | ################################################################################ 174 | # Begin Source File 175 | 176 | SOURCE=.\pdbtest.cpp 177 | 178 | !IF "$(CFG)" == "Win32 Release" 179 | 180 | ".\WinRel\pdbtest.obj" : $(SOURCE) "$(INTDIR)" 181 | 182 | !ELSEIF "$(CFG)" == "Win32 Debug" 183 | 184 | ".\WinDebug\pdbtest.obj" : $(SOURCE) "$(INTDIR)" 185 | 186 | !ENDIF 187 | 188 | # End Source File 189 | # End Target 190 | # End Project 191 | ################################################################################ 192 | -------------------------------------------------------------------------------- /PDB/dbi/src.cpp: -------------------------------------------------------------------------------- 1 | #include "pdbimpl.h" 2 | #include "dbiimpl.h" 3 | #include "srcimpl.h" 4 | 5 | 6 | BOOL PDB1::OpenSrc(Src ** ppsrc) { 7 | MTS_PROTECT(m_csForSrcImpl); 8 | #ifdef PDB_MT 9 | if (psrcimpl) { 10 | if (!m_fWriteShared && !m_fRead) { 11 | // can't open multiple time if we have write-exclusive 12 | setAccessError(); 13 | return FALSE; 14 | } 15 | assert(dwSrcImplOpenedCount); 16 | dwSrcImplOpenedCount++; 17 | *ppsrc = psrcimpl; 18 | return TRUE; 19 | } 20 | SrcImpl * psrc = new SrcImpl(this, (&s_internal_CloseSrc)); 21 | #else 22 | SrcImpl * psrc = new SrcImpl(this); 23 | #endif 24 | 25 | if (psrc) { 26 | if (psrc->internalInit(!m_fRead)) { 27 | *ppsrc = psrc; 28 | #ifdef PDB_MT 29 | assert(dwSrcImplOpenedCount == 0); 30 | dwSrcImplOpenedCount = 1; 31 | psrcimpl = psrc; 32 | #endif 33 | return TRUE; 34 | } 35 | delete psrc; 36 | } 37 | return FALSE; 38 | } 39 | 40 | #ifdef PDB_MT 41 | BOOL 42 | PDB1::internal_CloseSrc() { 43 | MTS_PROTECT(m_csForSrcImpl); 44 | 45 | assert(dwSrcImplOpenedCount); 46 | assert(psrcimpl); 47 | 48 | if (--dwSrcImplOpenedCount == 0) { 49 | psrcimpl = NULL; 50 | return TRUE; 51 | } 52 | return FALSE; 53 | } 54 | #endif 55 | 56 | void 57 | PDB1::CopySrc( PDB* ppdbFrom ) 58 | { 59 | #ifdef PDB_MT 60 | #pragma message(MTS_MESSAGE("Not thread safe - PDB1::CopySrc()")) 61 | #endif 62 | 63 | // we need to transfer any source file info from the from pdb to the to pdb 64 | // 65 | Src * psrcSrc = NULL; 66 | Src * psrcDst = NULL; 67 | NameMap * pnmp = NULL; 68 | 69 | // get setup to do the work by getting the two Src interfaces 70 | // and the namemap to get the names from the "from" pdb 71 | if (ppdbFrom->OpenSrc(&psrcSrc) && 72 | OpenSrc(&psrcDst) && 73 | NameMap::open(ppdbFrom, false, &pnmp)) 74 | { 75 | EnumSrc * pe = NULL; 76 | if (psrcSrc->GetEnum(&pe)) { 77 | 78 | // enumerate all of the "from" source files 79 | // 80 | while (pe->next()) { 81 | PCSrcHeaderOut pcsh; 82 | SZ_CONST sz; 83 | 84 | pe->get(&pcsh); 85 | if (pnmp->isValidNi(pcsh->niVirt) && 86 | pnmp->getName(pcsh->niVirt, &sz)) 87 | { 88 | // check to see if the file already exists 89 | // in the "to" side, or if the signatures don't match 90 | // 91 | SrcHeaderOut sho; 92 | if (!psrcDst->QueryByName(sz, &sho) || 93 | sho.sig != pcsh->sig) 94 | { 95 | Buffer buf; 96 | if (buf.SetInitAlloc(pcsh->cbSource) && 97 | psrcSrc->GetData(pcsh, PV(buf.Start()))) 98 | { 99 | // Build up the input SrcHeader based on 100 | // the info we retrieved from the "to" side, 101 | // which resides in the pcsh 102 | // 103 | BYTE rgb[ sizeof(SrcHeader) + 4 * _MAX_PATH]; 104 | PSrcHeader psh = PSrcHeader(rgb); 105 | psh->ver = pcsh->ver; 106 | psh->sig = pcsh->sig; 107 | psh->cbSource = pcsh->cbSource; 108 | psh->srccompress = pcsh->srccompress; 109 | psh->grFlags = pcsh->grFlags; 110 | PB pb = psh->szNames; 111 | 112 | // store the names and bail out if any are 113 | // invalid or cannot be retrieved. 114 | do { 115 | if (pnmp->isValidNi(pcsh->niFile) && 116 | pnmp->getName(pcsh->niFile, &sz)) 117 | { 118 | size_t len = strlen(sz); 119 | strncpy_s(SZ(pb), _MAX_PATH, sz, _TRUNCATE); 120 | pb += strlen(SZ(pb)) + 1; 121 | } 122 | else 123 | { 124 | break; 125 | } 126 | 127 | if (pnmp->isValidNi(pcsh->niObj) && 128 | pnmp->getName(pcsh->niObj, &sz)) 129 | { 130 | size_t len = strlen(sz); 131 | strncpy_s(SZ(pb), _MAX_PATH, sz, _TRUNCATE); 132 | pb += strlen(SZ(pb)) + 1; 133 | } 134 | else 135 | { 136 | break; 137 | } 138 | 139 | if (pnmp->isValidNi(pcsh->niVirt) && 140 | pnmp->getName(pcsh->niVirt, &sz)) 141 | { 142 | size_t len = strlen(sz); 143 | strncpy_s(SZ(pb), _MAX_PATH * 2, sz, _TRUNCATE); 144 | pb += strlen(SZ(pb)) + 1; 145 | } 146 | else 147 | { 148 | break; 149 | } 150 | 151 | // finally, set the size based on what we store 152 | // and write it to the "to" side 153 | // 154 | psh->cb = (unsigned long)(pb - PB(psh)); 155 | psrcDst->Add(psh, PV(buf.Start())); 156 | 157 | // We want to do one iteration only and use the 158 | // do/while to be able to easily skip. 159 | } while (false); 160 | } 161 | } 162 | } 163 | } 164 | } 165 | 166 | if (pe) { 167 | pe->release(); 168 | } 169 | } 170 | 171 | if (psrcSrc) 172 | psrcSrc->Close(); 173 | if (psrcDst) 174 | psrcDst->Close(); 175 | if (pnmp) 176 | pnmp->close(); 177 | } 178 | -------------------------------------------------------------------------------- /cvdump/cvdump.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | #define UNICODE 12 | #define _UNICODE 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "cvexefmt.h" 31 | #include "cvinfo.h" 32 | #include "output.h" 33 | 34 | #include "pdb.h" 35 | 36 | #include "cvtdef.h" 37 | 38 | // typedef unsigned char BYTE; 39 | // typedef int BOOL; 40 | // typedef unsigned short WORD; 41 | // typedef unsigned long DWORD; 42 | 43 | 44 | // Types necessary to use szst.h 45 | typedef char * SZ; 46 | typedef const char * SZ_CONST; 47 | typedef char * ST; 48 | typedef const char * ST_CONST; 49 | typedef unsigned char * PB; 50 | typedef long CB; 51 | 52 | #define LNGTHSZ 2 // The size of the length field 53 | #define MAXTYPE 0xffff 54 | 55 | // enumeration defining the OMF signature 56 | 57 | enum CVSIG 58 | { 59 | SIG02 = 0, // NB02 signature 60 | SIG05, // NB05 signature 61 | SIG06, // NB06 signature 62 | SIG07, // NB07 signature QCWIN 1.0 cvpacked 63 | SIG08, // NB08 signature C7.00 cvpacked 64 | SIG09, // NB08 signature C8.00 cvpacked 65 | SIG10, // NB10 signature VC 2.0 66 | SIG11, 67 | SIGOBSOLETE 68 | }; 69 | 70 | /* 71 | * definition of in core list of modules 72 | */ 73 | 74 | typedef struct DMC // DM Code 75 | { 76 | WORD sa; // Code seg base 77 | long ra; // Offset in code seg 78 | long cb; 79 | } DMC; 80 | 81 | 82 | typedef struct modlist 83 | { 84 | struct modlist *next; 85 | WORD iMod; 86 | char *ModName; 87 | DWORD ModulesAddr; 88 | DWORD SymbolsAddr; 89 | DWORD TypesAddr; 90 | DWORD PublicsAddr; 91 | DWORD PublicSymAddr; 92 | DWORD SrcLnAddr; 93 | DWORD SrcModuleAddr; 94 | DWORD ModuleSize; 95 | DWORD SymbolSize; 96 | DWORD TypeSize; 97 | DWORD PublicSize; 98 | DWORD SrcLnSize; 99 | DMC *rgdmc; 100 | char style[2]; // debugging style 101 | WORD dm_iov; // Overlay number of module 102 | WORD dm_ilib; // Library name index 103 | WORD dm_cSeg; // number of segments 104 | } modlist; 105 | 106 | typedef modlist *PMOD; 107 | 108 | extern int exefile; // Executable file handle 109 | extern size_t cbRec; 110 | extern long lfoBase; // file offset of base 111 | extern PMOD ModList; // List of module entries 112 | extern OMFDirEntry Libraries; // sstLibraries directory entry 113 | extern OMFDirEntry GlobalPub; 114 | extern OMFDirEntry GlobalSym; 115 | extern OMFDirEntry GlobalTypes; 116 | BYTE RecBuf[]; 117 | extern WORD Sig; // file signature 118 | 119 | 120 | void Fatal(const wchar_t *); 121 | 122 | void DumpCom(); 123 | void DumpTyp(); 124 | void DumpSym(); 125 | void GetBytes(void *, size_t); 126 | const wchar_t *SzNameReg(BYTE); 127 | const wchar_t *SzNameC7Reg(WORD); 128 | 129 | WORD Gets(); 130 | WORD WGets(); 131 | DWORD LGets(); 132 | const wchar_t *SzNameType(CV_typ_t); 133 | const wchar_t *SzNameC7Type(CV_typ_t typ); 134 | const wchar_t *SzNameC7Type2(CV_typ_t typ); 135 | void DumpModTypC6(size_t cbTyp); 136 | void DumpModTypC7(size_t cbTyp); 137 | DWORD PdbMapToken(DWORD tokenOld); 138 | 139 | // From cvdump.c 140 | 141 | extern bool fCoffSymRVA; 142 | extern bool fFileInd; 143 | extern bool fFpo; 144 | extern bool fFuncTokenMap; 145 | extern bool fGPSym; 146 | extern bool fHdr; 147 | extern bool fIDs; 148 | extern bool fILLines; 149 | extern bool fInlineeLines; 150 | extern bool fLines; 151 | extern bool fMergedAsmInput; 152 | extern bool fMod; 153 | extern bool fNum; 154 | extern bool fOmapf; 155 | extern bool fOmapt; 156 | extern bool fPdata; 157 | extern bool fPdbPath; 158 | extern bool fPub; 159 | extern bool fRaw; 160 | extern bool fSecContribs; 161 | extern bool fSectionHdr; 162 | extern bool fSegMap; 163 | extern bool fSrcFiles; 164 | extern bool fStatics; 165 | extern bool fStringTable; 166 | extern bool fSTSym; 167 | extern bool fSym; 168 | extern bool fTokenMap; 169 | extern bool fTyp; 170 | extern bool fTypMW; 171 | extern bool fTypTokenMap; 172 | extern bool fXdata; 173 | extern bool fXFixup; 174 | extern bool fXModExportIDs; 175 | extern bool fXModImportIDs; 176 | 177 | extern bool fSupportsQueryUDT; 178 | extern int iModToList; 179 | extern bool fUtf8Symbols; 180 | 181 | void DumpLines(const OMFSourceModule *); 182 | 183 | // From dumppdb.cpp 184 | 185 | void DumpPdb(PDB *); 186 | void DumpPdbFile(const wchar_t *); 187 | void ShowUdtTypeId(TPI *, const char *); 188 | 189 | // From dumpsym6.c 190 | 191 | extern size_t cchIndent; 192 | 193 | // From dumpsym7.cpp 194 | 195 | const unsigned char *PrintSt(bool fSz, const unsigned char *pst, bool fNewLine = true); 196 | const unsigned char *ShowSt(bool fSz, const wchar_t *psz, const unsigned char *pst, bool fNewLine = true); 197 | size_t PrintNumeric(const void *); 198 | size_t SkipNumeric(const void *); 199 | void DumpModSymC6(size_t); 200 | void DumpModSymC7(size_t, DWORD); 201 | void DumpModStringTable(size_t, DWORD); 202 | void DumpModC13Lines(size_t, DWORD); 203 | void DumpModInlineeSourceLines(size_t, PB); 204 | void DumpModFileChecksums(size_t, DWORD); 205 | void DumpModFramedata(size_t, DWORD); 206 | void DumpModCrossScopeRefs(size_t, PB); 207 | void DumpModCrossScopeExports(size_t, PB); 208 | void DumpModILLines(size_t, DWORD); 209 | void DumpModFuncTokenMap(size_t, PB); 210 | void DumpModTypeTokenMap(size_t, PB); 211 | void DumpModMergedAssemblyInput(size_t, PB); 212 | void DumpOneSymC7(Mod *, const void *, DWORD); 213 | void DumpGlobal(const wchar_t *pszTitle, const OMFDirEntry *pDir); 214 | 215 | 216 | // From type6.c 217 | 218 | extern const wchar_t * const display[4]; 219 | extern const wchar_t * const notdisplay[4]; 220 | 221 | // From type7.cpp 222 | 223 | CV_typ_t DumpTypRecC7(CV_typ_t, WORD, BYTE *, TPI *, PDB *); 224 | 225 | 226 | struct OMAP 227 | { 228 | DWORD rva; 229 | DWORD rvaTo; 230 | }; 231 | 232 | struct XFIXUP 233 | { 234 | WORD wType; 235 | WORD wExtra; 236 | DWORD rva; 237 | DWORD rvaTarget; 238 | }; 239 | -------------------------------------------------------------------------------- /PDB/dbi/locator.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // Locator implementation declarations 3 | 4 | class LOCATOR 5 | { 6 | public: 7 | LOCATOR(); 8 | ~LOCATOR(); 9 | 10 | DWORD CbCv() const; 11 | EC Ec() const; 12 | DWORD FoCv() const; 13 | bool FCrackExeOrDbg(const wchar_t *, bool = false); 14 | bool FGetNgenPdbInfo(const wchar_t *, _Deref_out_opt_ wchar_t **, GUID **, AGE *); 15 | bool FLocateDbg(const wchar_t *); 16 | bool FLocatePdb(const wchar_t *); 17 | PDB *Ppdb() const; 18 | void SetPfnQueryCallback(PfnPDBQueryCallback); 19 | void SetPvClient(void *); 20 | const wchar_t *WszDbgPath() const; 21 | const wchar_t *WszError() const; 22 | 23 | private: 24 | struct NB10I // NB10 debug info 25 | { 26 | DWORD dwSig; // NB10 27 | DWORD dwOffset; // offset, always 0 28 | SIG sig; 29 | AGE age; 30 | char szPdb[_MAX_PATH]; 31 | }; 32 | 33 | struct RSDSI // RSDS debug info 34 | { 35 | DWORD dwSig; // RSDS 36 | GUID guidSig; 37 | DWORD age; 38 | char szPdb[_MAX_PATH * 3]; 39 | }; 40 | 41 | union CV 42 | { 43 | DWORD dwSig; 44 | NB10I nb10i; 45 | RSDSI rsdsi; 46 | }; 47 | 48 | typedef BOOL (__stdcall *PFNSYMBOLSERVERW)(const wchar_t *, const wchar_t *, const void *, DWORD, DWORD, wchar_t *); 49 | typedef BOOL (__stdcall *PFNSYMBOLSERVERSETOPTIONS)(UINT_PTR, DWORDLONG); 50 | typedef BOOL (__stdcall *PFNSYMBOLSERVERSTOREFILEW)(const wchar_t *, const wchar_t *, void *, DWORD, DWORD, wchar_t *, size_t, DWORD); 51 | 52 | class REGISTRY 53 | { 54 | public: 55 | REGISTRY(HKEY); 56 | ~REGISTRY(); 57 | 58 | const wchar_t *WszSearchPath(); 59 | 60 | private: 61 | void Init(); 62 | 63 | HKEY m_hkey; 64 | bool m_fInit; 65 | wchar_t * m_wszSearchPath; // Allocated with new [] 66 | 67 | static CriticalSection m_cs; 68 | }; 69 | 70 | class SYMSRV 71 | { 72 | public: 73 | SYMSRV(); 74 | ~SYMSRV(); 75 | 76 | PFNSYMBOLSERVERSTOREFILEW m_pfnsymbolserverstorefilew; 77 | 78 | bool SymbolServer(LOCATOR *, const wchar_t *, const wchar_t *, const GUID *, DWORD, DWORD, DWORD, __out_ecount(PDB_MAX_FILENAME) wchar_t *, DWORD *pdwError); 79 | 80 | private: 81 | void Init(); 82 | 83 | bool m_fInit; 84 | HMODULE m_hmod; 85 | PFNSYMBOLSERVERW m_pfnsymbolserverw; 86 | PFNSYMBOLSERVERSETOPTIONS m_pfnsymbolserversetoptions; 87 | 88 | static CriticalSection m_cs; 89 | }; 90 | 91 | friend class SYMSRV; 92 | 93 | static void Close(FILE *); 94 | bool FDecodeCvData(const void *, size_t); 95 | bool FLocateCvFilePathHelper(const wchar_t *, const wchar_t *, size_t, bool); 96 | bool FLocateDbgDefault(); 97 | bool FLocateDbgPath(const wchar_t *); 98 | bool FLocateDbgRegistry(); 99 | bool FLocateDbgServer(); 100 | bool FLocateDbgSymsrv(const wchar_t *); 101 | bool FLocateDbgValidate(const wchar_t *); 102 | bool FLocatePdbDefault(const wchar_t *); 103 | bool FLocatePdbPath(const wchar_t *); 104 | bool FLocatePdbRegistry(); 105 | bool FLocatePdbServer(); 106 | bool FLocatePdbSymsrv(const wchar_t *); 107 | bool FOpenValidate4(const wchar_t *); 108 | bool FReadAt(FILE *, DWORD, DWORD, size_t, void *, bool = false); 109 | bool FReadCodeViewDebugData(); 110 | bool FReadDebugDirInfo(); 111 | bool FReadHeader(FILE *, DWORD, size_t, void *); 112 | bool FReadMiscDebugData(); 113 | bool FRestrictDBG(); 114 | bool FRestrictOriginalPath(); 115 | bool FRestrictReferencePath(); 116 | bool FRestrictRegistry(); 117 | bool FRestrictSymsrv(); 118 | bool FRestrictSystemRoot(); 119 | bool FSaveFileNames(const wchar_t *); 120 | void NotifyDebugDir(BOOL, const struct _IMAGE_DEBUG_DIRECTORY *); 121 | void NotifyMiscPath(const wchar_t *); 122 | void NotifyOpenDBG(const wchar_t *, PDBErrors, const wchar_t *); 123 | void NotifyOpenPDB(const wchar_t *, PDBErrors, const wchar_t *); 124 | PDBCALLBACK QueryCallback(POVC); 125 | void ReadMiscPath(PB, FILE *, DWORD, DWORD, DWORD); 126 | void SetError(EC, const wchar_t * = NULL); 127 | 128 | 129 | EC m_ec; 130 | wchar_t m_wszError[cbErrMax]; 131 | 132 | void * m_pvClient; 133 | PfnPDBQueryCallback m_pfnQueryCallback; 134 | 135 | bool m_fPfnNotifyDebugDir; 136 | PfnPDBNotifyDebugDir m_pfnNotifyDebugDir; 137 | 138 | bool m_fPfnNotifyMiscPath; 139 | PfnPDBNotifyMiscPath m_pfnNotifyMiscPath; 140 | 141 | bool m_fPfnNotifyOpenDBG; 142 | PfnPDBNotifyOpenDBG m_pfnNotifyOpenDBG; 143 | 144 | bool m_fPfnNotifyOpenPDB; 145 | PfnPDBNotifyOpenPDB m_pfnNotifyOpenPDB; 146 | 147 | PfnPDBReadExecutableAt m_pfnReadExecutableAt; 148 | PfnPDBReadExecutableAtRVA m_pfnReadExecutableAtRVA; 149 | PfnPDBReadCodeViewDebugData m_pfnReadCodeViewDebugData; 150 | PfnPDBReadMiscDebugData m_pfnReadMiscDebugData; 151 | 152 | bool m_fPfnRestrictDBG; 153 | PfnPdbRestrictDBG m_pfnPdbRestrictDBG; 154 | 155 | bool m_fPfnRestrictOriginalPath; 156 | PfnPdbRestrictOriginalPath m_pfnPdbRestrictOriginalPath; 157 | 158 | bool m_fPfnRestrictReferencePath; 159 | PfnPdbRestrictReferencePath m_pfnPdbRestrictReferencePath; 160 | 161 | bool m_fPfnRestrictRegistry; 162 | PfnPDBRestrictRegistry m_pfnRestrictRegistry; 163 | 164 | bool m_fPfnRestrictSymsrv; 165 | PfnPDBRestrictSymsrv m_pfnRestrictSymsrv; 166 | 167 | bool m_fPfnRestrictSystemRoot; 168 | PfnPDBRestrictSystemRoot m_pfnRestrictSystemRoot; 169 | 170 | 171 | FILE * m_fdExe; 172 | wchar_t * m_wszExePath; // Allocated with wcsdup() 173 | wchar_t m_wszExeFName[_MAX_FNAME]; 174 | wchar_t m_wszExeExt[_MAX_EXT]; 175 | const wchar_t * m_wszExt; 176 | 177 | bool m_fStripped; 178 | DWORD m_dwSizeOfImage; 179 | DWORD m_dwTimeStampExe; 180 | DWORD m_dwTimeStampDbg; 181 | wchar_t * m_wszMiscPath; // Allocated with new [] 182 | 183 | FILE * m_fdDbg; 184 | wchar_t * m_wszDbgPath; // Allocated with wcsdup() 185 | 186 | bool m_fCvInExe; 187 | DWORD m_cbCv; 188 | DWORD m_rvaCv; 189 | DWORD m_foCv; 190 | 191 | bool m_fGuid; 192 | GUID m_guidSig; 193 | SIG m_sig; 194 | AGE m_age; 195 | wchar_t * m_wszPdb; // Allocated with new [] 196 | 197 | PDB * m_ppdb; 198 | 199 | wchar_t * m_wszCache; // Allocated with wcsdup() 200 | 201 | static const wchar_t * const rgwszEnvName[3]; 202 | 203 | static REGISTRY m_registryUser; 204 | static REGISTRY m_registryMachine; 205 | static SYMSRV m_symsrv; 206 | }; 207 | -------------------------------------------------------------------------------- /cvdump/dumptyp6.cpp: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | #include "cvdump.h" 12 | 13 | static const wchar_t * const nametype[] = // The primitive types 14 | { 15 | L"CHAR", // 0 8 bit signed 16 | L"SHORT", // 1 16 bit signed 17 | L"LONG", // 2 32 bit signed 18 | L"???", 19 | L"UCHAR", // 4 8 bit unsigned 20 | L"USHORT", // 5 16 bit unsigned 21 | L"ULONG", // 6 32 bit unsigned 22 | L"???", 23 | L"REAL32", // 8 32 bit real 24 | L"REAL64", // 9 64 bit real 25 | L"REAL80", // 10 80 bit real 26 | L"???", 27 | L"CPLX32", // 12 8 byte complex 28 | L"CPLX64", // 13 16 byte complex 29 | L"CPLX80", // 14 20 byte complex 30 | L"???", 31 | L"BOOL08", // 16 8 bit boolean 32 | L"BOOL16", // 17 16 bit boolean 33 | L"BOOL32", // 18 32 bit boolean 34 | L"???", 35 | L"ASCII", // 20 1 byte character 36 | L"ASCII2", // 21 2 byte characters 37 | L"ASCII4", // 22 4 byte characters 38 | L"BSTRING", // 23 BASIC string 39 | L"???", 40 | L"???", 41 | L"???", 42 | L"???", 43 | L"VOID", // 28 VOID 44 | L"???", 45 | L"???", 46 | L"???", 47 | L"PCHAR", // 32 near pointer to 8 bit signed 48 | L"PSHORT", // 33 near pointer to 16 bit signed 49 | L"PLONG", // 34 near pointer to 32 bit signed 50 | L"???", 51 | L"PUCHAR", // 36 near pointer to 8 bit unsigned 52 | L"PUSHORT", // 37 near pointer to 16 bit unsigned 53 | L"PULONG", // 38 near pointer to 32 bit unsigned 54 | L"???", 55 | L"PREAL32", // 40 near pointer to 32 bit real 56 | L"PREAL64", // 41 near pointer to 64 bit real 57 | L"PREAL80", // 42 near pointer to 80 bit real 58 | L"???", 59 | L"PCPLX32", // 44 near pointer to 8 byte complex 60 | L"PCPLX64", // 45 near pointer to 16 byte complex 61 | L"PCPLX80", // 46 near pointer to 20 byte complex 62 | L"???", 63 | L"PBOOL08", // 48 near pointer to 8 bit boolean 64 | L"PBOOL16", // 49 near pointer to 16 bit boolean 65 | L"PBOOL32", // 50 near pointer to 32 bit boolean 66 | L"???", 67 | L"PASCII", // 52 near pointer to 1 byte character 68 | L"PASCII2", // 53 near pointer to 2 byte characters 69 | L"PASCII4", // 54 near pointer to 4 byte characters 70 | L"PBSTRING", // 55 near pointer to BASIC string 71 | L"???", 72 | L"???", 73 | L"???", 74 | L"???", 75 | L"PVOID", // 60 near pointer to VOID 76 | L"???", 77 | L"???", 78 | L"???", 79 | L"PFCHAR", // 64 far pointer to 8 bit signed 80 | L"PFSHORT", // 65 far pointer to 16 bit signed 81 | L"PFLONG", // 66 far pointer to 32 bit signed 82 | L"???", 83 | L"PFUCHAR", // 68 far pointer to 8 bit unsigned 84 | L"PFUSHORT", // 69 far pointer to 16 bit unsigned 85 | L"PFULONG", // 70 far pointer to 32 bit unsigned 86 | L"???", 87 | L"PFREAL32", // 72 far pointer to 32 bit real 88 | L"PFREAL64", // 73 far pointer to 64 bit real 89 | L"PFREAL80", // 74 far pointer to 80 bit real 90 | L"???", 91 | L"PFCPLX32", // 76 far pointer to 8 byte complex 92 | L"PFCPLX64", // 77 far pointer to 16 byte complex 93 | L"PFCPLX80", // 78 far pointer to 20 byte complex 94 | L"???", 95 | L"PFBOOL08", // 80 far pointer to 8 bit boolean 96 | L"PFBOOL16", // 81 far pointer to 16 bit boolean 97 | L"PFBOOL32", // 82 far pointer to 32 bit boolean 98 | L"???", 99 | L"PFASCII", // 84 far pointer to 1 byte character 100 | L"PFASCII2", // 85 far pointer to 2 byte characters 101 | L"PFASCII4", // 86 far pointer to 4 byte characters 102 | L"PFBSTRING", // 87 far pointer to BASIC string 103 | L"???", 104 | L"???", 105 | L"???", 106 | L"???", 107 | L"PFVOID", // 92 far pointer to VOID 108 | L"???", 109 | L"???", 110 | L"???", 111 | L"PHCHAR", // 96 huge pointer to 8 bit signed 112 | L"PHSHORT", // 97 huge pointer to 16 bit signed 113 | L"PHLONG", // 98 huge pointer to 32 bit signed 114 | L"???", 115 | L"PHUCHAR", // 100 huge pointer to 8 bit unsigned 116 | L"PHUSHORT", // 101 huge pointer to 16 bit unsigned 117 | L"PHULONG", // 102 huge pointer to 32 bit unsigned 118 | L"???", 119 | L"PHREAL32", // 104 huge pointer to 32 bit real 120 | L"PHREAL64", // 105 huge pointer to 64 bit real 121 | L"PHREAL80", // 106 huge pointer to 80 bit real 122 | L"???", 123 | L"PHCPLX32", // 108 huge pointer to 8 byte complex 124 | L"PHCPLX64", // 109 huge pointer to 16 byte complex 125 | L"PHCPLX80", // 110 huge pointer to 20 byte complex 126 | L"???", 127 | L"PHBOOL08", // 112 huge pointer to 8 bit boolean 128 | L"PHBOOL16", // 113 huge pointer to 16 bit boolean 129 | L"PHBOOL32", // 114 huge pointer to 32 bit boolean 130 | L"???", 131 | L"PHASCII", // 116 huge pointer to 1 byte character 132 | L"PHASCII2", // 117 huge pointer to 2 byte characters 133 | L"PHASCII4", // 118 huge pointer to 4 byte characters 134 | L"BHBSTRING", // 119 huge pointer to BASIC string 135 | L"???", 136 | L"???", 137 | L"???", 138 | L"???", 139 | L"PHVOID" // 124 huge pointer to VOID 140 | }; 141 | 142 | 143 | #define T_NOTYPE 0x0000 // uncharacterized type 144 | #define T_ABS 0x0001 // absolute symbol 145 | #define T_SEGMENT 0x0002 // segment symbol 146 | 147 | const wchar_t *SzNameType(CV_typ_t typ) 148 | { 149 | static wchar_t buf[16]; 150 | 151 | if (typ > 511) { // Not primitive 152 | swprintf_s(buf, _countof(buf), L"%u", typ); 153 | 154 | return(buf); 155 | } 156 | 157 | switch (typ) { 158 | case T_ABS: 159 | return(L"ABS"); 160 | 161 | case T_NOTYPE: 162 | return(L""); 163 | 164 | case T_SEGMENT: 165 | return(L"SEG"); 166 | 167 | default: 168 | if ((typ & 0xff00) || !(typ & 0x80)) { 169 | return(L"?unknown-type?"); 170 | } 171 | } 172 | 173 | return(nametype[typ & 0x7f]); 174 | } 175 | -------------------------------------------------------------------------------- /cvdump/symrec.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Microsoft (R) Debugging Information Dumper 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * File Comments: 7 | * 8 | * 9 | ***********************************************************************/ 10 | 11 | typedef struct BLKSYMTYPE // Obsolete 12 | { 13 | unsigned char reclen; /* Record length */ 14 | unsigned char rectyp; /* Record type */ 15 | unsigned long off; /* Offset in code seg */ 16 | unsigned short len; /* Block length */ 17 | char name[1]; /* Length-prefixed name */ 18 | } BLKSYMTYPE; 19 | 20 | typedef struct PROCSYMTYPE // Obsolete 21 | { 22 | unsigned char reclen; /* Record length */ 23 | unsigned char rectyp; /* Record type */ 24 | unsigned long off; /* Offset in code seg */ 25 | unsigned short typind; /* Type index */ 26 | unsigned short len; /* Proc length */ 27 | unsigned short startoff; /* Debug start offset */ 28 | unsigned short endoff; /* Debug end offset */ 29 | short res; /* Reserved */ 30 | char rtntyp; /* Return type (NEAR/FAR) */ 31 | char name[1]; /* Length-prefixed name */ 32 | } PROCSYMTYPE; 33 | 34 | typedef struct WITHSYMTYPE // Obsolete 35 | { 36 | unsigned char reclen; /* Record length */ 37 | unsigned char rectyp; /* Record type */ 38 | unsigned long off; /* Offset in code seg */ 39 | unsigned short len; /* Length of scope */ 40 | char name[1]; /* String to be evaluated */ 41 | } WITHSYMTYPE; 42 | 43 | typedef struct BPSYMTYPE 44 | { 45 | unsigned char reclen; /* Record length */ 46 | unsigned char rectyp; /* Record type */ 47 | unsigned long off; /* BP-relative offset */ 48 | unsigned short typind; /* Type index */ 49 | char name[1]; /* Length-prefixed name */ 50 | } BPSYMTYPE; 51 | 52 | typedef struct LABSYMTYPE //Obsolete 53 | { 54 | unsigned char reclen; /* Record length */ 55 | unsigned char rectyp; /* Record type */ 56 | unsigned long off; /* Offset in code seg */ 57 | char rtntyp; /* Return type (NEAR/FAR) */ 58 | char name[1]; /* Length-prefixed name */ 59 | } LABSYMTYPE; 60 | 61 | typedef struct LOCSYMTYPE 62 | { 63 | unsigned char reclen; /* Record length */ 64 | unsigned char rectyp; /* Record type */ 65 | unsigned long off; /* Offset in segment */ 66 | unsigned short seg; /* Segment address */ 67 | unsigned short typind; /* Type index */ 68 | char name[1]; /* Length-prefixed name */ 69 | } LOCSYMTYPE; 70 | 71 | typedef struct REGSYMTYPE 72 | { 73 | unsigned char reclen; /* Record length */ 74 | unsigned char rectyp; /* Record type */ 75 | unsigned short typind; /* Type index */ 76 | char reg; /* Which register */ 77 | char name[1]; /* Length-prefixed name */ 78 | } REGSYMTYPE; 79 | 80 | typedef struct CONSYMTYPE 81 | { 82 | unsigned char reclen; /* Record length */ 83 | unsigned char rectyp; /* Record type */ 84 | unsigned short typind; /* Type index */ 85 | char value[1]; /* Variable-length value */ 86 | char name[1]; /* Length-prefixed name */ 87 | } CONSYMTYPE; 88 | 89 | typedef struct TYPEDEFSYMTYPE 90 | { 91 | unsigned char reclen; /* Record length */ 92 | unsigned char rectyp; /* Record type */ 93 | unsigned short typind; /* Type index */ 94 | char name[1]; /* Length-prefixed name */ 95 | } TYPEDEFSYMTYPE; 96 | 97 | typedef struct CV4PROCSYMTYPE 98 | { 99 | unsigned char reclen; /* Record length */ 100 | unsigned char rectyp; /* Record type */ 101 | unsigned long parentsym; /* Offset of sym of enclosing proc */ 102 | unsigned long endsym; /* matching end */ 103 | unsigned long nextsym; /* Sym of closest following proc */ 104 | unsigned long off; /* Offset in code seg */ 105 | unsigned short seg; /* Seg of proc */ 106 | unsigned short typind; /* Type index */ 107 | unsigned long len; /* Proc length */ 108 | unsigned long startoff; /* Debug start offset */ 109 | unsigned long endoff; /* Debug end offset */ 110 | char rtntyp; /* Return type (NEAR/FAR) */ 111 | char name[1]; /* Length-prefixed name */ 112 | } CV4PROCSYMTYPE; 113 | 114 | typedef struct THUNKSYMTYPE 115 | { 116 | unsigned char reclen; /* Record length */ 117 | unsigned char rectyp; /* Record type */ 118 | unsigned long parentsym; /* Offset of sym of enclosing proc */ 119 | unsigned long endsym; /* matching end */ 120 | unsigned long nextsym; /* Sym of closest following proc */ 121 | char ord; /* Type of thunk */ 122 | unsigned long off; /* Offset in code seg */ 123 | unsigned short seg; /* Seg of proc */ 124 | unsigned short len; /* Thunk length */ 125 | char name[1]; /* Thunk name */ 126 | union { 127 | struct { 128 | short delta; /* Size of adjustment */ 129 | char name[1]; /* Name of target function */ 130 | } adjustor; 131 | short vtaboff; /* Offset into the vtable */ 132 | } variant; 133 | } THUNKSYMTYPE; 134 | 135 | typedef struct CV4BLKSYMTYPE 136 | { 137 | unsigned char reclen; /* Record length */ 138 | unsigned char rectyp; /* Record type */ 139 | unsigned long parentsym; /* Offset of sym of enclosing proc */ 140 | unsigned long endsym; /* matching end */ 141 | unsigned long off; /* Offset in code seg */ 142 | unsigned short seg; /* Segment of code */ 143 | unsigned long len; /* Block length */ 144 | char name[1]; /* Length-prefixed name */ 145 | } CV4BLKSYMTYPE; 146 | 147 | typedef struct CV4WITHSYMTYPE 148 | { 149 | unsigned char reclen; /* Record length */ 150 | unsigned char rectyp; /* Record type */ 151 | unsigned long parentsym; /* Offset of sym of enclosing proc */ 152 | unsigned long endsym; /* matching end */ 153 | unsigned long off; /* Offset in code seg */ 154 | unsigned short seg; /* Segment of code */ 155 | unsigned long len; /* Length of scope */ 156 | char name[1]; /* String to be evaluated */ 157 | } CV4WITHSYMTYPE; 158 | 159 | typedef struct CV4LABSYMTYPE 160 | { 161 | unsigned char reclen; /* Record length */ 162 | unsigned char rectyp; /* Record type */ 163 | unsigned long off; /* Offset in code seg */ 164 | unsigned short seg; /* Segment of code */ 165 | char rtntyp; /* Return type (NEAR/FAR) */ 166 | char name[1]; /* Length-prefixed name */ 167 | } CV4LABSYMTYPE; 168 | 169 | typedef struct CV4CHANGESYMTYPE 170 | { 171 | unsigned char reclen; /* Record length */ 172 | unsigned char rectyp; /* Record type */ 173 | unsigned long off; /* Offset in code seg */ 174 | unsigned short seg; /* Segment of code */ 175 | char model; /* Execution model to change to */ 176 | char var[1]; /* Variant info (unspecified) */ 177 | } CV4CHANGESYMTYPE; 178 | 179 | /* Far pointer definitions */ 180 | 181 | typedef BLKSYMTYPE *BLKSYMPTR; // Obsolete 182 | typedef CONSYMTYPE *CONSYMPTR; 183 | typedef REGSYMTYPE *REGSYMPTR; 184 | typedef LOCSYMTYPE *LOCSYMPTR; 185 | typedef LABSYMTYPE *LABSYMPTR; // Obsolete 186 | typedef BPSYMTYPE *BPSYMPTR; 187 | typedef WITHSYMTYPE *WITHSYMPTR; // Obsolete 188 | typedef PROCSYMTYPE *PROCSYMPTR; // Obsolete 189 | typedef TYPEDEFSYMTYPE *TYPEDEFSYMPTR; 190 | typedef CV4PROCSYMTYPE *CV4PROCSYMPTR; 191 | typedef THUNKSYMTYPE *THUNKSYMPTR; 192 | typedef CV4BLKSYMTYPE *CV4BLKSYMPTR; 193 | typedef CV4WITHSYMTYPE *CV4WITHSYMPTR; 194 | typedef CV4LABSYMTYPE *CV4LABSYMPTR; 195 | typedef CV4CHANGESYMTYPE *CV4CHANGESYMPTR; 196 | -------------------------------------------------------------------------------- /PDB/include/dbicommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if !defined(isectNil) 4 | #define isectNil ((ISECT)-1) 5 | #endif 6 | 7 | typedef IMOD XIMOD; // external module index; 1 based 8 | 9 | inline IMOD imodForXimod(XIMOD ximod) { return ximod - 1; } 10 | inline XIMOD ximodForImod(IMOD imod) { return imod + 1; } 11 | 12 | struct SC20 { 13 | ISECT isect; 14 | OFF off; 15 | CB cb; 16 | IMOD imod; 17 | }; 18 | 19 | struct SC40 { 20 | ISECT isect; 21 | OFF off; 22 | CB cb; 23 | DWORD dwCharacteristics; 24 | IMOD imod; 25 | 26 | SC40() : isect(isectNil), off(0), cb(cbNil), dwCharacteristics(0), imod(imodNil) { expect(fAlign(this)); } 27 | 28 | inline int IsAddrInSC(ISECT isect_, OFF off_) const 29 | { 30 | if (isect == isect_) { 31 | if (off_ < off) 32 | return -1; 33 | if (off_ - off < cb) 34 | return 0; 35 | return 1; 36 | } 37 | else 38 | return (isect_ - isect); 39 | } 40 | }; 41 | 42 | struct SC: public SC40 { 43 | DWORD dwDataCrc; 44 | DWORD dwRelocCrc; 45 | 46 | SC() : dwDataCrc(0), dwRelocCrc(0) {} 47 | 48 | inline bool Match(IMOD imod_, CB cb_, DWORD dwDataCrc_, DWORD dwRelocCrc_) const 49 | { 50 | return 51 | imod == imod_ // only interested in this one imod 52 | && dwDataCrc == dwDataCrc_ 53 | && dwRelocCrc == dwRelocCrc_ 54 | && cb == cb_; 55 | } 56 | inline bool Match(IMOD imod_, CB cb_, DWORD dwDataCrc_, DWORD dwRelocCrc_, DWORD dwCharacteristics_) const 57 | { 58 | return 59 | imod == imod_ // only interested in this one imod 60 | && dwDataCrc == dwDataCrc_ 61 | && dwRelocCrc == dwRelocCrc_ 62 | && cb == cb_ 63 | && dwCharacteristics == dwCharacteristics_; 64 | } 65 | SC& operator=(const SC20& sc20) 66 | { 67 | isect = sc20.isect; 68 | off = sc20.off; 69 | cb = sc20.cb; 70 | dwCharacteristics = 0; 71 | imod = sc20.imod; 72 | dwDataCrc = 0; 73 | dwRelocCrc = 0; 74 | return *this; 75 | } 76 | SC& operator=(const SC40& sc40) 77 | { 78 | isect = sc40.isect; 79 | off = sc40.off; 80 | cb = sc40.cb; 81 | dwCharacteristics = sc40.dwCharacteristics; 82 | imod = sc40.imod; 83 | dwDataCrc = 0; 84 | dwRelocCrc = 0; 85 | return *this; 86 | } 87 | SC& operator=(const SC& sc) 88 | { 89 | isect = sc.isect; 90 | off = sc.off; 91 | cb = sc.cb; 92 | dwCharacteristics = sc.dwCharacteristics; 93 | imod = sc.imod; 94 | dwDataCrc = sc.dwDataCrc; 95 | dwRelocCrc = sc.dwRelocCrc; 96 | return *this; 97 | } 98 | static int compareSC(const void* pv1, const void* pv2) 99 | { 100 | const SC *psc1 = reinterpret_cast(pv1); 101 | const SC *psc2 = reinterpret_cast(pv2); 102 | return psc2->IsAddrInSC(psc1->isect, psc1->off); 103 | } 104 | }; 105 | 106 | 107 | struct SC2: public SC { 108 | DWORD isectCoff; 109 | 110 | SC2() : isectCoff(0) {} 111 | 112 | SC2& operator=(const SC2& sc) 113 | { 114 | isect = sc.isect; 115 | off = sc.off; 116 | cb = sc.cb; 117 | dwCharacteristics = sc.dwCharacteristics; 118 | imod = sc.imod; 119 | dwDataCrc = sc.dwDataCrc; 120 | dwRelocCrc = sc.dwRelocCrc; 121 | isectCoff = sc.isectCoff; 122 | return *this; 123 | } 124 | static int compareSC2(const void* pv1, const void* pv2) 125 | { 126 | const SC2 *psc1 = reinterpret_cast(pv1); 127 | const SC2 *psc2 = reinterpret_cast(pv2); 128 | return psc2->IsAddrInSC(psc1->isect, psc1->off); 129 | } 130 | }; 131 | 132 | 133 | template 134 | class EnumSC : public EnumContrib 135 | { 136 | public: 137 | EnumSC(const Buffer& buf) : bufSC(buf) 138 | { 139 | reset(); 140 | } 141 | 142 | EnumSC(const EnumSC& esc) : bufSC(esc.bufSC), i(esc.i) 143 | { 144 | } 145 | 146 | void release() 147 | { 148 | delete this; 149 | } 150 | 151 | void reset() 152 | { 153 | i = (size_t)-1; 154 | } 155 | 156 | BOOL next() 157 | { 158 | if (++i * sizeof(T) < (size_t) bufSC.Size()) { 159 | return TRUE; 160 | } 161 | 162 | return FALSE; 163 | } 164 | 165 | BOOL prev() 166 | { 167 | BOOL ret = i != 0; 168 | 169 | if (i > 0) { 170 | i--; 171 | } 172 | 173 | return ret; 174 | } 175 | 176 | void get(OUT USHORT* pimod, OUT USHORT* pisect, OUT long* poff, OUT long* pcb, OUT ULONG* pdwCharacteristics) 177 | { 178 | assert(sizeof(T) == sizeof(SC)); 179 | assert(i != (size_t)-1); 180 | assert(i * sizeof(T) < (size_t)bufSC.Size()); 181 | 182 | const SC* psc = reinterpret_cast(bufSC.Start()) + i; 183 | 184 | *pimod = ximodForImod(psc->imod); 185 | *pisect = psc->isect; 186 | *poff = psc->off; 187 | *pcb = psc->cb; 188 | *pdwCharacteristics = psc->dwCharacteristics; 189 | } 190 | 191 | void get2(OUT USHORT* pimod, OUT USHORT* pisect, OUT DWORD* poff, OUT DWORD* pisectCoff, 192 | OUT DWORD* pcb, OUT ULONG* pdwCharacteristics) 193 | { 194 | assert(sizeof(T) == sizeof(SC2)); 195 | assert(i != (size_t)-1); 196 | assert(i * sizeof(T) < (size_t)bufSC.Size()); 197 | 198 | const SC2* psc = reinterpret_cast(bufSC.Start()) + i; 199 | 200 | *pimod = ximodForImod(psc->imod); 201 | *pisect = psc->isect; 202 | *poff = psc->off; 203 | *pisectCoff = psc->isectCoff; 204 | *pcb = psc->cb; 205 | *pdwCharacteristics = psc->dwCharacteristics; 206 | } 207 | 208 | void getCrcs(OUT DWORD* pcrcData, OUT DWORD* pcrcReloc) 209 | { 210 | const T* psc = (T *) bufSC.Start() + i; 211 | 212 | *pcrcData = psc->dwDataCrc; 213 | *pcrcReloc = psc->dwRelocCrc; 214 | } 215 | 216 | bool fUpdate(long off, long cb) 217 | { 218 | assert(i * sizeof(T) < size_t(bufSC.Size())); 219 | 220 | const size_t cElMax = s_cbMaxAlloc / sizeof(T); 221 | 222 | if (i <= cElMax && i * sizeof(T) < size_t(bufSC.Size())) { 223 | T *psc = reinterpret_cast(bufSC.Start()) + i; 224 | psc->off = off; 225 | psc->cb = cb; 226 | return true; 227 | } 228 | 229 | return false; 230 | } 231 | 232 | BOOL clone(EnumContrib **ppEnum) 233 | { 234 | return (*ppEnum = new EnumSC(*this)) != NULL; 235 | } 236 | 237 | BOOL locate(long isect, long off) 238 | { 239 | isect &= 0xFFFF; // ISECT(isect) is going to do this 240 | // anyway, just make it explicit! 241 | 242 | T* pscLo = reinterpret_cast(bufSC.Start()); 243 | T* pscHi = pscLo + ((bufSC.Size() / sizeof(T)) - 1); 244 | T* psc; 245 | 246 | assert(pscLo != NULL && pscHi != NULL); 247 | 248 | // binary search for containing SC 249 | while(pscLo < pscHi) { 250 | psc = pscLo + ((pscHi - pscLo) / 2); 251 | int iResult = psc->IsAddrInSC(ISECT(isect), off); 252 | if (iResult < 0) { 253 | pscHi = psc; 254 | } 255 | else if (iResult > 0) { 256 | pscLo = psc + 1; 257 | } 258 | else { 259 | i = (size_t)(psc - reinterpret_cast(bufSC.Start())) - 1; 260 | return TRUE; 261 | } 262 | } 263 | 264 | assert(pscHi == pscLo); 265 | psc = pscHi; 266 | 267 | if (psc->IsAddrInSC(ISECT(isect), off) == 0) { 268 | i = (size_t)(psc - reinterpret_cast(bufSC.Start())) - 1; 269 | return TRUE; 270 | } 271 | 272 | pscLo = reinterpret_cast(bufSC.Start()); 273 | pscHi = pscLo + ((bufSC.Size() / sizeof(T)) - 1); 274 | 275 | if (pscLo->IsAddrInSC(ISECT(isect), off) < 0) { 276 | i = (size_t) -1; 277 | } 278 | else if (pscHi->IsAddrInSC(ISECT(isect), off) > 0) { 279 | i = ((bufSC.Size() / sizeof(T)) - 1); 280 | } 281 | else { 282 | int iResult = psc->IsAddrInSC(ISECT(isect), off); 283 | i = psc - pscLo + (iResult > 0 ? 0 : -2); 284 | } 285 | 286 | return FALSE; 287 | } 288 | 289 | private: 290 | const Buffer& bufSC; 291 | size_t i; 292 | }; 293 | 294 | 295 | class DBICommon : public DBI { 296 | public: 297 | BOOL QueryTypeServerByPdb(const char* szPdb, OUT ITSM* pitsm); 298 | BOOL OpenMod(SZ_CONST szModule, SZ_CONST szObjFile, OUT Mod** ppmod); // mts safe 299 | }; 300 | -------------------------------------------------------------------------------- /PDB/dbi/pdbcommon.cpp: -------------------------------------------------------------------------------- 1 | #include "pdbimpl.h" 2 | #include "pdbcommon.h" 3 | #include "locator.h" 4 | 5 | #ifdef _DEBUG 6 | 7 | // Do some support for devenv and other processes for using vsassert instead of this 8 | 9 | typedef BOOL (__stdcall *PfnVsAssert)( 10 | SZ_CONST szMsg, 11 | SZ_CONST szAssert, 12 | SZ_CONST szFile, 13 | UINT line, 14 | BOOL * pfDisableAssert 15 | ); 16 | 17 | // List of process names we try to use VsAssert for 18 | 19 | const wchar_t * const rgszVsAssertProcesses[] = { 20 | L"concordeetest", 21 | L"devenv", 22 | L"glass2", 23 | L"glass3", 24 | L"msvsmon", 25 | L"natvisvalidator", 26 | L"pdbexplorer", 27 | L"rascal", 28 | L"rascalpro", 29 | L"vpdexpress", 30 | L"vswinexpress", 31 | L"wdexpress", 32 | NULL 33 | }; 34 | 35 | const wchar_t * const rgszVsAssertDlls[] = { 36 | L"diasymreader", 37 | L"shmetapdb", 38 | L"cpde", 39 | NULL 40 | }; 41 | 42 | const wchar_t szVsAssertDll[] = L"vsassert.dll"; 43 | const char szVsAssertProc[] = "_VsAssert@20"; 44 | 45 | extern "C" const IMAGE_DOS_HEADER __ImageBase; 46 | 47 | static void BaseName(__inout_ecount_z(cchModule) wchar_t *szModule, size_t cchModule) 48 | { 49 | // generate the base name of the filename back into the same buffer 50 | 51 | wchar_t szFile[_MAX_PATH]; 52 | 53 | _wsplitpath_s(szModule, NULL, 0, NULL, 0, szFile, _countof(szFile), NULL, 0); 54 | wcscpy_s(szModule, cchModule, szFile); 55 | } 56 | 57 | template 58 | static void BaseName(wchar_t (&szModule)[cchModule]) 59 | { 60 | BaseName(szModule, cchModule); 61 | } 62 | 63 | static bool fVsAssertDllOrProcess() 64 | { 65 | HMODULE hmodMe = HMODULE(&__ImageBase); 66 | 67 | // Check for various executables 68 | wchar_t szProcessName[_MAX_PATH]; 69 | wchar_t szMyName[_MAX_PATH]; 70 | 71 | if (GetModuleFileNameW(hmodMe, szMyName, _countof(szMyName))) { 72 | 73 | BaseName(szMyName); 74 | 75 | unsigned isz; 76 | for (isz = 0; rgszVsAssertDlls[isz] != NULL; isz++) { 77 | if (_wcsicmp(szMyName, rgszVsAssertDlls[isz]) == 0) { 78 | break; 79 | } 80 | } 81 | if (rgszVsAssertDlls[isz] != NULL) { 82 | return true; 83 | } 84 | } 85 | 86 | if (GetModuleFileNameW(NULL, szProcessName, _countof(szProcessName))) { 87 | 88 | BaseName(szProcessName); 89 | 90 | unsigned isz; 91 | for (isz = 0; rgszVsAssertProcesses[isz] != NULL; isz++) { 92 | if (_wcsicmp(szProcessName, rgszVsAssertProcesses[isz]) == 0) { 93 | break; 94 | } 95 | } 96 | if (rgszVsAssertProcesses[isz] != NULL) { 97 | return true; 98 | } 99 | } 100 | 101 | return false; 102 | } 103 | 104 | 105 | static bool fVsAssert(SZ_CONST szAssertFile, SZ_CONST szFunc, int line, SZ_CONST szCond) 106 | { 107 | bool fRet = false; // vsassert did/did not handle the assert 108 | 109 | if (fVsAssertDllOrProcess()) { 110 | 111 | HMODULE hmodVsAssert = GetModuleHandleW(szVsAssertDll); 112 | 113 | if (hmodVsAssert == NULL) { 114 | // Try LoadLibrary() 115 | hmodVsAssert = LoadLibraryExW(szVsAssertDll, NULL, 0); 116 | } 117 | 118 | if (hmodVsAssert != NULL) { 119 | PfnVsAssert pfn = PfnVsAssert(GetProcAddress(hmodVsAssert, szVsAssertProc)); 120 | 121 | if (pfn) { 122 | char szMessage[1024] = ""; 123 | char szCondition[] = ""; 124 | 125 | if (szFunc) { 126 | _snprintf_s( 127 | szMessage, 128 | _countof(szMessage), 129 | _TRUNCATE, 130 | "Failure in function %s", 131 | szFunc 132 | ); 133 | } 134 | 135 | if (!szCond) { 136 | szCond = szCondition; 137 | } 138 | 139 | BOOL fDisable = FALSE; 140 | pfn(szMessage, szCond, szAssertFile, UINT(line), &fDisable); 141 | fRet = true; 142 | } 143 | } 144 | } 145 | 146 | return fRet; 147 | } 148 | 149 | 150 | extern "C" void failAssertion(SZ_CONST szAssertFile, int line) 151 | { 152 | if (fVsAssert(szAssertFile, NULL, line, NULL)) { 153 | } 154 | else { 155 | fprintf(stderr, "assertion failure: file %s, line %d\n", szAssertFile, line); 156 | fflush(stderr); 157 | DebugBreak(); 158 | } 159 | } 160 | 161 | extern "C" void failExpect(SZ_CONST szFile, int line) 162 | { 163 | fprintf(stderr, "expectation failure: file %s, line %d\n", szFile, line); 164 | fflush(stderr); 165 | } 166 | 167 | extern "C" void failAssertionFunc(SZ_CONST szAssertFile, SZ_CONST szFunction, int line, SZ_CONST szCond) 168 | { 169 | if (fVsAssert(szAssertFile, szFunction, line, szCond)) { 170 | } 171 | // Still don't know what to do with mspdbsrv.exe yet. 172 | else { 173 | fprintf( 174 | stderr, 175 | "assertion failure:\n\tfile: %s,\n\tfunction: %s,\n\tline: %d,\n\tcondition(%s)\n\n", 176 | szAssertFile, 177 | szFunction, 178 | line, 179 | szCond 180 | ); 181 | fflush(stderr); 182 | DebugBreak(); 183 | } 184 | } 185 | 186 | extern "C" void failExpectFunc(SZ_CONST szFile, SZ_CONST szFunction, int line, SZ_CONST szCond) 187 | { 188 | fprintf( 189 | stderr, 190 | "expectation failure:\n\tfile: %s,\n\tfunction: %s,\n\tline: %d,\n\tcondition(%s)\n\n", 191 | szFile, 192 | szFunction, 193 | line, 194 | szCond 195 | ); 196 | fflush(stderr); 197 | } 198 | 199 | #endif 200 | 201 | extern const long cbPgPdbDef = 1024; 202 | 203 | 204 | BOOL PDBCommon::Open2W(const wchar_t *wszPDB, const char *szMode, OUT EC *pec, 205 | __out_ecount_opt(cchErrMax) wchar_t *wszError, size_t cchErrMax, OUT PDB **pppdb) 206 | { 207 | PDBLOG_FUNC(); 208 | dassert(wszPDB); 209 | dassert(szMode); 210 | dassert(pec); 211 | dassert(pppdb); 212 | 213 | return OpenEx2W(wszPDB, szMode, ::cbPgPdbDef, pec, wszError, cchErrMax, pppdb); 214 | } 215 | 216 | BOOL PDBCommon::OpenValidate5(const wchar_t *wszExecutable, 217 | const wchar_t *wszSearchPath, void *pvClient, 218 | PfnPDBQueryCallback pfnQueryCallback, OUT EC *pec, 219 | __out_ecount_opt(cchErrMax) wchar_t *wszError, size_t cchErrMax, OUT PDB **pppdb) 220 | { 221 | PDBLOG_FUNC(); 222 | dassert(wszExecutable); 223 | dassert(pec); 224 | dassert(pppdb); 225 | 226 | *pppdb = NULL; 227 | 228 | LOCATOR locator; 229 | 230 | locator.SetPvClient(pvClient); 231 | locator.SetPfnQueryCallback(pfnQueryCallback); 232 | 233 | if (!locator.FCrackExeOrDbg(wszExecutable) || !locator.FLocateDbg(wszSearchPath)) { 234 | HandleError: 235 | setError(pec, locator.Ec(), wszError, cchErrMax, locator.WszError()); 236 | 237 | return FALSE; 238 | } 239 | 240 | if (!locator.FLocatePdb(wszSearchPath)) { 241 | goto HandleError; 242 | } 243 | 244 | *pppdb = locator.Ppdb(); 245 | 246 | *pec = EC_OK; 247 | 248 | #ifdef PDB_TYPESERVER 249 | ((PDBCommon *) *pppdb)->setExeNameW(wszExecutable); 250 | #endif 251 | 252 | return TRUE; 253 | } 254 | 255 | EC PDBCommon::QueryLastError(char szErr[cbErrMax]) 256 | { 257 | PDBLOG_FUNC(); 258 | 259 | wchar_t wszErrLast[cbErrMax]; 260 | EC ecLast = QueryLastErrorExW(wszErrLast, cbErrMax); 261 | 262 | if (szErr != NULL) { 263 | if (WideCharToMultiByte(CP_ACP, 0, wszErrLast, -1, szErr, cbErrMax, NULL, NULL) == 0) { 264 | // Conversion failed 265 | 266 | szErr[0] = '\0'; 267 | } 268 | } 269 | 270 | return ecLast; 271 | } 272 | 273 | BOOL PDBCommon::CopyTo(const char *szPdbOut, DWORD dwCopyFilter, DWORD dwReserved) 274 | { 275 | wchar_t wszPdbOut[_MAX_PATH]; 276 | 277 | if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPdbOut, -1, wszPdbOut, _MAX_PATH) == 0) { 278 | // If we can't convert then the file will not be found 279 | //setLastError(EC_NOT_FOUND, szPdbOut); 280 | return FALSE; 281 | } 282 | 283 | return CopyToW2(wszPdbOut, dwCopyFilter, NULL, NULL); 284 | } 285 | BOOL PDBCommon::CopyToW(const wchar_t *wszPdbOut, DWORD dwCopyFilter, DWORD dwReserved) 286 | { 287 | return CopyToW2(wszPdbOut, dwCopyFilter, NULL, NULL); 288 | } 289 | 290 | BOOL PDBCommon::OpenStream(SZ_CONST sz, OUT Stream** ppstream) 291 | { 292 | return OpenStreamEx(sz, pdbRead pdbWriteShared, ppstream); 293 | } 294 | 295 | BOOL PDBCommon::OpenStreamW(const wchar_t * wszStream, OUT Stream** ppstream) 296 | { 297 | USES_STACKBUFFER(0x400); 298 | SZ utf8szStream = GetSZUTF8FromSZUnicode(wszStream); 299 | if (!utf8szStream) 300 | return FALSE; 301 | 302 | return OpenStream(utf8szStream, ppstream); 303 | } 304 | --------------------------------------------------------------------------------