From a7fa5f78ce27e8983450b90eb857c790976b2fba Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 9 Aug 2021 09:27:13 -0700 Subject: [PATCH] Remove unused System.Reflection.Emit leftovers --- .../src/System/Reflection/Emit/ILGenerator.cs | 84 - src/coreclr/debug/CMakeLists.txt | 1 - src/coreclr/debug/daccess/dacdbiimpl.cpp | 18 +- src/coreclr/debug/di/module.cpp | 8 - src/coreclr/debug/ee/debugger.cpp | 2 +- src/coreclr/debug/ildbsymlib/CMakeLists.txt | 15 - src/coreclr/debug/ildbsymlib/classfactory.h | 94 - src/coreclr/debug/ildbsymlib/ildbsymbols.cpp | 154 - src/coreclr/debug/ildbsymlib/pch.h | 39 - src/coreclr/debug/ildbsymlib/pdbdata.h | 91 - src/coreclr/debug/ildbsymlib/symbinder.cpp | 162 - src/coreclr/debug/ildbsymlib/symbinder.h | 72 - src/coreclr/debug/ildbsymlib/symread.cpp | 2770 ----------------- src/coreclr/debug/ildbsymlib/symread.h | 553 ---- src/coreclr/debug/ildbsymlib/symwrite.cpp | 1530 --------- src/coreclr/debug/ildbsymlib/symwrite.h | 1226 -------- src/coreclr/debug/ildbsymlib/umisc.h | 68 - src/coreclr/debug/inc/dacdbiinterface.h | 1 - src/coreclr/dlls/mscordbi/CMakeLists.txt | 1 - .../dlls/mscoree/coreclr/CMakeLists.txt | 1 - src/coreclr/inc/clrconfigvalues.h | 1 - src/coreclr/inc/ildbsymlib.h | 20 - src/coreclr/vm/ceeload.cpp | 164 +- src/coreclr/vm/ceeload.h | 123 +- src/coreclr/vm/commodule.cpp | 1 - 25 files changed, 22 insertions(+), 7177 deletions(-) delete mode 100644 src/coreclr/debug/ildbsymlib/CMakeLists.txt delete mode 100644 src/coreclr/debug/ildbsymlib/classfactory.h delete mode 100644 src/coreclr/debug/ildbsymlib/ildbsymbols.cpp delete mode 100644 src/coreclr/debug/ildbsymlib/pch.h delete mode 100644 src/coreclr/debug/ildbsymlib/pdbdata.h delete mode 100644 src/coreclr/debug/ildbsymlib/symbinder.cpp delete mode 100644 src/coreclr/debug/ildbsymlib/symbinder.h delete mode 100644 src/coreclr/debug/ildbsymlib/symread.cpp delete mode 100644 src/coreclr/debug/ildbsymlib/symread.h delete mode 100644 src/coreclr/debug/ildbsymlib/symwrite.cpp delete mode 100644 src/coreclr/debug/ildbsymlib/symwrite.h delete mode 100644 src/coreclr/debug/ildbsymlib/umisc.h delete mode 100644 src/coreclr/inc/ildbsymlib.h diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs index 76dd40037807b3..14554f9a127166 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs @@ -1672,88 +1672,4 @@ internal void EnsureCapacity() internal const int InitialSize = 16; internal LocalSymInfo?[] m_localSymInfos = null!; // keep track debugging local information } - - /// - /// This class tracks the line number info - /// - internal sealed class REDocument - { - internal REDocument(ISymbolDocumentWriter document) - { - // initialize data variables - m_iLineNumberCount = 0; - m_document = document; - } - - internal void AddLineNumberInfo( - ISymbolDocumentWriter? document, - int iOffset, - int iStartLine, - int iStartColumn, - int iEndLine, - int iEndColumn) - { - Debug.Assert(document == m_document, "Bad document look up!"); - - // make sure that arrays are large enough to hold addition info - EnsureCapacity(); - - m_iOffsets[m_iLineNumberCount] = iOffset; - m_iLines[m_iLineNumberCount] = iStartLine; - m_iColumns[m_iLineNumberCount] = iStartColumn; - m_iEndLines[m_iLineNumberCount] = iEndLine; - m_iEndColumns[m_iLineNumberCount] = iEndColumn; - checked { m_iLineNumberCount++; } - } - - /// - /// Helper to ensure arrays are large enough - /// - private void EnsureCapacity() - { - if (m_iLineNumberCount == 0) - { - // First time. Allocate the arrays. - m_iOffsets = new int[InitialSize]; - m_iLines = new int[InitialSize]; - m_iColumns = new int[InitialSize]; - m_iEndLines = new int[InitialSize]; - m_iEndColumns = new int[InitialSize]; - } - else if (m_iLineNumberCount == m_iOffsets.Length) - { - // the arrays are full. Enlarge the arrays - // It would probably be simpler to just use Lists here - int newSize = checked(m_iLineNumberCount * 2); - int[] temp = new int[newSize]; - Array.Copy(m_iOffsets, temp, m_iLineNumberCount); - m_iOffsets = temp; - - temp = new int[newSize]; - Array.Copy(m_iLines, temp, m_iLineNumberCount); - m_iLines = temp; - - temp = new int[newSize]; - Array.Copy(m_iColumns, temp, m_iLineNumberCount); - m_iColumns = temp; - - temp = new int[newSize]; - Array.Copy(m_iEndLines, temp, m_iLineNumberCount); - m_iEndLines = temp; - - temp = new int[newSize]; - Array.Copy(m_iEndColumns, temp, m_iLineNumberCount); - m_iEndColumns = temp; - } - } - - private int[] m_iOffsets = null!; // array of offsets - private int[] m_iLines = null!; // array of offsets - private int[] m_iColumns = null!; // array of offsets - private int[] m_iEndLines = null!; // array of offsets - private int[] m_iEndColumns = null!; // array of offsets - internal ISymbolDocumentWriter m_document; // The ISymbolDocumentWriter that this REDocument is tracking. - private int m_iLineNumberCount; // how many entries in the arrays are occupied - private const int InitialSize = 16; - } // end of REDocument } diff --git a/src/coreclr/debug/CMakeLists.txt b/src/coreclr/debug/CMakeLists.txt index 4fd69d9a82adc3..d49189ae1bb8cb 100644 --- a/src/coreclr/debug/CMakeLists.txt +++ b/src/coreclr/debug/CMakeLists.txt @@ -1,5 +1,4 @@ add_subdirectory(daccess) -add_subdirectory(ildbsymlib) add_subdirectory(ee) add_subdirectory(di) add_subdirectory(shim) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 27bfef83989b84..d8c13be0b8e254 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -4383,23 +4383,7 @@ void DacDbiInterfaceImpl::GetSymbolsBuffer(VMPTR_Module vmModule, TargetBuffer * } InitTargetBufferFromMemoryRange(m, pTargetBuffer); - // Set the symbol format appropriately - ESymbolFormat symFormat = pModule->GetInMemorySymbolStreamFormat(); - switch (symFormat) - { - case eSymbolFormatPDB: - *pSymbolFormat = kSymbolFormatPDB; - break; - - case eSymbolFormatILDB: - *pSymbolFormat = kSymbolFormatILDB; - break; - - default: - CONSISTENCY_CHECK_MSGF(false, "Unexpected symbol format"); - pTargetBuffer->Clear(); - ThrowHR(E_UNEXPECTED); - } + *pSymbolFormat = kSymbolFormatPDB; } diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp index 97ef6b135bdcb7..6ae996cdcb109c 100644 --- a/src/coreclr/debug/di/module.cpp +++ b/src/coreclr/debug/di/module.cpp @@ -15,7 +15,6 @@ #include "winbase.h" #include "corpriv.h" #include "corsym.h" -#include "ildbsymlib.h" #include "pedecoder.h" #include "stgpool.h" @@ -2577,13 +2576,6 @@ HRESULT CordbModule::CreateReaderForInMemorySymbols(REFIID riid, void** ppObj) (void**)&pBinder)); #endif } - else if (symFormat == IDacDbiInterface::kSymbolFormatILDB) - { - // ILDB format - use statically linked-in ildbsymlib - IfFailThrow(IldbSymbolsCreateInstance(CLSID_CorSymBinder_SxS, - IID_ISymUnmanagedBinder, - (void**)&pBinder)); - } else { // No in-memory symbols, return the appropriate error diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 23d0c12df463ce..ab0610226cbf5c 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -9712,7 +9712,7 @@ void Debugger::SendRawUpdateModuleSymsEvent(Module *pRuntimeModule, AppDomain *p // callback. That callback is defined to pass a PDB stream, and so we still use this // only for legacy compatibility reasons when we've actually got PDB symbols. // New clients know they must request a new symbol reader after ClassLoad events. - if (pRuntimeModule->GetInMemorySymbolStreamFormat() != eSymbolFormatPDB) + if (pRuntimeModule->GetInMemorySymbolStream() == NULL) return; // Non-PDB symbols DebuggerModule* module = LookupOrCreateModule(pRuntimeModule, pAppDomain); diff --git a/src/coreclr/debug/ildbsymlib/CMakeLists.txt b/src/coreclr/debug/ildbsymlib/CMakeLists.txt deleted file mode 100644 index 4aea0cfedb4adf..00000000000000 --- a/src/coreclr/debug/ildbsymlib/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -if(CLR_CMAKE_HOST_WIN32) - #use static crt - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) -endif(CLR_CMAKE_HOST_WIN32) - -set( ILDBSYMLIB_SOURCES - symread.cpp - symbinder.cpp - ildbsymbols.cpp - symwrite.cpp -) - -add_library_clr(ildbsymlib_obj OBJECT ${ILDBSYMLIB_SOURCES}) -add_library(ildbsymlib INTERFACE) -target_sources(ildbsymlib INTERFACE $) diff --git a/src/coreclr/debug/ildbsymlib/classfactory.h b/src/coreclr/debug/ildbsymlib/classfactory.h deleted file mode 100644 index 6cdc80b462f6ae..00000000000000 --- a/src/coreclr/debug/ildbsymlib/classfactory.h +++ /dev/null @@ -1,94 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: ClassFactory.h -// - -// =========================================================================== - -//***************************************************************************** -// ClassFactory.h -// -// Class factories are used by the pluming in COM to activate new objects. -// This module contains the class factory code to instantiate the -// ISymUnmanaged Reader,Writer and Binder -//***************************************************************************** -#ifndef __ILDBClassFactory__h__ -#define __ILDBClassFactory__h__ - -// This typedef is for a function which will create a new instance of an object. -typedef HRESULT (* PFN_CREATE_OBJ)(REFIID riid, void**ppvObject); - -//***************************************************************************** -// This structure is used to declare a global list of coclasses. The class -// factory object is created with a pointer to the correct one of these, so -// that when create instance is called, it can be created. -//***************************************************************************** -struct COCLASS_REGISTER -{ - const GUID *pClsid; // Class ID of the coclass. - LPCWSTR szProgID; // Prog ID of the class. - PFN_CREATE_OBJ pfnCreateObject; // Creation function for an instance. -}; - - - -//***************************************************************************** -// One class factory object satifies all of our clsid's, to reduce overall -// code bloat. -//***************************************************************************** -class CIldbClassFactory : - public IClassFactory -{ - CIldbClassFactory() { } // Can't use without data. - -public: - CIldbClassFactory(const COCLASS_REGISTER *pCoClass) - : m_cRef(1), m_pCoClass(pCoClass) - { } - - virtual ~CIldbClassFactory() {} - - // - // IUnknown methods. - // - - virtual HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void **ppvObject); - - virtual ULONG STDMETHODCALLTYPE AddRef() - { - return InterlockedIncrement(&m_cRef); - } - - virtual ULONG STDMETHODCALLTYPE Release() - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef <= 0) - DELETE(this); - return (cRef); - } - - - // - // IClassFactory methods. - // - - virtual HRESULT STDMETHODCALLTYPE CreateInstance( - IUnknown *pUnkOuter, - REFIID riid, - void **ppvObject); - - virtual HRESULT STDMETHODCALLTYPE LockServer( - BOOL fLock); - - -private: - LONG m_cRef; // Reference count. - const COCLASS_REGISTER *m_pCoClass; // The class we belong to. -}; - - - -#endif // __ClassFactory__h__ diff --git a/src/coreclr/debug/ildbsymlib/ildbsymbols.cpp b/src/coreclr/debug/ildbsymlib/ildbsymbols.cpp deleted file mode 100644 index 789f1877c1d616..00000000000000 --- a/src/coreclr/debug/ildbsymlib/ildbsymbols.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: ildbsymbols.cpp -// - -// =========================================================================== - -#include "pch.h" - -#include "classfactory.h" - -// GUID identifying the ILDB format version. -extern "C" const GUID ILDB_VERSION_GUID = {0x9e02e5b6, 0x8aef, 0x4d06, { 0x82, 0xe8, 0xe, 0x9b, 0x45, 0x49, 0x97, 0x16} }; - -// Version used for the "first source release", no longer supported. -extern "C" const GUID ILDB_VERSION_GUID_FSR = {0xCB2F6723, 0xAB3A, 0x11d, { 0x9C, 0x40, 0x00, 0xC0, 0x4F, 0xA3, 0x0A, 0x3E} }; - -// This map contains the list of coclasses which are exported from this module. -const COCLASS_REGISTER g_CoClasses[] = -{ -// pClsid szProgID pfnCreateObject - { &CLSID_CorSymReader_SxS, W("CorSymReader"), SymReader::NewSymReader}, - { &CLSID_CorSymWriter_SxS, W("CorSymWriter"), SymWriter::NewSymWriter}, - { &CLSID_CorSymBinder_SxS, W("CorSymBinder"), SymBinder::NewSymBinder}, - { NULL, NULL, NULL } -}; - -STDAPI IldbSymbolsGetClassObject(REFCLSID rclsid, REFIID riid, void** ppvObject) -{ - CIldbClassFactory *pClassFactory; // To create class factory object. - const COCLASS_REGISTER *pCoClass; // Loop control. - HRESULT hr = CLASS_E_CLASSNOTAVAILABLE; - - _ASSERTE(IsValidCLSID(rclsid)); - _ASSERTE(IsValidIID(riid)); - _ASSERTE(IsValidWritePtr(ppvObject, void*)); - - if (ppvObject) - { - *ppvObject = NULL; - - // Scan for the right one. - for (pCoClass=g_CoClasses; pCoClass->pClsid; pCoClass++) - { - if (*pCoClass->pClsid == rclsid) - { - // Allocate the new factory object. - pClassFactory = NEW(CIldbClassFactory(pCoClass)); - if (!pClassFactory) - return (E_OUTOFMEMORY); - - // Pick the v-table based on the caller's request. - hr = pClassFactory->QueryInterface(riid, ppvObject); - - // Always release the local reference, if QI failed it will be - // the only one and the object gets freed. - pClassFactory->Release(); - break; - } - } - } - else - { - hr = E_INVALIDARG; - } - - return hr; -} - -/* ------------------------------------------------------------------------- * - * CIldbClassFactory class - * ------------------------------------------------------------------------- */ - -//***************************************************************************** -// QueryInterface is called to pick a v-table on the co-class. -//***************************************************************************** -HRESULT STDMETHODCALLTYPE CIldbClassFactory::QueryInterface( - REFIID riid, - void **ppvObject) -{ - HRESULT hr; - - if (ppvObject == NULL) - { - return E_INVALIDARG; - } - - // Avoid confusion. - *ppvObject = NULL; - - // Pick the right v-table based on the IID passed in. - if (riid == IID_IUnknown) - *ppvObject = (IUnknown *) this; - else if (riid == IID_IClassFactory) - *ppvObject = (IClassFactory *) this; - - // If successful, add a reference for out pointer and return. - if (*ppvObject) - { - hr = S_OK; - AddRef(); - } - else - hr = E_NOINTERFACE; - return (hr); -} - - -//***************************************************************************** -// CreateInstance is called to create a new instance of the coclass for which -// this class was created in the first place. The returned pointer is the -// v-table matching the IID if there. -//***************************************************************************** -HRESULT STDMETHODCALLTYPE CIldbClassFactory::CreateInstance( - IUnknown *pUnkOuter, - REFIID riid, - void **ppvObject) -{ - HRESULT hr; - - _ASSERTE(IsValidIID(riid)); - _ASSERTE(IsValidWritePtr(ppvObject, void*)); - - // Avoid confusion. - *ppvObject = NULL; - _ASSERTE(m_pCoClass); - - // Aggregation is not supported by these objects. - if (pUnkOuter) - return (CLASS_E_NOAGGREGATION); - - // Ask the object to create an instance of itself, and check the iid. - hr = (*m_pCoClass->pfnCreateObject)(riid, ppvObject); - return (hr); -} - -// Version of CreateInstance called directly from clients -STDAPI IldbSymbolsCreateInstance(REFCLSID rclsid, REFIID riid, void** ppvIUnknown) -{ - IClassFactory *pClassFactory = NULL; - HRESULT hr = IldbSymbolsGetClassObject(rclsid, IID_IClassFactory, (void**)&pClassFactory); - if (SUCCEEDED(hr)) - hr = pClassFactory->CreateInstance(NULL, riid, ppvIUnknown); - if (pClassFactory) - pClassFactory->Release(); - return hr; -} - -HRESULT STDMETHODCALLTYPE CIldbClassFactory::LockServer( - BOOL fLock) -{ - return (S_OK); -} diff --git a/src/coreclr/debug/ildbsymlib/pch.h b/src/coreclr/debug/ildbsymlib/pch.h deleted file mode 100644 index 59582eba8ec0c5..00000000000000 --- a/src/coreclr/debug/ildbsymlib/pch.h +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: pch.h -// - -// =========================================================================== - -#ifndef _ILDBSYMLIB_PCH_H_ -#define _ILDBSYMLIB_PCH_H_ - -#include "ole2.h" - -#include "winwrap.h" -#include "umisc.h" - -#include "corhdr.h" -#include "corsym.h" -#include "palclr.h" -#include "cor.h" - -// I'm not sure why this code uses these macros for memory management (they should at least be -// in-line functions). DELETE is a symbol defined in WinNt.h as an access-type. We're probably -// not going to try and use that, so we'll just override it for now. -#ifdef DELETE -#undef DELETE -#endif - - -#define NEW( x ) ( ::new (nothrow) x ) -#define DELETE( x ) ( ::delete(x) ) -#define DELETEARRAY( x ) (::delete[] (x)) - -#include "ildbsymlib.h" -#include "symwrite.h" -#include "symread.h" -#include "symbinder.h" - -#endif diff --git a/src/coreclr/debug/ildbsymlib/pdbdata.h b/src/coreclr/debug/ildbsymlib/pdbdata.h deleted file mode 100644 index 97df443a3faccc..00000000000000 --- a/src/coreclr/debug/ildbsymlib/pdbdata.h +++ /dev/null @@ -1,91 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: pdbdata.h -// - -// =========================================================================== - -#ifndef PDBDATA_H_ -#define PDBDATA_H_ - -#include "umisc.h" -#include "palclr.h" - -struct SymMethodInfo; -struct SymLexicalScope; -struct SymVariable; -struct SymUsingNamespace; -struct SymConstant; -struct SequencePoint; -struct DocumentInfo; -struct MethodInfo; - -extern "C" const GUID ILDB_VERSION_GUID_FSR; -extern "C" const GUID ILDB_VERSION_GUID; - -#define ILDB_MINOR_VERSION_NUMBER 0 -#define ILDB_SIGNATURE "_ildb_signature" -#define ILDB_SIGNATURE_SIZE (16) - -typedef struct PDBInfo { - - // Entry point of the PE - mdMethodDef m_userEntryPoint; - - UINT32 m_CountOfMethods; - UINT32 m_CountOfScopes; - UINT32 m_CountOfVars; - UINT32 m_CountOfUsing; - UINT32 m_CountOfConstants; - UINT32 m_CountOfDocuments; - UINT32 m_CountOfSequencePoints; - UINT32 m_CountOfBytes; - UINT32 m_CountOfStringBytes; - -public: - PDBInfo() - { - memset(this, 0, sizeof(PDBInfo)); - // Make sure m_userEntryPoint initialized correctly - _ASSERTE(mdTokenNil == 0); - } - -#if BIGENDIAN - void ConvertEndianness() { - m_userEntryPoint = VAL32(m_userEntryPoint); - m_CountOfMethods = VAL32(m_CountOfMethods); - m_CountOfScopes = VAL32(m_CountOfScopes); - m_CountOfVars = VAL32(m_CountOfVars); - m_CountOfUsing = VAL32(m_CountOfUsing); - m_CountOfConstants = VAL32(m_CountOfConstants); - m_CountOfSequencePoints = VAL32(m_CountOfSequencePoints); - m_CountOfDocuments = VAL32(m_CountOfDocuments); - m_CountOfBytes = VAL32(m_CountOfBytes); - m_CountOfStringBytes = VAL32(m_CountOfStringBytes); - } -#else - void ConvertEndianness() {} -#endif - -} PDBInfo; - -// The signature, Guid version + PDBInfo data -#define ILDB_HEADER_SIZE (ILDB_SIGNATURE_SIZE + sizeof(GUID) + sizeof(PDBInfo) ) - -typedef struct PDBDataPointers -{ - SymMethodInfo * m_pMethods; // Method information - SymLexicalScope *m_pScopes; // Scopes - SymVariable *m_pVars; // Local Variables - SymUsingNamespace *m_pUsings; // list of using/imports - SymConstant *m_pConstants; // Constants - DocumentInfo *m_pDocuments; // Documents - SequencePoint *m_pSequencePoints; // Sequence Points - // Array of various bytes (variable signature, etc) - BYTE *m_pBytes; - // Strings - BYTE *m_pStringsBytes; -} PDBDataPointers; - -#endif /* PDBDATA_H_ */ diff --git a/src/coreclr/debug/ildbsymlib/symbinder.cpp b/src/coreclr/debug/ildbsymlib/symbinder.cpp deleted file mode 100644 index c4c3146a60c655..00000000000000 --- a/src/coreclr/debug/ildbsymlib/symbinder.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: symbinder.cpp -// - -// =========================================================================== - -#include "pch.h" -#include "symbinder.h" - -/* ------------------------------------------------------------------------- * - * SymBinder class - * ------------------------------------------------------------------------- */ - -HRESULT -SymBinder::QueryInterface( - REFIID riid, - void **ppvObject - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(IsValidIID(riid)); - _ASSERTE(IsValidWritePtr(ppvObject, void*)); - - IfFalseGo( ppvObject, E_INVALIDARG ); - - if (riid == IID_ISymUnmanagedBinder) - { - *ppvObject = (ISymUnmanagedBinder*) this; - } - else if (riid == IID_ISymUnmanagedBinder2) - { - *ppvObject = (ISymUnmanagedBinder2*) this; - } - else if (riid == IID_IUnknown) - { - *ppvObject = (IUnknown*)this; - } - else - { - *ppvObject = NULL; - hr = E_NOINTERFACE; - } - - if (*ppvObject) - { - AddRef(); - } - -ErrExit: - - return hr; -} - -HRESULT -SymBinder::NewSymBinder( - REFCLSID clsid, - void** ppObj - ) -{ - HRESULT hr = S_OK; - SymBinder* pSymBinder = NULL; - - _ASSERTE(IsValidCLSID(clsid)); - _ASSERTE(IsValidWritePtr(ppObj, IUnknown*)); - - if (clsid != IID_ISymUnmanagedBinder) - return (E_UNEXPECTED); - - IfFalseGo( ppObj, E_INVALIDARG ); - - *ppObj = NULL; - - IfNullGo( pSymBinder = NEW(SymBinder()) ); - *ppObj = pSymBinder; - pSymBinder->AddRef(); - pSymBinder = NULL; - -ErrExit: - - RELEASE( pSymBinder ); - - return hr; -} - -//----------------------------------------------------------- -// GetReaderForFile -//----------------------------------------------------------- -HRESULT -SymBinder::GetReaderForFile( - IUnknown *importer, // IMetaDataImporter - const WCHAR *fileName, // File we're looking symbols for - const WCHAR *searchPath, // Search path for file - ISymUnmanagedReader **ppRetVal) // Out: SymReader for file -{ - HRESULT hr = S_OK; - ISymUnmanagedReader *pSymReader = NULL; - IfFalseGo( ppRetVal && fileName && fileName[0] != '\0', E_INVALIDARG ); - - // Init Out parameter - *ppRetVal = NULL; - - // Call the class factory directly. - IfFailGo(IldbSymbolsCreateInstance(CLSID_CorSymReader_SxS, - IID_ISymUnmanagedReader, - (void**)&pSymReader)); - - IfFailGo(pSymReader->Initialize(importer, fileName, searchPath, NULL)); - - // Transfer ownership to the out parameter - *ppRetVal = pSymReader; - pSymReader = NULL; - -ErrExit: - RELEASE(pSymReader); - return hr; -} - -HRESULT -SymBinder::GetReaderFromStream( - IUnknown *importer, - IStream *pStream, - ISymUnmanagedReader **ppRetVal - ) -{ - HRESULT hr = S_OK; - ISymUnmanagedReader *pSymReader = NULL; - IfFalseGo( ppRetVal && importer && pStream, E_INVALIDARG ); - - // Init Out parameter - *ppRetVal = NULL; - - // Call the class factory directly - IfFailGo(IldbSymbolsCreateInstance(CLSID_CorSymReader_SxS, - IID_ISymUnmanagedReader, - (void**)&pSymReader)); - - IfFailGo(pSymReader->Initialize(importer, NULL, NULL, pStream)); - - // Transfer ownership to the out parameter - *ppRetVal = pSymReader; - pSymReader = NULL; - -ErrExit: - RELEASE(pSymReader); - return hr; -} - -HRESULT SymBinder::GetReaderForFile2( - IUnknown *importer, - const WCHAR *fileName, - const WCHAR *searchPath, - ULONG32 searchPolicy, - ISymUnmanagedReader **pRetVal) -{ - // This API exists just to allow VS to function properly. - // ILDB doesn't support any search policy or search path - we only look - // next to the image file. - return GetReaderForFile(importer, fileName, searchPath, pRetVal); -} diff --git a/src/coreclr/debug/ildbsymlib/symbinder.h b/src/coreclr/debug/ildbsymlib/symbinder.h deleted file mode 100644 index ff487314a5ffbd..00000000000000 --- a/src/coreclr/debug/ildbsymlib/symbinder.h +++ /dev/null @@ -1,72 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: SymBinder.h -// - -// =========================================================================== - -#ifndef SYMBINDER_H_ -#define SYMBINDER_H_ - -/* ------------------------------------------------------------------------- * - * SymBinder class - * ------------------------------------------------------------------------- */ - -class SymBinder : ISymUnmanagedBinder2 -{ -// ctor/dtor -public: - SymBinder() - { - m_refCount = 0; - } - - virtual ~SymBinder() {} - - static HRESULT NewSymBinder( REFCLSID clsid, void** ppObj ); - -// IUnknown methods -public: - - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); - - // ISymUnmanagedBinder -public: - - STDMETHOD(GetReaderForFile)( IUnknown *importer, - const WCHAR *fileName, - const WCHAR *searchPath, - ISymUnmanagedReader **pRetVal); - STDMETHOD(GetReaderFromStream)(IUnknown *importer, - IStream *pstream, - ISymUnmanagedReader **pRetVal); - - // ISymUnmanagedBinder2 - STDMETHOD(GetReaderForFile2)( IUnknown *importer, - const WCHAR *fileName, - const WCHAR *searchPath, - ULONG32 searchPolicy, - ISymUnmanagedReader **pRetVal); - -private: - SIZE_T m_refCount; - -}; -#endif diff --git a/src/coreclr/debug/ildbsymlib/symread.cpp b/src/coreclr/debug/ildbsymlib/symread.cpp deleted file mode 100644 index 168d84fc6e2195..00000000000000 --- a/src/coreclr/debug/ildbsymlib/symread.cpp +++ /dev/null @@ -1,2770 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: symread.cpp -// - -// =========================================================================== -#include "pch.h" -#include "symread.h" -#include "corimage.h" - -#define CODE_WITH_NO_SOURCE 0xfeefee -// ------------------------------------------------------------------------- -// SymReader class -// ------------------------------------------------------------------------- - -//----------------------------------------------------------- -// NewSymReader -// Static function used to create a new instance of SymReader -//----------------------------------------------------------- -HRESULT -SymReader::NewSymReader( - REFCLSID clsid, - void** ppObj - ) -{ - HRESULT hr = S_OK; - SymReader* pSymReader = NULL; - - _ASSERTE(IsValidCLSID(clsid)); - _ASSERTE(IsValidWritePtr(ppObj, IUnknown*)); - - if (clsid != IID_ISymUnmanagedReader) - return (E_UNEXPECTED); - - IfFalseGo(ppObj, E_INVALIDARG); - - *ppObj = NULL; - IfNullGo( pSymReader = NEW(SymReader())); - - *ppObj = pSymReader; - pSymReader->AddRef(); - pSymReader = NULL; - -ErrExit: - - RELEASE( pSymReader ); - - return hr; -} - - -//----------------------------------------------------------- -// ~SymReader -//----------------------------------------------------------- -SymReader::~SymReader() -{ - Cleanup(); -} - -//----------------------------------------------------------- -// Cleanup -// Release all memory and clear initialized data structures -// (eg. as a result of a failed Initialization attempt) -//----------------------------------------------------------- -void SymReader::Cleanup() -{ - if (m_pDocs) - { - unsigned i; - for(i = 0; i < m_pPDBInfo->m_CountOfDocuments; i++) - { - RELEASE(m_pDocs[i]); - } - } - - DELETE(m_pPDBInfo); - m_pPDBInfo = NULL; - - // If we loaded from stream, then free the memory we allocated - if (m_fInitializeFromStream) - { - DELETEARRAY(m_DataPointers.m_pBytes); - DELETEARRAY(m_DataPointers.m_pConstants); - DELETEARRAY(m_DataPointers.m_pDocuments); - DELETEARRAY(m_DataPointers.m_pMethods); - DELETEARRAY(m_DataPointers.m_pScopes); - DELETEARRAY(m_DataPointers.m_pSequencePoints); - DELETEARRAY(m_DataPointers.m_pStringsBytes); - DELETEARRAY(m_DataPointers.m_pUsings); - DELETEARRAY(m_DataPointers.m_pVars); - } - - DELETEARRAY(m_pDocs); - m_pDocs = NULL; - - RELEASE(m_pImporter); - m_pImporter = NULL; - - memset(&m_DataPointers, 0, sizeof(PDBDataPointers)); - m_szPath[0] = '\0'; -} - -//----------------------------------------------------------- -// ~QueryInterface -//----------------------------------------------------------- -HRESULT -SymReader::QueryInterface( - REFIID riid, - void **ppvObject - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(IsValidIID(riid)); - _ASSERTE(IsValidWritePtr(ppvObject, void*)); - - IfFalseGo(ppvObject, E_INVALIDARG); - if (riid == IID_ISymUnmanagedReader) - { - *ppvObject = (ISymUnmanagedReader*) this; - } - else - if (riid == IID_IUnknown) - { - *ppvObject = (IUnknown*)this; - } - else - { - *ppvObject = NULL; - hr = E_NOINTERFACE; - } - - if (*ppvObject) - { - AddRef(); - } - -ErrExit: - - return hr; -} - -static HRESULT ReadFromStream(IStream *pIStream, void *pv, ULONG cb) -{ - HRESULT hr = NOERROR; - ULONG ulBytesRead; - - IfFailGo(pIStream->Read(pv, cb, &ulBytesRead)); - if (ulBytesRead != cb) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// Initialize -// Pass in the required information to read in the debug info -// If a stream is passed in, it is used, otherwise a filename -// must be passed in -//----------------------------------------------------------- -HRESULT SymReader::Initialize( - IUnknown *importer, // Cash it to be consistent with CLR - const WCHAR* szFileName, // File name of the ildb - const WCHAR* szsearchPath, // Search Path - IStream *pIStream // IStream - ) -{ - HRESULT hr = NOERROR; - _ASSERTE(szFileName || pIStream); - IfFalseGo(szFileName || pIStream, E_INVALIDARG ); - - _ASSERTE(!m_fInitialized); - IfFalseGo(!m_fInitialized, E_UNEXPECTED); - - // If it's passed in, we need to AddRef to be consistent the - // desktop version since ReleaseImporterFromISymUnmanagedReader (ceeload.cpp) - // assumes there's an addref - if (importer) - { - m_pImporter = importer; - m_pImporter->AddRef(); - } - - // See if we're reading from a file or stream - if (pIStream == NULL) - { - // We're initializing from a file - m_fInitializeFromStream = false; - IfFailGo(InitializeFromFile(szFileName, szsearchPath)); - } - else - { - // We're reading in from a stream - m_fInitializeFromStream = true; - IfFailGo(InitializeFromStream(pIStream)); - } - - // Note that up to this point, the data we've read in has not been validated. Since we don't trust - // our input, it's important that we don't proceed with using this data until validation has been - // successful. - IfFailGo(ValidateData()); - - -ErrExit: - // If we have not succeeded, then we need to clean up our data structures. This would allow a client to call - // Initialize again, but also ensures we can't possibly use partial or otherwise invalid (possibly - // malicious) data. - if (FAILED(hr)) - { - Cleanup(); - } - else - { - // Otherwise we are not properly initialized - m_fInitialized = true; - } - - return hr; -} - -//----------------------------------------------------------- -// Initialize the data structures by reading from the supplied stream -// Note that upon completion the data has not yet been validated for safety. -//----------------------------------------------------------- -HRESULT SymReader::InitializeFromStream( - IStream *pIStream // IStream - ) -{ - GUID GuidVersion; - BYTE *pSignature; - HRESULT hr = S_OK; - - // Reset the stream to the beginning - LARGE_INTEGER li; - li.u.HighPart = 0; - li.u.LowPart = 0; - - // Make sure we're at the beginning of the stream - IfFailGo(pIStream->Seek(li, STREAM_SEEK_SET, NULL)); - - IfNullGo(pSignature = (BYTE *)_alloca(ILDB_SIGNATURE_SIZE)); - IfFailGo(ReadFromStream(pIStream, pSignature, ILDB_SIGNATURE_SIZE)); - - // Verify that we're looking at an ILDB File - if (memcmp(pSignature, ILDB_SIGNATURE, ILDB_SIGNATURE_SIZE)) - { - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - } - - IfFailGo(ReadFromStream(pIStream, &GuidVersion, sizeof(GUID))); - - SwapGuid(&GuidVersion); - - if (memcmp(&GuidVersion, &ILDB_VERSION_GUID, sizeof(GUID))) - { - IfFailGo(HrFromWin32(ERROR_INVALID_DATA)); - } - - IfNullGo(m_pPDBInfo = NEW(PDBInfo)); - - memset(m_pPDBInfo, 0 , sizeof(PDBInfo)); - IfFailGo(ReadFromStream(pIStream, m_pPDBInfo, sizeof(PDBInfo))); - - // Swap the counts - m_pPDBInfo->ConvertEndianness(); - - if (m_pPDBInfo->m_CountOfConstants) - { - IfNullGo(m_DataPointers.m_pConstants = NEW(SymConstant[m_pPDBInfo->m_CountOfConstants])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pConstants, m_pPDBInfo->m_CountOfConstants*sizeof(SymConstant))); - } - - if (m_pPDBInfo->m_CountOfMethods) - { - IfNullGo(m_DataPointers.m_pMethods = NEW(SymMethodInfo[m_pPDBInfo->m_CountOfMethods])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pMethods, m_pPDBInfo->m_CountOfMethods*sizeof(SymMethodInfo))); - } - - if (m_pPDBInfo->m_CountOfScopes) - { - IfNullGo(m_DataPointers.m_pScopes = NEW(SymLexicalScope[m_pPDBInfo->m_CountOfScopes])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pScopes, m_pPDBInfo->m_CountOfScopes*sizeof(SymLexicalScope))); - } - - if (m_pPDBInfo->m_CountOfVars) - { - IfNullGo(m_DataPointers.m_pVars = NEW(SymVariable[m_pPDBInfo->m_CountOfVars])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pVars, m_pPDBInfo->m_CountOfVars*sizeof(SymVariable))); - } - - if (m_pPDBInfo->m_CountOfUsing) - { - IfNullGo(m_DataPointers.m_pUsings = NEW(SymUsingNamespace[m_pPDBInfo->m_CountOfUsing])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pUsings, m_pPDBInfo->m_CountOfUsing*sizeof(SymUsingNamespace))); - } - - if (m_pPDBInfo->m_CountOfSequencePoints) - { - IfNullGo(m_DataPointers.m_pSequencePoints = NEW(SequencePoint[m_pPDBInfo->m_CountOfSequencePoints])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pSequencePoints, m_pPDBInfo->m_CountOfSequencePoints*sizeof(SequencePoint))); - } - - if (m_pPDBInfo->m_CountOfDocuments) - { - IfNullGo(m_DataPointers.m_pDocuments = NEW(DocumentInfo[m_pPDBInfo->m_CountOfDocuments])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pDocuments, m_pPDBInfo->m_CountOfDocuments*sizeof(DocumentInfo))); - } - - if (m_pPDBInfo->m_CountOfBytes) - { - IfNullGo(m_DataPointers.m_pBytes = NEW(BYTE[m_pPDBInfo->m_CountOfBytes])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pBytes, m_pPDBInfo->m_CountOfBytes*sizeof(BYTE))); - } - - - if (m_pPDBInfo->m_CountOfStringBytes) - { - IfNullGo(m_DataPointers.m_pStringsBytes = NEW(BYTE[m_pPDBInfo->m_CountOfStringBytes])); - IfFailGo(ReadFromStream(pIStream, m_DataPointers.m_pStringsBytes, m_pPDBInfo->m_CountOfStringBytes)); - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// ValidateData -// Checks the contents of everything in m_DataPointers (i.e. all the structures read from the file) -// to make sure it is valid. Specifically, validates that all indexes are within bounds for the -// sizes allocated. -//----------------------------------------------------------- -HRESULT SymReader::ValidateData() -{ - HRESULT hr = S_OK; - - for (UINT32 i = 0; i < m_pPDBInfo->m_CountOfConstants; i++) - { - SymConstant & c = m_DataPointers.m_pConstants[i]; - IfFalseGo(c.ParentScope() < m_pPDBInfo->m_CountOfScopes, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(c.Name() < m_pPDBInfo->m_CountOfStringBytes, HrFromWin32(ERROR_BAD_FORMAT)); - IfFailGo(ValidateBytes(c.Signature(), c.SignatureSize())); - } - - for (UINT32 i = 0; i < m_pPDBInfo->m_CountOfMethods; i++) - { - // Note that start/end values may equal the count (i.e. point one past the end) because - // the end is the extent, and start can equal end to indicate no entries. - SymMethodInfo & m = m_DataPointers.m_pMethods[i]; - IfFalseGo(m.StartScopes() <= m_pPDBInfo->m_CountOfScopes, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.EndScopes() <= m_pPDBInfo->m_CountOfScopes, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartScopes() <= m.EndScopes(), HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartVars() <= m_pPDBInfo->m_CountOfVars, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.EndVars() <= m_pPDBInfo->m_CountOfVars, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartVars() <= m.EndVars(), HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartUsing() <= m_pPDBInfo->m_CountOfUsing, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.EndUsing() <= m_pPDBInfo->m_CountOfUsing, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartUsing() <= m.EndUsing(), HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartConstant() <= m_pPDBInfo->m_CountOfConstants, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.EndConstant() <= m_pPDBInfo->m_CountOfConstants, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartConstant() <= m.EndConstant(), HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartDocuments() <= m_pPDBInfo->m_CountOfDocuments, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.EndDocuments() <= m_pPDBInfo->m_CountOfDocuments, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartDocuments() <= m.EndDocuments(), HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartSequencePoints() <= m_pPDBInfo->m_CountOfSequencePoints, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.EndSequencePoints() <= m_pPDBInfo->m_CountOfSequencePoints, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(m.StartSequencePoints() <= m.EndSequencePoints(), HrFromWin32(ERROR_BAD_FORMAT)); - } - - for (UINT32 i = 0; i < m_pPDBInfo->m_CountOfScopes; i++) - { - SymLexicalScope & s = m_DataPointers.m_pScopes[i]; - IfFalseGo((s.ParentScope() == (UINT32)-1) || (s.ParentScope() < m_pPDBInfo->m_CountOfScopes), HrFromWin32(ERROR_BAD_FORMAT)); - } - - for (UINT32 i = 0; i < m_pPDBInfo->m_CountOfVars; i++) - { - SymVariable & v = m_DataPointers.m_pVars[i]; - IfFalseGo(v.Scope() < m_pPDBInfo->m_CountOfScopes, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(v.Name() < m_pPDBInfo->m_CountOfStringBytes, HrFromWin32(ERROR_BAD_FORMAT)); - IfFailGo(ValidateBytes(v.Signature(), v.SignatureSize())); - } - - for (UINT32 i = 0; i < m_pPDBInfo->m_CountOfUsing; i++) - { - SymUsingNamespace & u = m_DataPointers.m_pUsings[i]; - IfFalseGo(u.ParentScope() < m_pPDBInfo->m_CountOfScopes, HrFromWin32(ERROR_BAD_FORMAT)); - IfFalseGo(u.Name() < m_pPDBInfo->m_CountOfStringBytes, HrFromWin32(ERROR_BAD_FORMAT)); - } - - for (UINT32 i = 0; i < m_pPDBInfo->m_CountOfSequencePoints; i++) - { - SequencePoint & s = m_DataPointers.m_pSequencePoints[i]; - IfFalseGo(s.Document() < m_pPDBInfo->m_CountOfDocuments, HrFromWin32(ERROR_BAD_FORMAT)); - } - - for (UINT32 i = 0; i < m_pPDBInfo->m_CountOfDocuments; i++) - { - DocumentInfo & d = m_DataPointers.m_pDocuments[i]; - IfFailGo(ValidateBytes(d.CheckSumEntry(), d.CheckSumSize())); - IfFailGo(ValidateBytes(d.SourceEntry(), d.SourceSize())); - IfFalseGo(d.UrlEntry() < m_pPDBInfo->m_CountOfStringBytes, HrFromWin32(ERROR_BAD_FORMAT)); - } - - // Nothing to validate for the m_pBytes array - each reference must validate above that it's - // length doesn't exceed the array - - // We expect all strings to be null terminated. To ensure no string operation overruns the buffer - // it sufficies to check that the buffer ends in a null character - if (m_pPDBInfo->m_CountOfStringBytes > 0) - { - IfFalseGo(m_DataPointers.m_pStringsBytes[m_pPDBInfo->m_CountOfStringBytes-1] == '\0', HrFromWin32(ERROR_BAD_FORMAT)); - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// Validate a reference to the bytes array -//----------------------------------------------------------- -HRESULT SymReader::ValidateBytes(UINT32 bytesIndex, UINT32 bytesLen) -{ - S_UINT32 extent = S_UINT32(bytesIndex) + S_UINT32(bytesLen); - if (!extent.IsOverflow() && - (extent.Value() <= m_pPDBInfo->m_CountOfBytes)) - { - return S_OK; - } - - return HrFromWin32(ERROR_BAD_FORMAT); -} - -//----------------------------------------------------------- -// VerifyPEDebugInfo -// Verify that the debug info in the PE is the one we want -//----------------------------------------------------------- -HRESULT SymReader::VerifyPEDebugInfo(const WCHAR* szFileName) -{ - HRESULT hr = E_FAIL; - HANDLE hFile = INVALID_HANDLE_VALUE; - HANDLE hMapFile = INVALID_HANDLE_VALUE; - BYTE *pMod = NULL; - DWORD dwFileSize; - IMAGE_DEBUG_DIRECTORY *pDebugDir; - RSDSI *pDebugInfo; - DWORD dwUtf8Length; - DWORD dwUnicodeLength; - - // We need to change the .pdb extension to .ildb - // compatible with VS7 - WCHAR fullpath[_MAX_PATH]; - WCHAR drive[_MAX_DRIVE]; - WCHAR dir[_MAX_DIR]; - WCHAR fname[_MAX_FNAME]; - - IMAGE_NT_HEADERS*pNT; - - hFile = WszCreateFile(szFileName, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (hFile == INVALID_HANDLE_VALUE) - { - // Get the last error if we can - return HrFromWin32(GetLastError()); - } - - dwFileSize = GetFileSize(hFile, NULL); - if (dwFileSize < ILDB_HEADER_SIZE) - { - IfFailGo(HrFromWin32(ERROR_INVALID_DATA)); - } - - hMapFile = WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); - if (hMapFile == NULL) - IfFailGo(HrFromWin32(GetLastError())); - - pMod = (BYTE *) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); - if (pMod == NULL) - IfFailGo(HrFromWin32(GetLastError())); - - pNT = Cor_RtlImageNtHeader(pMod, dwFileSize); - - // If there is no DebugEntry, then just error out - if (VAL32(pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress) == 0) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - - // NOTE: This code is not secure against malformed PE files - any of the pointer additions below - // may be outside the range of memory mapped for the file. If we ever want to use this code - // on untrusted PE files, we should properly validate everything (probably by using PEDecoder). - - DWORD offset; - offset = Cor_RtlImageRvaToOffset(pNT, VAL32(pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress), dwFileSize); - if (offset == NULL) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - pDebugDir = (IMAGE_DEBUG_DIRECTORY *)(pMod + offset); - pDebugInfo = (RSDSI *)(pMod + VAL32(pDebugDir->PointerToRawData)); - - if (pDebugInfo->dwSig != VAL32(0x53445352)) // "SDSR" - { - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - } - - - // Try the returned Stored Name since it might be a fully qualified path - dwUtf8Length = VAL32(pDebugDir->SizeOfData) - sizeof(RSDSI); - dwUnicodeLength = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) pDebugInfo->szPDB, dwUtf8Length, fullpath, COUNTOF(fullpath) - 1); - - // Make sure it's NULL terminated - _ASSERTE(dwUnicodeLength < COUNTOF(fullpath)); - fullpath[dwUnicodeLength]='\0'; - - // Replace the extension with ildb - if (_wsplitpath_s( fullpath, drive, COUNTOF(drive), dir, COUNTOF(dir), fname, COUNTOF(fname), NULL, 0 )) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - if (_wmakepath_s(m_szStoredSymbolName, MAX_LONGPATH, drive, dir, fname, W("ildb") )) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - - // It looks valid, make sure to set the return code - hr = S_OK; -ErrExit: - if (pMod) - UnmapViewOfFile(pMod); - if (hMapFile != INVALID_HANDLE_VALUE) - CloseHandle(hMapFile); - if (hFile != INVALID_HANDLE_VALUE) - CloseHandle(hFile); - return hr; - -} - -//----------------------------------------------------------- -// InitializeFromFile -// Initialize the reader using the passed in file name -// Note that upon completion the data hasn't yet been validated for safety. -//----------------------------------------------------------- -HRESULT -SymReader::InitializeFromFile( - const WCHAR* szFileName, - const WCHAR* szsearchPath) -{ - HRESULT hr = S_OK; - WCHAR fullpath[_MAX_PATH]; - WCHAR drive[_MAX_DRIVE]; - WCHAR dir[_MAX_DIR]; - WCHAR fname[_MAX_FNAME]; - HANDLE hFile = INVALID_HANDLE_VALUE; - HANDLE hMapFile = INVALID_HANDLE_VALUE; - HMODULE hMod = NULL; - BYTE *CurrentOffset; - DWORD dwFileSize; - S_UINT32 dwDataSize; - GUID VersionInfo; - - _ASSERTE(szFileName); - IfFalseGo(szFileName, E_INVALIDARG ); - - IfFailGo(VerifyPEDebugInfo(szFileName)); - // We need to open the exe and check to see if the DebugInfo matches - - if (_wsplitpath_s( szFileName, drive, COUNTOF(drive), dir, COUNTOF(dir), fname, COUNTOF(fname), NULL, 0 )) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - if (_wmakepath_s( fullpath, _MAX_PATH, drive, dir, fname, W("ildb") )) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - if (wcsncpy_s( m_szPath, COUNTOF(m_szPath), fullpath, _TRUNCATE) == STRUNCATE) - IfFailGo(HrFromWin32(ERROR_INSUFFICIENT_BUFFER)); - - hFile = WszCreateFile(m_szPath, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (hFile == INVALID_HANDLE_VALUE) - { - - // If the stored string is empty, don't do anything - if (m_szStoredSymbolName[0] == '\0') - { - return HrFromWin32(GetLastError()); - } - - if (_wsplitpath_s( m_szStoredSymbolName, drive, COUNTOF(drive), dir, COUNTOF(dir), fname, COUNTOF(fname), NULL, 0 )) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - if (_wmakepath_s( fullpath, _MAX_PATH, drive, dir, fname, W("ildb") )) - IfFailGo(HrFromWin32(ERROR_BAD_FORMAT)); - if (wcsncpy_s( m_szPath, COUNTOF(m_szPath), fullpath, _TRUNCATE) == STRUNCATE) - IfFailGo(HrFromWin32(ERROR_INSUFFICIENT_BUFFER)); - - hFile = WszCreateFile(m_szPath, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (hFile == INVALID_HANDLE_VALUE) - { - return HrFromWin32(GetLastError()); - } - } - - dwFileSize = GetFileSize(hFile, NULL); - if (dwFileSize < ILDB_HEADER_SIZE) - { - IfFailGo(HrFromWin32(ERROR_INVALID_DATA)); - } - - hMapFile = WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); - if (hMapFile == NULL) - IfFailGo(HrFromWin32(GetLastError())); - - hMod = (HMODULE) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); - if (hMod == NULL) - IfFailGo(HrFromWin32(GetLastError())); - - // We've opened the file, now let's get the pertinent info - CurrentOffset = (BYTE *)hMod; - - // Verify that we're looking at an ILDB File - if (memcmp(CurrentOffset, ILDB_SIGNATURE, ILDB_SIGNATURE_SIZE)) - { - IfFailGo(E_FAIL); - } - CurrentOffset += ILDB_SIGNATURE_SIZE; - - memcpy( &VersionInfo, CurrentOffset, sizeof(GUID)); - SwapGuid( &VersionInfo ); - CurrentOffset += sizeof(GUID); - - if (memcmp(&VersionInfo, &ILDB_VERSION_GUID, sizeof(GUID))) - { - IfFailGo(HrFromWin32(ERROR_INVALID_DATA)); - } - - IfNullGo(m_pPDBInfo = NEW(PDBInfo)); - - memcpy(m_pPDBInfo, CurrentOffset, sizeof(PDBInfo)); - - // Swap the counts - m_pPDBInfo->ConvertEndianness(); - - // Check to make sure we have enough data to be read in. - dwDataSize = S_UINT32(ILDB_HEADER_SIZE); - dwDataSize += m_pPDBInfo->m_CountOfConstants*sizeof(SymConstant); - dwDataSize += m_pPDBInfo->m_CountOfMethods * sizeof(SymMethodInfo); - dwDataSize += m_pPDBInfo->m_CountOfScopes*sizeof(SymLexicalScope); - dwDataSize += m_pPDBInfo->m_CountOfVars*sizeof(SymVariable); - dwDataSize += m_pPDBInfo->m_CountOfUsing*sizeof(SymUsingNamespace); - dwDataSize += m_pPDBInfo->m_CountOfSequencePoints*sizeof(SequencePoint); - dwDataSize += m_pPDBInfo->m_CountOfDocuments*sizeof(DocumentInfo); - dwDataSize += m_pPDBInfo->m_CountOfBytes*sizeof(BYTE); - dwDataSize += m_pPDBInfo->m_CountOfStringBytes*sizeof(BYTE); - - if (dwDataSize.IsOverflow() || dwDataSize.Value() > dwFileSize) - { - IfFailGo(HrFromWin32(ERROR_INVALID_DATA)); - } - - CurrentOffset += sizeof(PDBInfo); - - if (m_pPDBInfo->m_CountOfConstants) - { - m_DataPointers.m_pConstants = (SymConstant*)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfConstants*sizeof(SymConstant)); - } - - if (m_pPDBInfo->m_CountOfMethods) - { - m_DataPointers.m_pMethods = (SymMethodInfo *)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfMethods*sizeof(SymMethodInfo)); - } - - if (m_pPDBInfo->m_CountOfScopes) - { - m_DataPointers.m_pScopes = (SymLexicalScope *)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfScopes*sizeof(SymLexicalScope)); - } - - if (m_pPDBInfo->m_CountOfVars) - { - m_DataPointers.m_pVars = (SymVariable *)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfVars*sizeof(SymVariable)); - } - - if (m_pPDBInfo->m_CountOfUsing) - { - m_DataPointers.m_pUsings = (SymUsingNamespace *)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfUsing*sizeof(SymUsingNamespace)); - } - - if (m_pPDBInfo->m_CountOfSequencePoints) - { - m_DataPointers.m_pSequencePoints = (SequencePoint*)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfSequencePoints*sizeof(SequencePoint)); - } - - if (m_pPDBInfo->m_CountOfDocuments) - { - m_DataPointers.m_pDocuments = (DocumentInfo*)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfDocuments*sizeof(DocumentInfo)); - } - - if (m_pPDBInfo->m_CountOfBytes) - { - m_DataPointers.m_pBytes = (BYTE*)CurrentOffset; - CurrentOffset += (m_pPDBInfo->m_CountOfBytes*sizeof(BYTE)); - } - - if (m_pPDBInfo->m_CountOfStringBytes) - { - m_DataPointers.m_pStringsBytes = (BYTE*)CurrentOffset; - } - -ErrExit: - if (hMod) - UnmapViewOfFile(hMod); - if (hMapFile != INVALID_HANDLE_VALUE) - CloseHandle(hMapFile); - if (hFile != INVALID_HANDLE_VALUE) - CloseHandle(hFile); - - return hr; -} - -//----------------------------------------------------------- -// GetDocument -// Get the document for the passed in information -//----------------------------------------------------------- -HRESULT -SymReader::GetDocument( - __in LPWSTR wcsUrl, // URL of the document - GUID language, // Language for the file - GUID languageVendor, // Language vendor - GUID documentType, // Type of document - ISymUnmanagedDocument **ppRetVal // [out] Document - ) -{ - HRESULT hr = S_OK; - unsigned i; - SymDocument* pDoc = NULL; - WCHAR *wcsDocumentUrl = NULL; - WCHAR *wcsDocumentUrlAlloc = NULL; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(ppRetVal && wcsUrl); - IfFalseGo(ppRetVal, E_INVALIDARG); - IfFalseGo(wcsUrl, E_INVALIDARG); - - // Init Out Parameter - *ppRetVal = NULL; - - for (i = 0; i < m_pPDBInfo->m_CountOfDocuments; i++) - { - int cchName; - - // Convert the UTF8 string to Wide - cchName = (ULONG32) MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_DataPointers.m_pStringsBytes[m_DataPointers.m_pDocuments[i].UrlEntry()]), - -1, - 0, - NULL); - IfNullGo( wcsDocumentUrlAlloc = NEW(WCHAR[cchName]) ); - - cchName = (ULONG32) MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_DataPointers.m_pStringsBytes[m_DataPointers.m_pDocuments[i].UrlEntry()]), - -1, - wcsDocumentUrlAlloc, - cchName); - wcsDocumentUrl = wcsDocumentUrlAlloc; - - // Compare the url - if (wcscmp(wcsUrl, wcsDocumentUrl) == 0) - { - IfFailGo(GetDocument(i, &pDoc)); - break; - } - DELETEARRAY(wcsDocumentUrlAlloc); - wcsDocumentUrlAlloc = NULL; - } - - if (pDoc) - { - IfFailGo( pDoc->QueryInterface( IID_ISymUnmanagedDocument, - (void**) ppRetVal ) ); - } - -ErrExit: - DELETEARRAY(wcsDocumentUrlAlloc); - - RELEASE( pDoc ); - - return hr; -} - -//----------------------------------------------------------- -// GetDocuments -// Get the documents for this reader -//----------------------------------------------------------- -HRESULT -SymReader::GetDocuments( - ULONG32 cDocs, - ULONG32 *pcDocs, - ISymUnmanagedDocument *pDocs[] - ) -{ - HRESULT hr = S_OK; - unsigned cDocCount = 0; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(pDocs || pcDocs); - IfFalseGo(pDocs || pcDocs, E_INVALIDARG); - - cDocs = min(cDocs, m_pPDBInfo->m_CountOfDocuments); - - for (cDocCount = 0; cDocCount < cDocs; cDocCount++) - { - if (pDocs) - { - SymDocument *pDoc; - IfFailGo(GetDocument(cDocCount, &pDoc)); - pDocs[cDocCount] = pDoc; - } - } - if (pcDocs) - { - *pcDocs = (ULONG32)m_pPDBInfo->m_CountOfDocuments; - } - -ErrExit: - if (FAILED(hr)) - { - unsigned i; - for (i = 0; i < cDocCount; i++) - { - RELEASE(pDocs[cDocCount]); - } - } - return hr; -} - -//----------------------------------------------------------- -// GetUserEntryPoint -// Get the entry point for the pe -//----------------------------------------------------------- -HRESULT -SymReader::GetUserEntryPoint( - mdMethodDef *pRetVal - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - - // If it wasn't set then return E_FAIL - if (m_pPDBInfo->m_userEntryPoint == mdTokenNil) - { - hr = E_FAIL; - } - else - { - *pRetVal = m_pPDBInfo->m_userEntryPoint; - } -ErrExit: - return hr; -} - -// Compare the method token with the SymMethodInfo Entry and return the -// value expected by bsearch -int __cdecl CompareMethodToToken(const void *pMethodToken, const void *pMethodInfoEntry) -{ - mdMethodDef MethodDef = *(mdMethodDef *)pMethodToken; - SymMethodInfo *pMethodInfo = (SymMethodInfo *)pMethodInfoEntry; - - return MethodDef - pMethodInfo->MethodToken(); -} - -//----------------------------------------------------------- -// GetMethod -// Get the method for the methoddef -//----------------------------------------------------------- -HRESULT -SymReader::GetMethod( - mdMethodDef method, // MethodDef - ISymUnmanagedMethod **ppRetVal // [out] Method - ) -{ - HRESULT hr = S_OK; - UINT32 MethodEntry = 0; - SymMethodInfo *pMethodInfo; - SymMethod * pMethod = NULL; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(ppRetVal); - IfFalseGo(ppRetVal, E_INVALIDARG); - - pMethodInfo = (SymMethodInfo *)bsearch(&method, m_DataPointers.m_pMethods, m_pPDBInfo->m_CountOfMethods, sizeof(SymMethodInfo), CompareMethodToToken); - IfFalseGo(pMethodInfo, E_FAIL); // no matching method found - - // Found a match - MethodEntry = UINT32 (pMethodInfo - m_DataPointers.m_pMethods); - _ASSERTE(m_DataPointers.m_pMethods[MethodEntry].MethodToken() == method); - IfNullGo( pMethod = NEW(SymMethod(this, &m_DataPointers, MethodEntry)) ); - *ppRetVal = pMethod; - pMethod->AddRef(); - hr = S_OK; - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetMethodByVersion -//----------------------------------------------------------- -HRESULT -SymReader::GetMethodByVersion( - mdMethodDef method, - int version, - ISymUnmanagedMethod **ppRetVal - ) -{ - // Don't support multiple version of the same Method so just - // call GetMethod - return GetMethod(method, ppRetVal); -} - - -//----------------------------------------------------------- -// GetMethodFromDocumentPosition -//----------------------------------------------------------- -HRESULT -SymReader::GetMethodFromDocumentPosition( - ISymUnmanagedDocument *document, - ULONG32 line, - ULONG32 column, - ISymUnmanagedMethod **ppRetVal -) -{ - HRESULT hr = S_OK; - UINT32 DocumentEntry; - UINT32 Method; - UINT32 point; - SequencePoint *pSequencePointBefore; - SequencePoint *pSequencePointAfter; - bool found = false; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(document && ppRetVal); - IfFalseGo(document, E_INVALIDARG); - IfFalseGo(ppRetVal, E_INVALIDARG); - - DocumentEntry = ((SymDocument *)document)->GetDocumentEntry(); - - // Init out parameter - *ppRetVal = NULL; - - // Walk all Methods, check their Document and SequencePoints to see if it's in this doc - // and the line/column - - // This function returns the first match if more than one methods cover the specified position. - for (Method = 0; Method < m_pPDBInfo->m_CountOfMethods; Method++) - { - pSequencePointBefore = NULL; - pSequencePointAfter = NULL; - - // Walk the sequence points - for (point = m_DataPointers.m_pMethods[Method].StartSequencePoints(); - point < m_DataPointers.m_pMethods[Method].EndSequencePoints(); - point++) - { - // Check to see if this sequence point is in this doc - if (m_DataPointers.m_pSequencePoints[point].Document() == DocumentEntry) - { - // If the point is position is within the sequence point then - // we're done. - if (m_DataPointers.m_pSequencePoints[point].IsWithin(line, column)) - { - IfFailGo(GetMethod(m_DataPointers.m_pMethods[Method].MethodToken(), ppRetVal)); - found = true; - break; - } - - // If the sequence is before the point then just remember the point - if (m_DataPointers.m_pSequencePoints[point].IsUserLine() && - m_DataPointers.m_pSequencePoints[point].IsLessThan(line, column)) - { - pSequencePointBefore = &m_DataPointers.m_pSequencePoints[point]; - } - - // If the sequence is before the point then just remember the point - if (m_DataPointers.m_pSequencePoints[point].IsUserLine() && - m_DataPointers.m_pSequencePoints[point].IsGreaterThan(line, column)) - { - pSequencePointAfter = &m_DataPointers.m_pSequencePoints[point]; - } - } - } - - // If we found an exact match, we're done. - if (found) - { - break; - } - - // If we found sequence points within the method before and after - // the line/column then we may have found the method. Record the return value, but keep looking - // to see if we find an exact match. This may not actually be the right method. Iron Python, for instance, - // issues a "method" containing sequence points for all the method headers in a class. Sequence points - // in this "method" would then span the sequence points in the bodies of all but the last method. - if (pSequencePointBefore && pSequencePointAfter) - { - IfFailGo(GetMethod(m_DataPointers.m_pMethods[Method].MethodToken(), ppRetVal)); - } - } - - // This function returns E_FAIL if no match is found. - // Note that this is different from the behaviour of GetMethodsFromDocumentPosition() (see below). - if (*ppRetVal == NULL) - { - hr = E_FAIL; - } - -ErrExit: - return hr; -} - -//--------------------------------------------------------------------------------------- -// -// Return all methods with sequence points covering the specified source location. This -// is actually not as straighforward as it sounds, since we need to mimic the behaviour of -// diasymreader and PDBs here. For PDBs, diasymreader actually does two passes over the -// sequence points. It tries to find an exact match in the first pass, and if that fails, -// it'll do a second pass looking for an approximate match. An approximate match is a sequence -// point which doesn't start on the specified line but covers it. If there's an exact match, -// then it ignores all the approximate matches. In both cases, diasymreader only checks the -// start line number of the sequence point and it ignores the column number. -// -// For backward compatibility, I'm leaving GetMethodFromDocumentPosition() unchanged. -// - -HRESULT -SymReader::GetMethodsFromDocumentPosition( - ISymUnmanagedDocument *document, - ULONG32 line, - ULONG32 column, - ULONG32 cMethod, - ULONG32* pcMethod, //[Optional]: How many method actually returned - ISymUnmanagedMethod** ppRetVal - ) -{ - HRESULT hr = S_OK; - UINT32 DocumentEntry; - UINT32 Method; - UINT32 point; - - UINT CurMethod = 0; - bool found = false; - bool fExactMatch = true; - - ULONG32 maxPreLine = 0; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(document); - IfFalseGo(document, E_INVALIDARG); - - _ASSERTE((cMethod == 0) || (ppRetVal != NULL)); - IfFalseGo(cMethod == 0 || ppRetVal != NULL, E_INVALIDARG); - - // Initialize the out parameter if it has been provided. - if (pcMethod != NULL) - { - *pcMethod = 0; - } - - DocumentEntry = ((SymDocument *)document)->GetDocumentEntry(); - - // Enumerate the sequence points in two passes. - while (true) - { - // Walk all Methods, check their Document and SequencePoints to see if it's in this doc - // and the line/column - - for (Method = 0; Method < m_pPDBInfo->m_CountOfMethods; Method++) - { - found = false; - - // Walk the sequence points - for (point = m_DataPointers.m_pMethods[Method].StartSequencePoints(); - point < m_DataPointers.m_pMethods[Method].EndSequencePoints(); - point++) - { - // Check to see if this sequence point is in this doc - if (m_DataPointers.m_pSequencePoints[point].Document() == DocumentEntry) - { - // PDBs (more specifically the DIA APIs) only check the start line number and not the end line number when - // trying to determine whether a sequence point covers the specified line number. We need to match this - // behaviour here. For backward compatibility reasons, GetMethodFromDocumentPosition() is still checking - // against the entire range of a sequence point, but we should revisit that in the next release. - ULONG32 curLine = m_DataPointers.m_pSequencePoints[point].StartLine(); - - if (fExactMatch) - { - if (curLine == line) - { - found = true; - } - else if ((maxPreLine < curLine) && (curLine < line)) - { - // This is not an exact match, but let's keep track of the sequence point closest to the specified - // line. We'll use this info if we have to do a second pass. - maxPreLine = curLine; - } - } - else - { - // We are in the second pass, looking for approximate matches. - if ((maxPreLine != 0) && (maxPreLine == curLine)) - { - // Make sure the sequence point covers the specified line. - if (m_DataPointers.m_pSequencePoints[point].IsWithinLineOnly(line)) - { - found = true; - } - } - } - - // If we have found a match (whether it's exact or approximate), then save this method unless the caller is - // only interested in the number of matching methods or the array provided by the caller isn't big enough. - if (found) - { - if (CurMethod < cMethod) - { - IfFailGo(GetMethod(m_DataPointers.m_pMethods[Method].MethodToken(), &(ppRetVal[CurMethod]))); - } - CurMethod++; - break; - } - } - } - - if (found) - { - // If we have already filled out the entire array provided by the caller, then we are done. - if ((cMethod > 0) && (cMethod == CurMethod)) - { - break; - } - else - { - // Otherwise move on to the next method. - continue; - } - } - } - - // If we haven't found an exact match, then try it again looking for a sequence point covering the specified line. - if (fExactMatch && (CurMethod == 0)) - { - fExactMatch = false; - continue; - } - else - { - // If we have found an exact match, or if we have done two passes already, then bail. - break; - } - } - - // Note that unlike GetMethodFromDocumentPosition(), this function returns S_OK even if a match is not found. - if (SUCCEEDED(hr)) - { - if (pcMethod != NULL) - { - *pcMethod = CurMethod; - } - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetSymbolStoreFileName -//----------------------------------------------------------- -HRESULT -SymReader::GetSymbolStoreFileName( - ULONG32 cchName, // Length of szName - ULONG32 *pcchName, // [Optional] - __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[] // [Optional] - ) -{ - _ASSERTE(m_fInitialized); - if (!m_fInitialized) - return E_UNEXPECTED; - - if (pcchName) - { - *pcchName = (ULONG32)(wcslen(m_szPath)+1); - } - - if( szName ) - { - if (wcsncpy_s( szName, cchName, m_szPath, _TRUNCATE) == STRUNCATE) - return HrFromWin32(ERROR_INSUFFICIENT_BUFFER); - } - - return NOERROR; -} - -//----------------------------------------------------------- -// GetMethodVersion -//----------------------------------------------------------- -HRESULT -SymReader::GetMethodVersion( - ISymUnmanagedMethod * pMethod, - int* pVersion - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(pMethod && pVersion); - IfFalseGo( pMethod && pVersion, E_INVALIDARG); - // This symbol store only supports one version of a method - *pVersion = 0; -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetDocumentVersion -//----------------------------------------------------------- -HRESULT -SymReader::GetDocumentVersion( - ISymUnmanagedDocument* pDoc, - int* pVersion, - BOOL* pbCurrent // [Optional] - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(pVersion && pDoc); - IfFalseGo(pVersion, E_INVALIDARG); - IfFalseGo(pDoc, E_INVALIDARG); - - // This symbol store only supports one version of a document - *pVersion = 0; - if (pbCurrent) - { - *pbCurrent = TRUE; - } -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetDocument -// Return the document for the given entry -//----------------------------------------------------------- -HRESULT SymReader::GetDocument( - UINT32 DocumentEntry, - SymDocument **ppDocument) -{ - HRESULT hr = NOERROR; - - _ASSERTE(m_fInitialized); - IfFalseGo(m_fInitialized, E_UNEXPECTED); - - _ASSERTE(ppDocument); - IfFalseGo(ppDocument, E_INVALIDARG); - - _ASSERTE(DocumentEntry < m_pPDBInfo->m_CountOfDocuments); - IfFalseGo(DocumentEntry < m_pPDBInfo->m_CountOfDocuments, E_INVALIDARG); - - if (m_pDocs == NULL) - { - IfNullGo(m_pDocs = NEW(SymDocument *[m_pPDBInfo->m_CountOfDocuments])); - memset(m_pDocs, 0, m_pPDBInfo->m_CountOfDocuments * sizeof(void *)); - } - - if (m_pDocs[DocumentEntry] == NULL) - { - m_pDocs[DocumentEntry] = NEW(SymDocument(this, &m_DataPointers, m_pPDBInfo->m_CountOfMethods, DocumentEntry)); - IfNullGo(m_pDocs[DocumentEntry]); - // AddRef the table version - m_pDocs[DocumentEntry]->AddRef(); - - } - - //Set and AddRef the Out Parameter - *ppDocument = m_pDocs[DocumentEntry]; - (*ppDocument)->AddRef(); - -ErrExit: - return hr; -} - -HRESULT -SymReader::UpdateSymbolStore( - const WCHAR *filename, - IStream *pIStream - ) -{ - // This symbol store doesn't support updating the symbol store. - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -HRESULT -SymReader::ReplaceSymbolStore( - const WCHAR *filename, - IStream *pIStream - ) -{ - // This symbol store doesn't support updating the symbol store. - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetVariables -//----------------------------------------------------------- -HRESULT -SymReader::GetVariables( - mdToken parent, - ULONG32 cVars, - ULONG32 *pcVars, - ISymUnmanagedVariable *pVars[] - ) -{ - // - // This symbol reader doesn't support non-local variables. - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetGlobalVariables -//----------------------------------------------------------- -HRESULT -SymReader::GetGlobalVariables( - ULONG32 cVars, - ULONG32 *pcVars, - ISymUnmanagedVariable *pVars[] - ) -{ - // - // This symbol reader doesn't support non-local variables. - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetSymAttribute -//----------------------------------------------------------- -HRESULT -SymReader::GetSymAttribute( - mdToken parent, - __in LPWSTR name, - ULONG32 cBuffer, - ULONG32 *pcBuffer, - __out_bcount_part_opt(cBuffer, *pcBuffer) BYTE buffer[] - ) -{ - // This symbol store doesn't support attributes - // VS may query for certain attributes, but will survive without them, - // so don't ASSERT here. - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetNamespaces -//----------------------------------------------------------- -HRESULT -SymReader::GetNamespaces( - ULONG32 cNameSpaces, - ULONG32 *pcNameSpaces, - ISymUnmanagedNamespace *namespaces[] - ) -{ - // This symbol store doesn't support this - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -/* ------------------------------------------------------------------------- * - * SymDocument class - * ------------------------------------------------------------------------- */ - -HRESULT -SymDocument::QueryInterface( - REFIID riid, - void **ppInterface - ) -{ - if (ppInterface == NULL) - return E_INVALIDARG; - - if (riid == IID_ISymUnmanagedDocument) - *ppInterface = (ISymUnmanagedDocument*)this; - else if (riid == IID_IUnknown) - *ppInterface = (IUnknown*)(ISymUnmanagedDocument*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - - -//----------------------------------------------------------- -// GetURL -//----------------------------------------------------------- -HRESULT -SymDocument::GetURL( - ULONG32 cchUrl, // The allocated size of the buffer - ULONG32 *pcchUrl, // [optional,out] The number of characters available for return - __out_ecount_part_opt(cchUrl, *pcchUrl) WCHAR szUrl[] // [optional,out] The string buffer. - ) -{ - if (pcchUrl) - { - // Convert the UTF8 string to Wide - *pcchUrl = (ULONG32) MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_pData->m_pStringsBytes[m_pData->m_pDocuments[m_DocumentEntry].UrlEntry()]), - -1, - 0, - NULL); - } - - if( szUrl ) - { - // Convert the UTF8 string to Wide - MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_pData->m_pStringsBytes[m_pData->m_pDocuments[m_DocumentEntry].UrlEntry()]), - -1, - szUrl, - cchUrl); - } - return NOERROR; -} - -//----------------------------------------------------------- -// GetDocumentType -//----------------------------------------------------------- -HRESULT -SymDocument::GetDocumentType( - GUID *pRetVal - ) -{ - HRESULT hr = NOERROR; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - *pRetVal = m_pData->m_pDocuments[m_DocumentEntry].DocumentType(); - SwapGuid(pRetVal); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetLanguage -//----------------------------------------------------------- -HRESULT -SymDocument::GetLanguage( - GUID *pRetVal - ) -{ - HRESULT hr = NOERROR; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - - *pRetVal = m_pData->m_pDocuments[m_DocumentEntry].Language(); - SwapGuid(pRetVal); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetLanguageVendor -//----------------------------------------------------------- -HRESULT -SymDocument::GetLanguageVendor( - GUID *pRetVal - ) -{ - HRESULT hr = NOERROR; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - *pRetVal = m_pData->m_pDocuments[m_DocumentEntry].LanguageVendor(); - SwapGuid(pRetVal); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetCheckSumAlgorithmId -//----------------------------------------------------------- -HRESULT -SymDocument::GetCheckSumAlgorithmId( - GUID *pRetVal - ) -{ - HRESULT hr = NOERROR; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - *pRetVal = m_pData->m_pDocuments[m_DocumentEntry].AlgorithmId(); - SwapGuid(pRetVal); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetCheckSum -//----------------------------------------------------------- -HRESULT -SymDocument::GetCheckSum( - ULONG32 cData, // The allocated size of the buffer. - ULONG32 *pcData, // [optional] The number of bytes available for return - BYTE data[]) // [optional] The buffer to receive the checksum. -{ - BYTE *pCheckSum = &m_pData->m_pBytes[m_pData->m_pDocuments[m_DocumentEntry].CheckSumEntry()]; - ULONG32 CheckSumSize = m_pData->m_pDocuments[m_DocumentEntry].CheckSumSize(); - if (pcData) - { - *pcData = CheckSumSize; - } - if(data) - { - memcpy(data, pCheckSum, min(CheckSumSize, cData)); - } - return NOERROR; -} - -//----------------------------------------------------------- -// FindClosestLine -// Search the sequence points looking a line that is closest -// line following this one that is a sequence point -//----------------------------------------------------------- -HRESULT -SymDocument::FindClosestLine( - ULONG32 line, - ULONG32 *pRetVal - ) -{ - HRESULT hr = NOERROR; - UINT32 Method; - UINT32 point; - ULONG32 closestLine = 0; // GCC can't tell this isn't used before initialization - bool found = false; - - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - - // Walk all Methods, check their Document and SequencePoints to see if it's in this doc - // and the line/column - for (Method = 0; Method < m_CountOfMethods; Method++) - { - // Walk the sequence points - for (point = m_pData->m_pMethods[Method].StartSequencePoints(); - point < m_pData->m_pMethods[Method].EndSequencePoints(); - point++) - { - SequencePoint & sp = m_pData->m_pSequencePoints[point]; - // Check to see if this sequence point is in this doc, and is at or - // after the requested line - if ((sp.Document() == m_DocumentEntry) && sp.IsUserLine()) - { - if (sp.IsWithin(line, 0) || sp.IsGreaterThan(line, 0)) - { - // This sequence point is at or after the requested line. If we haven't - // already found a "closest", or this is even closer than the one we have, - // then mark this as the best line so far. - if (!found || m_pData->m_pSequencePoints[point].StartLine() < closestLine) - { - found = true; - closestLine = m_pData->m_pSequencePoints[point].StartLine(); - } - } - } - } - } - - if (found) - { - *pRetVal = closestLine; - } - else - { - // Didn't find any lines at or after the one requested. - hr = E_FAIL; - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymDocument HasEmbeddedSource -//----------------------------------------------------------- -HRESULT -SymDocument::HasEmbeddedSource( - BOOL *pRetVal - ) -{ - // - // This symbol reader doesn't support embedded source. - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// SymDocument GetSourceLength -//----------------------------------------------------------- -HRESULT -SymDocument::GetSourceLength( - ULONG32 *pRetVal - ) -{ - // - // This symbol reader doesn't support embedded source. - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// SymDocument GetSourceRange -//----------------------------------------------------------- -HRESULT -SymDocument::GetSourceRange( - ULONG32 startLine, - ULONG32 startColumn, - ULONG32 endLine, - ULONG32 endColumn, - ULONG32 cSourceBytes, - ULONG32 *pcSourceBytes, - BYTE source[] - ) -{ - // - // This symbol reader doesn't support embedded source. - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -/* ------------------------------------------------------------------------- * - * SymMethod class - * ------------------------------------------------------------------------- */ -HRESULT -SymMethod::QueryInterface( - REFIID riid, - void **ppInterface - ) -{ - if (ppInterface == NULL) - return E_INVALIDARG; - - if (riid == IID_ISymUnmanagedMethod) - *ppInterface = (ISymUnmanagedMethod*)this; - else if (riid == IID_IUnknown) - *ppInterface = (IUnknown*)(ISymUnmanagedMethod*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - -//----------------------------------------------------------- -// GetToken -//----------------------------------------------------------- -HRESULT -SymMethod::GetToken( - mdMethodDef *pRetVal -) -{ - HRESULT hr = S_OK; - - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - *pRetVal = m_pData->m_pMethods[m_MethodEntry].MethodToken(); -ErrExit: - return hr; -} - - -//----------------------------------------------------------- -// GetSequencePointCount -//----------------------------------------------------------- -HRESULT -SymMethod::GetSequencePointCount( - ULONG32* pRetVal - ) -{ - - HRESULT hr = S_OK; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - - *pRetVal = (ULONG32)(m_pData->m_pMethods[m_MethodEntry].EndSequencePoints() - - m_pData->m_pMethods[m_MethodEntry].StartSequencePoints()); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetSequencePoints -//----------------------------------------------------------- -HRESULT -SymMethod::GetSequencePoints( - ULONG32 cPoints, // The size of the allocated arrays. - ULONG32* pcPoints, // [optional] The number of sequence points available for return. - ULONG32 offsets[], // [optional] - ISymUnmanagedDocument *documents[], // [Optional] - ULONG32 lines[], // [Optional] - ULONG32 columns[], // [Optional] - ULONG32 endLines[], // [Optional] - ULONG32 endColumns[] // [Optional] - ) -{ - HRESULT hr = NOERROR; - UINT32 i = 0; - ULONG32 Points = 0; - - for (i = m_pData->m_pMethods[m_MethodEntry].StartSequencePoints(); - (i < m_pData->m_pMethods[m_MethodEntry].EndSequencePoints()); - i++, Points++) - { - if (Points < cPoints) - { - if (documents) - { - SymDocument *pDoc; - IfFailGo(m_pReader->GetDocument(m_pData->m_pSequencePoints[i].Document(), &pDoc)); - documents[Points] = pDoc; - } - - if (offsets) - { - offsets[Points] = m_pData->m_pSequencePoints[i].Offset(); - } - - if (lines) - { - lines[Points] = m_pData->m_pSequencePoints[i].StartLine(); - } - if (columns) - { - columns[Points] = m_pData->m_pSequencePoints[i].StartColumn(); - } - if (endLines) - { - endLines[Points] = m_pData->m_pSequencePoints[i].EndLine(); - } - if (endColumns) - { - endColumns[Points] = m_pData->m_pSequencePoints[i].EndColumn(); - } - } - } - - if (pcPoints) - { - *pcPoints = Points; - } - -ErrExit: - if (FAILED(hr)) - { - if (documents) - { - unsigned j; - for (j = 0; j < i; j++) - { - RELEASE(documents[i]); - } - } - } - return hr; -} - -//----------------------------------------------------------- -// GetRootScope -//----------------------------------------------------------- -HRESULT -SymMethod::GetRootScope( - ISymUnmanagedScope **ppRetVal - ) -{ - HRESULT hr = S_OK; - SymScope *pScope = NULL; - _ASSERTE(ppRetVal); - IfFalseGo(ppRetVal, E_INVALIDARG); - - // Init Out Param - *ppRetVal = NULL; - if (m_pData->m_pMethods[m_MethodEntry].EndScopes() - m_pData->m_pMethods[m_MethodEntry].StartScopes()) - { - IfNullGo(pScope = NEW(SymScope(this, m_pData, m_MethodEntry, m_pData->m_pMethods[m_MethodEntry].StartScopes()))); - pScope->AddRef(); - *ppRetVal = pScope; - } -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetOffset -// Given a position in a document, gets the offset within the -// method that corresponds to the position. -//----------------------------------------------------------- -HRESULT -SymMethod::GetOffset( - ISymUnmanagedDocument *document, - ULONG32 line, - ULONG32 column, - ULONG32 *pRetVal - ) -{ - HRESULT hr = S_OK; - bool fFound = false; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - - UINT32 point; - UINT32 DocumentEntry; - - DocumentEntry = ((SymDocument *)document)->GetDocumentEntry(); - - // Walk the sequence points - for (point = m_pData->m_pMethods[m_MethodEntry].StartSequencePoints(); - point < m_pData->m_pMethods[m_MethodEntry].EndSequencePoints(); - point++) - { - // Check to see if this sequence point is in this doc - if (m_pData->m_pSequencePoints[point].Document() == DocumentEntry) - { - // Check to see if it's within the sequence point - if (m_pData->m_pSequencePoints[point].IsWithin(line, column)) - { - *pRetVal = m_pData->m_pSequencePoints[point].Offset(); - fFound = true; - break; - } - } - } - if (!fFound) - { - hr = E_FAIL; - } -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetRanges -//----------------------------------------------------------- -HRESULT -SymMethod::GetRanges( - ISymUnmanagedDocument *pDocument, // [in] Document we're working on - ULONG32 line, // [in] The document line corresponding to the ranges. - ULONG32 column, // [in] Ignored - ULONG32 cRanges, // [in] The size of the allocated ranges[] array. - ULONG32 *pcRanges, // [out] The number of ranges available for return - ULONG32 ranges[] // [out] The range array. - ) -{ - HRESULT hr = NOERROR; - DWORD iRange = 0; - UINT32 DocumentEntry; - UINT32 point; - bool fFound = false; - - // Validate some of the parameters - _ASSERTE(pDocument && (cRanges % 2) == 0); - IfFalseGo(pDocument, E_INVALIDARG); - IfFalseGo((cRanges % 2) == 0, E_INVALIDARG); - - // Init out parameter - if (pcRanges) - { - *pcRanges=0; - } - - DocumentEntry = ((SymDocument *)pDocument)->GetDocumentEntry(); - - // Walk the sequence points - for (point = m_pData->m_pMethods[m_MethodEntry].StartSequencePoints(); - point < m_pData->m_pMethods[m_MethodEntry].EndSequencePoints(); - point++) - { - // Check to see if this sequence point is in this doc - if (m_pData->m_pSequencePoints[point].Document() == DocumentEntry) - { - // Check to see if the line is within this sequence - // Note, to be compatible with VS7, ignore the column information - if (line >= m_pData->m_pSequencePoints[point].StartLine() && - line <= m_pData->m_pSequencePoints[point].EndLine()) - { - fFound = true; - break; - } - } - } - - if (fFound) - { - for (;point < m_pData->m_pMethods[m_MethodEntry].EndSequencePoints(); point++) - { - - // Search through all the sequence points since line might have there - // IL spread across multiple ranges (for loops for example) - if (m_pData->m_pSequencePoints[point].Document() == DocumentEntry && - line >= m_pData->m_pSequencePoints[point].StartLine() && - line <= m_pData->m_pSequencePoints[point].EndLine()) - { - if (iRange < cRanges) - { - ranges[iRange] = m_pData->m_pSequencePoints[point].Offset(); - } - iRange++; - if (iRange < cRanges) - { - if (point+1 < m_pData->m_pMethods[m_MethodEntry].EndSequencePoints()) - { - ranges[iRange] = m_pData->m_pSequencePoints[point+1].Offset(); - } - else - { - // Then it must be till the end of the function which is the root scope's endoffset - ranges[iRange] = m_pData->m_pScopes[m_pData->m_pMethods[m_MethodEntry].StartScopes()].EndOffset()+1; - } - } - iRange++; - } - } - if (pcRanges) - { - // If cRanges passed in, return the number - // of elements actually filled in - if (cRanges) - { - *pcRanges = min(iRange, cRanges); - } - else - { - // Otherwise return the max number - *pcRanges = iRange; - } - } - } - else - { - return E_FAIL; - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetScopeFromOffset -//----------------------------------------------------------- -HRESULT -SymMethod::GetScopeFromOffset( - ULONG32 offset, - ISymUnmanagedScope **pRetVal - ) -{ - // - // This symbol reader doesn't support this functionality - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetParameters -//----------------------------------------------------------- -HRESULT -SymMethod::GetParameters( - ULONG32 cParams, - ULONG32 *pcParams, - ISymUnmanagedVariable *params[] - ) -{ - // - // This symbol reader doesn't support parameter access. Parameters - // can be found in the normal metadata. - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetNamespace -//----------------------------------------------------------- -HRESULT -SymMethod::GetNamespace( - ISymUnmanagedNamespace **ppRetVal - ) -{ - // - // This symbol reader doesn't support namespaces - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetSourceStartEnd -//----------------------------------------------------------- -HRESULT -SymMethod::GetSourceStartEnd( - ISymUnmanagedDocument *docs[2], - ULONG32 lines[2], - ULONG32 columns[2], - BOOL *pRetVal - ) -{ - // - // This symbol reader doesn't support source start/end for methods. - // - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -/* ------------------------------------------------------------------------- * - * SymScope class - * ------------------------------------------------------------------------- */ - -//----------------------------------------------------------- -// QueryInterface -//----------------------------------------------------------- -HRESULT -SymScope::QueryInterface( - REFIID riid, - void **ppInterface - ) -{ - if (ppInterface == NULL) - return E_INVALIDARG; - - if (riid == IID_ISymUnmanagedScope) - *ppInterface = (ISymUnmanagedScope*)this; - else if (riid == IID_IUnknown) - *ppInterface = (IUnknown*)(ISymUnmanagedScope*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - -//----------------------------------------------------------- -// GetMethod -//----------------------------------------------------------- -HRESULT -SymScope::GetMethod( - ISymUnmanagedMethod **ppRetVal - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(ppRetVal); - IfFalseGo(ppRetVal, E_INVALIDARG); - - *ppRetVal = m_pSymMethod; - m_pSymMethod->AddRef(); - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetParent -//----------------------------------------------------------- -HRESULT -SymScope::GetParent( - ISymUnmanagedScope **ppRetVal - ) -{ - HRESULT hr = S_OK; - _ASSERTE(ppRetVal); - IfFalseGo(ppRetVal, E_INVALIDARG); - if (m_pData->m_pScopes[m_ScopeEntry].ParentScope() != (UINT32)-1) - { - IfNullGo(*ppRetVal = static_cast(NEW(SymScope(m_pSymMethod, m_pData, m_MethodEntry, - m_pData->m_pScopes[m_ScopeEntry].ParentScope())))); - (*ppRetVal)->AddRef(); - } - else - { - *ppRetVal = NULL; - } -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetChildren -//----------------------------------------------------------- -HRESULT -SymScope::GetChildren( - ULONG32 cChildren, // [optional] Number of entries in children - ULONG32 *pcChildren, // [optional, out] Number of Children available for retur - ISymUnmanagedScope *children[] // [optional] array to store children into - ) -{ - HRESULT hr = S_OK; - ULONG32 ChildrenCount = 0; - _ASSERTE(pcChildren || (children && cChildren)); - IfFalseGo((pcChildren || (children && cChildren)), E_INVALIDARG); - - if (m_pData->m_pScopes[m_ScopeEntry].HasChildren()) - { - UINT32 ScopeEntry; - for(ScopeEntry = m_pData->m_pMethods[m_MethodEntry].StartScopes(); - (ScopeEntry < m_pData->m_pMethods[m_MethodEntry].EndScopes()); - ScopeEntry++) - { - if (m_pData->m_pScopes[ScopeEntry].ParentScope() == m_ScopeEntry) - { - if (children && ChildrenCount < cChildren) - { - SymScope *pScope; - // Found a child - IfNullGo(pScope = NEW(SymScope(m_pSymMethod, m_pData, m_MethodEntry, ScopeEntry))); - children[ChildrenCount] = pScope; - pScope->AddRef(); - } - ChildrenCount++; - } - } - } - - if (pcChildren) - { - *pcChildren = ChildrenCount; - } - -ErrExit: - if (FAILED(hr) && ChildrenCount) - { - unsigned i; - for (i =0; i< ChildrenCount; i++) - { - RELEASE(children[i]); - } - } - return hr; -} - -//----------------------------------------------------------- -// GetStartOffset -//----------------------------------------------------------- -HRESULT -SymScope::GetStartOffset( - ULONG32* pRetVal - ) -{ - HRESULT hr = S_OK; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - *pRetVal = m_pData->m_pScopes[m_ScopeEntry].StartOffset(); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetEndOffset -//----------------------------------------------------------- -HRESULT -SymScope::GetEndOffset( - ULONG32* pRetVal - ) -{ - HRESULT hr = S_OK; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - *pRetVal = m_pData->m_pScopes[m_ScopeEntry].EndOffset(); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetLocalCount -//----------------------------------------------------------- -HRESULT -SymScope::GetLocalCount( - ULONG32 *pRetVal - ) -{ - HRESULT hr = S_OK; - ULONG32 LocalCount = 0; - _ASSERTE(pRetVal); - IfFalseGo(pRetVal, E_INVALIDARG); - - // Init out parameter - *pRetVal = 0; - if (m_pData->m_pScopes[m_ScopeEntry].HasVars()) - { - UINT32 var; - // Walk and get the locals for this Scope - for (var = m_pData->m_pMethods[m_MethodEntry].StartVars(); - var < m_pData->m_pMethods[m_MethodEntry].EndVars(); - var++) - { - if (m_pData->m_pVars[var].Scope() == m_ScopeEntry && - m_pData->m_pVars[var].IsParam() == false) - { - LocalCount++; - } - } - } - - *pRetVal = LocalCount; -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetLocals -// Input: either pcLocals or -// cLocals and pLocals -//----------------------------------------------------------- -HRESULT -SymScope::GetLocals( - ULONG32 cLocals, // [optional] available entries in pLocals - ULONG32 *pcLocals, // [optional, out] Number of locals returned - ISymUnmanagedVariable *pLocals[] // [optional] array to store locals into - ) -{ - HRESULT hr = S_OK; - - ULONG32 LocalCount = 0; - _ASSERTE(pcLocals || pLocals); - IfFalseGo(pcLocals || pLocals, E_INVALIDARG); - - if (m_pData->m_pScopes[m_ScopeEntry].HasVars()) - { - UINT32 var; - // Walk and get the locals for this Scope - for (var = m_pData->m_pMethods[m_MethodEntry].StartVars(); - var < m_pData->m_pMethods[m_MethodEntry].EndVars(); - var++) - { - if (m_pData->m_pVars[var].Scope() == m_ScopeEntry && - m_pData->m_pVars[var].IsParam() == false) - { - if (pLocals && LocalCount < cLocals) - { - SymReaderVar *pVar; - IfNullGo( pVar = NEW(SymReaderVar(this, m_pData, var))); - pLocals[LocalCount] = pVar; - pVar->AddRef(); - } - LocalCount++; - } - } - } - if (pcLocals) - { - *pcLocals = LocalCount; - } -ErrExit: - if (FAILED(hr) && LocalCount != 0) - { - unsigned i; - for (i =0; i < LocalCount; i++) - { - RELEASE(pLocals[i]); - } - } - return hr; -} - -//----------------------------------------------------------- -// GetNamespaces -// Input: either pcNameSpaces or -// cNameSpaces and pNameSpaces -//----------------------------------------------------------- -HRESULT -SymScope::GetNamespaces( - ULONG32 cNameSpaces, // [optional] number of entries pNameSpaces - ULONG32 *pcNameSpaces, // [optional, out] Maximum number of Namespace - ISymUnmanagedNamespace *pNameSpaces[] // [optional] array to store namespaces into - ) -{ - HRESULT hr = NOERROR; - unsigned i; - UINT32 NameSpace; - unsigned NameSpaceCount = 0; - - _ASSERTE(pcNameSpaces || (pNameSpaces && cNameSpaces)); - IfFalseGo(pcNameSpaces || (pNameSpaces && cNameSpaces), E_INVALIDARG); - - for (NameSpace = m_pData->m_pMethods[m_MethodEntry].StartUsing(); - NameSpace < m_pData->m_pMethods[m_MethodEntry].EndUsing(); - NameSpace++) - { - if (m_pData->m_pUsings[NameSpace].ParentScope() == m_ScopeEntry) - { - if (pNameSpaces && (NameSpaceCount < cNameSpaces) ) - { - IfNullGo(pNameSpaces[NameSpaceCount] = NEW(SymReaderNamespace(this, m_pData, NameSpace))); - pNameSpaces[NameSpaceCount]->AddRef(); - } - NameSpaceCount++; - } - } - if (pcNameSpaces) - { - *pcNameSpaces = NameSpaceCount; - } -ErrExit: - if (FAILED(hr) && pNameSpaces) - { - for (i = 0; (i < cNameSpaces) && (i < NameSpaceCount); i++) - { - RELEASE(pNameSpaces[i]); - } - } - return hr; -} - -/* ------------------------------------------------------------------------- * - * SymReaderVar class - * ------------------------------------------------------------------------- */ - -//----------------------------------------------------------- -// QueryInterface -//----------------------------------------------------------- -HRESULT -SymReaderVar::QueryInterface( - REFIID riid, - void **ppInterface - ) -{ - if (ppInterface == NULL) - return E_INVALIDARG; - - if (riid == IID_ISymUnmanagedVariable) - *ppInterface = (ISymUnmanagedVariable*)this; - else if (riid == IID_IUnknown) - *ppInterface = (IUnknown*)(ISymUnmanagedVariable*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - -//----------------------------------------------------------- -// GetName -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetName( - ULONG32 cchName, // [optional] Length of szName buffer - ULONG32 *pcchName, // [optional, out] Total size needed to return the name - __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[] // [optional] Buffer to store the name into. - ) -{ - HRESULT hr = S_OK; - - // We must have at least one combination - _ASSERTE(pcchName || (szName && cchName)); - IfFalseGo( (pcchName || (szName && cchName)), E_INVALIDARG ); - - if (pcchName) - { - // Convert the UTF8 string to Wide - *pcchName = (ULONG32) MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_pData->m_pStringsBytes[m_pData->m_pVars[m_VarEntry].Name()]), - -1, - 0, - NULL); - - } - if (szName) - { - // Convert the UTF8 string to Wide - MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_pData->m_pStringsBytes[m_pData->m_pVars[m_VarEntry].Name()]), - -1, - szName, - cchName); - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetAttributes -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetAttributes( - ULONG32 *pRetVal // [out] - ) -{ - if (pRetVal == NULL) - return E_INVALIDARG; - - *pRetVal = m_pData->m_pVars[m_VarEntry].Attributes(); - return S_OK; -} - -//----------------------------------------------------------- -// GetSignature -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetSignature( - ULONG32 cSig, // Size of allocated buffer passed in (sig) - ULONG32 *pcSig, // [optional, out] Total size needed to return the signature - BYTE sig[] // [Optional] Signature - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(pcSig || sig); - IfFalseGo( pcSig || sig, E_INVALIDARG ); - if (pcSig) - { - *pcSig = m_pData->m_pVars[m_VarEntry].SignatureSize(); - } - if (sig) - { - cSig = min(m_pData->m_pVars[m_VarEntry].SignatureSize(), cSig); - memcpy(sig, &m_pData->m_pBytes[m_pData->m_pVars[m_VarEntry].Signature()],cSig); - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetAddressKind -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetAddressKind( - ULONG32 *pRetVal // [out] - ) -{ - HRESULT hr = S_OK; - _ASSERTE(pRetVal); - IfFalseGo( pRetVal, E_INVALIDARG ); - *pRetVal = m_pData->m_pVars[m_VarEntry].AddrKind(); -ErrExit: - return S_OK; -} - -//----------------------------------------------------------- -// GetAddressField1 -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetAddressField1( - ULONG32 *pRetVal // [out] - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(pRetVal); - IfFalseGo( pRetVal, E_INVALIDARG ); - - *pRetVal = m_pData->m_pVars[m_VarEntry].Addr1(); - -ErrExit: - - return hr; -} - -//----------------------------------------------------------- -// GetAddressField2 -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetAddressField2( - ULONG32 *pRetVal // [out] - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(pRetVal); - IfFalseGo( pRetVal, E_INVALIDARG ); - - *pRetVal = m_pData->m_pVars[m_VarEntry].Addr2(); - -ErrExit: - - return hr; -} - -//----------------------------------------------------------- -// GetAddressField3 -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetAddressField3( - ULONG32 *pRetVal // [out] - ) -{ - HRESULT hr = S_OK; - - _ASSERTE(pRetVal); - IfFalseGo( pRetVal, E_INVALIDARG ); - - *pRetVal = m_pData->m_pVars[m_VarEntry].Addr3(); - -ErrExit: - - return hr; -} - -//----------------------------------------------------------- -// GetStartOffset -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetStartOffset( - ULONG32 *pRetVal - ) -{ - // - // This symbol reader doesn't support variable sub-offsets. - // - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetEndOffset -//----------------------------------------------------------- -HRESULT -SymReaderVar::GetEndOffset( - ULONG32 *pRetVal - ) -{ - // - // This symbol reader doesn't support variable sub-offsets. - // - return E_NOTIMPL; -} - - -/* ------------------------------------------------------------------------- * - * SymReaderNamespace class - * ------------------------------------------------------------------------- */ - -//----------------------------------------------------------- -// QueryInterface -//----------------------------------------------------------- -HRESULT -SymReaderNamespace::QueryInterface( - REFIID riid, - void** ppInterface - ) -{ - if (ppInterface == NULL) - return E_INVALIDARG; - - if (riid == IID_ISymUnmanagedNamespace) - *ppInterface = (ISymUnmanagedNamespace*)this; - else if (riid == IID_IUnknown) - *ppInterface = (IUnknown*)(ISymUnmanagedNamespace*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - -//----------------------------------------------------------- -// GetName -//----------------------------------------------------------- -HRESULT -SymReaderNamespace::GetName( - ULONG32 cchName, // [optional] Chars available in szName - ULONG32 *pcchName, // [optional] Total size needed to return the name - __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[] // [optional] Location to store the name into. - ) -{ - HRESULT hr = S_OK; - _ASSERTE(pcchName || (szName && cchName)); - IfFalseGo( (pcchName || (szName && cchName)), E_INVALIDARG ); - - if (pcchName) - { - *pcchName = (ULONG32) MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_pData->m_pStringsBytes[m_pData->m_pUsings[m_NamespaceEntry].Name()]), - -1, - 0, - NULL); - } - if (szName) - { - MultiByteToWideChar(CP_UTF8, - 0, - (LPCSTR)&(m_pData->m_pStringsBytes[m_pData->m_pUsings[m_NamespaceEntry].Name()]), - -1, - szName, - cchName); - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// GetNamespaces -//----------------------------------------------------------- -HRESULT -SymReaderNamespace::GetNamespaces( - ULONG32 cNamespaces, - ULONG32 *pcNamespaces, - ISymUnmanagedNamespace* namespaces[] - ) -{ - // This symbol store doesn't support namespaces. - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// GetVariables -//----------------------------------------------------------- -HRESULT -SymReaderNamespace::GetVariables( - ULONG32 cVariables, - ULONG32 *pcVariables, - ISymUnmanagedVariable *pVars[]) -{ - // This symbol store doesn't support namespaces. - _ASSERTE(!"NYI"); - return E_NOTIMPL; -} - - -/* ------------------------------------------------------------------------- * - * SequencePoint struct functions - * ------------------------------------------------------------------------- */ - -//----------------------------------------------------------- -// IsWithin - Is the point given within this sequence point -//----------------------------------------------------------- -bool SequencePoint::IsWithin( - ULONG32 line, - ULONG32 column) -{ - // If the sequence point starts on the same line - // Check the start column (if present) - if (StartLine() == line) - { - if (0 < column && StartColumn() > column) - { - return false; - } - } - - // If the sequence point ends on the same line - // Check the end column - if (EndLine() == line) - { - if (EndColumn() < column) - { - return false; - } - } - - // Make sure the line is within this sequence point - if (!((StartLine() <= line) && (EndLine() >= line))) - { - return false; - } - - // Yep it's within this sequence point - return true; - -} - -//----------------------------------------------------------- -// IsWithinLineOnly - Is the given line within this sequence point -//----------------------------------------------------------- -bool SequencePoint::IsWithinLineOnly( - ULONG32 line) -{ - return ((StartLine() <= line) && (line <= EndLine())); -} - -//----------------------------------------------------------- -// IsGreaterThan - Is the sequence point greater than the position -//----------------------------------------------------------- -bool SequencePoint::IsGreaterThan( - ULONG32 line, - ULONG32 column) -{ - return (StartLine() > line) || - (StartLine() == line && StartColumn() > column); -} - -//----------------------------------------------------------- -// IsLessThan - Is the sequence point less than the position -//----------------------------------------------------------- -bool SequencePoint::IsLessThan -( - ULONG32 line, - ULONG32 column -) -{ - return (StartLine() < line) || - (StartLine() == line && StartColumn() < column); -} - -//----------------------------------------------------------- -// IsUserLine - Is the sequence part of user code -//----------------------------------------------------------- -bool SequencePoint::IsUserLine() -{ - return StartLine() != CODE_WITH_NO_SOURCE; -} diff --git a/src/coreclr/debug/ildbsymlib/symread.h b/src/coreclr/debug/ildbsymlib/symread.h deleted file mode 100644 index a82af393f32687..00000000000000 --- a/src/coreclr/debug/ildbsymlib/symread.h +++ /dev/null @@ -1,553 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: SymRead.h -// - -// =========================================================================== - -#ifndef SYMREAD_H_ -#define SYMREAD_H_ - -class SymScope; -class SymReaderVar; -class SymDocument; - -// ------------------------------------------------------------------------- -// SymReader class -// ------------------------------------------------------------------------- - -class SymReader : public ISymUnmanagedReader -{ -// ctor/dtor -public: - SymReader() - { - m_refCount = 0; - m_pPDBInfo = NULL; - m_pDocs = NULL; - m_pImporter = NULL; - m_fInitialized = false; - m_fInitializeFromStream = false; - memset(&m_DataPointers, 0, sizeof(PDBDataPointers)); - m_szPath[0] = '\0'; - } - virtual ~SymReader(); - static HRESULT NewSymReader( REFCLSID clsid, void** ppObj ); - -public: - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); - -// ISymUnmanagedReader -public: - STDMETHOD(GetDocument)(__in LPWSTR url, - GUID language, - GUID languageVendor, - GUID documentType, - ISymUnmanagedDocument **pRetVal); - STDMETHOD(GetDocuments)(ULONG32 cDocs, - ULONG32 *pcDocs, - ISymUnmanagedDocument *pDocs[]); - STDMETHOD(GetUserEntryPoint)(mdMethodDef *pRetVal); - STDMETHOD(GetMethod)(mdMethodDef method, - ISymUnmanagedMethod **pRetVal); - STDMETHOD(GetMethodByVersion)(mdMethodDef method, - int version, - ISymUnmanagedMethod **pRetVal); - STDMETHOD(GetVariables)(mdToken parent, - ULONG32 cVars, - ULONG32 *pcVars, - ISymUnmanagedVariable *pVars[]); - STDMETHOD(GetGlobalVariables)(ULONG32 cVars, - ULONG32 *pcVars, - ISymUnmanagedVariable *pVars[]); - STDMETHOD(GetMethodFromDocumentPosition)(ISymUnmanagedDocument *document, - ULONG32 line, - ULONG32 column, - ISymUnmanagedMethod **pRetVal); - STDMETHOD(GetSymAttribute)(mdToken parent, - __in LPWSTR name, - ULONG32 cBuffer, - ULONG32 *pcBuffer, - __out_bcount_part_opt(cBuffer, *pcBuffer) BYTE buffer[]); - STDMETHOD(GetNamespaces)(ULONG32 cNameSpaces, - ULONG32 *pcNameSpaces, - ISymUnmanagedNamespace *namespaces[]); - STDMETHOD(Initialize)(IUnknown *importer, - const WCHAR* szFileName, - const WCHAR* szsearchPath, - IStream *pIStream); - STDMETHOD(UpdateSymbolStore)(const WCHAR *filename, - IStream *pIStream); - - STDMETHOD(ReplaceSymbolStore)(const WCHAR *filename, - IStream *pIStream); - - STDMETHOD(GetSymbolStoreFileName)(ULONG32 cchName, - ULONG32 *pcchName, - __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]); - - STDMETHOD(GetMethodsFromDocumentPosition)(ISymUnmanagedDocument* document, - ULONG32 line, - ULONG32 column, - ULONG32 cMethod, - ULONG32* pcMethod, - ISymUnmanagedMethod* pRetVal[]); - - STDMETHOD(GetDocumentVersion)(ISymUnmanagedDocument *pDoc, int* version, BOOL* pbCurrent); - - STDMETHOD(GetMethodVersion)(ISymUnmanagedMethod* pMethod, int* version); - - //----------------------------------------------------------- - // Methods not exposed via a COM interface. - //----------------------------------------------------------- -public: - HRESULT GetDocument(UINT32 DocumentEntry, SymDocument **ppDocument); -private: - void Cleanup(); - - HRESULT InitializeFromFile(const WCHAR* szFileName, - const WCHAR* szsearchPath); - - HRESULT InitializeFromStream(IStream * pIStream); - - HRESULT VerifyPEDebugInfo(const WCHAR* szFileName); - - HRESULT ValidateData(); - - HRESULT ValidateBytes(UINT32 bytesIndex, UINT32 bytesLength); - -private: - // Data Members - UINT32 m_refCount; - - // Symbol File Name - WCHAR m_szPath[ _MAX_PATH ]; - WCHAR m_szStoredSymbolName[ _MAX_PATH ]; - - PDBInfo *m_pPDBInfo; - SymDocument **m_pDocs; - IUnknown *m_pImporter; - PDBDataPointers m_DataPointers; - - // Are we initialized yet? - bool m_fInitialized; - - // Did we initialize from stream - bool m_fInitializeFromStream; - }; - -/* ------------------------------------------------------------------------- * - * SymDocument class - * ------------------------------------------------------------------------- */ - -class SymDocument : public ISymUnmanagedDocument -{ -// ctor/dtor -public: - SymDocument(SymReader *pReader, - PDBDataPointers *pData, - UINT32 CountOfMethods, - UINT32 DocumentEntry) - { - m_refCount = 0; - m_pData = pData; - m_DocumentEntry = DocumentEntry; - m_CountOfMethods = CountOfMethods; - m_pReader = pReader; - pReader->AddRef(); - - } - virtual ~SymDocument() - { - RELEASE(m_pReader); - } - -// IUnknown -public: - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); - -// ISymUnmanagedDocument -public: - STDMETHOD(GetURL)(ULONG32 cchUrl, - ULONG32 *pcchUrl, - __out_ecount_part_opt(cchUrl, *pcchUrl) WCHAR szUrl[]); - STDMETHOD(GetDocumentType)(GUID *pRetVal); - STDMETHOD(GetLanguage)(GUID *pRetVal); - STDMETHOD(GetLanguageVendor)(GUID *pRetVal); - STDMETHOD(GetCheckSumAlgorithmId)(GUID *pRetVal); - STDMETHOD(GetCheckSum)(ULONG32 cData, - ULONG32 *pcData, - BYTE data[]); - STDMETHOD(FindClosestLine)(ULONG32 line, ULONG32 *pRetVal); - STDMETHOD(HasEmbeddedSource)(BOOL *pRetVal); - STDMETHOD(GetSourceLength)(ULONG32 *pRetVal); - STDMETHOD(GetSourceRange)(ULONG32 startLine, - ULONG32 startColumn, - ULONG32 endLine, - ULONG32 endColumn, - ULONG32 cSourceBytes, - ULONG32 *pcSourceBytes, - BYTE source[]); - - //----------------------------------------------------------- - // Methods not exposed via a COM interface. - //----------------------------------------------------------- - UINT32 GetDocumentEntry() - { - return m_DocumentEntry; - } - -// Data members -private: - UINT32 m_refCount; - - SymReader *m_pReader; - - // Data Pointer - PDBDataPointers *m_pData; - - // Entry into the document array - UINT32 m_DocumentEntry; - - // Total number of methods in the ildb - UINT32 m_CountOfMethods; - -}; - -/* ------------------------------------------------------------------------- * - * SymMethod class - * ------------------------------------------------------------------------- */ - -class SymMethod : public ISymUnmanagedMethod -{ -// ctor/dtor -public: - SymMethod(SymReader *pSymReader, PDBDataPointers *pData, UINT32 MethodEntry) - { - m_pData = pData; - m_MethodEntry = MethodEntry; - m_refCount = 0; - m_pReader = pSymReader; - pSymReader->AddRef(); - } - - virtual ~SymMethod() - { - RELEASE(m_pReader); - }; - -public: - - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); - -// ISymUnmanagedMethod -public: - STDMETHOD(GetToken)(mdMethodDef *pRetVal); - STDMETHOD(GetSequencePointCount)(ULONG32 *pRetVal); - - STDMETHOD(GetRootScope)(ISymUnmanagedScope **pRetVal); - STDMETHOD(GetScopeFromOffset)(ULONG32 offset, - ISymUnmanagedScope **pRetVal); - STDMETHOD(GetOffset)(ISymUnmanagedDocument *document, - ULONG32 line, - ULONG32 column, - ULONG32 *pRetVal); - STDMETHOD(GetRanges)(ISymUnmanagedDocument *document, - ULONG32 line, - ULONG32 column, - ULONG32 cRanges, - ULONG32 *pcRanges, - ULONG32 ranges[]); - STDMETHOD(GetParameters)(ULONG32 cParams, - ULONG32 *pcParams, - ISymUnmanagedVariable *params[]); - STDMETHOD(GetNamespace)(ISymUnmanagedNamespace **pRetVal); - STDMETHOD(GetSourceStartEnd)(ISymUnmanagedDocument *docs[2], - ULONG32 lines[2], - ULONG32 columns[2], - BOOL *pRetVal); - STDMETHOD(GetSequencePoints)(ULONG32 cpoints, - ULONG32* pcpoints, - ULONG32 offsets[], - ISymUnmanagedDocument *documents[], - ULONG32 lines[], - ULONG32 columns[], - ULONG32 endlines[], - ULONG32 endcolumns[]); - -// Data members -private: - // AddRef/Release support - UINT32 m_refCount; - - // Data Pointer - PDBDataPointers *m_pData; - - // SymReader - SymReader *m_pReader; - - // Entry into the SymMethodInfo array - UINT32 m_MethodEntry; - -}; - -/* ------------------------------------------------------------------------- * - * SymScope class - * ------------------------------------------------------------------------- */ - -class SymScope : public ISymUnmanagedScope -{ -// ctor/dtor -public: - SymScope( - ISymUnmanagedMethod *pSymMethod, - PDBDataPointers *pData, - UINT32 MethodEntry, - UINT32 ScopeEntry) - { - m_pSymMethod = pSymMethod; - m_pSymMethod->AddRef(); - m_pData = pData; - m_MethodEntry = MethodEntry; - m_ScopeEntry = ScopeEntry; - m_refCount = 0; - } - virtual ~SymScope() - { - RELEASE(m_pSymMethod); - } - -public: - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); - -// ISymUnmanagedScope -public: - STDMETHOD(GetMethod)(ISymUnmanagedMethod **pRetVal); - STDMETHOD(GetParent)(ISymUnmanagedScope **pRetVal); - STDMETHOD(GetChildren)(ULONG32 cChildren, - ULONG32 *pcChildren, - ISymUnmanagedScope *children[]); - STDMETHOD(GetStartOffset)(ULONG32 *pRetVal); - STDMETHOD(GetEndOffset)(ULONG32 *pRetVal); - STDMETHOD(GetLocalCount)(ULONG32 *pRetVal); - STDMETHOD(GetLocals)(ULONG32 cLocals, - ULONG32 *pcLocals, - ISymUnmanagedVariable *locals[]); - STDMETHOD(GetNamespaces)(ULONG32 cNameSpaces, - ULONG32 *pcNameSpaces, - ISymUnmanagedNamespace *namespaces[]); - -// Data members -private: - - UINT32 m_refCount; // Add/Ref Release - - ISymUnmanagedMethod *m_pSymMethod; - - // Data Pointer - PDBDataPointers *m_pData; - // Entry into the SymMethodInfo array - UINT32 m_MethodEntry; - // Entry into the scope array - UINT32 m_ScopeEntry; -}; - -/* ------------------------------------------------------------------------- * - * SymReaderVar class - * ------------------------------------------------------------------------- */ - -class SymReaderVar : public ISymUnmanagedVariable -{ -// ctor/dtor -public: - SymReaderVar(SymScope *pScope, PDBDataPointers *pData, UINT32 VarEntry) - { - m_pData = pData; - m_VarEntry = VarEntry; - m_refCount = 0; - m_pScope = pScope; - pScope->AddRef(); - } - virtual ~SymReaderVar() - { - RELEASE(m_pScope); - } - -public: - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); - -// ISymUnmanagedReaderVar -public: - STDMETHOD(GetName)(ULONG32 cchName, - ULONG32 *pcchName, - __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]); - STDMETHOD(GetAttributes)(ULONG32 *pRetVal); - STDMETHOD(GetSignature)(ULONG32 cSig, - ULONG32 *pcSig, - BYTE sig[]); - STDMETHOD(GetAddressKind)(ULONG32 *pRetVal); - STDMETHOD(GetAddressField1)(ULONG32 *pRetVal); - STDMETHOD(GetAddressField2)(ULONG32 *pRetVal); - STDMETHOD(GetAddressField3)(ULONG32 *pRetVal); - STDMETHOD(GetStartOffset)(ULONG32 *pRetVal); - STDMETHOD(GetEndOffset)(ULONG32 *pRetVal); - - -// Data members -private: - UINT32 m_refCount; // Add/Ref Release - - // Data Pointer - PDBDataPointers *m_pData; - - // Scope of the variable - SymScope *m_pScope; - - // Entry into the SymMethodInfo array - UINT32 m_VarEntry; -}; - -class SymReaderNamespace : public ISymUnmanagedNamespace -{ - -public: - SymReaderNamespace(SymScope *pScope, PDBDataPointers *pData, UINT32 NamespaceEntry) - { - m_pData = pData; - m_NamespaceEntry = NamespaceEntry; - m_refCount = 0; - m_pScope = pScope; - pScope->AddRef(); - } - virtual ~SymReaderNamespace() - { - } - -public: - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject); - -public: - //----------------------------------------------------------- - // ISymUnmanagedNamespace support - //----------------------------------------------------------- - STDMETHOD(GetName)(ULONG32 cchName, - ULONG32 *pcchName, - __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]); - STDMETHOD(GetNamespaces)(ULONG32 cNamespaces, - ULONG32 *pcNamespaces, - ISymUnmanagedNamespace* namespaces[]); - STDMETHOD(GetVariables)(ULONG32 cchName, - ULONG32 *pcchName, - ISymUnmanagedVariable *pVars[]); - -private: - UINT32 m_refCount; // Add/Ref Release - - // Owning scope - SymScope *m_pScope; - - // Data Pointer - PDBDataPointers *m_pData; - // Entry into the NameSpace array - UINT32 m_NamespaceEntry; - -}; - -#endif diff --git a/src/coreclr/debug/ildbsymlib/symwrite.cpp b/src/coreclr/debug/ildbsymlib/symwrite.cpp deleted file mode 100644 index 1f19186c7b598a..00000000000000 --- a/src/coreclr/debug/ildbsymlib/symwrite.cpp +++ /dev/null @@ -1,1530 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: symwrite.cpp -// - -// -// Note: The various SymWriter_* and SymDocumentWriter_* are entry points -// called via PInvoke from the managed symbol wrapper used by managed languages -// to emit debug information (such as jscript) -// =========================================================================== - -#include "pch.h" -#include "symwrite.h" - - -// ------------------------------------------------------------------------- -// SymWriter class -// ------------------------------------------------------------------------- - -// This is a COM object which is called both directly from the runtime, and from managed code -// via PInvoke (CoreSymWrapper) and IJW (ISymWrapper). This is an unusual pattern, and it's not -// clear exactly how best to address it. Eg., should we be using BEGIN_EXTERNAL_ENTRYPOINT -// macros? Conceptually this is just a drop-in replacement for diasymreader.dll, and could -// live in a different DLL instead of being statically linked into the runtime. But since it -// relies on utilcode (and actually gets the runtime utilcode, not the nohost utilcode like -// other external tools), it does have some properties of runtime code. -// - -//----------------------------------------------------------- -// NewSymWriter -// Static function used to create a new instance of SymWriter -//----------------------------------------------------------- -HRESULT SymWriter::NewSymWriter(const GUID& id, void **object) -{ - if (id != IID_ISymUnmanagedWriter) - return (E_UNEXPECTED); - - SymWriter *writer = NEW(SymWriter()); - - if (writer == NULL) - return (E_OUTOFMEMORY); - - *object = (ISymUnmanagedWriter*)writer; - writer->AddRef(); - - return (S_OK); -} - -//----------------------------------------------------------- -// SymWriter Constuctor -//----------------------------------------------------------- -SymWriter::SymWriter() : - m_refCount(0), - m_openMethodToken(mdMethodDefNil), - m_LargestMethodToken(mdMethodDefNil), - m_pmethod(NULL), - m_currentScope(k_noScope), - m_hFile(NULL), - m_pIStream(NULL), - m_pStringPool(NULL), - m_closed( false ), - m_sortLines (false), - m_sortMethodEntries(false) -{ - memset(m_szPath, 0, sizeof(m_szPath)); - memset(&ModuleLevelInfo, 0, sizeof(PDBInfo)); -} - -//----------------------------------------------------------- -// SymWriter QI -//----------------------------------------------------------- -COM_METHOD SymWriter::QueryInterface(REFIID riid, void **ppInterface) -{ - if (ppInterface == NULL) - return E_INVALIDARG; - - if (riid == IID_ISymUnmanagedWriter ) - *ppInterface = (ISymUnmanagedWriter*)this; - else if (riid == IID_ISymUnmanagedWriter2 ) - *ppInterface = (ISymUnmanagedWriter2*)this; - else if (riid == IID_ISymUnmanagedWriter3 ) - *ppInterface = (ISymUnmanagedWriter3*)this; - else if (riid == IID_IUnknown) - *ppInterface = (IUnknown*)(ISymUnmanagedWriter*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter Destructor -//----------------------------------------------------------- -SymWriter::~SymWriter() -{ - // Note that this must be thread-safe - it may be invoked on the finalizer thread - // But since this dtor can only be invoked when all references have been released, - // no other threads can be manipulating the writer. - // Ideally we'd probably just add locking to all methods, but this is low-priority - // because diasymreader.dll isn't thread-safe and so we need to ensure the CLR's use - // of these interfaces are properly syncrhonized. - if ( !m_closed ) - Close(); - RELEASE(m_pIStream); - DELETE(m_pStringPool); -} - -//----------------------------------------------------------- -// SymWriter Initialize the SymWriter -//----------------------------------------------------------- -COM_METHOD SymWriter::Initialize -( - IUnknown *emitter, // Emitter (IMetaData Emit/Import) - unused by ILDB - const WCHAR *szFilename, // FileName of the exe we're creating - IStream *pIStream, // Stream to store into - BOOL fFullBuild // Is this a full build or an incremental build -) -{ - HRESULT hr = S_OK; - - // Incremental compile not implemented - _ASSERTE(fFullBuild); - - if (emitter == NULL) - return E_INVALIDARG; - - if (pIStream != NULL) - { - m_pIStream = pIStream; - pIStream->AddRef(); - } - else - { - if (szFilename == NULL) - { - IfFailRet(E_INVALIDARG); - } - } - - m_pStringPool = NEW(StgStringPool()); - IfFailRet(m_pStringPool->InitNew()); - - if (szFilename != NULL) - { - WCHAR fullpath[_MAX_PATH]; - WCHAR drive[_MAX_DRIVE]; - WCHAR dir[_MAX_DIR]; - WCHAR fname[_MAX_FNAME]; - _wsplitpath_s( szFilename, drive, COUNTOF(drive), dir, COUNTOF(dir), fname, COUNTOF(fname), NULL, 0 ); - _wmakepath_s( fullpath, COUNTOF(fullpath), drive, dir, fname, W("ildb") ); - if (wcsncpy_s( m_szPath, COUNTOF(m_szPath), fullpath, _TRUNCATE) == STRUNCATE) - return HrFromWin32(ERROR_INSUFFICIENT_BUFFER); - } - - // Note that we don't need the emitter - ILDB is agnostic to the module metadata. - - return hr; -} - -//----------------------------------------------------------- -// SymWriter Initialize2 the SymWriter -// Delegate to Initialize then use the szFullPathName param -//----------------------------------------------------------- -COM_METHOD SymWriter::Initialize2 -( - IUnknown *emitter, // Emitter (IMetaData Emit/Import) - const WCHAR *szTempPath, // Location of the file - IStream *pIStream, // Stream to store into - BOOL fFullBuild, // Full build or not - const WCHAR *szFullPathName // Final destination of the ildb -) -{ - HRESULT hr = S_OK; - IfFailGo( Initialize( emitter, szTempPath, pIStream, fFullBuild ) ); - // We don't need the final location of the ildb - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter GetorCreateDocument -// creates a new symbol document writer for a specified source -// Arguments: -// input: wcsUrl - The source file name -// output: ppRetVal - The new document writer -// Return Value: hr - S_OK if success, OOM otherwise -//----------------------------------------------------------- -HRESULT SymWriter::GetOrCreateDocument( - const WCHAR *wcsUrl, // Document name - const GUID *pLanguage, // What Language we're compiling - const GUID *pLanguageVendor, // What vendor - const GUID *pDocumentType, // Type - ISymUnmanagedDocumentWriter **ppRetVal // [out] Created DocumentWriter -) -{ - ULONG UrlEntry; - DWORD strLength = WszWideCharToMultiByte(CP_UTF8, 0, wcsUrl, -1, 0, 0, 0, 0); - LPSTR multiByteURL = (LPSTR) new char [strLength]; - HRESULT hr = S_OK; - - if (multiByteURL == NULL) - { - return E_OUTOFMEMORY; - } - - WszWideCharToMultiByte(CP_UTF8, 0, wcsUrl, -1, multiByteURL, strLength, 0, 0); - - if (m_pStringPool->FindString(multiByteURL, &UrlEntry) == S_FALSE) // no file of that name has been seen before - { - hr = CreateDocument(wcsUrl, pLanguage, pLanguageVendor, pDocumentType, ppRetVal); - } - else // we already have a writer for this file - { - UINT32 docInfo = 0; - - CRITSEC_COOKIE cs = ClrCreateCriticalSection(CrstLeafLock, CRST_DEFAULT); - - ClrEnterCriticalSection(cs); - - while ((docInfo < m_MethodInfo.m_documents.count()) && (m_MethodInfo.m_documents[docInfo].UrlEntry() != UrlEntry)) - { - docInfo++; - } - - if (docInfo == m_MethodInfo.m_documents.count()) // something went wrong and we didn't find the writer - { - hr = CreateDocument(wcsUrl, pLanguage, pLanguageVendor, pDocumentType, ppRetVal); - } - else - { - *ppRetVal = m_MethodInfo.m_documents[docInfo].DocumentWriter(); - (*ppRetVal)->AddRef(); - } - ClrLeaveCriticalSection(cs); - } - - delete [] multiByteURL; - return hr; - -} // SymWriter::GetOrCreateDocument - -//----------------------------------------------------------- -// SymWriter CreateDocument -// creates a new symbol document writer for a specified source -// Arguments: -// input: wcsUrl - The source file name -// output: ppRetVal - The new document writer -// Return Value: hr - S_OK if success, OOM otherwise -//----------------------------------------------------------- -HRESULT SymWriter::CreateDocument(const WCHAR *wcsUrl, // Document name - const GUID *pLanguage, // What Language we're compiling - const GUID *pLanguageVendor, // What vendor - const GUID *pDocumentType, // Type - ISymUnmanagedDocumentWriter **ppRetVal // [out] Created DocumentWriter -) - -{ - DocumentInfo* pDocument = NULL; - SymDocumentWriter *sdw = NULL; - UINT32 DocumentEntry; - ULONG UrlEntry; - HRESULT hr = NOERROR; - - DocumentEntry = m_MethodInfo.m_documents.count(); - IfNullGo(pDocument = m_MethodInfo.m_documents.next()); - memset(pDocument, 0, sizeof(DocumentInfo)); - - // Create the new document writer. - sdw = NEW(SymDocumentWriter(DocumentEntry, this)); - IfNullGo(sdw); - - pDocument->SetLanguage(*pLanguage); - pDocument->SetLanguageVendor(*pLanguageVendor); - pDocument->SetDocumentType(*pDocumentType); - pDocument->SetDocumentWriter(sdw); - - // stack check needed to call back into utilcode - hr = m_pStringPool->AddStringW(wcsUrl, (UINT32 *)&UrlEntry); - IfFailGo(hr); - - pDocument->SetUrlEntry(UrlEntry); - - // Pass out the new ISymUnmanagedDocumentWriter. - sdw->AddRef(); - *ppRetVal = (ISymUnmanagedDocumentWriter*)sdw; - sdw = NULL; - -ErrExit: - DELETE(sdw); - return hr; -} - -//----------------------------------------------------------- -// SymWriter DefineDocument -//----------------------------------------------------------- -COM_METHOD SymWriter::DefineDocument( - const WCHAR *wcsUrl, // Document name - const GUID *pLanguage, // What Language we're compiling - const GUID *pLanguageVendor, // What vendor - const GUID *pDocumentType, // Type - ISymUnmanagedDocumentWriter **ppRetVal // [out] Created DocumentWriter -) -{ - HRESULT hr = NOERROR; - - IfFalseGo(wcsUrl, E_INVALIDARG); - IfFalseGo(pLanguage, E_INVALIDARG); - IfFalseGo(pLanguageVendor, E_INVALIDARG); - IfFalseGo(pDocumentType, E_INVALIDARG); - IfFalseGo(ppRetVal, E_INVALIDARG); - - // Init out parameter - *ppRetVal = NULL; - - hr = GetOrCreateDocument(wcsUrl, pLanguage, pLanguageVendor, pDocumentType, ppRetVal); -ErrExit: - return hr; -} - - -//----------------------------------------------------------- -// SymWriter SetDocumentSrc -//----------------------------------------------------------- -HRESULT SymWriter::SetDocumentSrc( - UINT32 DocumentEntry, - DWORD SourceSize, - BYTE* pSource -) -{ - DocumentInfo* pDocument = NULL; - HRESULT hr = S_OK; - - IfFalseGo( SourceSize == 0 || pSource, E_INVALIDARG); - IfFalseGo( DocumentEntry < m_MethodInfo.m_documents.count(), E_INVALIDARG); - - pDocument = &m_MethodInfo.m_documents[DocumentEntry]; - - if (pSource) - { - UINT32 i; - IfFalseGo( m_MethodInfo.m_bytes.grab(SourceSize, &i), E_OUTOFMEMORY); - memcpy(&m_MethodInfo.m_bytes[i], pSource, SourceSize); - pDocument->SetSourceEntry(i); - pDocument->SetSourceSize(SourceSize); - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter SetDocumentCheckSum -//----------------------------------------------------------- -HRESULT SymWriter::SetDocumentCheckSum( - UINT32 DocumentEntry, - GUID AlgorithmId, - DWORD CheckSumSize, - BYTE* pCheckSum -) -{ - DocumentInfo* pDocument = NULL; - HRESULT hr = S_OK; - - IfFalseGo( CheckSumSize == 0 || pCheckSum, E_INVALIDARG); - IfFalseGo( DocumentEntry < m_MethodInfo.m_documents.count(), E_INVALIDARG); - - pDocument = &m_MethodInfo.m_documents[DocumentEntry]; - - if (pCheckSum) - { - UINT32 i; - IfFalseGo( m_MethodInfo.m_bytes.grab(CheckSumSize, &i), E_OUTOFMEMORY); - memcpy(&m_MethodInfo.m_bytes[i], pCheckSum, CheckSumSize); - pDocument->SetCheckSumEntry(i); - pDocument->SetCheckSymSize(CheckSumSize); - } - - pDocument->SetAlgorithmId(AlgorithmId); - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter SetUserEntryPoint -//----------------------------------------------------------- -COM_METHOD SymWriter::SetUserEntryPoint(mdMethodDef entryMethod) -{ - HRESULT hr = S_OK; - - // Make sure that an entry point hasn't already been set. - if (ModuleLevelInfo.m_userEntryPoint == 0) - ModuleLevelInfo.m_userEntryPoint = entryMethod; - - return hr; -} - -//----------------------------------------------------------- -// SymWriter OpenMethod -// Get ready to get information about a new method -//----------------------------------------------------------- -COM_METHOD SymWriter::OpenMethod(mdMethodDef method) -{ - HRESULT hr = S_OK; - - // We can only have one open method at a time. - if (m_openMethodToken != mdMethodDefNil) - return E_INVALIDARG; - - m_LargestMethodToken = max(method, m_LargestMethodToken); - - if (m_LargestMethodToken != method) - { - m_sortMethodEntries = true; - // Check to see if we're trying to open a method we've already done - unsigned i; - for (i = 0; i < m_MethodInfo.m_methods.count(); i++) - { - if (m_MethodInfo.m_methods[i].MethodToken() == method) - { - return E_INVALIDARG; - } - } - } - - // Remember the token for this method. - m_openMethodToken = method; - - IfNullGo( m_pmethod = m_MethodInfo.m_methods.next() ); - m_pmethod->SetMethodToken(m_openMethodToken); - m_pmethod->SetStartScopes(m_MethodInfo.m_scopes.count()); - m_pmethod->SetStartVars(m_MethodInfo.m_vars.count()); - m_pmethod->SetStartUsing(m_MethodInfo.m_usings.count()); - m_pmethod->SetStartConstant(m_MethodInfo.m_constants.count()); - m_pmethod->SetStartDocuments(m_MethodInfo.m_documents.count()); - m_pmethod->SetStartSequencePoints(m_MethodInfo.m_auxSequencePoints.count()); - - // By default assume the lines are inserted in the correct order - m_sortLines = false; - - // Initialize the maximum scope end offset for this method - m_maxScopeEnd = 1; - - // Open the implicit root scope for the method - _ASSERTE(m_currentScope == k_noScope); - - IfFailRet(OpenScope(0, NULL)); - - _ASSERTE(m_currentScope != k_noScope); - -ErrExit: - return hr; -} - -COM_METHOD SymWriter::OpenMethod2( - mdMethodDef method, - ULONG32 isect, - ULONG32 offset) -{ - // This symbol writer doesn't support section offsets - _ASSERTE(FALSE); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// compareAuxLines -// Used to sort SequencePoint -//----------------------------------------------------------- -int __cdecl SequencePoint::compareAuxLines(const void *elem1, const void *elem2 ) -{ - SequencePoint* p1 = (SequencePoint*)elem1; - SequencePoint* p2 = (SequencePoint*)elem2; - return p1->Offset() - p2->Offset(); -} - -//----------------------------------------------------------- -// SymWriter CloseMethod -// We're done with this function, write it out. -//----------------------------------------------------------- -COM_METHOD SymWriter::CloseMethod() -{ - HRESULT hr = S_OK; - UINT32 CountOfSequencePoints; - - // Must have an open method. - if (m_openMethodToken == mdMethodDefNil) - return E_UNEXPECTED; - - // All scopes up to the root must have been closed (and the root must not have been closed). - _ASSERTE(m_currentScope != k_noScope); - if (m_MethodInfo.m_scopes[m_currentScope].ParentScope() != k_noScope) - return E_FAIL; - - // Close the implicit root scope using the largest end offset we've seen in this method, or 1 if none. - IfFailRet(CloseScopeInternal(m_maxScopeEnd)); - - m_pmethod->SetEndScopes(m_MethodInfo.m_scopes.count()); - m_pmethod->SetEndVars(m_MethodInfo.m_vars.count()); - m_pmethod->SetEndUsing(m_MethodInfo.m_usings.count()); - m_pmethod->SetEndConstant(m_MethodInfo.m_constants.count()); - m_pmethod->SetEndDocuments(m_MethodInfo.m_documents.count()); - m_pmethod->SetEndSequencePoints(m_MethodInfo.m_auxSequencePoints.count()); - - CountOfSequencePoints = m_pmethod->EndSequencePoints() - m_pmethod->StartSequencePoints(); - // Write any sequence points. - if (CountOfSequencePoints > 0 ) { - // sort the sequence points - if ( m_sortLines ) - { - qsort(&m_MethodInfo.m_auxSequencePoints[m_pmethod->StartSequencePoints()], - CountOfSequencePoints, - sizeof( SequencePoint ), - SequencePoint::compareAuxLines ); - } - } - - // All done with this method. - m_openMethodToken = mdMethodDefNil; - - return hr; -} - -//----------------------------------------------------------- -// SymWriter DefineSequencePoints -// Define the sequence points for this function -//----------------------------------------------------------- -COM_METHOD SymWriter::DefineSequencePoints( - ISymUnmanagedDocumentWriter *document, // - ULONG32 spCount, // Count of sequence points - ULONG32 offsets[], // Offsets - ULONG32 lines[], // Beginning Lines - ULONG32 columns[], // [optional] Columns - ULONG32 endLines[], // [optional] End Lines - ULONG32 endColumns[] // [optional] End Columns -) -{ - HRESULT hr = S_OK; - DWORD docnum; - - // We must have a document, offsets, and lines. - IfFalseGo(document && offsets && lines, E_INVALIDARG); - // Must have some sequence points - IfFalseGo(spCount != 0, E_INVALIDARG); - // Must have an open method. - IfFalseGo(m_openMethodToken != mdMethodDefNil, E_INVALIDARG); - - // Remember that we've loaded the sequence points and - // which document they were for. - docnum = (DWORD)((SymDocumentWriter *)document)->GetDocumentEntry();; - - // if sets of lines have been inserted out-of-order, remember to sort when emitting - if ( m_MethodInfo.m_auxSequencePoints.count() > 0 && m_MethodInfo.m_auxSequencePoints[ m_MethodInfo.m_auxSequencePoints.count()-1 ].Offset() > offsets[0] ) - m_sortLines = true; - - // Copy the incomming arrays into the internal format. - - for ( UINT32 i = 0; i < spCount; i++) - { - SequencePoint * paux; - IfNullGo(paux = m_MethodInfo.m_auxSequencePoints.next()); - paux->SetOffset(offsets[i]); - paux->SetStartLine(lines[i]); - paux->SetStartColumn(columns ? columns[i] : 0); - // If no endLines specified, assume same as start - paux->SetEndLine(endLines ? endLines[i] : lines[i]); - paux->SetEndColumn(endColumns ? endColumns[i]: 0); - paux->SetDocument(docnum); - } - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter OpenScope -// Open a new scope for this function -//----------------------------------------------------------- -COM_METHOD SymWriter::OpenScope(ULONG32 startOffset, ULONG32 *scopeID) -{ - HRESULT hr = S_OK; - - // Make sure the startOffset is within the current scope. - if ((m_currentScope != k_noScope) && - (unsigned int)startOffset < m_MethodInfo.m_scopes[m_currentScope].StartOffset()) - return E_INVALIDARG; - - // Fill in the new scope. - UINT32 newScope = m_MethodInfo.m_scopes.count(); - - // Make sure that adding 1 below won't overflow (although "next" should fail much - // sooner if we were anywhere near close enough). - if (newScope >= UINT_MAX) - return E_UNEXPECTED; - - SymLexicalScope *sc; - IfNullGo( sc = m_MethodInfo.m_scopes.next()); - sc->SetParentScope(m_currentScope); // parent is the current scope. - sc->SetStartOffset(startOffset); - sc->SetHasChildren(FALSE); - sc->SetHasVars(FALSE); - sc->SetEndOffset(0); - - // The current scope has a child now. - if (m_currentScope != k_noScope) - m_MethodInfo.m_scopes[m_currentScope].SetHasChildren(TRUE); - - // The new scope is now the current scope. - m_currentScope = newScope; - _ASSERTE(m_currentScope != k_noScope); - - // Pass out the "scope id", which is a _1_ based id for the scope. - if (scopeID) - *scopeID = m_currentScope + 1; - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter CloseScope -//----------------------------------------------------------- -COM_METHOD SymWriter::CloseScope( - ULONG32 endOffset // Closing offset of scope -) -{ - // This API can only be used to close explicit user scopes. - // The implicit root scope is only closed internally by CloseMethod. - if ((m_currentScope == k_noScope) || (m_MethodInfo.m_scopes[m_currentScope].ParentScope() == k_noScope)) - return E_FAIL; - - HRESULT hr = CloseScopeInternal(endOffset); - - _ASSERTE(m_currentScope != k_noScope); - - return hr; -} - -//----------------------------------------------------------- -// CloseScopeInternal -// Implementation for ISymUnmanagedWriter::CloseScope but can be called even to -// close the implicit root scope. -//----------------------------------------------------------- -COM_METHOD SymWriter::CloseScopeInternal( - ULONG32 endOffset // Closing offset of scope -) -{ - _ASSERTE(m_currentScope != k_noScope); - - // Capture the end offset - m_MethodInfo.m_scopes[m_currentScope].SetEndOffset(endOffset); - - // The current scope is now the parent scope. - m_currentScope = m_MethodInfo.m_scopes[m_currentScope].ParentScope(); - - // Update the maximum scope end offset for this method - if (endOffset > m_maxScopeEnd) - m_maxScopeEnd = endOffset; - - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter SetScopeRange -// Set the Start/End Offset for this scope -//----------------------------------------------------------- -COM_METHOD SymWriter::SetScopeRange( - ULONG32 scopeID, // ID for the scope - ULONG32 startOffset, // Start Offset - ULONG32 endOffset // End Offset -) -{ - if (scopeID <= 0) - return E_INVALIDARG; - - if (scopeID > m_MethodInfo.m_scopes.count() ) - return E_INVALIDARG; - - // Remember the new start and end offsets. Also remember that the - // scopeID is _1_ based!!! - SymLexicalScope *sc = &(m_MethodInfo.m_scopes[scopeID - 1]); - sc->SetStartOffset(startOffset); - sc->SetEndOffset(endOffset); - - // Update the maximum scope end offset for this method - if (endOffset > m_maxScopeEnd) - m_maxScopeEnd = endOffset; - - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter DefineLocalVariable -//----------------------------------------------------------- -COM_METHOD SymWriter::DefineLocalVariable( - const WCHAR *name, // Name of the variable - ULONG32 attributes, // Attributes for the var - ULONG32 cSig, // Signature for the variable - BYTE signature[], - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3, - ULONG32 startOffset, ULONG32 endOffset) -{ - HRESULT hr = S_OK; - ULONG NameEntry; - - // We must have a current scope. - if (m_currentScope == k_noScope) - return E_FAIL; - - // We must have a name and a signature. - if (!name || !signature) - return E_INVALIDARG; - - if (cSig == 0) - return E_INVALIDARG; - - // Make a new local variable and copy the data. - SymVariable *var; - IfNullGo( var = m_MethodInfo.m_vars.next()); - var->SetIsParam(FALSE); - var->SetAttributes(attributes); - var->SetAddrKind(addrKind); - var->SetIsHidden(attributes & VAR_IS_COMP_GEN); - var->SetAddr1(addr1); - var->SetAddr2(addr2); - var->SetAddr3(addr3); - - - // Length of the sig? - ULONG32 sigLen; - sigLen = cSig; - - // Copy the name. - hr = m_pStringPool->AddStringW(name, (UINT32 *)&NameEntry); - IfFailGo(hr); - var->SetName(NameEntry); - - // Copy the signature - // Note that we give this back exactly as-is, but callers typically remove any calling - // convention prefix. - UINT32 i; - IfFalseGo(m_MethodInfo.m_bytes.grab(sigLen, &i), E_OUTOFMEMORY); - memcpy(&m_MethodInfo.m_bytes[i], signature, sigLen); - var->SetSignature(i); - var->SetSignatureSize(sigLen); - - // This var is in the current scope - var->SetScope(m_currentScope); - m_MethodInfo.m_scopes[m_currentScope].SetHasVars(TRUE); - - var->SetStartOffset(startOffset); - var->SetEndOffset(endOffset); - -ErrExit: - return hr; -} - -COM_METHOD SymWriter::DefineLocalVariable2( - const WCHAR *name, - ULONG32 attributes, - mdSignature sigToken, - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3, - ULONG32 startOffset, ULONG32 endOffset) -{ - // This symbol writer doesn't support definiting signatures via tokens - _ASSERTE(FALSE); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// SymWriter DefineParameter -//----------------------------------------------------------- -COM_METHOD SymWriter::DefineParameter( - const WCHAR *name, // Param name - ULONG32 attributes, // Attribute for the parameter - ULONG32 sequence, - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3) -{ - HRESULT hr = S_OK; - ULONG NameEntry; - - // We must have a method. - if (m_openMethodToken == mdMethodDefNil) - return E_INVALIDARG; - - // We must have a name. - if (!name) - return E_INVALIDARG; - - SymVariable *var; - IfNullGo( var = m_MethodInfo.m_vars.next()); - var->SetIsParam(TRUE); - var->SetAttributes(attributes); - var->SetAddrKind(addrKind); - var->SetIsHidden(attributes & VAR_IS_COMP_GEN); - var->SetAddr1(addr1); - var->SetAddr2(addr2); - var->SetAddr3(addr3); - var->SetSequence(sequence); - - - // Copy the name. - hr = m_pStringPool->AddStringW(name, (UINT32 *)&NameEntry); - IfFailGo(hr); - var->SetName(NameEntry); - - // This var is in the current scope - if (m_currentScope != k_noScope) - m_MethodInfo.m_scopes[m_currentScope].SetHasVars(TRUE); - - var->SetStartOffset(0); - var->SetEndOffset(0); - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// verifyConstTypes -// Verify that the type is a type we support -//----------------------------------------------------------- -static bool verifyConstTypes( DWORD vt ) -{ - switch ( vt ) { - case VT_UI8: - case VT_I8: - case VT_I4: - case VT_UI1: // value < LF_NUMERIC - case VT_I2: - case VT_R4: - case VT_R8: - case VT_BOOL: // value < LF_NUMERIC - case VT_DATE: - case VT_BSTR: - case VT_I1: - case VT_UI2: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_DECIMAL: - return true; - } - return false; -} - -//----------------------------------------------------------- -// SymWriter DefineConstant -//----------------------------------------------------------- -COM_METHOD SymWriter::DefineConstant( - const WCHAR __RPC_FAR *name, - VARIANT value, - ULONG32 cSig, - unsigned char __RPC_FAR signature[]) -{ - HRESULT hr = S_OK; - ULONG ValueBstr = 0; - ULONG Name; - - // currently we only support local constants - - // We must have a method. - if (m_openMethodToken == mdMethodDefNil) - return E_INVALIDARG; - - // We must have a name and signature. - IfFalseGo(name, E_INVALIDARG); - IfFalseGo(signature, E_INVALIDARG); - IfFalseGo(cSig > 0, E_INVALIDARG); - - // - // Support byref decimal values - // - if ( (V_VT(&value)) == ( VT_BYREF | VT_DECIMAL ) ) { - if ( V_DECIMALREF(&value) == NULL ) - return E_INVALIDARG; - V_DECIMAL(&value) = *V_DECIMALREF(&value); - V_VT(&value) = VT_DECIMAL; - } - - // we only support non-ref constants - if ( ( V_VT(&value) & VT_BYREF ) != 0 ) - return E_INVALIDARG; - - if ( !verifyConstTypes( V_VT(&value) ) ) - return E_INVALIDARG; - - // If it's a BSTR, we need to persist the Bstr as an entry into - // the stringpool - if (V_VT(&value) == VT_BSTR) - { - // Copy the bstrValue. - hr = m_pStringPool->AddStringW(V_BSTR(&value), (UINT32 *)&ValueBstr); - IfFailGo(hr); - V_BSTR(&value) = NULL; - } - - SymConstant *con; - IfNullGo( con = m_MethodInfo.m_constants.next()); - con->SetValue(value, ValueBstr); - - - // Copy the name. - hr = m_pStringPool->AddStringW(name, (UINT32 *)&Name); - IfFailGo(hr); - con->SetName(Name); - - // Copy the signature - UINT32 i; - IfFalseGo(m_MethodInfo.m_bytes.grab(cSig, &i), E_OUTOFMEMORY); - memcpy(&m_MethodInfo.m_bytes[i], signature, cSig); - con->SetSignature(i); - con->SetSignatureSize(cSig); - - // This const is in the current scope - con->SetParentScope(m_currentScope); - m_MethodInfo.m_scopes[m_currentScope].SetHasVars(TRUE); - -ErrExit: - return hr; -} - -COM_METHOD SymWriter::DefineConstant2( - const WCHAR *name, - VARIANT value, - mdSignature sigToken) -{ - // This symbol writer doesn't support definiting signatures via tokens - _ASSERTE(FALSE); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// SymWriter Abort -//----------------------------------------------------------- -COM_METHOD SymWriter::Abort(void) -{ - m_closed = true; - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter DefineField -//----------------------------------------------------------- -COM_METHOD SymWriter::DefineField( - mdTypeDef parent, - const WCHAR *name, - ULONG32 attributes, - ULONG32 csig, - BYTE signature[], - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3) -{ - // This symbol store doesn't support extra random variable - // definitions. - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter DefineGlobalVariable -//----------------------------------------------------------- -COM_METHOD SymWriter::DefineGlobalVariable( - const WCHAR *name, - ULONG32 attributes, - ULONG32 csig, - BYTE signature[], - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3) -{ - // This symbol writer doesn't support global variables - _ASSERTE(FALSE); - return E_NOTIMPL; -} - -COM_METHOD SymWriter::DefineGlobalVariable2( - const WCHAR *name, - ULONG32 attributes, - mdSignature sigToken, - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3) -{ - // This symbol writer doesn't support global variables - _ASSERTE(FALSE); - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// compareMethods -// Used to sort method entries -//----------------------------------------------------------- -int __cdecl SymMethodInfo::compareMethods(const void *elem1, const void *elem2 ) -{ - SymMethodInfo* p1 = (SymMethodInfo*)elem1; - SymMethodInfo* p2 = (SymMethodInfo*)elem2; - return p1->MethodToken() - p2->MethodToken(); -} - -//----------------------------------------------------------- -// SymWriter Close -//----------------------------------------------------------- -COM_METHOD SymWriter::Close() -{ - HRESULT hr = Commit(); - m_closed = true; - for (UINT32 docInfo = 0; docInfo < m_MethodInfo.m_documents.count(); docInfo++) - { - m_MethodInfo.m_documents[docInfo].SetDocumentWriter(NULL); - } - return hr; -} - -//----------------------------------------------------------- -// SymWriter Commit -//----------------------------------------------------------- -COM_METHOD SymWriter::Commit(void) -{ - // Sort the entries if need be - if (m_sortMethodEntries) - { - // First remap any tokens we need to - if (m_MethodMap.count()) - { - unsigned i; - for (i = 0; i< m_MethodMap.count(); i++) - { - m_MethodInfo.m_methods[m_MethodMap[i].MethodEntry].SetMethodToken(m_MethodMap[i].m_MethodToken); - } - } - - // Now sort the array - qsort(&m_MethodInfo.m_methods[0], - m_MethodInfo.m_methods.count(), - sizeof( SymMethodInfo ), - SymMethodInfo::compareMethods ); - m_sortMethodEntries = false; - } - return WritePDB(); -} - -//----------------------------------------------------------- -// SymWriter SetSymAttribute -//----------------------------------------------------------- -COM_METHOD SymWriter::SetSymAttribute( - mdToken parent, - const WCHAR *name, - ULONG32 cData, - BYTE data[]) -{ - // Setting attributes on the symbol isn't supported - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter OpenNamespace -//----------------------------------------------------------- -COM_METHOD SymWriter::OpenNamespace(const WCHAR *name) -{ - // This symbol store doesn't support namespaces. - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// SymWriter OpenNamespace -//----------------------------------------------------------- -COM_METHOD SymWriter::CloseNamespace() -{ - // This symbol store doesn't support namespaces. - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter UsingNamespace -// Add a Namespace to the list of namespace for this method -//----------------------------------------------------------- -COM_METHOD SymWriter::UsingNamespace(const WCHAR *fullName) -{ - HRESULT hr = S_OK; - ULONG Name; - - // We must have a current scope. - if (m_currentScope == k_noScope) - return E_FAIL; - - // We must have a name. - if (!fullName) - return E_INVALIDARG; - - - SymUsingNamespace *use; - IfNullGo( use = m_MethodInfo.m_usings.next()); - - // Copy the name. - hr = m_pStringPool->AddStringW(fullName, (UINT32 *)&Name); - IfFailGo(hr); - use->SetName(Name); - - use->SetParentScope(m_currentScope); - -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter SetMethodSourceRange -//----------------------------------------------------------- -COM_METHOD SymWriter::SetMethodSourceRange( - ISymUnmanagedDocumentWriter *startDoc, - ULONG32 startLine, - ULONG32 startColumn, - ISymUnmanagedDocumentWriter *endDoc, - ULONG32 endLine, - ULONG32 endColumn) -{ - // This symbol store doesn't support source ranges. - return E_NOTIMPL; -} - -//----------------------------------------------------------- -// UnicodeToUTF8 -// Translate the Unicode string to a UTF8 string -// Return the length in UTF8 of the Unicode string -// Including NULL terminator -//----------------------------------------------------------- -inline int WINAPI UnicodeToUTF8( - LPCWSTR pUni, // Unicode string - __out_bcount_opt(cbUTF) PSTR pUTF8, // [optional, out] Buffer for UTF8 string - int cbUTF // length of UTF8 buffer -) -{ - // Pass in the length including the NULL terminator - int cchSrc = (int)wcslen(pUni)+1; - return WideCharToMultiByte(CP_UTF8, 0, pUni, cchSrc, pUTF8, cbUTF, NULL, NULL); -} - -//----------------------------------------------------------- -// SymWriter GetDebugCVInfo -// Get the size and potentially the debug info -//----------------------------------------------------------- -COM_METHOD SymWriter::GetDebugCVInfo( - DWORD cbBuf, // [optional] Size of buf - DWORD *pcbBuf, // [out] Size needed for the DebugInfo - BYTE buf[]) // [optional, out] Buffer for DebugInfo -{ - - if ( *m_szPath == 0 ) - return E_UNEXPECTED; - - // We need to change the .ildb extension to .pdb to be - // compatible with VS7 - WCHAR fullpath[_MAX_PATH]; - WCHAR drive[_MAX_DRIVE]; - WCHAR dir[_MAX_DIR]; - WCHAR fname[_MAX_FNAME]; - if (_wsplitpath_s( m_szPath, drive, COUNTOF(drive), dir, COUNTOF(dir), fname, COUNTOF(fname), NULL, 0 )) - return E_FAIL; - if (_wmakepath_s( fullpath, COUNTOF(fullpath), drive, dir, fname, W("pdb") )) - return E_FAIL; - - // Get UTF-8 string size, including the Null Terminator - int Utf8Length = UnicodeToUTF8( fullpath, NULL, 0 ); - if (Utf8Length < 0 ) - return HRESULT_FROM_GetLastError(); - - DWORD dwSize = sizeof(RSDSI) + DWORD(Utf8Length); - - // If the caller is just checking for the size - if ( cbBuf == 0 && pcbBuf != NULL ) - { - *pcbBuf = dwSize; - return S_OK; - } - - if (cbBuf < dwSize) - { - return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - } - - if ( buf == NULL ) - { - return E_INVALIDARG; - } - - RSDSI* pRsdsi = (RSDSI*)buf; - pRsdsi->dwSig = VAL32(0x53445352); // "SDSR"; - pRsdsi->guidSig = ILDB_VERSION_GUID; - SwapGuid(&(pRsdsi->guidSig)); - // Age of 0 represent VC6.0 format so make sure it's 1 - pRsdsi->age = VAL32(1); - UnicodeToUTF8( fullpath, pRsdsi->szPDB, Utf8Length ); - if ( pcbBuf ) - *pcbBuf = dwSize; - return S_OK; -} - -//----------------------------------------------------------- -// SymWriter GetDebugInfo -// Get the size and potentially the debug info -//----------------------------------------------------------- -COM_METHOD SymWriter::GetDebugInfo( - IMAGE_DEBUG_DIRECTORY *pIDD, // [out] IDD to fill in - DWORD cData, // [optional] size of data - DWORD *pcData, // [optional, out] return needed size for DebugInfo - BYTE data[]) // [optional] Buffer to store into -{ - HRESULT hr = S_OK; - if ( cData == 0 && pcData != NULL ) - { - // just checking for the size - return GetDebugCVInfo( 0, pcData, NULL ); - } - - if ( pIDD == NULL ) - return E_INVALIDARG; - - DWORD cTheData = 0; - IfFailGo( GetDebugCVInfo( cData, &cTheData, data ) ); - - memset( pIDD, 0, sizeof( *pIDD ) ); - pIDD->Type = VAL32(IMAGE_DEBUG_TYPE_CODEVIEW); - pIDD->SizeOfData = VAL32(cTheData); - - if ( pcData ) { - *pcData = cTheData; - } - -ErrExit: - return hr; -} - -COM_METHOD SymWriter::RemapToken(mdToken oldToken, mdToken newToken) -{ - HRESULT hr = NOERROR; - if (oldToken != newToken) - { - // We only care about methods - if ((TypeFromToken(oldToken) == mdtMethodDef) || - (TypeFromToken(newToken) == mdtMethodDef)) - { - // Make sure they are both methods - _ASSERTE(TypeFromToken(newToken) == mdtMethodDef); - _ASSERTE(TypeFromToken(oldToken) == mdtMethodDef); - - // Make sure we sort before saving - m_sortMethodEntries = true; - - // Check to see if we're trying to map a token we know about - unsigned i; - for (i = 0; i < m_MethodInfo.m_methods.count(); i++) - { - if (m_MethodInfo.m_methods[i].MethodToken() == oldToken) - { - // Remember the map, we need to actually do the actual - // mapping later because we might already have a function - // with a token 'newToken' - SymMap *pMethodMap; - IfNullGo( pMethodMap = m_MethodMap.next() ); - pMethodMap->m_MethodToken = newToken; - pMethodMap->MethodEntry = i; - break; - } - } - } - } -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter Write -// Write the information to a file or to a stream -//----------------------------------------------------------- -COM_METHOD SymWriter::Write(void *pData, DWORD SizeOfData) -{ - HRESULT hr = NOERROR; - DWORD NumberOfBytesWritten = 0; - if (m_pIStream) - { - IfFailGo(m_pIStream->Write(pData, - SizeOfData, - &NumberOfBytesWritten)); - } - else - { - // Write out a signature to recognize that we're an ildb - if (!WriteFile(m_hFile, pData, SizeOfData, &NumberOfBytesWritten, NULL)) - return HrFromWin32(GetLastError()); - } - _ASSERTE(NumberOfBytesWritten == SizeOfData); -ErrExit: - return hr; -} - -//----------------------------------------------------------- -// SymWriter WriteStringPool -// Write the information to a file or to a stream -//----------------------------------------------------------- -COM_METHOD SymWriter::WriteStringPool() -{ - IStream *pIStream = NULL; - BYTE *pStreamMem = NULL; - - HRESULT hr = NOERROR; - if (m_pIStream) - { - IfFailGo(m_pStringPool->PersistToStream(m_pIStream)); - } - else - { - LARGE_INTEGER disp = { {0, 0} }; - DWORD NumberOfBytes; - DWORD SizeOfData; - STATSTG statStg; - - IfFailGo(CreateStreamOnHGlobal(NULL, - TRUE, - &pIStream)); - - IfFailGo(m_pStringPool->PersistToStream(pIStream)); - - IfFailGo(pIStream->Stat(&statStg, STATFLAG_NONAME)); - SizeOfData = statStg.cbSize.u.LowPart; - - IfFailGo(pIStream->Seek(disp, STREAM_SEEK_SET, NULL)); - - pStreamMem = NEW(BYTE[SizeOfData]); - IfFailGo(pIStream->Read(pStreamMem, SizeOfData, &NumberOfBytes)); - - if (!WriteFile(m_hFile, pStreamMem, SizeOfData, &NumberOfBytes, NULL)) - return HrFromWin32(GetLastError()); - - _ASSERTE(NumberOfBytes == SizeOfData); - - } -ErrExit: - RELEASE(pIStream); - DELETEARRAY(pStreamMem); - return hr; -} - -//----------------------------------------------------------- -// SymWriter WritePDB -// Write the PDB information to a file or to a stream -//----------------------------------------------------------- -COM_METHOD SymWriter::WritePDB() -{ - - HRESULT hr = NOERROR; - GUID ildb_guid = ILDB_VERSION_GUID; - - // Make sure the ModuleLevelInfo is set - ModuleLevelInfo.m_CountOfVars = VAL32(m_MethodInfo.m_vars.count()); - ModuleLevelInfo.m_CountOfBytes = VAL32(m_MethodInfo.m_bytes.count()); - ModuleLevelInfo.m_CountOfUsing = VAL32(m_MethodInfo.m_usings.count()); - ModuleLevelInfo.m_CountOfScopes = VAL32(m_MethodInfo.m_scopes.count()); - ModuleLevelInfo.m_CountOfMethods = VAL32(m_MethodInfo.m_methods.count()); - if (m_pStringPool) - { - DWORD dwSaveSize; - IfFailGo(m_pStringPool->GetSaveSize((UINT32 *)&dwSaveSize)); - ModuleLevelInfo.m_CountOfStringBytes = VAL32(dwSaveSize); - } - else - { - ModuleLevelInfo.m_CountOfStringBytes = 0; - } - ModuleLevelInfo.m_CountOfConstants = VAL32(m_MethodInfo.m_constants.count()); - ModuleLevelInfo.m_CountOfDocuments = VAL32(m_MethodInfo.m_documents.count()); - ModuleLevelInfo.m_CountOfSequencePoints = VAL32(m_MethodInfo.m_auxSequencePoints.count()); - - // Open the file - if (m_pIStream == NULL) - { - // We need to open the output file. - m_hFile = WszCreateFile(m_szPath, - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (m_hFile == INVALID_HANDLE_VALUE) - { - IfFailGo(HrFromWin32(GetLastError())); - } - } - else - { - // We're writing to a stream. Make sure we're at the beginning - // (eg. if this is being called more than once). - // Note that technically we should probably call SetSize to truncate the - // stream to ensure we don't leave reminants of the previous contents - // at the end of the new stream. But with our current CGrowableStream - // implementation, this would have a big performance impact (causing us to - // do linear growth and lots of reallocations at every write). We only - // ever add data to a symbol writer (don't remove anything), and so subsequent - // streams should always get larger. Regardless, ILDB supports trailing garbage - // without a problem (we used to always have the remainder of a page at the end - // of the stream), and so this is not an issue of correctness. - LARGE_INTEGER pos0; - pos0.QuadPart = 0; - IfFailGo(m_pIStream->Seek(pos0, STREAM_SEEK_SET, NULL)); - } - -#if _DEBUG - // We need to make sure the Variant entry in the constants is 8 byte - // aligned so make sure everything up to the there is aligned correctly - if ((ILDB_SIGNATURE_SIZE % 8) || - (sizeof(PDBInfo) % 8) || - (sizeof(GUID) % 8)) - { - _ASSERTE(!"We need to safe the data in an aligned format"); - } -#endif - - // Write out a signature to recognize that we're an ildb - IfFailGo(Write((void *)ILDB_SIGNATURE, ILDB_SIGNATURE_SIZE)); - // Write out a guid representing the version - SwapGuid(&ildb_guid); - IfFailGo(Write((void *)&ildb_guid, sizeof(GUID))); - - // Now we need to write the Project level - IfFailGo(Write(&ModuleLevelInfo, sizeof(PDBInfo))); - - // Now we have to write out each array as appropriate - IfFailGo(Write(m_MethodInfo.m_constants.m_array, sizeof(SymConstant) * m_MethodInfo.m_constants.count())); - - // These members are all 4 byte aligned - IfFailGo(Write(m_MethodInfo.m_methods.m_array, sizeof(SymMethodInfo) * m_MethodInfo.m_methods.count())); - IfFailGo(Write(m_MethodInfo.m_scopes.m_array, sizeof(SymLexicalScope) * m_MethodInfo.m_scopes.count())); - IfFailGo(Write(m_MethodInfo.m_vars.m_array, sizeof(SymVariable) * m_MethodInfo.m_vars.count())); - IfFailGo(Write(m_MethodInfo.m_usings.m_array, sizeof(SymUsingNamespace) * m_MethodInfo.m_usings.count())); - IfFailGo(Write(m_MethodInfo.m_auxSequencePoints.m_array, sizeof(SequencePoint) * m_MethodInfo.m_auxSequencePoints.count())); - IfFailGo(Write(m_MethodInfo.m_documents.m_array, sizeof(DocumentInfo) * m_MethodInfo.m_documents.count())); - IfFailGo(Write(m_MethodInfo.m_bytes.m_array, sizeof(BYTE) * m_MethodInfo.m_bytes.count())); - IfFailGo(WriteStringPool()); - -ErrExit: - if (m_hFile) - CloseHandle(m_hFile); - return hr; -} - -/* ------------------------------------------------------------------------- * - * SymDocumentWriter class - * ------------------------------------------------------------------------- */ -SymDocumentWriter::SymDocumentWriter( - UINT32 DocumentEntry, - SymWriter *pEmitter -) : - m_refCount ( 0 ), - m_DocumentEntry ( DocumentEntry ), - m_pEmitter( pEmitter ) -{ - _ASSERTE(pEmitter); - m_pEmitter->AddRef(); -} - -SymDocumentWriter::~SymDocumentWriter() -{ - // Note that this must be thread-safe - it may be invoked on the finalizer thread - RELEASE(m_pEmitter); -} - -COM_METHOD SymDocumentWriter::QueryInterface(REFIID riid, void **ppInterface) -{ - if (ppInterface == NULL) - return E_INVALIDARG; - - if (riid == IID_ISymUnmanagedDocumentWriter) - *ppInterface = (ISymUnmanagedDocumentWriter*)this; - else if (riid == IID_IUnknown) - *ppInterface = (IUnknown*)(ISymUnmanagedDocumentWriter*)this; - else - { - *ppInterface = NULL; - return E_NOINTERFACE; - } - - AddRef(); - return S_OK; -} - -//----------------------------------------------------------- -// SymDocumentWriter SetSource -//----------------------------------------------------------- -COM_METHOD SymDocumentWriter::SetSource(ULONG32 sourceSize, - BYTE source[]) -{ - return m_pEmitter->SetDocumentSrc(m_DocumentEntry, sourceSize, source); -} - -//----------------------------------------------------------- -// SymDocumentWriter SetCheckSum -//----------------------------------------------------------- -COM_METHOD SymDocumentWriter::SetCheckSum(GUID algorithmId, - ULONG32 checkSumSize, - BYTE checkSum[]) -{ - return m_pEmitter->SetDocumentCheckSum(m_DocumentEntry, algorithmId, checkSumSize, checkSum); -} - - -//----------------------------------------------------------- -// DocumentInfo SetDocumentWriter -//----------------------------------------------------------- -// Set the pointer to the SymDocumentWriter instance corresponding to this instance of DocumentInfo -// An argument of NULL will call Release -// Arguments -// input: pDoc - pointer to the associated SymDocumentWriter or NULL - -void DocumentInfo::SetDocumentWriter(SymDocumentWriter * pDoc) -{ - if (m_pDocumentWriter != NULL) - { - m_pDocumentWriter->Release(); - } - m_pDocumentWriter = pDoc; - if (m_pDocumentWriter != NULL) - { - pDoc->AddRef(); - } -} diff --git a/src/coreclr/debug/ildbsymlib/symwrite.h b/src/coreclr/debug/ildbsymlib/symwrite.h deleted file mode 100644 index b62407497c2319..00000000000000 --- a/src/coreclr/debug/ildbsymlib/symwrite.h +++ /dev/null @@ -1,1226 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: SymWrite.h -// - -// =========================================================================== - -#ifndef SYMWRITE_H_ -#define SYMWRITE_H_ -#ifdef _MSC_VER -#pragma warning(disable:4786) -#endif - -#include -#include -#include - -#include "cor.h" -#include "umisc.h" -#include "stgpool.h" -#include "safemath.h" - -#include -#include "pdbdata.h" - -class SymDocumentWriter; - -#if BIGENDIAN -/*** -*PUBLIC void VariantSwap -*Purpose: -* Swap the Variant members -* -*Entry: -* SrcInBigEndian = whether pvarg is in BIGENDIAN or not -* pvargDest = Destination variant -* pvarg = pointer to a VARIANT to swap -* -*Exit: -* Filled in pvarDest -* -***********************************************************************/ -inline HRESULT VariantSwap(bool SrcInBigEndian, VARIANT FAR *pvargDest, VARIANT FAR* pvarg) -{ - if (pvargDest == NULL || pvarg == NULL) - return E_INVALIDARG; - VARTYPE vt = VT_EMPTY; - - if (SrcInBigEndian) - { - vt = V_VT(pvarg); - } - *(UINT32*)pvargDest = VAL32(*(UINT32*)pvarg); - if (!SrcInBigEndian) - { - vt = V_VT(pvargDest); - } - - switch (vt) - { - case VT_EMPTY: - case VT_NULL: - // No Value to swap - break; - - // 1 byte - case VT_I1: - case VT_UI1: - V_I1(pvargDest) = V_I1(pvarg); - break; - - // 2 bytes - case VT_I2: - case VT_UI2: - case VT_INT: - case VT_UINT: - case VT_BOOL: - V_I2(pvargDest) = VAL16(V_I2(pvarg)); - break; - - // 4 bytes - case VT_I4: - case VT_UI4: - case VT_R4: - V_I4(pvargDest) = VAL32(V_I4(pvarg)); - break; - - // 8 bytes - case VT_I8: - case VT_UI8: - case VT_R8: - case VT_DATE: - V_I8(pvargDest) = VAL64(V_I8(pvarg)); - break; - - case VT_DECIMAL: - DECIMAL_HI32(V_DECIMAL(pvargDest)) = VAL32(DECIMAL_HI32(V_DECIMAL(pvarg))); - DECIMAL_LO32(V_DECIMAL(pvargDest)) = VAL32(DECIMAL_LO32(V_DECIMAL(pvarg))); - DECIMAL_MID32(V_DECIMAL(pvargDest)) = VAL32(DECIMAL_MID32(V_DECIMAL(pvarg))); - break; - - // These aren't currently supported - case VT_CY: //6 - case VT_BSTR: //8 - case VT_DISPATCH: //9 - case VT_ERROR: //10 - case VT_VARIANT: //12 - case VT_UNKNOWN: //13 - case VT_VOID: //24 - case VT_HRESULT: //25 - case VT_PTR: //26 - case VT_SAFEARRAY: //27 - case VT_CARRAY: //28 - case VT_USERDEFINED://29 - case VT_LPSTR: //30 - case VT_LPWSTR: //31 - case VT_FILETIME: //64 - case VT_BLOB: //65 - case VT_STREAM: //66 - case VT_STORAGE: //67 - case VT_STREAMED_OBJECT: //68 - case VT_STORED_OBJECT: //69 - case VT_BLOB_OBJECT: //70 - case VT_CF: //71 - case VT_CLSID: //72 - default: - _ASSERTE(!"NYI"); - break; - } - return NOERROR; -} -#endif // BIGENDIAN - -// Default space sizes for the various arrays. Make it too small in a -// checked build so we exercise the growing code. -#ifdef _DEBUG -#define DEF_LOCAL_SPACE 2 -#define DEF_MISC_SPACE 64 -#else -#define DEF_LOCAL_SPACE 64 -#define DEF_MISC_SPACE 1024 -#endif - -/* ------------------------------------------------------------------------- * - * SymVariable struct - * ------------------------------------------------------------------------- */ -struct SymVariable -{ -private: - UINT32 m_Scope; // index of parent scope - UINT32 m_Name; // index into misc byte array - ULONG32 m_Attributes; // Attributes - UINT32 m_Signature; // index into misc byte array - ULONG32 m_SignatureSize; // Signature size - ULONG32 m_AddrKind; // Address Kind - ULONG32 m_Addr1; // Additional info - ULONG32 m_Addr2; - ULONG32 m_Addr3; - ULONG32 m_StartOffset; // StartOffset - ULONG32 m_EndOffset; // EndOffset - ULONG32 m_Sequence; - BOOL m_IsParam; // parameter? - BOOL m_IsHidden; // Is not visible to the user - -public: - UINT32 Scope() - { - return VAL32(m_Scope); - } - void SetScope(UINT32 Scope) - { - m_Scope = VAL32(Scope); - } - - UINT32 Name() - { - return VAL32(m_Name); - } - void SetName(UINT32 Name) - { - m_Name = VAL32(Name); - } - - ULONG32 Attributes() - { - return VAL32(m_Attributes); - } - void SetAttributes(ULONG32 Attributes) - { - m_Attributes = VAL32(Attributes); - } - - UINT32 Signature() - { - return VAL32(m_Signature); - } - void SetSignature(UINT32 Signature) - { - m_Signature = VAL32(Signature); - } - ULONG32 SignatureSize() - { - return VAL32(m_SignatureSize); - } - void SetSignatureSize(ULONG32 SignatureSize) - { - m_SignatureSize = VAL32(SignatureSize); - } - - ULONG32 AddrKind() - { - return VAL32(m_AddrKind); - } - void SetAddrKind(ULONG32 AddrKind) - { - m_AddrKind = VAL32(AddrKind); - } - ULONG32 Addr1() - { - return VAL32(m_Addr1); - } - void SetAddr1(ULONG32 Addr1) - { - m_Addr1 = VAL32(Addr1); - } - - ULONG32 Addr2() - { - return VAL32(m_Addr2); - } - void SetAddr2(ULONG32 Addr2) - { - m_Addr2 = VAL32(Addr2); - } - - ULONG32 Addr3() - { - return VAL32(m_Addr3); - } - void SetAddr3(ULONG32 Addr3) - { - m_Addr3 = VAL32(Addr3); - } - - ULONG32 StartOffset() - { - return VAL32(m_StartOffset); - } - void SetStartOffset(ULONG32 StartOffset) - { - m_StartOffset = VAL32(StartOffset); - } - ULONG32 EndOffset() - { - return VAL32(m_EndOffset); - } - void SetEndOffset(ULONG EndOffset) - { - m_EndOffset = VAL32(EndOffset); - } - ULONG32 Sequence() - { - return VAL32(m_Sequence); - } - void SetSequence(ULONG32 Sequence) - { - m_Sequence = VAL32(Sequence); - } - - BOOL IsParam() - { - return VAL32(m_IsParam); - } - void SetIsParam(BOOL IsParam) - { - m_IsParam = IsParam; - } - BOOL IsHidden() - { - return VAL32(m_IsHidden); - } - void SetIsHidden(BOOL IsHidden) - { - m_IsHidden = IsHidden; - } -}; - -/* ------------------------------------------------------------------------- * - * SymLexicalScope struct - * ------------------------------------------------------------------------- */ -struct SymLexicalScope -{ -private: - - UINT32 m_ParentScope; // parent index (-1 for no parent) - ULONG32 m_StartOffset; // start offset - ULONG32 m_EndOffset; // end offset - BOOL m_HasChildren; // scope has children - BOOL m_HasVars; // scope has vars? -public: - UINT32 ParentScope() - { - return VAL32(m_ParentScope); - } - void SetParentScope(UINT32 ParentScope) - { - m_ParentScope = VAL32(ParentScope); - } - - ULONG32 StartOffset() - { - return VAL32(m_StartOffset); - } - void SetStartOffset(ULONG32 StartOffset) - { - m_StartOffset = VAL32(StartOffset); - } - ULONG32 EndOffset() - { - return VAL32(m_EndOffset); - } - void SetEndOffset(ULONG32 EndOffset) - { - m_EndOffset = VAL32(EndOffset); - } - BOOL HasChildren() - { - return m_HasChildren; - } - void SetHasChildren(BOOL HasChildren) - { - m_HasChildren = HasChildren; - } - BOOL HasVars() - { - return m_HasVars; - } - void SetHasVars(BOOL HasVars) - { - m_HasVars = HasVars; - } - -}; - -/* ------------------------------------------------------------------------- * - * SymUsingNamespace struct - * ------------------------------------------------------------------------- */ -struct SymUsingNamespace -{ -private: - - UINT32 m_ParentScope; // index of parent scope - UINT32 m_Name; // Index of name -public: - UINT32 ParentScope() - { - return VAL32(m_ParentScope); - } - void SetParentScope(UINT32 ParentScope) - { - m_ParentScope = VAL32(ParentScope); - } - UINT32 Name() - { - return VAL32(m_Name); - } - void SetName(UINT32 Name) - { - m_Name = VAL32(Name); - } -}; - -/* ------------------------------------------------------------------------- * - * SymConstant struct - * ------------------------------------------------------------------------- */ -struct SymConstant -{ -private: - - VARIANT m_Value; // Constant Value - UINT32 m_ParentScope; // Parent scope - UINT32 m_Name; // Name index - UINT32 m_Signature; // Signature index - ULONG32 m_SignatureSize;// Signature size - UINT32 m_ValueBstr; // If the variant is a bstr, store the string - -public: - UINT32 ParentScope() - { - return VAL32(m_ParentScope); - } - void SetParentScope(UINT32 ParentScope) - { - m_ParentScope = VAL32(ParentScope); - } - UINT32 Name() - { - return VAL32(m_Name); - } - void SetName(UINT32 Name) - { - m_Name = VAL32(Name); - } - UINT32 Signature() - { - return VAL32(m_Signature); - } - void SetSignature(UINT32 Signature) - { - m_Signature = VAL32(Signature); - } - ULONG32 SignatureSize() - { - return VAL32(m_SignatureSize); - } - void SetSignatureSize(ULONG32 SignatureSize) - { - m_SignatureSize = VAL32(SignatureSize); - } - VARIANT Value(UINT32 *pValueBstr) - { - *pValueBstr = VAL32(m_ValueBstr); -#if BIGENDIAN - VARIANT VariantValue; - VariantInit(&VariantValue); - // VT_BSTR's are dealt with ValueBStr - if (m_ValueBstr) - { - V_VT(&VariantValue) = VT_BSTR; - } - else - { - VariantSwap(false, &VariantValue, &m_Value); - } - return VariantValue; -#else - return m_Value; -#endif - } - void SetValue(VARIANT VariantValue, UINT32 ValueBstr) - { - m_Value = VariantValue; - m_ValueBstr = VAL32(ValueBstr); -#if BIGENDIAN - // VT_BSTR's are dealt with ValueBStr - if (m_ValueBstr) - { - V_VT(&m_Value) = VAL16(VT_BSTR); - } - else - { - VariantSwap(true, &m_Value, &VariantValue); - } -#endif - } -}; - -/* ------------------------------------------------------------------------- * - * SymMethodInfo struct - * ------------------------------------------------------------------------- */ -struct SymMethodInfo -{ -private: - - mdMethodDef m_MethodToken; // Method token - - // Start/End Entries into the respective tables - // End values are extents - one past the last index (and so may actually be an index off - // the end of the array). Start may equal end if the method has none of the item. - UINT32 m_StartScopes; - UINT32 m_EndScopes; - UINT32 m_StartVars; - UINT32 m_EndVars; - UINT32 m_StartUsing; - UINT32 m_EndUsing; - UINT32 m_StartConstant; - UINT32 m_EndConstant; - UINT32 m_StartDocuments; - UINT32 m_EndDocuments; - UINT32 m_StartSequencePoints; - UINT32 m_EndSequencePoints; - -public: - static int __cdecl compareMethods(const void *elem1, const void *elem2 ); - - mdMethodDef MethodToken() - { - return VAL32(m_MethodToken); - } - void SetMethodToken(mdMethodDef MethodToken) - { - m_MethodToken = VAL32(MethodToken); - } - UINT32 StartScopes() - { - return VAL32(m_StartScopes); - } - void SetStartScopes(UINT32 StartScopes) - { - m_StartScopes = VAL32(StartScopes); - } - UINT32 EndScopes() - { - return VAL32(m_EndScopes); - } - void SetEndScopes(UINT32 EndScopes) - { - m_EndScopes = VAL32(EndScopes); - } - UINT32 StartVars() - { - return VAL32(m_StartVars); - } - void SetStartVars(UINT32 StartVars) - { - m_StartVars = VAL32(StartVars); - } - UINT32 EndVars() - { - return VAL32(m_EndVars); - } - void SetEndVars(UINT32 EndVars) - { - m_EndVars = VAL32(EndVars); - } - UINT32 StartUsing() - { - return VAL32(m_StartUsing); - } - void SetStartUsing(UINT32 StartUsing) - { - m_StartUsing = VAL32(StartUsing); - } - UINT32 EndUsing() - { - return VAL32(m_EndUsing); - } - void SetEndUsing(UINT32 EndUsing) - { - m_EndUsing = VAL32(EndUsing); - } - UINT32 StartConstant() - { - return VAL32(m_StartConstant); - } - void SetStartConstant(UINT32 StartConstant) - { - m_StartConstant = VAL32(StartConstant); - } - UINT32 EndConstant() - { - return VAL32(m_EndConstant); - } - void SetEndConstant(UINT32 EndConstant) - { - m_EndConstant = VAL32(EndConstant); - } - UINT32 StartDocuments() - { - return VAL32(m_StartDocuments); - } - void SetStartDocuments(UINT32 StartDocuments) - { - m_StartDocuments = VAL32(StartDocuments); - } - UINT32 EndDocuments() - { - return VAL32(m_EndDocuments); - } - void SetEndDocuments(UINT32 EndDocuments) - { - m_EndDocuments = VAL32(EndDocuments); - } - UINT32 StartSequencePoints() - { - return VAL32(m_StartSequencePoints); - } - void SetStartSequencePoints(UINT32 StartSequencePoints) - { - m_StartSequencePoints = VAL32(StartSequencePoints); - } - UINT32 EndSequencePoints() - { - return VAL32(m_EndSequencePoints); - } - void SetEndSequencePoints(UINT32 EndSequencePoints) - { - m_EndSequencePoints = VAL32(EndSequencePoints); - } -}; - -/* ------------------------------------------------------------------------- * - * SymMap struct - * ------------------------------------------------------------------------- */ -struct SymMap -{ - mdMethodDef m_MethodToken; // New Method token - UINT32 MethodEntry; // Method Entry -}; - -/* ------------------------------------------------------------------------- * - * SequencePoint struct - * ------------------------------------------------------------------------- */ -struct SequencePoint { - -private: - - DWORD m_Offset; - DWORD m_StartLine; - DWORD m_StartColumn; - DWORD m_EndLine; - DWORD m_EndColumn; - DWORD m_Document; - -public: - bool IsWithin(ULONG32 line, ULONG32 column); - bool IsWithinLineOnly(ULONG32 line); - bool IsGreaterThan(ULONG32 line, ULONG32 column); - bool IsLessThan(ULONG32 line, ULONG32 column); - bool IsUserLine(); - static int __cdecl compareAuxLines(const void *elem1, const void *elem2 ); - - DWORD Offset() - { - return VAL32(m_Offset); - } - void SetOffset(DWORD Offset) - { - m_Offset = VAL32(Offset); - } - DWORD StartLine() - { - return VAL32(m_StartLine); - } - void SetStartLine(DWORD StartLine) - { - m_StartLine = VAL32(StartLine); - } - - DWORD StartColumn() - { - return VAL32(m_StartColumn); - } - void SetStartColumn(DWORD StartColumn) - { - m_StartColumn = VAL32(StartColumn); - } - - DWORD EndLine() - { - return VAL32(m_EndLine); - } - void SetEndLine(DWORD EndLine) - { - m_EndLine = VAL32(EndLine); - } - DWORD EndColumn() - { - return VAL32(m_EndColumn); - } - void SetEndColumn(DWORD EndColumn) - { - m_EndColumn = VAL32(EndColumn); - } - DWORD Document() - { - return VAL32(m_Document); - } - void SetDocument(DWORD Document) - { - m_Document = VAL32(Document); - } -}; - - -/* ------------------------------------------------------------------------- * - * DocumentInfo struct - * ------------------------------------------------------------------------- */ -typedef struct DocumentInfo { - -private: - - GUID m_Language; - GUID m_LanguageVendor; - GUID m_DocumentType; - GUID m_AlgorithmId; - DWORD m_CheckSumSize; - UINT32 m_CheckSumEntry; - UINT32 m_SourceSize; - UINT32 m_SourceEntry; - UINT32 m_UrlEntry; - SymDocumentWriter * m_pDocumentWriter; - -public: - - GUID Language() - { - GUID TmpGuid = m_Language; - SwapGuid(&TmpGuid); - return TmpGuid; - } - void SetLanguage(GUID Language) - { - SwapGuid(&Language); - m_Language = Language; - } - GUID LanguageVendor() - { - GUID TmpGuid = m_LanguageVendor; - SwapGuid(&TmpGuid); - return TmpGuid; - } - void SetLanguageVendor(GUID LanguageVendor) - { - SwapGuid(&LanguageVendor); - m_LanguageVendor = LanguageVendor; - } - GUID DocumentType() - { - GUID TmpGuid = m_DocumentType; - SwapGuid(&TmpGuid); - return TmpGuid; - } - void SetDocumentType(GUID DocumentType) - { - SwapGuid(&DocumentType); - m_DocumentType = DocumentType; - } - - // Set the pointer to the SymDocumentWriter instance corresponding to this instance of DocumentInfo - // An argument of NULL will call Release - void SetDocumentWriter(SymDocumentWriter * pDoc); - - // get the associated SymDocumentWriter - SymDocumentWriter * DocumentWriter() - { - return m_pDocumentWriter; - } - - GUID AlgorithmId() - { - GUID TmpGuid = m_AlgorithmId; - SwapGuid(&TmpGuid); - return TmpGuid; - } - void SetAlgorithmId(GUID AlgorithmId) - { - SwapGuid(&AlgorithmId); - m_AlgorithmId = AlgorithmId; - } - - DWORD CheckSumSize() - { - return VAL32(m_CheckSumSize); - } - void SetCheckSymSize(DWORD CheckSumSize) - { - m_CheckSumSize = VAL32(CheckSumSize); - } - UINT32 CheckSumEntry() - { - return VAL32(m_CheckSumEntry); - } - void SetCheckSumEntry(UINT32 CheckSumEntry) - { - m_CheckSumEntry = VAL32(CheckSumEntry); - } - UINT32 SourceSize() - { - return VAL32(m_SourceSize); - } - void SetSourceSize(UINT32 SourceSize) - { - m_SourceSize = VAL32(SourceSize); - } - UINT32 SourceEntry() - { - return VAL32(m_SourceEntry); - } - void SetSourceEntry(UINT32 SourceEntry) - { - m_SourceEntry = VAL32(SourceEntry); - } - UINT32 UrlEntry() - { - return VAL32(m_UrlEntry); - } - void SetUrlEntry(UINT32 UrlEntry) - { - m_UrlEntry = VAL32(UrlEntry); - } - -} DocumentInfo; - -template -class ArrayStorage -{ -public: - - ArrayStorage( int initialSize = 0 ) - : m_spaceSize(0), m_instanceCount( 0 ), m_array( NULL ) - { - grow( initialSize ); - } - ~ArrayStorage() - { - - if ( m_array ) - DELETEARRAY(m_array); - m_array = NULL; - m_spaceSize = 0; - m_instanceCount = 0; - } - T* next() - { - if( !grow ( m_instanceCount ) ) - return NULL; - _ASSERTE( m_instanceCount < m_spaceSize ); - return &m_array[ m_instanceCount++ ]; - } - bool grab(UINT32 n, UINT32 * pIndex) - { - S_UINT32 newSize = S_UINT32(m_instanceCount) + S_UINT32(n); - if (newSize.IsOverflow()) - return false; - if (!grow(newSize.Value())) - return false; - _ASSERTE( m_instanceCount < m_spaceSize ); - *pIndex = m_instanceCount; - m_instanceCount += n; - return true; - } - - T& operator[]( UINT32 i ) { - _ASSERTE( i < m_instanceCount ); - if (i >= m_instanceCount) - { - // Help mitigate the impact of buffer overflow - // Fail fast with a null-reference AV - volatile char* nullPointer = nullptr; - *nullPointer; - } - return m_array[ i ]; - } - void reset() { - m_instanceCount = 0; - } - UINT32 size() { - return m_spaceSize; - } - UINT32 count() { - return m_instanceCount; - } - - UINT32 m_spaceSize; // Total size of array in elements - UINT32 m_instanceCount; // total T's in the file - T *m_array; // array of T's -private: - bool grow( UINT32 n ) - { - if (n >= m_spaceSize) - { - // Make a new, bigger array. - UINT32 newSpaceSize; - - if (n == 0) - newSpaceSize = DEF_LOCAL_SPACE; - else - newSpaceSize = max( m_spaceSize * 2, n); - - // Make sure we're not asking for more than 4GB of bytes to ensure no integer-overflow attacks are possible - S_UINT32 newBytes = S_UINT32(newSpaceSize) * S_UINT32(sizeof(T)); - if (newBytes.IsOverflow()) - return false; - - T *newTs; - newTs = NEW(T[newSpaceSize]); - if ( newTs == NULL ) - return false; - - // Copy over the old Ts. - memcpy(newTs, m_array, - sizeof(T) * m_spaceSize); - - // Delete the old Ts. - DELETEARRAY(m_array); - - // Hang onto the new array. - m_array = newTs; - m_spaceSize = newSpaceSize; - } - return true; - } - -}; - -typedef struct MethodInfo { - - ArrayStorage m_methods; // Methods information - ArrayStorage m_scopes; // Scope information for the method - ArrayStorage m_vars; // Variables - ArrayStorage m_usings; // using/imports - ArrayStorage m_constants; // Constants - ArrayStorage m_documents; // Document Source Format - ArrayStorage m_auxSequencePoints; // Sequence Points - // Array of various bytes (variable signature, etc) - ArrayStorage m_bytes; - - -public: - - MethodInfo() : - m_bytes( DEF_MISC_SPACE ) - { - } -} MethodInfo; - -/* ------------------------------------------------------------------------- * - * SymWriter class - * ------------------------------------------------------------------------- */ - -class SymWriter : public ISymUnmanagedWriter3 -{ -public: - SymWriter(); - virtual ~SymWriter(); - - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - // Note that this must be thread-safe - it may be invoked on the finalizer thread - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ISymUnmanagedWriter - //----------------------------------------------------------- - COM_METHOD DefineDocument(const WCHAR *url, - const GUID *language, - const GUID *languageVendor, - const GUID *documentType, - ISymUnmanagedDocumentWriter **pRetVal); - COM_METHOD SetUserEntryPoint(mdMethodDef entryMethod); - COM_METHOD OpenMethod(mdMethodDef method); - COM_METHOD CloseMethod(); - COM_METHOD DefineSequencePoints(ISymUnmanagedDocumentWriter *document, - ULONG32 spCount, - ULONG32 offsets[], - ULONG32 lines[], - ULONG32 columns[], - ULONG32 endLines[], - ULONG32 encColumns[]); - COM_METHOD OpenScope(ULONG32 startOffset, ULONG32 *scopeID); - COM_METHOD CloseScope(ULONG32 endOffset); - COM_METHOD SetScopeRange(ULONG32 scopeID, ULONG32 startOffset, ULONG32 endOffset); - COM_METHOD DefineLocalVariable(const WCHAR *name, - ULONG32 attributes, - ULONG32 cSig, - BYTE signature[], - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3, - ULONG32 startOffset, ULONG32 endOffset); - COM_METHOD DefineParameter(const WCHAR *name, - ULONG32 attributes, - ULONG32 sequence, - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3); - COM_METHOD DefineField(mdTypeDef parent, - const WCHAR *name, - ULONG32 attributes, - ULONG32 cSig, - BYTE signature[], - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3); - COM_METHOD DefineGlobalVariable(const WCHAR *name, - ULONG32 attributes, - ULONG32 cSig, - BYTE signature[], - ULONG32 addrKind, - ULONG32 addr1, ULONG32 addr2, ULONG32 addr3); - COM_METHOD Close(); - COM_METHOD SetSymAttribute(mdToken parent, - const WCHAR *name, - ULONG32 cData, - BYTE data[]); - COM_METHOD OpenNamespace(const WCHAR *name); - COM_METHOD CloseNamespace(); - COM_METHOD UsingNamespace(const WCHAR *fullName); - COM_METHOD SetMethodSourceRange(ISymUnmanagedDocumentWriter *startDoc, - ULONG32 startLine, - ULONG32 startColumn, - ISymUnmanagedDocumentWriter *endDoc, - ULONG32 endLine, - ULONG32 endColumn); - COM_METHOD GetDebugCVInfo(DWORD cData, - DWORD *pcData, - BYTE data[]); - - COM_METHOD Initialize(IUnknown *emitter, - const WCHAR *filename, - IStream *pIStream, - BOOL fFullBuild); - - COM_METHOD Initialize2(IUnknown *emitter, - const WCHAR *pdbTempPath, // location to write pdb file - IStream *pIStream, - BOOL fFullBuild, - const WCHAR *pdbFinalPath); // location exe should contain for pdb file - - COM_METHOD GetDebugInfo(IMAGE_DEBUG_DIRECTORY *pIDD, - DWORD cData, - DWORD *pcData, - BYTE data[]); - - COM_METHOD RemapToken(mdToken oldToken, - mdToken newToken); - - COM_METHOD DefineConstant(const WCHAR __RPC_FAR *name, - VARIANT value, - ULONG32 cSig, - unsigned char __RPC_FAR signature[ ]); - - COM_METHOD Abort(void); - - //----------------------------------------------------------- - // ISymUnmanagedWriter2 - //----------------------------------------------------------- - COM_METHOD DefineLocalVariable2(const WCHAR *name, - ULONG32 attributes, - mdSignature sigToken, - ULONG32 addrKind, - ULONG32 addr1, - ULONG32 addr2, - ULONG32 addr3, - ULONG32 startOffset, - ULONG32 endOffset); - - COM_METHOD DefineGlobalVariable2(const WCHAR *name, - ULONG32 attributes, - mdSignature sigToken, - ULONG32 addrKind, - ULONG32 addr1, - ULONG32 addr2, - ULONG32 addr3); - - COM_METHOD DefineConstant2(const WCHAR *name, - VARIANT value, - mdSignature sigToken); - - //----------------------------------------------------------- - // ISymUnmanagedWriter3 - //----------------------------------------------------------- - - COM_METHOD OpenMethod2(mdMethodDef method, - ULONG32 isect, - ULONG32 offset); - - COM_METHOD Commit(); - - //----------------------------------------------------------- - // Methods not exposed via a COM interface. - //----------------------------------------------------------- - - static HRESULT NewSymWriter(REFIID clsid, void** ppObj); - HRESULT SetDocumentCheckSum( - UINT32 DocumentEntry, - GUID AlgorithmId, - DWORD CheckSumSize, - BYTE* pCheckSum); - HRESULT SetDocumentSrc(UINT32 DocumentEntry, - DWORD SourceSize, - BYTE* pSource); - - COM_METHOD Write(void *pData, DWORD SizeOfData); - COM_METHOD WriteStringPool(); - COM_METHOD WritePDB(); - - COM_METHOD Initialize(const WCHAR *szFilename, IStream *pIStream); - - void SetFullPathName(const WCHAR *szFullPathName) - { - - } - -private: - // Helper API for CloserScope - COM_METHOD CloseScopeInternal(ULONG32 endOffset); - HRESULT GetOrCreateDocument( - const WCHAR *wcsUrl, // Document name - const GUID *pLanguage, // What Language we're compiling - const GUID *pLanguageVendor, // What vendor - const GUID *pDocumentType, // Type - ISymUnmanagedDocumentWriter **ppRetVal // [out] Created DocumentWriter - ); - HRESULT CreateDocument( - const WCHAR *wcsUrl, // Document name - const GUID *pLanguage, // What Language we're compiling - const GUID *pLanguageVendor, // What vendor - const GUID *pDocumentType, // Type - ISymUnmanagedDocumentWriter **ppRetVal // [out] Created DocumentWriter - ); - - - //----------------------------------------------------------- - // Data members - //----------------------------------------------------------- -private: - UINT32 m_refCount; // AddRef/Release - - mdMethodDef m_openMethodToken; - mdMethodDef m_LargestMethodToken; - SymMethodInfo * m_pmethod; - - // index of currently open scope - UINT32 m_currentScope; - - // special scope "index" meaning there is no such scope - static const UINT32 k_noScope = (UINT32)-1; - - // maximum scope end offset seen so far in this method - ULONG32 m_maxScopeEnd; - - MethodInfo m_MethodInfo; - ArrayStorage m_MethodMap; // Methods information - - // Symbol File Name - WCHAR m_szPath[ _MAX_PATH ]; - // File Handle - HANDLE m_hFile; - // Stream we're storing into if asked to. - IStream* m_pIStream; - - // StringPool we use to store the string into - StgStringPool *m_pStringPool; - - // Project level symbol information - PDBInfo ModuleLevelInfo; - - bool m_closed; // Have we closed the file yet? - bool m_sortLines; // sort the line for current method - bool m_sortMethodEntries; // Sort the method entries - - -}; - -/* ------------------------------------------------------------------------- * - * SymDocumentWriter class - * ------------------------------------------------------------------------- */ - -class SymDocumentWriter : public ISymUnmanagedDocumentWriter -{ -public: - SymDocumentWriter(UINT32 DocumentEntry, - SymWriter *pEmitter); - - virtual ~SymDocumentWriter(); - - //----------------------------------------------------------- - // IUnknown support - //----------------------------------------------------------- - ULONG STDMETHODCALLTYPE AddRef() - { - return (InterlockedIncrement((LONG *) &m_refCount)); - } - - ULONG STDMETHODCALLTYPE Release() - { - // Note that this must be thread-safe - it may be invoked on the finalizer thread - LONG refCount = InterlockedDecrement((LONG *) &m_refCount); - if (refCount == 0) - DELETE(this); - - return (refCount); - } - COM_METHOD QueryInterface(REFIID riid, void **ppInterface); - - //----------------------------------------------------------- - // ISymUnmanagedDocumentWriter - //----------------------------------------------------------- - COM_METHOD SetSource(ULONG32 sourceSize, BYTE source[]); - COM_METHOD SetCheckSum(GUID algorithmId, - ULONG32 checkSumSize, BYTE checkSum[]); - - //----------------------------------------------------------- - // Methods not exposed via a COM interface. - //----------------------------------------------------------- - // - // Commit the doc to the pdb - // - UINT32 GetDocumentEntry() - { - return m_DocumentEntry; - } - - //----------------------------------------------------------- - // Data members - //----------------------------------------------------------- -private: - UINT32 m_refCount; // AddRef/Release - UINT32 m_DocumentEntry; // Entry into the documents array - SymWriter *m_pEmitter; // Associated SymWriter -}; - -// Debug Info -struct RSDSI // RSDS debug info -{ - DWORD dwSig; // RSDS - GUID guidSig; - DWORD age; - char szPDB[0]; // followed by a zero-terminated UTF8 file name -}; - -#endif /* SYMWRITE_H_ */ diff --git a/src/coreclr/debug/ildbsymlib/umisc.h b/src/coreclr/debug/ildbsymlib/umisc.h deleted file mode 100644 index 78c3ea3d55616b..00000000000000 --- a/src/coreclr/debug/ildbsymlib/umisc.h +++ /dev/null @@ -1,68 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// =========================================================================== -// File: umisc.h -// - -// =========================================================================== - - -// Abstract: -// -// A collection of utility macros. -// - -#ifndef UMISC_H -#define UMISC_H - -#define COM_METHOD HRESULT STDMETHODCALLTYPE - -inline HRESULT HrFromWin32(DWORD dwWin32Error) -{ - return HRESULT_FROM_WIN32(dwWin32Error); -} - -// Some helper #def's to safely Release, close & delete Objects under -// failure conditions - -#define RELEASE(x) \ - do \ - { \ - if (x) \ - { \ - IUnknown *punk = x; \ - x = NULL; \ - punk->Release(); \ - } \ - } while (0) - - -#include "debugmacros.h" -// -// Good for verifying params withing range. -// -#define IfFalseGo(expr, HR) IfFailGo((expr) ? S_OK : (HR)) - -// ---------------------------------------------------------------------------- -// Validation macros -// Note that the Win32 APIs like IsBadReadPtr are banned -// -#define IsValidReadPtr(ptr, type) ((ptr)!=NULL) - -#define IsValidWritePtr(ptr, type) ((ptr)!=NULL) - -#define IsValidReadBufferPtr(ptr, type, len) ((ptr)!=NULL) - -#define IsValidWriteBufferPtr(ptr, type, len) ((ptr)!=NULL) - -#define IsValidInterfacePtr(ptr, type) ((ptr)!=NULL) - -#define IsValidCodePtr(ptr) ((ptr)!=NULL) - -#define IsValidStringPtr(ptr) ((ptr)!=NULL) - -#define IsValidIID(iid) TRUE - -#define IsValidCLSID(clsid) TRUE - -#endif diff --git a/src/coreclr/debug/inc/dacdbiinterface.h b/src/coreclr/debug/inc/dacdbiinterface.h index 2dc0beca1c0ada..dcf4608825379f 100644 --- a/src/coreclr/debug/inc/dacdbiinterface.h +++ b/src/coreclr/debug/inc/dacdbiinterface.h @@ -547,7 +547,6 @@ class IDacDbiInterface { kSymbolFormatNone, // No symbols available kSymbolFormatPDB, // PDB symbol format - use diasymreader.dll - kSymbolFormatILDB, // ILDB symbol format - use ildbsymlib } SymbolFormat; // diff --git a/src/coreclr/dlls/mscordbi/CMakeLists.txt b/src/coreclr/dlls/mscordbi/CMakeLists.txt index 8a915ab1811abd..c7a23c9923fe1d 100644 --- a/src/coreclr/dlls/mscordbi/CMakeLists.txt +++ b/src/coreclr/dlls/mscordbi/CMakeLists.txt @@ -66,7 +66,6 @@ set(COREDBI_LIBRARIES debug-pal cordbdi utilcodestaticnohost - ildbsymlib mdcompiler-dbi mdruntime-dbi mdruntimerw-dbi diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 9b8e4b649864d9..cfc08adbc43406 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -104,7 +104,6 @@ set(CORECLR_LIBRARIES comfloat_wks corguids gcinfo - ildbsymlib utilcode v3binder System.Globalization.Native-Static diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 60cdfe9ada3b20..f8ffae0672e8a6 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -170,7 +170,6 @@ CONFIG_DWORD_INFO(INTERNAL_DbgBreakOnRawInt3, W("DbgBreakOnRawInt3"), 0, "Allows CONFIG_DWORD_INFO(INTERNAL_DbgBreakOnSendBreakpoint, W("DbgBreakOnSendBreakpoint"), 0, "Allows an assert when sending a breakpoint to the right side") CONFIG_DWORD_INFO(INTERNAL_DbgBreakOnSetIP, W("DbgBreakOnSetIP"), 0, "Allows an assert when setting the IP") CONFIG_DWORD_INFO(INTERNAL_DbgCheckInt3, W("DbgCheckInt3"), 0, "Asserts if the debugger explicitly writes int3 instead of calling SetUnmanagedBreakpoint") -RETAIL_CONFIG_DWORD_INFO(INTERNAL_DbgForcePDBSymbols, W("DbgForcePDBSymbols"), 0, "") CONFIG_DWORD_INFO(INTERNAL_DbgDACAssertOnMismatch, W("DbgDACAssertOnMismatch"), 0, "Allows an assert when the mscordacwks and mscorwks dll versions don't match") CONFIG_DWORD_INFO(INTERNAL_DbgDACEnableAssert, W("DbgDACEnableAssert"), 0, "Enables extra validity checking in DAC - assumes target isn't corrupt") RETAIL_CONFIG_DWORD_INFO(INTERNAL_DbgDACSkipVerifyDlls, W("DbgDACSkipVerifyDlls"), 0, "Allows disabling the check to ensure mscordacwks and mscorwks dll versions match") diff --git a/src/coreclr/inc/ildbsymlib.h b/src/coreclr/inc/ildbsymlib.h deleted file mode 100644 index bc20a71d2e6087..00000000000000 --- a/src/coreclr/inc/ildbsymlib.h +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//***************************************************************************** -// IldbSymLib.h -// -// ILDB debug symbols functions implemented in IldbSymLib.lib -// Provides support for ILDB-format debug symbols using the same interfaces -// that diasymreader.dll exposes for PDB symbols. -// -//***************************************************************************** -#ifndef __IldbSymLib_h__ -#define __IldbSymLib_h__ - -// Get the IClassFactory for one of the ILDB symbols CLSIDs -STDAPI IldbSymbolsGetClassObject(REFCLSID rclsid, REFIID riid, void** ppvObject); - -// Create an inststance of an ILDB ISymUnmanagedReader, ISymUnmanagedWriter or ISymUnmanagedBinder -STDAPI IldbSymbolsCreateInstance(REFCLSID rclsid, REFIID riid, void** ppvIUnknown); - -#endif // __IldbSymLib_h__ diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index 8540e907ffb455..144c2c7f57f33e 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -71,7 +71,6 @@ #include "../md/compiler/custattr.h" #include "typekey.h" #include "peimagelayout.inl" -#include "ildbsymlib.h" #if defined(PROFILING_SUPPORTED) #include "profilermetadataemitvalidator.h" @@ -413,7 +412,6 @@ Module::Module(Assembly *pAssembly, mdFile moduleRef, PEFile *file) { // Memory allocated on LoaderHeap is zero-filled. Spot-check it here. _ASSERTE(m_pBinder == NULL); - _ASSERTE(m_symbolFormat == eSymbolFormatNone); } file->AddRef(); @@ -3425,35 +3423,25 @@ ISymUnmanagedReader *Module::GetISymUnmanagedReader(void) "reachable or needs to be reimplemented for CoreCLR!"); } - if (this->GetInMemorySymbolStreamFormat() == eSymbolFormatILDB) + // We're going to be working with Windows PDB format symbols. Attempt to CoCreate the symbol binder. + // CoreCLR supports not having a symbol reader installed, so CoCreate searches the PATH env var + // and then tries coreclr dll location. + // On desktop, the framework installer is supposed to install diasymreader.dll as well + // and so this shouldn't happen. + hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, NATIVE_SYMBOL_READER_DLL, IID_ISymUnmanagedBinder, (void**)&pBinder, NULL); + if (FAILED(hr)) { - // We've got in-memory ILDB symbols, create the ILDB symbol binder - // Note that in this case, we must be very careful not to use diasymreader.dll - // at all - we don't trust it, and shouldn't run any code in it - IfFailThrow(IldbSymbolsCreateInstance(CLSID_CorSymBinder_SxS, IID_ISymUnmanagedBinder, (void**)&pBinder)); - } - else - { - // We're going to be working with Windows PDB format symbols. Attempt to CoCreate the symbol binder. - // CoreCLR supports not having a symbol reader installed, so CoCreate searches the PATH env var - // and then tries coreclr dll location. - // On desktop, the framework installer is supposed to install diasymreader.dll as well - // and so this shouldn't happen. - hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, NATIVE_SYMBOL_READER_DLL, IID_ISymUnmanagedBinder, (void**)&pBinder, NULL); + PathString symbolReaderPath; + hr = GetClrModuleDirectory(symbolReaderPath); if (FAILED(hr)) { - PathString symbolReaderPath; - hr = GetClrModuleDirectory(symbolReaderPath); - if (FAILED(hr)) - { - RETURN (NULL); - } - symbolReaderPath.Append(NATIVE_SYMBOL_READER_DLL); - hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, symbolReaderPath.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL); - if (FAILED(hr)) - { - RETURN (NULL); - } + RETURN (NULL); + } + symbolReaderPath.Append(NATIVE_SYMBOL_READER_DLL); + hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, symbolReaderPath.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL); + if (FAILED(hr)) + { + RETURN (NULL); } } @@ -3547,14 +3535,6 @@ BOOL Module::IsSymbolReadingEnabled() } CONTRACTL_END; - // If the module has symbols in-memory (eg. RefEmit) that are in ILDB - // format, then there isn't any reason not to supply them. The reader - // code is always available, and we trust it's security. - if (this->GetInMemorySymbolStreamFormat() == eSymbolFormatILDB) - { - return TRUE; - } - #ifdef DEBUGGING_SUPPORTED if (!g_pDebugInterface) { @@ -3586,7 +3566,7 @@ void Module::SetSymbolBytes(LPCBYTE pbSyms, DWORD cbSyms) // Make sure to set the symbol stream on the module before // attempting to send UpdateModuleSyms messages up for it. - SetInMemorySymbolStream(pStream, eSymbolFormatPDB); + SetInMemorySymbolStream(pStream); // This can only be called when the module is being created. No-one should have // tried to use the symbols yet, and so there should not be a reader. @@ -3714,57 +3694,6 @@ void Module::AddClass(mdTypeDef classdef) { BuildClassForModule(); } - - // Since the module is being modified, the in-memory symbol stream - // (if any) has probably also been modified. If we support reading the symbols - // then we need to commit the changes to the writer and flush any old readers - // However if we don't support reading then we can skip this which will give - // a substantial perf improvement. See DDB 671107. - if(IsSymbolReadingEnabled()) - { - CONSISTENCY_CHECK(IsReflection()); // this is only used for dynamic modules - ISymUnmanagedWriter * pWriter = GetReflectionModule()->GetISymUnmanagedWriter(); - if (pWriter != NULL) - { - // Serialize with any concurrent reader creations - // Specifically, if we started creating a reader on one thread, and then updated the - // symbols on another thread, we need to wait until the initial reader creation has - // completed and release it so we don't get stuck with a stale reader. - // Also, if we commit to the stream while we're in the process of creating a reader, - // the reader will get corrupted/incomplete data. - // Note that we must also be in co-operative mode here to ensure the debugger helper - // thread can't be simultaneously reading this stream while the process is synchronized - // (code:Debugger::GetSymbolBytes) - CrstHolder holder(&m_ISymUnmanagedReaderCrst); - - // Flush writes to the symbol store to the symbol stream - // Note that we do this when finishing the addition of the class, instead of - // on-demand in GetISymUnmanagedReader because the writer is not thread-safe. - // Here, we're inside the lock of TypeBuilder.CreateType, and so it's safe to - // manipulate the writer. - SafeComHolderPreemp pWriter3; - HRESULT thr = pWriter->QueryInterface(IID_ISymUnmanagedWriter3, (void**)&pWriter3); - CONSISTENCY_CHECK(SUCCEEDED(thr)); - if (SUCCEEDED(thr)) - { - thr = pWriter3->Commit(); - if (SUCCEEDED(thr)) - { - // Flush any cached symbol reader to ensure we pick up any new symbols - ReleaseISymUnmanagedReader(); - } - } - - // If either the QI or Commit failed - if (FAILED(thr)) - { - // The only way we expect this might fail is out-of-memory. In that - // case we silently fail to update the symbol stream with new data, but - // we leave the existing reader intact. - CONSISTENCY_CHECK(thr==E_OUTOFMEMORY); - } - } - } } //--------------------------------------------------------------------------- @@ -12494,11 +12423,9 @@ ReflectionModule::ReflectionModule(Assembly *pAssembly, mdFile token, PEFile *pF m_pInMemoryWriter = NULL; m_sdataSection = NULL; - m_pISymUnmanagedWriter = NULL; m_pCreatingAssembly = NULL; m_pCeeFileGen = NULL; m_pDynamicMetadata = NULL; - m_fSuppressMetadataCapture = false; } HRESULT STDMETHODCALLTYPE CreateICeeGen(REFIID riid, void **pCeeGen); @@ -12551,13 +12478,6 @@ void ReflectionModule::Destruct() delete m_pInMemoryWriter; - if (m_pISymUnmanagedWriter) - { - m_pISymUnmanagedWriter->Close(); - m_pISymUnmanagedWriter->Release(); - m_pISymUnmanagedWriter = NULL; - } - if (m_pCeeFileGen) m_pCeeFileGen->Release(); @@ -12569,17 +12489,6 @@ void ReflectionModule::Destruct() m_CrstLeafLock.Destroy(); } -// Returns true iff metadata capturing is suppressed. -// -// Notes: -// This is during the window after code:ReflectionModule.SuppressMetadataCapture and before -// code:ReflectionModule.ResumeMetadataCapture. -// -// If metadata updates are suppressed, then class-load notifications should be suppressed too. -bool ReflectionModule::IsMetadataCaptureSuppressed() -{ - return m_fSuppressMetadataCapture; -} // // Holder of changed value of MDUpdateMode via IMDInternalEmit::SetMDUpdateMode. // Returns back the original value on release. @@ -12679,13 +12588,11 @@ void ReflectionModule::CaptureModuleMetaDataToMemory() } CONTRACTL_END; - // If we've suppresed metadata capture, then skip this. We'll recapture when we enable it. This allows - // for batching up capture. // If a debugger is attached, then the CLR will still send ClassLoad notifications for dynamic modules, // which mean we still need to keep the metadata available. This is the same as Whidbey. // An alternative (and better) design would be to suppress ClassLoad notifications too, but then we'd // need some way of sending a "catchup" notification to the debugger after we re-enable notifications. - if (IsMetadataCaptureSuppressed() && !CORDebuggerAttached()) + if (!CORDebuggerAttached()) { return; } @@ -12735,41 +12642,6 @@ void ReflectionModule::CaptureModuleMetaDataToMemory() _ASSERTE(hr == S_OK); } -// Suppress the eager metadata serialization. -// -// Notes: -// This casues code:ReflectionModule.CaptureModuleMetaDataToMemory to be a nop. -// This is not nestable. -// This exists purely for performance reasons. -// -// Don't call this directly. Use a SuppressMetadataCaptureHolder holder to ensure it's -// balanced with code:ReflectionModule.ResumeMetadataCapture -// -// Types generating while eager metadata-capture is suppressed should not actually be executed until -// after metadata capture is restored. -void ReflectionModule::SuppressMetadataCapture() -{ - LIMITED_METHOD_CONTRACT; - // If this fires, then you probably missed a call to ResumeMetadataCapture. - CONSISTENCY_CHECK_MSG(!m_fSuppressMetadataCapture, "SuppressMetadataCapture is not nestable"); - m_fSuppressMetadataCapture = true; -} - -// Resumes eager metadata serialization. -// -// Notes: -// This casues code:ReflectionModule.CaptureModuleMetaDataToMemory to resume eagerly serializing metadata. -// This must be called after code:ReflectionModule.SuppressMetadataCapture. -// -void ReflectionModule::ResumeMetadataCapture() -{ - WRAPPER_NO_CONTRACT; - _ASSERTE(m_fSuppressMetadataCapture); - m_fSuppressMetadataCapture = false; - - CaptureModuleMetaDataToMemory(); -} - #endif // !CROSSGEN_COMPILE #endif // !DACCESS_COMPILE diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index 963ee161605540..fc8d76ed3a6b12 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -1093,15 +1093,6 @@ typedef SHash DynamicILBlobTable; typedef DPTR(DynamicILBlobTable) PTR_DynamicILBlobTable; -// ESymbolFormat specified the format used by a symbol stream -typedef enum -{ - eSymbolFormatNone, /* symbol format to use not yet determined */ - eSymbolFormatPDB, /* PDB format from diasymreader.dll - only safe for trusted scenarios */ - eSymbolFormatILDB /* ILDB format from ildbsymbols.dll */ -}ESymbolFormat; - - #ifdef FEATURE_COMINTEROP //--------------------------------------------------------------------------------------- @@ -1434,9 +1425,6 @@ class Module // Debugger may retrieve this from out-of-process. PTR_CGrowableStream m_pIStreamSym; - // Format the above stream is in (if any) - ESymbolFormat m_symbolFormat; - // For protecting additions to the heap CrstExplicitInit m_LookupTableCrst; @@ -1940,54 +1928,29 @@ class Module // Get the in-memory symbol stream for this module, if any. // If none, this will return null. This is used by modules loaded in-memory (eg. from a byte-array) - // and by dynamic modules. Callers that actually do anything with the return value will almost - // certainly want to check GetInMemorySymbolStreamFormat to know how to interpret the bytes - // in the stream. + // and by dynamic modules. PTR_CGrowableStream GetInMemorySymbolStream() { LIMITED_METHOD_CONTRACT; SUPPORTS_DAC; - // Symbol format should be "none" if-and-only-if our stream is null - // If this fails, it may mean somebody is trying to examine this module after - // code:Module::Destruct has been called. - _ASSERTE( (m_symbolFormat == eSymbolFormatNone) == (m_pIStreamSym == NULL) ); - return m_pIStreamSym; } - // Get the format of the in-memory symbol stream for this module, or - // eSymbolFormatNone if no in-memory symbols. - ESymbolFormat GetInMemorySymbolStreamFormat() - { - LIMITED_METHOD_CONTRACT; - SUPPORTS_DAC; - - // Symbol format should be "none" if-and-only-if our stream is null - // If this fails, it may mean somebody is trying to examine this module after - // code:Module::Destruct has been called. - _ASSERTE( (m_symbolFormat == eSymbolFormatNone) == (m_pIStreamSym == NULL) ); - - return m_symbolFormat; - } - #ifndef DACCESS_COMPILE // Set the in-memory stream for debug symbols // This must only be called when there is no existing stream. // This takes an AddRef on the supplied stream. - void SetInMemorySymbolStream(CGrowableStream *pStream, ESymbolFormat symbolFormat) + void SetInMemorySymbolStream(CGrowableStream *pStream) { LIMITED_METHOD_CONTRACT; // Must have provided valid stream data CONSISTENCY_CHECK(pStream != NULL); - CONSISTENCY_CHECK(symbolFormat != eSymbolFormatNone); // we expect set to only be called once CONSISTENCY_CHECK(m_pIStreamSym == NULL); - CONSISTENCY_CHECK(m_symbolFormat == eSymbolFormatNone); - m_symbolFormat = symbolFormat; m_pIStreamSym = pStream; m_pIStreamSym->AddRef(); } @@ -2000,10 +1963,6 @@ class Module { m_pIStreamSym->Release(); m_pIStreamSym = NULL; - // We could set m_symbolFormat to eSymbolFormatNone to be consistent with not having - // a stream, but no-one should be trying to look at it after destruct time, so it's - // better to leave it inconsistent and get an ASSERT if someone tries to examine the - // module's sybmol stream after the module was destructed. } } @@ -3194,7 +3153,6 @@ class ReflectionModule : public Module ICeeGenInternal * m_pCeeFileGen; private: Assembly *m_pCreatingAssembly; - ISymUnmanagedWriter *m_pISymUnmanagedWriter; RefClassWriter *m_pInMemoryWriter; @@ -3211,25 +3169,6 @@ class ReflectionModule : public Module bool m_fSuppressMetadataCapture; #if !defined DACCESS_COMPILE && !defined CROSSGEN_COMPILE - // Returns true iff metadata capturing is suppressed - bool IsMetadataCaptureSuppressed(); - - // Toggle whether CaptureModuleMetaDataToMemory should do antyhing. This can be an important perf win to - // allow batching up metadata capture. Use SuppressMetadataCaptureHolder to ensure they're balanced. - // These are not nestable. - void SuppressMetadataCapture(); - void ResumeMetadataCapture(); - - // Glue functions for holders. - static void SuppressCaptureWrapper(ReflectionModule * pModule) - { - pModule->SuppressMetadataCapture(); - } - static void ResumeCaptureWrapper(ReflectionModule * pModule) - { - pModule->ResumeMetadataCapture(); - } - ReflectionModule(Assembly *pAssembly, mdFile token, PEFile *pFile); #endif // !DACCESS_COMPILE && !CROSSGEN_COMPILE @@ -3273,64 +3212,6 @@ class ReflectionModule : public Module return m_pInMemoryWriter; } - ISymUnmanagedWriter *GetISymUnmanagedWriter() - { - LIMITED_METHOD_CONTRACT; - return m_pISymUnmanagedWriter; - } - - // Note: we now use the same writer instance for the life of a module, - // so there should no longer be any need for the extra indirection. - ISymUnmanagedWriter **GetISymUnmanagedWriterAddr() - { - LIMITED_METHOD_CONTRACT; - - // We must have setup the writer before trying to get - // the address for it. Any calls to this before a - // SetISymUnmanagedWriter are very incorrect. - _ASSERTE(m_pISymUnmanagedWriter != NULL); - - return &m_pISymUnmanagedWriter; - } - -#ifndef DACCESS_COMPILE -#ifndef CROSSGEN_COMPILE - - typedef Wrapper< - ReflectionModule*, - ReflectionModule::SuppressCaptureWrapper, - ReflectionModule::ResumeCaptureWrapper> SuppressMetadataCaptureHolder; -#endif // !CROSSGEN_COMPILE - - HRESULT SetISymUnmanagedWriter(ISymUnmanagedWriter *pWriter) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - INJECT_FAULT(return E_OUTOFMEMORY;); - } - CONTRACTL_END - - - // Setting to NULL when we've never set a writer before should - // do nothing. - if ((pWriter == NULL) && (m_pISymUnmanagedWriter == NULL)) - return S_OK; - - if (m_pISymUnmanagedWriter != NULL) - { - // We shouldn't be trying to replace an existing writer anymore - _ASSERTE( pWriter == NULL ); - - m_pISymUnmanagedWriter->Release(); - } - - m_pISymUnmanagedWriter = pWriter; - return S_OK; - } -#endif // !DACCESS_COMPILE - // Eagerly serialize the metadata to a buffer that the debugger can retrieve. void CaptureModuleMetaDataToMemory(); }; diff --git a/src/coreclr/vm/commodule.cpp b/src/coreclr/vm/commodule.cpp index f38b8797e3a0a0..31bdeb649ef0bc 100644 --- a/src/coreclr/vm/commodule.cpp +++ b/src/coreclr/vm/commodule.cpp @@ -11,7 +11,6 @@ #include #include "typeparse.h" #include "typekey.h" -#include "ildbsymlib.h" //**************************************************