summaryrefslogtreecommitdiff
path: root/src/debug/ildbsymlib/symwrite.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/ildbsymlib/symwrite.h')
-rw-r--r--src/debug/ildbsymlib/symwrite.h1226
1 files changed, 1226 insertions, 0 deletions
diff --git a/src/debug/ildbsymlib/symwrite.h b/src/debug/ildbsymlib/symwrite.h
new file mode 100644
index 0000000000..055b8ec21f
--- /dev/null
+++ b/src/debug/ildbsymlib/symwrite.h
@@ -0,0 +1,1226 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+// ===========================================================================
+// File: SymWrite.h
+//
+
+// ===========================================================================
+
+#ifndef SYMWRITE_H_
+#define SYMWRITE_H_
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cor.h"
+#include "umisc.h"
+#include "stgpool.h"
+#include "safemath.h"
+
+#include <corsym.h>
+#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 T>
+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
+ return *(static_cast<T*>(0)) ;
+ }
+ 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<SymMethodInfo> m_methods; // Methods information
+ ArrayStorage<SymLexicalScope> m_scopes; // Scope information for the method
+ ArrayStorage<SymVariable> m_vars; // Variables
+ ArrayStorage<SymUsingNamespace> m_usings; // using/imports
+ ArrayStorage<SymConstant> m_constants; // Constants
+ ArrayStorage<DocumentInfo> m_documents; // Document Source Format
+ ArrayStorage<SequencePoint> m_auxSequencePoints; // Sequence Points
+ // Array of various bytes (variable signature, etc)
+ ArrayStorage<BYTE> 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<SymMap> 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_ */