From: David Wrighton Date: Wed, 12 Jun 2019 16:57:51 +0000 (-0700) Subject: Replace IMDInternalImport with IMetaDataImport (#329) X-Git-Tag: submit/tizen/20190813.035844~4^2^2~35 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=44cdf7dbb7a5cea36e33b342391a6b0ac6d847cb;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git Replace IMDInternalImport with IMetaDataImport (#329) * Convert all use of IMDInternal to IMetaDataImport * Improve pretty printing of method tokens - Print signature as well as just name - Add minimal DumpIL testing to test suite --- diff --git a/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script b/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script index e811167ec..c3559bbaf 100644 --- a/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script +++ b/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script @@ -150,10 +150,16 @@ SOSCOMMAND:IP2MD .*\s+()\s+SymbolTestApp\.Program\.Foo4.*\s+ VERIFY:.*\s+Method Name:\s+SymbolTestApp\.Program\.Foo4\(System\.String\)\s+ VERIFY:.*\s+Source file:\s+(?i:.*[\\|/]SymbolTestApp\.cs) @ 54\s+ +# Verify that DumpIL works (depends on the IP2MD right above) +SOSCOMMAND:DumpIL \s*MethodDesc:\s+()\s* +VERIFY:.*IL_: call class \[System.Runtime\]System\.Reflection\.Assembly System\.Reflection\.Assembly::Load\(uint8\[\],uint8\[\]\) + !IFDEF:DOTNETDUMP IFDEF:PROJECTK -# Verify that "u" works (depends on the IP2MD right above) +# Verify that "u" works (depends on the IP2MD here) +SOSCOMMAND:ClrStack +SOSCOMMAND:IP2MD .*\s+()\s+SymbolTestApp\.Program\.Foo4.*\s+ SOSCOMMAND:u \s*MethodDesc:\s+()\s* VERIFY:\s*Normal JIT generated code\s+ VERIFY:\s+SymbolTestApp\.Program\.Foo4\(System\.String\)\s+ diff --git a/src/SOS/Strike/CMakeLists.txt b/src/SOS/Strike/CMakeLists.txt index 2e031cf9d..ae4ff471f 100644 --- a/src/SOS/Strike/CMakeLists.txt +++ b/src/SOS/Strike/CMakeLists.txt @@ -69,6 +69,7 @@ if(WIN32) gcroot.cpp hostcoreclr.cpp metadata.cpp + sigparser.cpp sildasm.cpp sos.cpp stressLogDump.cpp @@ -124,6 +125,7 @@ else(WIN32) gcroot.cpp hostcoreclr.cpp metadata.cpp + sigparser.cpp sildasm.cpp stressLogDump.cpp strike.cpp diff --git a/src/SOS/Strike/metadata.cpp b/src/SOS/Strike/metadata.cpp index 77bccd52e..292ed4a8a 100644 --- a/src/SOS/Strike/metadata.cpp +++ b/src/SOS/Strike/metadata.cpp @@ -166,90 +166,6 @@ HRESULT NameForToken_s(mdTypeDef mb, IMetaDataImport *pImport, __out_ecount (cap return hr; } -/**********************************************************************\ -* Routine Description: * -* * -* Find the name for a metadata token given an importer. * -* * -\**********************************************************************/ -/* -HRESULT NameForTokenNew(mdTypeDef mb, IMDInternalImport *pImport, WCHAR *mdName, size_t capacity_mdName, - bool bClassName) -{ - - // TODO: Change calls to use the secure versions (string as well as to functions defined here) - // Simply uncommenting this function will not result in a clean compile - // --chirayuk @ 11/23/2004 - - mdName[0] = L'\0'; - if ((mb & 0xff000000) != mdtTypeDef - && (mb & 0xff000000) != mdtFieldDef - && (mb & 0xff000000) != mdtMethodDef) - { - //ExtOut("unsupported\n"); - return E_FAIL; - } - - HRESULT hr; - - __try - { - static WCHAR name[MAX_CLASSNAME_LENGTH]; - if (TypeFromToken(mb) == mdtTypeDef) - { - hr = NameForTypeDefNew (mb, pImport, mdName); - } - else if (TypeFromToken(mb) == mdtFieldDef) - { - mdTypeDef mdClass; - ULONG size; - MultiByteToWideChar (CP_ACP,0,pImport->GetNameOfFieldDef(mb),-1,name,MAX_CLASSNAME_LENGTH); - - hr = pImport->GetParentToken (mb, &mdClass); - if (SUCCEEDED (hr)) - { - if (mdClass != mdTypeDefNil && bClassName) - { - hr = NameForTypeDefNew (mdClass, pImport, mdName); - _wcscat (mdName, W(".")); - } - name[size] = L'\0'; - _wcscat (mdName, name); - } - } - else if (TypeFromToken(mb) == mdtMethodDef) - { - mdTypeDef mdClass; - ULONG size; - - MultiByteToWideChar (CP_ACP,0,pImport->GetNameOfMethodDef(mb),-1,name,MAX_CLASSNAME_LENGTH); - hr = pImport->GetParentToken (mb, &mdClass); - if (SUCCEEDED (hr)) - { - if (mdClass != mdTypeDefNil && bClassName) - { - hr = NameForTypeDefNew (mdClass, pImport, mdName); - _wcscat (mdName, W(".")); - } - name[size] = L'\0'; - _wcscat (mdName, name); - } - } - else - { - ExtOut ("Unsupported token type\n"); - hr = E_FAIL; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - //ExtOut("Metadata operation failure\n"); - hr = E_FAIL; - } - return hr; -} -*/ - /**********************************************************************\ * Routine Description: * * * diff --git a/src/SOS/Strike/sigparser.cpp b/src/SOS/Strike/sigparser.cpp new file mode 100644 index 000000000..029d164b4 --- /dev/null +++ b/src/SOS/Strike/sigparser.cpp @@ -0,0 +1,166 @@ +// 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. + +#ifndef FEATURE_PAL +#include +#endif +#include "strike.h" +#include "util.h" + +#ifndef IfFailRet +#define IfFailRet(EXPR) do { HRESULT Status = (EXPR); if(FAILED(Status)) { return (Status); } } while (0) +#endif + +HRESULT SigParser::SkipExactlyOne() +{ + CorElementType typ; + HRESULT hr = GetElemType(&typ); + + IfFailRet(hr); + + if (!CorIsPrimitiveType(typ)) + { + switch ((DWORD)typ) + { + default: + // _ASSERT(!"Illegal or unimplement type in COM+ sig."); + return META_E_BAD_SIGNATURE; + break; + case ELEMENT_TYPE_VAR: + case ELEMENT_TYPE_MVAR: + IfFailRet(GetData(NULL)); // Skip variable number + break; +/* case ELEMENT_TYPE_VAR_ZAPSIG: + IfFailRet(GetData(NULL)); // Skip RID + break;*/ + case ELEMENT_TYPE_OBJECT: + case ELEMENT_TYPE_STRING: + case ELEMENT_TYPE_TYPEDBYREF: +/* case ELEMENT_TYPE_CANON_ZAPSIG:*/ + break; + + case ELEMENT_TYPE_BYREF: //fallthru + case ELEMENT_TYPE_PTR: + case ELEMENT_TYPE_PINNED: + case ELEMENT_TYPE_SZARRAY: +/* case ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG: + case ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG:*/ + IfFailRet(SkipExactlyOne()); // Skip referenced type + break; + + case ELEMENT_TYPE_VALUETYPE: //fallthru + case ELEMENT_TYPE_CLASS: + IfFailRet(GetToken(NULL)); // Skip RID + break; + +/* case ELEMENT_TYPE_MODULE_ZAPSIG: + IfFailRet(GetData(NULL)); // Skip index + IfFailRet(SkipExactlyOne()); // Skip type + break;*/ + + case ELEMENT_TYPE_FNPTR: + IfFailRet(SkipSignature()); + break; + + case ELEMENT_TYPE_ARRAY: + { + IfFailRet(SkipExactlyOne()); // Skip element type + ULONG rank; + IfFailRet(GetData(&rank)); // Get rank + if (rank) + { + ULONG nsizes; + IfFailRet(GetData(&nsizes)); // Get # of sizes + while (nsizes--) + { + IfFailRet(GetData(NULL)); // Skip size + } + + ULONG nlbounds; + IfFailRet(GetData(&nlbounds)); // Get # of lower bounds + while (nlbounds--) + { + IfFailRet(GetData(NULL)); // Skip lower bounds + } + } + + } + break; + + case ELEMENT_TYPE_SENTINEL: + // Should be unreachable since GetElem strips it + break; + + case ELEMENT_TYPE_INTERNAL: + IfFailRet(GetPointer(NULL)); + break; + + case ELEMENT_TYPE_GENERICINST: + IfFailRet(SkipExactlyOne()); // Skip generic type + ULONG argCnt; + IfFailRet(GetData(&argCnt)); // Get number of parameters + while (argCnt--) + { + IfFailRet(SkipExactlyOne()); // Skip the parameters + } + break; + + } + } + + return hr; +} + +//--------------------------------------------------------------------------------------- +// +// Skip only a method header signature - not the sigs of the args to the method. +// +HRESULT +SigParser::SkipMethodHeaderSignature( + ULONG * pcArgs) +{ + HRESULT hr = S_OK; + + // Skip calling convention + ULONG uCallConv; + IfFailRet(GetCallingConvInfo(&uCallConv)); + + if ((uCallConv == IMAGE_CEE_CS_CALLCONV_FIELD) || + (uCallConv == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG)) + { + return META_E_BAD_SIGNATURE; + } + + // Skip type parameter count + if (uCallConv & IMAGE_CEE_CS_CALLCONV_GENERIC) + IfFailRet(GetData(NULL)); + + // Get arg count; + IfFailRet(GetData(pcArgs)); + + // Skip return type; + IfFailRet(SkipExactlyOne()); + + return hr; +} // SigParser::SkipMethodHeaderSignature + +//--------------------------------------------------------------------------------------- +// +// Skip a sub signature (as immediately follows an ELEMENT_TYPE_FNPTR). +HRESULT SigParser::SkipSignature() +{ + HRESULT hr = S_OK; + + ULONG cArgs; + + IfFailRet(SkipMethodHeaderSignature(&cArgs)); + + // Skip args. + while (cArgs) { + IfFailRet(SkipExactlyOne()); + cArgs--; + } + + return hr; +} diff --git a/src/SOS/Strike/sigparser.h b/src/SOS/Strike/sigparser.h new file mode 100644 index 000000000..94dcd58bf --- /dev/null +++ b/src/SOS/Strike/sigparser.h @@ -0,0 +1,693 @@ +// 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. +// +// sigparser.h +// + +// + +#ifndef _H_SIGPARSER +#define _H_SIGPARSER + +//------------------------------------------------------------------------ +// Encapsulates how compressed integers and typeref tokens are encoded into +// a bytestream. +// +// As you use this class please understand the implicit normalizations +// on the CorElementType's returned by the various methods, especially +// for variable types (e.g. !0 in generic signatures), string types +// (i.e. E_T_STRING), object types (E_T_OBJECT), constructed types +// (e.g. List) and enums. +//------------------------------------------------------------------------ +class SigParser +{ + protected: + // This type is performance critical - do not add fields to it. + // (If you must, check for managed types that may use a SigParser or SigPointer inline, like ArgIterator.) + PCCOR_SIGNATURE m_ptr; + DWORD m_dwLen; + + //------------------------------------------------------------------------ + // Skips specified number of bytes WITHOUT VALIDATION. Only to be used + // when it is known that it won't overflow the signature buffer. + //------------------------------------------------------------------------ + FORCEINLINE void SkipBytes(ULONG cb) + { + _ASSERTE(cb <= m_dwLen); + m_ptr += cb; + m_dwLen -= cb; + } + + public: + //------------------------------------------------------------------------ + // Constructor. + //------------------------------------------------------------------------ + SigParser() { + m_ptr = NULL; + m_dwLen = 0; + } + + SigParser(const SigParser &sig); + + //------------------------------------------------------------------------ + // Initialize + //------------------------------------------------------------------------ + FORCEINLINE SigParser(PCCOR_SIGNATURE ptr) + { + m_ptr = ptr; + // We don't know the size of the signature, so we'll say it's "big enough" + m_dwLen = 0xffffffff; + } + + FORCEINLINE SigParser(PCCOR_SIGNATURE ptr, DWORD len) + { + m_ptr = ptr; + m_dwLen = len; + } + + inline void SetSig(PCCOR_SIGNATURE ptr) + { + m_ptr = ptr; + // We don't know the size of the signature, so we'll say it's "big enough" + m_dwLen = 0xffffffff; + } + + inline void SetSig(PCCOR_SIGNATURE ptr, DWORD len) + { + m_ptr = ptr; + m_dwLen = len; + } + + + inline BOOL IsNull() const + { + return (m_ptr == NULL); + } + + // Returns represented signature as pointer and size. + void + GetSignature( + PCCOR_SIGNATURE * pSig, + DWORD * pcbSigSize) + { + *pSig = m_ptr; + *pcbSigSize = m_dwLen; + } + + + //========================================================================= + // The RAW interface for reading signatures. You see exactly the signature, + // apart from custom modifiers which for historical reasons tend to get eaten. + // + // DO NOT USE THESE METHODS UNLESS YOU'RE TOTALLY SURE YOU WANT + // THE RAW signature. You nearly always want GetElemTypeClosed() or + // PeekElemTypeClosed() or one of the MetaSig functions. See the notes above. + // These functions will return E_T_INTERNAL, E_T_VAR, E_T_MVAR and such + // so the caller must be able to deal with those + //========================================================================= + + //------------------------------------------------------------------------ + // Remove one compressed integer (using CorSigUncompressData) from + // the head of the stream and return it. + //------------------------------------------------------------------------ + __checkReturn + FORCEINLINE HRESULT GetData(ULONG* data) + { + ULONG sizeOfData = 0; + ULONG tempData; + + if (data == NULL) + data = &tempData; + + HRESULT hr = CorSigUncompressData(m_ptr, m_dwLen, data, &sizeOfData); + + if (SUCCEEDED(hr)) + { + SkipBytes(sizeOfData); + } + + return hr; + } + + + //------------------------------------------------------------------------- + // Remove one byte and return it. + //------------------------------------------------------------------------- + __checkReturn + FORCEINLINE HRESULT GetByte(BYTE *data) + { + if (m_dwLen > 0) + { + if (data != NULL) + *data = *m_ptr; + + SkipBytes(1); + + return S_OK; + } + + if (data != NULL) + *data = 0; + return META_E_BAD_SIGNATURE; + } + + //------------------------------------------------------------------------- + // Peek at value of one byte and return it. + //------------------------------------------------------------------------- + __checkReturn + FORCEINLINE HRESULT PeekByte(BYTE *data) + { + if (m_dwLen > 0) + { + if (data != NULL) + *data = *m_ptr; + + return S_OK; + } + + if (data != NULL) + *data = 0; + return META_E_BAD_SIGNATURE; + } + + //------------------------------------------------------------------------- + // The element type as defined in CorElementType. No normalization for + // generics (E_T_VAR, E_T_MVAR,..) or dynamic methods (E_T_INTERNAL occurs) + //------------------------------------------------------------------------- + __checkReturn + HRESULT GetElemTypeSlow(CorElementType * etype) + { + CorElementType tmpEType; + + if (etype == NULL) + etype = &tmpEType; + + SigParser sigTemp(*this); + + HRESULT hr = sigTemp.SkipCustomModifiers(); + + if (SUCCEEDED(hr)) + { + BYTE bElemType = 0; + hr = sigTemp.GetByte(&bElemType); + *etype = (CorElementType)bElemType; + + if (SUCCEEDED(hr)) + { + *this = sigTemp; + return S_OK; + } + } + + *etype = ELEMENT_TYPE_END; + + return META_E_BAD_SIGNATURE; + } + + // Inlined version + __checkReturn + FORCEINLINE HRESULT GetElemType(CorElementType * etype) + { + if (m_dwLen > 0) + { + CorElementType typ = (CorElementType) * m_ptr; + + if (typ < ELEMENT_TYPE_CMOD_REQD) // fast path with no modifiers: single byte + { + if (etype != NULL) + { + * etype = typ; + } + + SkipBytes(1); + + return S_OK; + } + } + + // Slower/normal path + return GetElemTypeSlow(etype); + } + + // Note: Calling convention is always one byte, not four bytes + __checkReturn + HRESULT GetCallingConvInfo(ULONG * data) + { + ULONG tmpData; + + if (data == NULL) + data = &tmpData; + + HRESULT hr = CorSigUncompressCallingConv(m_ptr, m_dwLen, data); + if (SUCCEEDED(hr)) + { + SkipBytes(1); + } + + return hr; + } + + __checkReturn + HRESULT GetCallingConv(ULONG* data) // @REVISIT_TODO: Calling convention is one byte, not four. + { + ULONG info; + HRESULT hr = GetCallingConvInfo(&info); + + if (SUCCEEDED(hr) && data != NULL) + { + *data = IMAGE_CEE_CS_CALLCONV_MASK & info; + } + + return hr; + } + + //------------------------------------------------------------------------ + // Non-destructive read of compressed integer. + //------------------------------------------------------------------------ + __checkReturn + HRESULT PeekData(ULONG *data) const + { + _ASSERTE(data != NULL); + + ULONG sizeOfData = 0; + return CorSigUncompressData(m_ptr, m_dwLen, data, &sizeOfData); + } + + + //------------------------------------------------------------------------ + // Non-destructive read of element type. + // + // This routine makes it look as if the String type is encoded + // via ELEMENT_TYPE_CLASS followed by a token for the String class, + // rather than the ELEMENT_TYPE_STRING. This is partially to avoid + // rewriting client code which depended on this behavior previously. + // But it also seems like the right thing to do generally. + // No normalization for generics (E_T_VAR, E_T_MVAR,..) or + // dynamic methods (E_T_INTERNAL occurs) + //------------------------------------------------------------------------ + __checkReturn + HRESULT PeekElemTypeSlow(CorElementType *etype) const + { + _ASSERTE(etype != NULL); + + SigParser sigTemp(*this); + HRESULT hr = sigTemp.GetElemType(etype); + if (SUCCEEDED(hr) && (*etype == ELEMENT_TYPE_STRING || *etype == ELEMENT_TYPE_OBJECT)) + *etype = ELEMENT_TYPE_CLASS; + + return hr; + } + + // inline version + __checkReturn + FORCEINLINE HRESULT PeekElemType(CorElementType *etype) const + { + _ASSERTE(etype != NULL); + + if (m_dwLen > 0) + { + CorElementType typ = (CorElementType) * m_ptr; + + if (typ < ELEMENT_TYPE_CMOD_REQD) // fast path with no modifiers: single byte + { + if ((typ == ELEMENT_TYPE_STRING) || (typ == ELEMENT_TYPE_OBJECT)) + { + *etype = ELEMENT_TYPE_CLASS; + } + else + { + *etype = typ; + } + + return S_OK; + } + } + + return PeekElemTypeSlow(etype); + } + + //------------------------------------------------------------------------- + // Returns the raw size of the type next in the signature, or returns + // E_INVALIDARG for base types that have variables sizes. + //------------------------------------------------------------------------- + __checkReturn + HRESULT PeekElemTypeSize(ULONG *pSize) + { + HRESULT hr = S_OK; + + DWORD dwSize = 0; + + if (pSize == NULL) + { + pSize = &dwSize; + } + + SigParser sigTemp(*this); + + hr = sigTemp.SkipAnyVASentinel(); + + if (FAILED(hr)) + { + return hr; + } + + *pSize = 0; + + BYTE bElementType = 0; + hr = sigTemp.GetByte(&bElementType); + + if (FAILED(hr)) + { + return hr; + } + + switch (bElementType) + { + case ELEMENT_TYPE_I8: + case ELEMENT_TYPE_U8: + case ELEMENT_TYPE_R8: + #ifdef _WIN64 + case ELEMENT_TYPE_I: + case ELEMENT_TYPE_U: + #endif // WIN64 + + *pSize = 8; + break; + + case ELEMENT_TYPE_I4: + case ELEMENT_TYPE_U4: + case ELEMENT_TYPE_R4: + #ifndef _WIN64 + case ELEMENT_TYPE_I: + case ELEMENT_TYPE_U: + #endif // _WIN64 + + *pSize = 4; + break; + + case ELEMENT_TYPE_I2: + case ELEMENT_TYPE_U2: + case ELEMENT_TYPE_CHAR: + *pSize = 2; + break; + + case ELEMENT_TYPE_I1: + case ELEMENT_TYPE_U1: + case ELEMENT_TYPE_BOOLEAN: + *pSize = 1; + break; + + case ELEMENT_TYPE_STRING: + case ELEMENT_TYPE_PTR: + case ELEMENT_TYPE_BYREF: + case ELEMENT_TYPE_CLASS: + case ELEMENT_TYPE_OBJECT: + case ELEMENT_TYPE_FNPTR: + case ELEMENT_TYPE_TYPEDBYREF: + case ELEMENT_TYPE_ARRAY: + case ELEMENT_TYPE_SZARRAY: + *pSize = sizeof(void *); + break; + + case ELEMENT_TYPE_VOID: + break; + + case ELEMENT_TYPE_END: + case ELEMENT_TYPE_CMOD_REQD: + case ELEMENT_TYPE_CMOD_OPT: + _ASSERTE(!"Asked for the size of an element that doesn't have a size!"); + return E_INVALIDARG; + + case ELEMENT_TYPE_VALUETYPE: + _ASSERTE(!"Asked for the size of an element that doesn't have a size!"); + return E_INVALIDARG; + + default: + + _ASSERTE( !"CorSigGetElementTypeSize given invalid signature to size!" ); + return META_E_BAD_SIGNATURE; + } + + return hr; + } + + //------------------------------------------------------------------------ + // Is this at the Sentinal (the ... in a varargs signature) that marks + // the begining of varguments that are not decared at the target + + bool AtSentinel() const + { + if (m_dwLen > 0) + return *m_ptr == ELEMENT_TYPE_SENTINEL; + else + return false; + } + + //------------------------------------------------------------------------ + // Removes a compressed metadata token and returns it. + // WARNING: dynamic methods do not have tokens so this api is completely + // broken in that case. Make sure you call this function if + // you are absolutely sure E_T_INTERNAL was not in the sig + //------------------------------------------------------------------------ + __checkReturn + FORCEINLINE + HRESULT GetToken(mdToken * token) + { + DWORD dwLen; + mdToken tempToken; + + if (token == NULL) + token = &tempToken; + + HRESULT hr = CorSigUncompressToken(m_ptr, m_dwLen, token, &dwLen); + + if (SUCCEEDED(hr)) + { + SkipBytes(dwLen); + } + + return hr; + } + + //------------------------------------------------------------------------ + // Removes a pointer value and returns it. Used for ELEMENT_TYPE_INTERNAL. + __checkReturn + FORCEINLINE + HRESULT GetPointer(void ** pPtr) + { + if (m_dwLen < sizeof(void *)) + { // Not enough data to read a pointer + if (pPtr != NULL) + { + *pPtr = NULL; + } + return META_E_BAD_SIGNATURE; + } + if (pPtr != NULL) + { + *pPtr = *(void * UNALIGNED *)m_ptr; + } + SkipBytes(sizeof(void *)); + + return S_OK; + } + + //------------------------------------------------------------------------ + // Tests if two SigParsers point to the same location in the stream. + //------------------------------------------------------------------------ + FORCEINLINE BOOL Equals(SigParser sp) const + { + return m_ptr == sp.m_ptr; + } + + __checkReturn + HRESULT SkipCustomModifiers() + { + HRESULT hr = S_OK; + + SigParser sigTemp(*this); + + hr = sigTemp.SkipAnyVASentinel(); + + if (FAILED(hr)) + { + return hr; + } + + BYTE bElementType = 0; + + hr = sigTemp.PeekByte(&bElementType); + if (FAILED(hr)) + return hr; + + while ((ELEMENT_TYPE_CMOD_REQD == bElementType) || + (ELEMENT_TYPE_CMOD_OPT == bElementType)) + { + sigTemp.SkipBytes(1); + + mdToken token; + + hr = sigTemp.GetToken(&token); + + if (FAILED(hr)) + return hr; + + hr = sigTemp.PeekByte(&bElementType); + if (FAILED(hr)) + return hr; + } + + // Following custom modifiers must be an element type value which is less than ELEMENT_TYPE_MAX, or one of the other element types + // that we support while parsing various signatures + if (bElementType >= ELEMENT_TYPE_MAX) + { + switch (bElementType) + { +/* case ELEMENT_TYPE_VAR_ZAPSIG: + case ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG: + case ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG: + case ELEMENT_TYPE_CANON_ZAPSIG: + case ELEMENT_TYPE_MODULE_ZAPSIG:*/ + case ELEMENT_TYPE_PINNED: + break; + default: + return META_E_BAD_SIGNATURE; + } + } + + *this = sigTemp; + return hr; + }// SkipCustomModifiers + + __checkReturn + HRESULT SkipFunkyAndCustomModifiers() + { + SigParser sigTemp(*this); + HRESULT hr = S_OK; + hr = sigTemp.SkipAnyVASentinel(); + + if (FAILED(hr)) + { + return hr; + } + + BYTE bElementType = 0; + + hr = sigTemp.PeekByte(&bElementType); + if (FAILED(hr)) + return hr; + + while (ELEMENT_TYPE_CMOD_REQD == bElementType || + ELEMENT_TYPE_CMOD_OPT == bElementType || + ELEMENT_TYPE_MODIFIER == bElementType || + ELEMENT_TYPE_PINNED == bElementType) + { + sigTemp.SkipBytes(1); + + mdToken token; + + hr = sigTemp.GetToken(&token); + + if (FAILED(hr)) + return hr; + + hr = sigTemp.PeekByte(&bElementType); + if (FAILED(hr)) + return hr; + } + + // Following custom modifiers must be an element type value which is less than ELEMENT_TYPE_MAX, or one of the other element types + // that we support while parsing various signatures + if (bElementType >= ELEMENT_TYPE_MAX) + { + switch (bElementType) + { +/* case ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG: + case ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG: + case ELEMENT_TYPE_CANON_ZAPSIG: + case ELEMENT_TYPE_MODULE_ZAPSIG:*/ + case ELEMENT_TYPE_PINNED: + break; + default: + return META_E_BAD_SIGNATURE; + } + } + + *this = sigTemp; + return hr; + }// SkipFunkyAndCustomModifiers + + + __checkReturn + HRESULT SkipAnyVASentinel() + { + HRESULT hr = S_OK; + BYTE bElementType = 0; + + hr = PeekByte(&bElementType); + if (FAILED(hr)) + return hr; + + if (bElementType == ELEMENT_TYPE_SENTINEL) + { + SkipBytes(1); + } + + return hr; + }// SkipAnyVASentinel + + //------------------------------------------------------------------------ + // Assumes that the SigParser points to the start of an element type + // (i.e. function parameter, function return type or field type.) + // Advances the pointer to the first data after the element type. + //------------------------------------------------------------------------ + __checkReturn + HRESULT SkipExactlyOne(); + + //------------------------------------------------------------------------ + // Skip only the method header of the signature, not the signature of + // the arguments. + //------------------------------------------------------------------------ + __checkReturn + HRESULT SkipMethodHeaderSignature(ULONG *pcArgs); + + //------------------------------------------------------------------------ + // Skip a sub signature (as immediately follows an ELEMENT_TYPE_FNPTR). + //------------------------------------------------------------------------ + __checkReturn + HRESULT SkipSignature(); + +public: + + //------------------------------------------------------------------------ + // Return pointer + // PLEASE DON'T USE THIS. + // + // Return the internal pointer. It's hard to resist, but please try + // not to use this. Certainly don't use it if there's any chance of the + // signature containing generic type variables. + // + // It's currently only used for working on the + // signatures stored in TypeSpec tokens (we should add a new abstraction, + // i.e. on MetaSig for this) and a couple of places to do with COM + // and native interop signature parsing. + // We should try to get rid of these uses as well. + //------------------------------------------------------------------------ + PCCOR_SIGNATURE GetPtr() const + { + return m_ptr; + } + +}; // class SigParser + +//------------------------------------------------------------------------ +FORCEINLINE +SigParser::SigParser( + const SigParser &sig) + : m_ptr(sig.m_ptr), m_dwLen(sig.m_dwLen) +{ +} + + +#endif // _H_SIGPARSER \ No newline at end of file diff --git a/src/SOS/Strike/sildasm.cpp b/src/SOS/Strike/sildasm.cpp index aa6b8762e..d0d32eeb1 100644 --- a/src/SOS/Strike/sildasm.cpp +++ b/src/SOS/Strike/sildasm.cpp @@ -90,6 +90,81 @@ unsigned int readOpcode() void DisassembleToken(IMetaDataImport *i, DWORD token) { + class MethodSigArgPrettyPrinter + { + SigParser sigParser; + ULONG cParamTypes = 0; + bool isField = true; + IMetaDataImport *pMDImport; + + public: + MethodSigArgPrettyPrinter(PCCOR_SIGNATURE sig, ULONG cbSig, IMetaDataImport *_pMDImport) : sigParser(sig, cbSig), pMDImport(_pMDImport) + { + } + + void HandleReturnType() + { + HRESULT hr; + ULONG callConv; + hr = sigParser.GetCallingConvInfo(&callConv); + if (SUCCEEDED(hr)) + { + isField = ((callConv & IMAGE_CEE_CS_CALLCONV_FIELD) == IMAGE_CEE_CS_CALLCONV_FIELD); + + if (!isField) + { + // Discard generic arg count + if ((callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) == IMAGE_CEE_CS_CALLCONV_GENERIC) + { + ULONG unused; + hr = sigParser.GetData(&unused); + } + } + + if (SUCCEEDED(hr)) + { + // Get arg count; + hr = sigParser.GetData(&cParamTypes); + if (SUCCEEDED(hr)) + { + // Print type + CQuickBytes out; + PrettyPrintType(sigParser.GetPtr(), &out, pMDImport); + int cchString = MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, NULL, 0); + WCHAR *psz = new WCHAR[cchString]; + MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, psz, cchString); + printf("%S ", psz); + delete[] psz; + sigParser.SkipExactlyOne(); + } + } + } + } + + void HandleArguments() + { + if (!isField) + { + printf("("); + for (ULONG paramIndex = 0; paramIndex < cParamTypes; paramIndex++) + { + CQuickBytes out; + PrettyPrintType(sigParser.GetPtr(), &out, pMDImport); + int cchString = MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, NULL, 0); + WCHAR *psz = new WCHAR[cchString]; + MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, psz, cchString); + if ((paramIndex + 1) < cParamTypes) + printf("%S,", psz); + else + printf("%S", psz); + delete[] psz; + sigParser.SkipExactlyOne(); + } + printf(")"); + } + } + }; + HRESULT hr; switch (TypeFromToken(token)) @@ -155,12 +230,18 @@ void DisassembleToken(IMetaDataImport *i, WCHAR szFieldName[50]; WCHAR szClassName[50]; mdTypeDef mdClass; + PCCOR_SIGNATURE sig; + ULONG cbSigBlob; hr = i->GetMethodProps(token, &mdClass, szFieldName, 49, &cLen, - NULL, NULL, NULL, NULL, NULL); + NULL, &sig, &cbSigBlob, NULL, NULL); + + MethodSigArgPrettyPrinter methodPrettyPrinter(sig, cbSigBlob, i); if (FAILED(hr)) StringCchCopyW(szFieldName, COUNTOF(szFieldName), W("")); + else + methodPrettyPrinter.HandleReturnType(); hr = i->GetTypeDefProps(mdClass, szClassName, 49, &cLen, NULL, NULL); @@ -169,6 +250,7 @@ void DisassembleToken(IMetaDataImport *i, StringCchCopyW(szClassName, COUNTOF(szClassName), W("")); printf("%S::%S", szClassName, szFieldName); + methodPrettyPrinter.HandleArguments(); // Safe to call in all cases if HandleReturnType hasn't been called. Will do nothing. } break; @@ -178,16 +260,23 @@ void DisassembleToken(IMetaDataImport *i, LPCWSTR pMemberName; WCHAR memberName[50]; ULONG memberNameLen; + PCCOR_SIGNATURE sig; + ULONG cbSigBlob; hr = i->GetMemberRefProps(token, &cr, memberName, 49, - &memberNameLen, NULL, NULL); + &memberNameLen, &sig, &cbSigBlob); + + MethodSigArgPrettyPrinter methodPrettyPrinter(sig, cbSigBlob, i); if (FAILED(hr)) { pMemberName = W(""); } else + { pMemberName = memberName; + methodPrettyPrinter.HandleReturnType(); + } ULONG cLen; WCHAR szName[50]; @@ -209,27 +298,17 @@ void DisassembleToken(IMetaDataImport *i, } else if(TypeFromToken(cr) == mdtTypeSpec) { - IMDInternalImport *pIMDI = NULL; - if (SUCCEEDED(GetMDInternalFromImport(i, &pIMDI))) + CQuickBytes out; + ULONG cSig; + PCCOR_SIGNATURE sig; + if (FAILED(i->GetTypeSpecFromToken(cr, &sig, &cSig))) { - CQuickBytes out; - ULONG cSig; - PCCOR_SIGNATURE sig; - if (FAILED(pIMDI->GetSigFromToken(cr, &cSig, &sig))) - { - StringCchCopyW(szName, COUNTOF(szName), W("")); - } - else - { - PrettyPrintType(sig, &out, pIMDI); - MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, szName, 50); - } - - pIMDI->Release(); + StringCchCopyW(szName, COUNTOF(szName), W("")); } else { - StringCchCopyW(szName, COUNTOF(szName), W("")); + PrettyPrintType(sig, &out, i); + MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, szName, 50); } } else @@ -237,7 +316,8 @@ void DisassembleToken(IMetaDataImport *i, StringCchCopyW(szName, COUNTOF(szName), W("")); } - printf("%S::%S ", szName, pMemberName); + printf("%S::%S", szName, pMemberName); + methodPrettyPrinter.HandleArguments(); // Safe to call in all cases if HandleReturnType hasn't been called. Will do nothing. } break; } @@ -642,6 +722,16 @@ static void appendStr(CQuickBytes *out, const char* str, unsigned len=-1) { // Note no trailing null! } +static void appendStr(CQuickBytes *out, const WCHAR* str, unsigned len=-1) { + if(len == (unsigned)(-1)) len = (unsigned)_wcslen(str); + + int acpSize = WideCharToMultiByte(CP_ACP, 0, str, len, NULL, 0, NULL, NULL); + char *pAcpString = (char*)_alloca(acpSize + 1); + WideCharToMultiByte(CP_ACP, 0, str, len, pAcpString, acpSize, NULL, NULL); + pAcpString[acpSize] = '\0'; + appendStr(out, pAcpString, acpSize); +} + static void appendChar(CQuickBytes *out, char chr) { SIZE_T oldSize = out->Size(); out->ReSize(oldSize + 1); @@ -670,7 +760,7 @@ static void appendStrNum(CQuickBytes *out, int num) { PCCOR_SIGNATURE PrettyPrintType( PCCOR_SIGNATURE typePtr, // type to convert, CQuickBytes *out, // where to put the pretty printed string - IMDInternalImport *pIMDI, // ptr to IMDInternal class with ComSig + IMetaDataImport *pIMD, // ptr to IMetaDataImport class with ComSig DWORD formatFlags /*= formatILDasm*/) { mdToken tk; @@ -742,7 +832,7 @@ PCCOR_SIGNATURE PrettyPrintType( { appendStr(out, "[ERROR! NIL TOKEN]"); } - else PrettyPrintClass(out, tk, pIMDI, formatFlags); + else PrettyPrintClass(out, tk, pIMD, formatFlags); break; case ELEMENT_TYPE_SZARRAY : @@ -752,7 +842,7 @@ PCCOR_SIGNATURE PrettyPrintType( case ELEMENT_TYPE_ARRAY : { - typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags); + typePtr = PrettyPrintType(typePtr, out, pIMD, formatFlags); unsigned rank = CorSigUncompressData(typePtr); // what is the syntax for the rank 0 case? if (rank == 0) { @@ -829,12 +919,12 @@ PCCOR_SIGNATURE PrettyPrintType( case ELEMENT_TYPE_FNPTR : appendStr(out, "method "); - appendStr(out, "METHOD"); // was: typePtr = PrettyPrintSignature(typePtr, 0x7FFF, "*", out, pIMDI, NULL); + appendStr(out, "METHOD"); // was: typePtr = PrettyPrintSignature(typePtr, 0x7FFF, "*", out, pIMD, NULL); break; case ELEMENT_TYPE_GENERICINST : { - typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags); + typePtr = PrettyPrintType(typePtr, out, pIMD, formatFlags); if ((formatFlags & FormatSignature) == 0) break; @@ -848,7 +938,7 @@ PCCOR_SIGNATURE PrettyPrintType( { if (needComma) appendChar(out, ','); - typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags); + typePtr = PrettyPrintType(typePtr, out, pIMD, formatFlags); needComma = true; } if ((formatFlags & FormatAngleBrackets) != 0) @@ -867,7 +957,28 @@ PCCOR_SIGNATURE PrettyPrintType( MODIFIER: insertStr(&Appendix, str); Reiterate = TRUE; - break; + break; + case ELEMENT_TYPE_CMOD_REQD: + appendStr(out, " mod req "); + typePtr += CorSigUncompressToken(typePtr, &tk); + if(IsNilToken(tk)) + { + appendStr(out, "[ERROR! NIL TOKEN]"); + } + else PrettyPrintClass(out, tk, pIMD, formatFlags); + Reiterate = TRUE; + break; + case ELEMENT_TYPE_CMOD_OPT: + appendStr(out, " mod opt "); + typePtr += CorSigUncompressToken(typePtr, &tk); + if(IsNilToken(tk)) + { + appendStr(out, "[ERROR! NIL TOKEN]"); + } + else PrettyPrintClass(out, tk, pIMD, formatFlags); + Reiterate = TRUE; + break; + default: case ELEMENT_TYPE_SENTINEL : @@ -889,24 +1000,26 @@ PCCOR_SIGNATURE PrettyPrintType( } // Protection against null names, used by ILDASM/SOS -const char *const szStdNamePrefix[] = {"MO","TR","TD","","FD","","MD","","PA","II","MR","","CA","","PE","","","SG","","","EV", -"","","PR","","","MOR","TS","","","","","AS","","","AR","","","FL","ET","MAR"}; +const WCHAR *const szStdNamePrefix[] = {W("MO"),W("TR"),W("TD"),W(""),W("FD"),W(""),W("MD"),W(""),W("PA"),W("II"),W("MR"),W(""),W("CA"),W(""),W("PE"),W(""),W(""),W("SG"),W(""),W(""),W("EV"), +W(""),W(""),W("PR"),W(""),W(""),W("MOR"),W("TS"),W(""),W(""),W(""),W(""),W("AS"),W(""),W(""),W("AR"),W(""),W(""),W("FL"),W("ET"),W("MAR")}; -#define MAKE_NAME_IF_NONE(psz, tk) { if(!(psz && *psz)) { char* sz = (char*)_alloca(16); \ -sprintf_s(sz,16,"$%s$%X",szStdNamePrefix[tk>>24],tk&0x00FFFFFF); psz = sz; } } +#define MAKE_NAME_IF_NONE(psz, tk) { if(!(psz && *psz)) { WCHAR* sz = (WCHAR*)_alloca(16 * sizeof(WCHAR)); \ +swprintf_s(sz,16,W("$%s$%X"),szStdNamePrefix[tk>>24],tk&0x00FFFFFF); psz = sz; } } const char* PrettyPrintClass( CQuickBytes *out, // where to put the pretty printed string mdToken tk, // The class token to look up - IMDInternalImport *pIMDI, // ptr to IMDInternalImport class with ComSig + IMetaDataImport *pIMD, // ptr to IMetaDataImport class with ComSig DWORD formatFlags /*= formatILDasm*/) { +#define MAX_TYPE_NAME_LEN MAX_CLASSNAME_LENGTH + MAX_CLASSNAME_LENGTH + 1 + WCHAR nameComplete[MAX_TYPE_NAME_LEN]; if(tk == mdTokenNil) // Zero resolution scope for "somewhere here" TypeRefs { appendStr(out,"[*]"); return(asString(out)); } - if (!pIMDI->IsValidToken(tk)) + if (!pIMD->IsValidToken(tk)) { char str[1024]; sprintf_s(str,COUNTOF(str)," [ERROR: INVALID TOKEN 0x%8.8X] ",tk); @@ -918,14 +1031,13 @@ const char* PrettyPrintClass( case mdtTypeRef: case mdtTypeDef: { - const char *nameSpace = 0; - const char *name = 0; + WCHAR *name = NULL; + ULONG unused; mdToken tkEncloser = mdTokenNil; if (TypeFromToken(tk) == mdtTypeRef) { - if (((formatFlags & FormatAssembly) && FAILED(pIMDI->GetResolutionScopeOfTypeRef(tk, &tkEncloser))) || - FAILED(pIMDI->GetNameOfTypeRef(tk, &nameSpace, &name))) + if (((formatFlags & FormatAssembly) && FAILED(pIMD->GetTypeRefProps(tk, &tkEncloser, nameComplete, MAX_TYPE_NAME_LEN, &unused)))) { char str[1024]; sprintf_s(str, COUNTOF(str), " [ERROR: Invalid TypeRef record 0x%8.8X] ", tk); @@ -935,24 +1047,51 @@ const char* PrettyPrintClass( } else { - if (((formatFlags & FormatNamespace) == 0) || FAILED(pIMDI->GetNestedClassProps(tk,&tkEncloser))) - { - tkEncloser = mdTypeDefNil; - } - if (FAILED(pIMDI->GetNameOfTypeDef(tk, &name, &nameSpace))) + DWORD typeDefFlags = 0; + mdToken tkExtends; + + if (FAILED(pIMD->GetTypeDefProps(tk, nameComplete, MAX_TYPE_NAME_LEN, &unused, &typeDefFlags, &tkExtends))) { char str[1024]; sprintf_s(str, COUNTOF(str), " [ERROR: Invalid TypeDef record 0x%8.8X] ", tk); appendStr(out, str); return asString(out); } + + if (IsTdNested(typeDefFlags)) + { + if (FAILED(pIMD->GetNestedClassProps(tk, &tkEncloser))) + { + tkEncloser = mdTypeDefNil; + } + } + } + + if ((formatFlags & FormatNamespace) == 0) + { + tkEncloser = mdTypeDefNil; + auto nameLen = _wcslen(nameComplete); + name = nameComplete; + + for (decltype(nameLen) index = 0; index < nameLen; index++) + { + if (nameComplete[index] == '.') + { + name = nameComplete + index + 1; + } + } + } + else + { + name = nameComplete; } + MAKE_NAME_IF_NONE(name,tk); if((tkEncloser == mdTokenNil) || RidFromToken(tkEncloser)) { if (TypeFromToken(tkEncloser) == mdtTypeRef || TypeFromToken(tkEncloser) == mdtTypeDef) { - PrettyPrintClass(out,tkEncloser,pIMDI, formatFlags); + PrettyPrintClass(out,tkEncloser,pIMD, formatFlags); if (formatFlags & FormatSlashSep) appendChar(out, '/'); else @@ -961,74 +1100,52 @@ const char* PrettyPrintClass( } else if (formatFlags & FormatAssembly) { - PrettyPrintClass(out,tkEncloser,pIMDI, formatFlags); + PrettyPrintClass(out,tkEncloser,pIMD, formatFlags); } } - if(TypeFromToken(tk)==mdtTypeDef) - { - unsigned L = (unsigned)strlen(name)+1; - char* szFN = NULL; - if(((formatFlags & FormatNamespace) != 0) && nameSpace && *nameSpace) - { - const char* sz = nameSpace; - L+= (unsigned)strlen(sz)+1; - szFN = new char[L]; - sprintf_s(szFN,L,"%s.",sz); - } - else - { - szFN = new char[L]; - *szFN = 0; - } - strcat_s(szFN,L, name); - appendStr(out, szFN); - if (szFN) delete[] (szFN); - } - else - { - if (((formatFlags & FormatNamespace) != 0) && nameSpace && *nameSpace) { - appendStr(out, nameSpace); - appendChar(out, '.'); - } - - appendStr(out, name); - } + appendStr(out, name); } break; case mdtAssemblyRef: { LPCSTR szName = NULL; - pIMDI->GetAssemblyRefProps(tk,NULL,NULL,&szName,NULL,NULL,NULL,NULL); - if(szName && *szName) + ULONG unused; + ToRelease pAsmImport; + if (SUCCEEDED(pIMD->QueryInterface(IID_IMetaDataAssemblyImport, (LPVOID *)&pAsmImport))) { - appendChar(out, '['); - appendStr(out, szName); - appendChar(out, ']'); + if(SUCCEEDED(pAsmImport->GetAssemblyRefProps(tk,NULL,NULL,nameComplete, MAX_TYPE_NAME_LEN,&unused,NULL, NULL, NULL, NULL))) + { + appendChar(out, '['); + appendStr(out, nameComplete); + appendChar(out, ']'); + } } } break; case mdtAssembly: { - LPCSTR szName = NULL; - pIMDI->GetAssemblyProps(tk,NULL,NULL,NULL,&szName,NULL,NULL); - if(szName && *szName) + ULONG unused; + ToRelease pAsmImport; + if (SUCCEEDED(pIMD->QueryInterface(IID_IMetaDataAssemblyImport, (LPVOID *)&pAsmImport))) { - appendChar(out, '['); - appendStr(out, szName); - appendChar(out, ']'); + if(SUCCEEDED(pAsmImport->GetAssemblyProps(tk,NULL,NULL,NULL,nameComplete, MAX_TYPE_NAME_LEN,&unused,NULL, NULL))) + { + appendChar(out, '['); + appendStr(out, nameComplete); + appendChar(out, ']'); + } } } break; case mdtModuleRef: { - LPCSTR szName = NULL; - pIMDI->GetModuleRefProps(tk,&szName); - if(szName && *szName) + ULONG unused; + if(SUCCEEDED(pIMD->GetModuleRefProps(tk,nameComplete, MAX_TYPE_NAME_LEN, &unused))) { appendChar(out, '['); appendStr(out, ".module "); - appendStr(out, szName); + appendStr(out, nameComplete); appendChar(out, ']'); } } @@ -1038,7 +1155,7 @@ const char* PrettyPrintClass( { ULONG cSig; PCCOR_SIGNATURE sig; - if (FAILED(pIMDI->GetSigFromToken(tk, &cSig, &sig))) + if (FAILED(pIMD->GetTypeSpecFromToken(tk, &sig, &cSig))) { char str[128]; sprintf_s(str, COUNTOF(str), " [ERROR: Invalid token 0x%8.8X] ", tk); @@ -1046,7 +1163,7 @@ const char* PrettyPrintClass( } else { - PrettyPrintType(sig, out, pIMDI, formatFlags); + PrettyPrintType(sig, out, pIMD, formatFlags); } } break; @@ -1080,12 +1197,8 @@ void PrettyPrintClassFromToken( return; ToRelease pImport(MDImportForModule(&dmd)); - ToRelease pIMDI = NULL; - - if ((pImport == NULL) || FAILED(GetMDInternalFromImport(pImport, &pIMDI))) - return; CQuickBytes qb; - PrettyPrintClass(&qb, tok, pIMDI, formatFlags); + PrettyPrintClass(&qb, tok, pImport, formatFlags); MultiByteToWideChar (CP_ACP, 0, asString(&qb), -1, mdName, (int) cbName); } diff --git a/src/SOS/Strike/sos_md.h b/src/SOS/Strike/sos_md.h index b58910998..71a874376 100644 --- a/src/SOS/Strike/sos_md.h +++ b/src/SOS/Strike/sos_md.h @@ -42,810 +42,6 @@ class CQuickBytes; * from the EE. * */ -typedef enum tagEnumType -{ - MDSimpleEnum = 0x0, // simple enumerator that doesn't allocate memory - MDDynamicArrayEnum = 0x2, // dynamic array that holds tokens - MDCustomEnum = 0x3, // Custom enumerator that doesnt work with the enum functions -} EnumType; - -struct HENUMInternal -{ - DWORD m_tkKind; // kind of tables that the enum is holding the result - ULONG m_ulCount; // count of total entries holding by the enumerator - - EnumType m_EnumType; - - struct { - ULONG m_ulStart; - ULONG m_ulEnd; - ULONG m_ulCur; - } u; - - // m_cursor will go away when we no longer support running EE with uncompressed - // format. WHEN WE REMOVE THIS, REMOVE ITS VESTIAGES FROM ZeroEnum as well - // - char m_cursor[32]; // cursor holding query result for read/write mode -}; - -typedef struct _MDDefaultValue -{ -#if DBG_TARGET_BIGENDIAN - _MDDefaultValue(void) - { - m_bType = ELEMENT_TYPE_END; - } - ~_MDDefaultValue(void) - { - if (m_bType == ELEMENT_TYPE_STRING) - { - delete[] m_wzValue; - } - } -#endif - - // type of default value - BYTE m_bType; // CorElementType for the default value - - // the default value - union - { - BOOL m_bValue; // ELEMENT_TYPE_BOOLEAN - CHAR m_cValue; // ELEMENT_TYPE_I1 - BYTE m_byteValue; // ELEMENT_TYPE_UI1 - SHORT m_sValue; // ELEMENT_TYPE_I2 - USHORT m_usValue; // ELEMENT_TYPE_UI2 - LONG m_lValue; // ELEMENT_TYPE_I4 - ULONG m_ulValue; // ELEMENT_TYPE_UI4 - LONGLONG m_llValue; // ELEMENT_TYPE_I8 - ULONGLONG m_ullValue; // ELEMENT_TYPE_UI8 - FLOAT m_fltValue; // ELEMENT_TYPE_R4 - DOUBLE m_dblValue; // ELEMENT_TYPE_R8 - LPCWSTR m_wzValue; // ELEMENT_TYPE_STRING - IUnknown *m_unkValue; // ELEMENT_TYPE_CLASS - }; - ULONG m_cbSize; // default value size (for blob) - -} MDDefaultValue; - -typedef struct -{ - RID m_ridFieldCur; // indexing to the field table - RID m_ridFieldEnd; // end index to field table -} MD_CLASS_LAYOUT; - -typedef struct -{ - USHORT usMajorVersion; // Major Version. - USHORT usMinorVersion; // Minor Version. - USHORT usBuildNumber; // Build Number. - USHORT usRevisionNumber; // Revision Number. - LPCSTR szLocale; // Locale. - DWORD *rProcessor; // Processor array. - ULONG ulProcessor; // [IN/OUT] Size of the processor array/Actual # of entries filled in. - OSINFO *rOS; // OSINFO array. - ULONG ulOS; // [IN/OUT]Size of the OSINFO array/Actual # of entries filled in. -} AssemblyMetaDataInternal; - -typedef struct -{ - mdMethodDef m_memberdef; - DWORD m_dwSemantics; -} ASSOCIATE_RECORD; - -typedef BOOL (*PSIGCOMPARE)(PCCOR_SIGNATURE, DWORD, PCCOR_SIGNATURE, DWORD, void*); - -EXTERN_GUID(IID_IMDInternalImport, 0xce0f34ed, 0xbbc6, 0x11d2, 0x94, 0x1e, 0x0, 0x0, 0xf8, 0x8, 0x34, 0x60); -#undef INTERFACE -#define INTERFACE IMDInternalImport -DECLARE_INTERFACE_(IMDInternalImport, IUnknown) -{ - //***************************************************************************** - // return the count of entries of a given kind in a scope - // For example, pass in mdtMethodDef will tell you how many MethodDef - // contained in a scope - //***************************************************************************** - STDMETHOD_(ULONG, GetCountWithTokenKind)(// return hresult - DWORD tkKind) PURE; // [IN] pass in the kind of token. - - //***************************************************************************** - // enumerator for typedef - //***************************************************************************** - STDMETHOD(EnumTypeDefInit)( // return hresult - HENUMInternal *phEnum) PURE; // [OUT] buffer to fill for enumerator data - - STDMETHOD_(ULONG, EnumTypeDefGetCount)( - HENUMInternal *phEnum) PURE; // [IN] the enumerator to retrieve information - - STDMETHOD_(void, EnumTypeDefReset)( - HENUMInternal *phEnum) PURE; // [IN] the enumerator to retrieve information - - STDMETHOD_(bool, EnumTypeDefNext)( // return hresult - HENUMInternal *phEnum, // [IN] input enum - mdTypeDef *ptd) PURE; // [OUT] return token - - STDMETHOD_(void, EnumTypeDefClose)( - HENUMInternal *phEnum) PURE; // [IN] the enumerator to retrieve information - - //***************************************************************************** - // enumerator for MethodImpl - //***************************************************************************** - STDMETHOD(EnumMethodImplInit)( // return hresult - mdTypeDef td, // [IN] TypeDef over which to scope the enumeration. - HENUMInternal *phEnumBody, // [OUT] buffer to fill for enumerator data for MethodBody tokens. - HENUMInternal *phEnumDecl) PURE; // [OUT] buffer to fill for enumerator data for MethodDecl tokens. - - STDMETHOD_(ULONG, EnumMethodImplGetCount)( - HENUMInternal *phEnumBody, // [IN] MethodBody enumerator. - HENUMInternal *phEnumDecl) PURE; // [IN] MethodDecl enumerator. - - STDMETHOD_(void, EnumMethodImplReset)( - HENUMInternal *phEnumBody, // [IN] MethodBody enumerator. - HENUMInternal *phEnumDecl) PURE; // [IN] MethodDecl enumerator. - - STDMETHOD(EnumMethodImplNext)( // return hresult (S_OK = TRUE, S_FALSE = FALSE or error code) - HENUMInternal *phEnumBody, // [IN] input enum for MethodBody - HENUMInternal *phEnumDecl, // [IN] input enum for MethodDecl - mdToken *ptkBody, // [OUT] return token for MethodBody - mdToken *ptkDecl) PURE; // [OUT] return token for MethodDecl - - STDMETHOD_(void, EnumMethodImplClose)( - HENUMInternal *phEnumBody, // [IN] MethodBody enumerator. - HENUMInternal *phEnumDecl) PURE; // [IN] MethodDecl enumerator. - - //***************************************** - // Enumerator helpers for memberdef, memberref, interfaceimp, - // event, property, exception, param - //***************************************** - - STDMETHOD(EnumGlobalFunctionsInit)( // return hresult - HENUMInternal *phEnum) PURE; // [OUT] buffer to fill for enumerator data - - STDMETHOD(EnumGlobalFieldsInit)( // return hresult - HENUMInternal *phEnum) PURE; // [OUT] buffer to fill for enumerator data - - STDMETHOD(EnumInit)( // return S_FALSE if record not found - DWORD tkKind, // [IN] which table to work on - mdToken tkParent, // [IN] token to scope the search - HENUMInternal *phEnum) PURE; // [OUT] the enumerator to fill - - STDMETHOD(EnumAllInit)( // return S_FALSE if record not found - DWORD tkKind, // [IN] which table to work on - HENUMInternal *phEnum) PURE; // [OUT] the enumerator to fill - - STDMETHOD_(bool, EnumNext)( - HENUMInternal *phEnum, // [IN] the enumerator to retrieve information - mdToken *ptk) PURE; // [OUT] token to scope the search - - STDMETHOD_(ULONG, EnumGetCount)( - HENUMInternal *phEnum) PURE; // [IN] the enumerator to retrieve information - - STDMETHOD_(void, EnumReset)( - HENUMInternal *phEnum) PURE; // [IN] the enumerator to be reset - - STDMETHOD_(void, EnumClose)( - HENUMInternal *phEnum) PURE; // [IN] the enumerator to be closed - - //***************************************** - // Enumerator helpers for declsecurity. - //***************************************** - STDMETHOD(EnumPermissionSetsInit)( // return S_FALSE if record not found - mdToken tkParent, // [IN] token to scope the search - CorDeclSecurity Action, // [IN] Action to scope the search - HENUMInternal *phEnum) PURE; // [OUT] the enumerator to fill - - //***************************************** - // Enumerator helpers for CustomAttribute - //***************************************** - STDMETHOD(EnumCustomAttributeByNameInit)(// return S_FALSE if record not found - mdToken tkParent, // [IN] token to scope the search - LPCSTR szName, // [IN] CustomAttribute's name to scope the search - HENUMInternal *phEnum) PURE; // [OUT] the enumerator to fill - - //***************************************** - // Nagivator helper to navigate back to the parent token given a token. - // For example, given a memberdef token, it will return the containing typedef. - // - // the mapping is as following: - // ---given child type---------parent type - // mdMethodDef mdTypeDef - // mdFieldDef mdTypeDef - // mdInterfaceImpl mdTypeDef - // mdParam mdMethodDef - // mdProperty mdTypeDef - // mdEvent mdTypeDef - // - //***************************************** - STDMETHOD(GetParentToken)( - mdToken tkChild, // [IN] given child token - mdToken *ptkParent) PURE; // [OUT] returning parent - - //***************************************** - // Custom value helpers - //***************************************** - STDMETHOD(GetCustomAttributeProps)( // S_OK or error. - mdCustomAttribute at, // [IN] The attribute. - mdToken *ptkType) PURE; // [OUT] Put attribute type here. - - STDMETHOD(GetCustomAttributeAsBlob)( - mdCustomAttribute cv, // [IN] given custom value token - void const **ppBlob, // [OUT] return the pointer to internal blob - ULONG *pcbSize) PURE; // [OUT] return the size of the blob - - // returned void in v1.0/v1.1 - STDMETHOD (GetScopeProps)( - LPCSTR *pszName, // [OUT] scope name - GUID *pmvid) PURE; // [OUT] version id - - // finding a particular method - STDMETHOD(FindMethodDef)( - mdTypeDef classdef, // [IN] given typedef - LPCSTR szName, // [IN] member name - PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of CLR signature - ULONG cbSigBlob, // [IN] count of bytes in the signature blob - mdMethodDef *pmd) PURE; // [OUT] matching memberdef - - // return a iSeq's param given a MethodDef - STDMETHOD(FindParamOfMethod)( // S_OK or error. - mdMethodDef md, // [IN] The owning method of the param. - ULONG iSeq, // [IN] The sequence # of the param. - mdParamDef *pparamdef) PURE; // [OUT] Put ParamDef token here. - - //***************************************** - // - // GetName* functions - // - //***************************************** - - // return the name and namespace of typedef - STDMETHOD(GetNameOfTypeDef)( - mdTypeDef classdef, // given classdef - LPCSTR *pszname, // return class name(unqualified) - LPCSTR *psznamespace) PURE; // return the name space name - - STDMETHOD(GetIsDualOfTypeDef)( - mdTypeDef classdef, // [IN] given classdef. - ULONG *pDual) PURE; // [OUT] return dual flag here. - - STDMETHOD(GetIfaceTypeOfTypeDef)( - mdTypeDef classdef, // [IN] given classdef. - ULONG *pIface) PURE; // [OUT] 0=dual, 1=vtable, 2=dispinterface - - // get the name of either methoddef - STDMETHOD(GetNameOfMethodDef)( // return the name of the memberdef in UTF8 - mdMethodDef md, // given memberdef - LPCSTR *pszName) PURE; - - STDMETHOD(GetNameAndSigOfMethodDef)( - mdMethodDef methoddef, // [IN] given memberdef - PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to a blob value of CLR signature - ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob - LPCSTR *pszName) PURE; - - // return the name of a FieldDef - STDMETHOD(GetNameOfFieldDef)( - mdFieldDef fd, // given memberdef - LPCSTR *pszName) PURE; - - // return the name of typeref - STDMETHOD(GetNameOfTypeRef)( - mdTypeRef classref, // [IN] given typeref - LPCSTR *psznamespace, // [OUT] return typeref name - LPCSTR *pszname) PURE; // [OUT] return typeref namespace - - // return the resolutionscope of typeref - STDMETHOD(GetResolutionScopeOfTypeRef)( - mdTypeRef classref, // given classref - mdToken *ptkResolutionScope) PURE; - - // Find the type token given the name. - STDMETHOD(FindTypeRefByName)( - LPCSTR szNamespace, // [IN] Namespace for the TypeRef. - LPCSTR szName, // [IN] Name of the TypeRef. - mdToken tkResolutionScope, // [IN] Resolution Scope fo the TypeRef. - mdTypeRef *ptk) PURE; // [OUT] TypeRef token returned. - - // return the TypeDef properties - // returned void in v1.0/v1.1 - STDMETHOD(GetTypeDefProps)( - mdTypeDef classdef, // given classdef - DWORD *pdwAttr, // return flags on class, tdPublic, tdAbstract - mdToken *ptkExtends) PURE; // [OUT] Put base class TypeDef/TypeRef here - - // return the item's guid - STDMETHOD(GetItemGuid)( - mdToken tkObj, // [IN] given item. - CLSID *pGuid) PURE; // [out[ put guid here. - - // Get enclosing class of the NestedClass. - STDMETHOD(GetNestedClassProps)( // S_OK or error - mdTypeDef tkNestedClass, // [IN] NestedClass token. - mdTypeDef *ptkEnclosingClass) PURE; // [OUT] EnclosingClass token. - - // Get count of Nested classes given the enclosing class. - STDMETHOD(GetCountNestedClasses)( // return count of Nested classes. - mdTypeDef tkEnclosingClass, // Enclosing class. - ULONG *pcNestedClassesCount) PURE; - - // Return array of Nested classes given the enclosing class. - STDMETHOD(GetNestedClasses)( // Return actual count. - mdTypeDef tkEnclosingClass, // [IN] Enclosing class. - mdTypeDef *rNestedClasses, // [OUT] Array of nested class tokens. - ULONG ulNestedClasses, // [IN] Size of array. - ULONG *pcNestedClasses) PURE; - - // return the ModuleRef properties - // returned void in v1.0/v1.1 - STDMETHOD(GetModuleRefProps)( - mdModuleRef mur, // [IN] moduleref token - LPCSTR *pszName) PURE; // [OUT] buffer to fill with the moduleref name - - //***************************************** - // - // GetSig* functions - // - //***************************************** - STDMETHOD(GetSigOfMethodDef)( - mdMethodDef methoddef, // [IN] given memberdef - ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob - PCCOR_SIGNATURE *ppSig) PURE; - - STDMETHOD(GetSigOfFieldDef)( - mdMethodDef methoddef, // [IN] given memberdef - ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob - PCCOR_SIGNATURE *ppSig) PURE; - - STDMETHOD(GetSigFromToken)( - mdToken tk, - ULONG * pcbSig, - PCCOR_SIGNATURE * ppSig) PURE; - - - - //***************************************** - // get method property - //***************************************** - STDMETHOD(GetMethodDefProps)( - mdMethodDef md, // The method for which to get props. - DWORD *pdwFlags) PURE; - - //***************************************** - // return method implementation informaiton, like RVA and implflags - //***************************************** - // returned void in v1.0/v1.1 - STDMETHOD(GetMethodImplProps)( - mdToken tk, // [IN] MethodDef - ULONG *pulCodeRVA, // [OUT] CodeRVA - DWORD *pdwImplFlags) PURE; // [OUT] Impl. Flags - - //***************************************** - // return method implementation informaiton, like RVA and implflags - //***************************************** - STDMETHOD(GetFieldRVA)( - mdFieldDef fd, // [IN] fielddef - ULONG *pulCodeRVA) PURE; // [OUT] CodeRVA - - //***************************************** - // get field property - //***************************************** - STDMETHOD(GetFieldDefProps)( - mdFieldDef fd, // [IN] given fielddef - DWORD *pdwFlags) PURE; // [OUT] return fdPublic, fdPrive, etc flags - - //***************************************************************************** - // return default value of a token(could be paramdef, fielddef, or property - //***************************************************************************** - STDMETHOD(GetDefaultValue)( - mdToken tk, // [IN] given FieldDef, ParamDef, or Property - MDDefaultValue *pDefaultValue) PURE;// [OUT] default value to fill - - - //***************************************** - // get dispid of a MethodDef or a FieldDef - //***************************************** - STDMETHOD(GetDispIdOfMemberDef)( // return hresult - mdToken tk, // [IN] given methoddef or fielddef - ULONG *pDispid) PURE; // [OUT] Put the dispid here. - - //***************************************** - // return TypeRef/TypeDef given an InterfaceImpl token - //***************************************** - STDMETHOD(GetTypeOfInterfaceImpl)( // return the TypeRef/typedef token for the interfaceimpl - mdInterfaceImpl iiImpl, // given a interfaceimpl - mdToken *ptkType) PURE; - - //***************************************** - // look up function for TypeDef - //***************************************** - STDMETHOD(FindTypeDef)( - LPCSTR szNamespace, // [IN] Namespace for the TypeDef. - LPCSTR szName, // [IN] Name of the TypeDef. - mdToken tkEnclosingClass, // [IN] TypeRef/TypeDef Token for the enclosing class. - mdTypeDef *ptypedef) PURE; // [IN] return typedef - - //***************************************** - // return name and sig of a memberref - //***************************************** - STDMETHOD(GetNameAndSigOfMemberRef)( // return name here - mdMemberRef memberref, // given memberref - PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to a blob value of CLR signature - ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob - LPCSTR *pszName) PURE; - - //***************************************************************************** - // Given memberref, return the parent. It can be TypeRef, ModuleRef, MethodDef - //***************************************************************************** - STDMETHOD(GetParentOfMemberRef)( - mdMemberRef memberref, // given memberref - mdToken *ptkParent) PURE; // return the parent token - - STDMETHOD(GetParamDefProps)( - mdParamDef paramdef, // given a paramdef - USHORT *pusSequence, // [OUT] slot number for this parameter - DWORD *pdwAttr, // [OUT] flags - LPCSTR *pszName) PURE; // [OUT] return the name of the parameter - - STDMETHOD(GetPropertyInfoForMethodDef)( // Result. - mdMethodDef md, // [IN] memberdef - mdProperty *ppd, // [OUT] put property token here - LPCSTR *pName, // [OUT] put pointer to name here - ULONG *pSemantic) PURE; // [OUT] put semantic here - - //***************************************** - // class layout/sequence information - //***************************************** - STDMETHOD(GetClassPackSize)( // return error if class doesn't have packsize - mdTypeDef td, // [IN] give typedef - ULONG *pdwPackSize) PURE; // [OUT] 1, 2, 4, 8, or 16 - - STDMETHOD(GetClassTotalSize)( // return error if class doesn't have total size info - mdTypeDef td, // [IN] give typedef - ULONG *pdwClassSize) PURE; // [OUT] return the total size of the class - - STDMETHOD(GetClassLayoutInit)( - mdTypeDef td, // [IN] give typedef - MD_CLASS_LAYOUT *pLayout) PURE; // [OUT] set up the status of query here - - STDMETHOD(GetClassLayoutNext)( - MD_CLASS_LAYOUT *pLayout, // [IN|OUT] set up the status of query here - mdFieldDef *pfd, // [OUT] return the fielddef - ULONG *pulOffset) PURE; // [OUT] return the offset/ulSequence associate with it - - //***************************************** - // marshal information of a field - //***************************************** - STDMETHOD(GetFieldMarshal)( // return error if no native type associate with the token - mdFieldDef fd, // [IN] given fielddef - PCCOR_SIGNATURE *pSigNativeType, // [OUT] the native type signature - ULONG *pcbNativeType) PURE; // [OUT] the count of bytes of *ppvNativeType - - - //***************************************** - // property APIs - //***************************************** - // find a property by name - STDMETHOD(FindProperty)( - mdTypeDef td, // [IN] given a typdef - LPCSTR szPropName, // [IN] property name - mdProperty *pProp) PURE; // [OUT] return property token - - // returned void in v1.0/v1.1 - STDMETHOD(GetPropertyProps)( - mdProperty prop, // [IN] property token - LPCSTR *szProperty, // [OUT] property name - DWORD *pdwPropFlags, // [OUT] property flags. - PCCOR_SIGNATURE *ppvSig, // [OUT] property type. pointing to meta data internal blob - ULONG *pcbSig) PURE; // [OUT] count of bytes in *ppvSig - - //********************************** - // Event APIs - //********************************** - STDMETHOD(FindEvent)( - mdTypeDef td, // [IN] given a typdef - LPCSTR szEventName, // [IN] event name - mdEvent *pEvent) PURE; // [OUT] return event token - - // returned void in v1.0/v1.1 - STDMETHOD(GetEventProps)( - mdEvent ev, // [IN] event token - LPCSTR *pszEvent, // [OUT] Event name - DWORD *pdwEventFlags, // [OUT] Event flags. - mdToken *ptkEventType) PURE; // [OUT] EventType class - - - //********************************** - // find a particular associate of a property or an event - //********************************** - STDMETHOD(FindAssociate)( - mdToken evprop, // [IN] given a property or event token - DWORD associate, // [IN] given a associate semantics(setter, getter, testdefault, reset, AddOn, RemoveOn, Fire) - mdMethodDef *pmd) PURE; // [OUT] return method def token - - // Note, void function in v1.0/v1.1 - STDMETHOD(EnumAssociateInit)( - mdToken evprop, // [IN] given a property or an event token - HENUMInternal *phEnum) PURE; // [OUT] cursor to hold the query result - - // returned void in v1.0/v1.1 - STDMETHOD(GetAllAssociates)( - HENUMInternal *phEnum, // [IN] query result form GetPropertyAssociateCounts - ASSOCIATE_RECORD *pAssociateRec, // [OUT] struct to fill for output - ULONG cAssociateRec) PURE; // [IN] size of the buffer - - - //********************************** - // Get info about a PermissionSet. - //********************************** - // returned void in v1.0/v1.1 - STDMETHOD(GetPermissionSetProps)( - mdPermission pm, // [IN] the permission token. - DWORD *pdwAction, // [OUT] CorDeclSecurity. - void const **ppvPermission, // [OUT] permission blob. - ULONG *pcbPermission) PURE; // [OUT] count of bytes of pvPermission. - - //**************************************** - // Get the String given the String token. - // Returns a pointer to the string, or NULL in case of error. - //**************************************** - STDMETHOD(GetUserString)( - mdString stk, // [IN] the string token. - ULONG *pchString, // [OUT] count of characters in the string. - BOOL *pbIs80Plus, // [OUT] specifies where there are extended characters >= 0x80. - LPCWSTR *pwszUserString) PURE; - - //***************************************************************************** - // p-invoke APIs. - //***************************************************************************** - STDMETHOD(GetPinvokeMap)( - mdToken tk, // [IN] FieldDef, MethodDef. - DWORD *pdwMappingFlags, // [OUT] Flags used for mapping. - LPCSTR *pszImportName, // [OUT] Import name. - mdModuleRef *pmrImportDLL) PURE; // [OUT] ModuleRef token for the target DLL. - - //***************************************************************************** - // helpers to convert a text signature to a com format - //***************************************************************************** - STDMETHOD(ConvertTextSigToComSig)( // Return hresult. - BOOL fCreateTrIfNotFound, // [IN] create typeref if not found - LPCSTR pSignature, // [IN] class file format signature - CQuickBytes *pqbNewSig, // [OUT] place holder for CLR signature - ULONG *pcbCount) PURE; // [OUT] the result size of signature - - //***************************************************************************** - // Assembly MetaData APIs. - //***************************************************************************** - // returned void in v1.0/v1.1 - STDMETHOD(GetAssemblyProps)( - mdAssembly mda, // [IN] The Assembly for which to get the properties. - const void **ppbPublicKey, // [OUT] Pointer to the public key. - ULONG *pcbPublicKey, // [OUT] Count of bytes in the public key. - ULONG *pulHashAlgId, // [OUT] Hash Algorithm. - LPCSTR *pszName, // [OUT] Buffer to fill with name. - AssemblyMetaDataInternal *pMetaData,// [OUT] Assembly MetaData. - DWORD *pdwAssemblyFlags) PURE;// [OUT] Flags. - - // returned void in v1.0/v1.1 - STDMETHOD(GetAssemblyRefProps)( - mdAssemblyRef mdar, // [IN] The AssemblyRef for which to get the properties. - const void **ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token. - ULONG *pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token. - LPCSTR *pszName, // [OUT] Buffer to fill with name. - AssemblyMetaDataInternal *pMetaData,// [OUT] Assembly MetaData. - const void **ppbHashValue, // [OUT] Hash blob. - ULONG *pcbHashValue, // [OUT] Count of bytes in the hash blob. - DWORD *pdwAssemblyRefFlags) PURE; // [OUT] Flags. - - // returned void in v1.0/v1.1 - STDMETHOD(GetFileProps)( - mdFile mdf, // [IN] The File for which to get the properties. - LPCSTR *pszName, // [OUT] Buffer to fill with name. - const void **ppbHashValue, // [OUT] Pointer to the Hash Value Blob. - ULONG *pcbHashValue, // [OUT] Count of bytes in the Hash Value Blob. - DWORD *pdwFileFlags) PURE; // [OUT] Flags. - - // returned void in v1.0/v1.1 - STDMETHOD(GetExportedTypeProps)( - mdExportedType mdct, // [IN] The ExportedType for which to get the properties. - LPCSTR *pszNamespace, // [OUT] Namespace. - LPCSTR *pszName, // [OUT] Name. - mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ExportedType. - mdTypeDef *ptkTypeDef, // [OUT] TypeDef token within the file. - DWORD *pdwExportedTypeFlags) PURE; // [OUT] Flags. - - // returned void in v1.0/v1.1 - STDMETHOD(GetManifestResourceProps)( - mdManifestResource mdmr, // [IN] The ManifestResource for which to get the properties. - LPCSTR *pszName, // [OUT] Buffer to fill with name. - mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ExportedType. - DWORD *pdwOffset, // [OUT] Offset to the beginning of the resource within the file. - DWORD *pdwResourceFlags) PURE;// [OUT] Flags. - - STDMETHOD(FindExportedTypeByName)( // S_OK or error - LPCSTR szNamespace, // [IN] Namespace of the ExportedType. - LPCSTR szName, // [IN] Name of the ExportedType. - mdExportedType tkEnclosingType, // [IN] ExportedType for the enclosing class. - mdExportedType *pmct) PURE; // [OUT] Put ExportedType token here. - - STDMETHOD(FindManifestResourceByName)( // S_OK or error - LPCSTR szName, // [IN] Name of the ManifestResource. - mdManifestResource *pmmr) PURE; // [OUT] Put ManifestResource token here. - - STDMETHOD(GetAssemblyFromScope)( // S_OK or error - mdAssembly *ptkAssembly) PURE; // [OUT] Put token here. - - STDMETHOD(GetCustomAttributeByName)( // S_OK or error - mdToken tkObj, // [IN] Object with Custom Attribute. - LPCUTF8 szName, // [IN] Name of desired Custom Attribute. - const void **ppData, // [OUT] Put pointer to data here. - ULONG *pcbData) PURE; // [OUT] Put size of data here. - - // Note: The return type of this method was void in v1 - STDMETHOD(GetTypeSpecFromToken)( // S_OK or error. - mdTypeSpec typespec, // [IN] Signature token. - PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to token. - ULONG *pcbSig) PURE; // [OUT] return size of signature. - - STDMETHOD(SetUserContextData)( // S_OK or E_NOTIMPL - IUnknown *pIUnk) PURE; // The user context. - - STDMETHOD_(BOOL, IsValidToken)( // True or False. - mdToken tk) PURE; // [IN] Given token. - - STDMETHOD(TranslateSigWithScope)( - IMDInternalImport *pAssemImport, // [IN] import assembly scope. - const void *pbHashValue, // [IN] hash value for the import assembly. - ULONG cbHashValue, // [IN] count of bytes in the hash value. - PCCOR_SIGNATURE pbSigBlob, // [IN] signature in the importing scope - ULONG cbSigBlob, // [IN] count of bytes of signature - IMetaDataAssemblyEmit *pAssemEmit, // [IN] assembly emit scope. - IMetaDataEmit *emit, // [IN] emit interface - CQuickBytes *pqkSigEmit, // [OUT] buffer to hold translated signature - ULONG *pcbSig) PURE; // [OUT] count of bytes in the translated signature - - // since SOS does not need to call method below, change return value to IUnknown* (from IMetaModelCommon*) - STDMETHOD_(IUnknown*, GetMetaModelCommon)( // Return MetaModelCommon interface. - ) PURE; - - STDMETHOD_(IUnknown *, GetCachedPublicInterface)(BOOL fWithLock) PURE; // return the cached public interface - STDMETHOD(SetCachedPublicInterface)(IUnknown *pUnk) PURE; // no return value - // since SOS does not use the next 2 methods replace UTSemReadWrite* with void* in the signature - STDMETHOD_(void*, GetReaderWriterLock)() PURE; // return the reader writer lock - STDMETHOD(SetReaderWriterLock)(void * pSem) PURE; - - STDMETHOD_(mdModule, GetModuleFromScope)() PURE; // [OUT] Put mdModule token here. - - - //----------------------------------------------------------------- - // Additional custom methods - - // finding a particular method - STDMETHOD(FindMethodDefUsingCompare)( - mdTypeDef classdef, // [IN] given typedef - LPCSTR szName, // [IN] member name - PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of CLR signature - ULONG cbSigBlob, // [IN] count of bytes in the signature blob - PSIGCOMPARE pSignatureCompare, // [IN] Routine to compare signatures - void* pSignatureArgs, // [IN] Additional info to supply the compare function - mdMethodDef *pmd) PURE; // [OUT] matching memberdef - - // Additional v2 methods. - - //***************************************** - // return a field offset for a given field - //***************************************** - STDMETHOD(GetFieldOffset)( - mdFieldDef fd, // [IN] fielddef - ULONG *pulOffset) PURE; // [OUT] FieldOffset - - STDMETHOD(GetMethodSpecProps)( - mdMethodSpec ms, // [IN] The method instantiation - mdToken *tkParent, // [OUT] MethodDef or MemberRef - PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data - ULONG *pcbSigBlob) PURE; // [OUT] actual size of signature blob - - STDMETHOD(GetTableInfoWithIndex)( - ULONG index, // [IN] pass in the table index - void **pTable, // [OUT] pointer to table at index - void **pTableSize) PURE; // [OUT] size of table at index - - STDMETHOD(ApplyEditAndContinue)( - void *pDeltaMD, // [IN] the delta metadata - ULONG cbDeltaMD, // [IN] length of pData - IMDInternalImport **ppv) PURE; // [OUT] the resulting metadata interface - - //********************************** - // Generics APIs - //********************************** - STDMETHOD(GetGenericParamProps)( // S_OK or error. - mdGenericParam rd, // [IN] The type parameter - ULONG* pulSequence, // [OUT] Parameter sequence number - DWORD* pdwAttr, // [OUT] Type parameter flags (for future use) - mdToken *ptOwner, // [OUT] The owner (TypeDef or MethodDef) - DWORD *reserved, // [OUT] The kind (TypeDef/Ref/Spec, for future use) - LPCSTR *szName) PURE; // [OUT] The name - - STDMETHOD(GetGenericParamConstraintProps)( // S_OK or error. - mdGenericParamConstraint rd, // [IN] The constraint token - mdGenericParam *ptGenericParam, // [OUT] GenericParam that is constrained - mdToken *ptkConstraintType) PURE; // [OUT] TypeDef/Ref/Spec constraint - - //***************************************************************************** - // This function gets the "built for" version of a metadata scope. - // NOTE: if the scope has never been saved, it will not have a built-for - // version, and an empty string will be returned. - //***************************************************************************** - STDMETHOD(GetVersionString)( // S_OK or error. - LPCSTR *pVer) PURE; // [OUT] Put version string here. - - - STDMETHOD(SafeAndSlowEnumCustomAttributeByNameInit)(// return S_FALSE if record not found - mdToken tkParent, // [IN] token to scope the search - LPCSTR szName, // [IN] CustomAttribute's name to scope the search - HENUMInternal *phEnum) PURE; // [OUT] The enumerator - - STDMETHOD(SafeAndSlowEnumCustomAttributeByNameNext)(// return S_FALSE if record not found - mdToken tkParent, // [IN] token to scope the search - LPCSTR szName, // [IN] CustomAttribute's name to scope the search - HENUMInternal *phEnum, // [IN] The enumerator - mdCustomAttribute *mdAttribute) PURE; // [OUT] The custom attribute that was found - - - STDMETHOD(GetTypeDefRefTokenInTypeSpec)(// return S_FALSE if enclosing type does not have a token - mdTypeSpec tkTypeSpec, // [IN] TypeSpec token to look at - mdToken *tkEnclosedToken) PURE; // [OUT] The enclosed type token - -#define MD_STREAM_VER_1X 0x10000 -#define MD_STREAM_VER_2_B1 0x10001 -#define MD_STREAM_VER_2 0x20000 - STDMETHOD_(DWORD, GetMetadataStreamVersion)() PURE; //returns DWORD with major version of - // MD stream in senior word and minor version--in junior word - - STDMETHOD(GetNameOfCustomAttribute)(// S_OK or error - mdCustomAttribute mdAttribute, // [IN] The Custom Attribute - LPCUTF8 *pszNamespace, // [OUT] Namespace of Custom Attribute. - LPCUTF8 *pszName) PURE; // [OUT] Name of Custom Attribute. - - STDMETHOD(SetOptimizeAccessForSpeed)(// S_OK or error - BOOL fOptSpeed) PURE; - - STDMETHOD(SetVerifiedByTrustedSource)(// S_OK or error - BOOL fVerified) PURE; - -}; // IMDInternalImport - -EXTERN_GUID(IID_IMetaDataHelper, 0xad93d71d, 0xe1f2, 0x11d1, 0x94, 0x9, 0x0, 0x0, 0xf8, 0x8, 0x34, 0x60); - -#undef INTERFACE -#define INTERFACE IMetaDataHelper -DECLARE_INTERFACE_(IMetaDataHelper, IUnknown) -{ - // helper functions - // This function is exposing the ability to translate signature from a given - // source scope to a given target scope. - // - STDMETHOD(TranslateSigWithScope)( - IMetaDataAssemblyImport *pAssemImport, // [IN] importing assembly interface - const void *pbHashValue, // [IN] Hash Blob for Assembly. - ULONG cbHashValue, // [IN] Count of bytes. - IMetaDataImport *import, // [IN] importing interface - PCCOR_SIGNATURE pbSigBlob, // [IN] signature in the importing scope - ULONG cbSigBlob, // [IN] count of bytes of signature - IMetaDataAssemblyEmit *pAssemEmit, // [IN] emit assembly interface - IMetaDataEmit *emit, // [IN] emit interface - PCOR_SIGNATURE pvTranslatedSig, // [OUT] buffer to hold translated signature - ULONG cbTranslatedSigMax, - ULONG *pcbTranslatedSig) PURE;// [OUT] count of bytes in the translated signature - - STDMETHOD(GetMetadata)( - ULONG ulSelect, // [IN] Selector. - void **ppData) PURE; // [OUT] Put pointer to data here. - - STDMETHOD_(IUnknown *, GetCachedInternalInterface)(BOOL fWithLock) PURE; // S_OK or error - STDMETHOD(SetCachedInternalInterface)(IUnknown * pUnk) PURE; // S_OK or error - // since SOS does not use the next 2 methods replace UTSemReadWrite* with void* in the signature - STDMETHOD_(void*, GetReaderWriterLock)() PURE; // return the reader writer lock - STDMETHOD(SetReaderWriterLock)(void * pSem) PURE; -}; /********************************************************************************/ @@ -877,13 +73,13 @@ char* asString(CQuickBytes *out); PCCOR_SIGNATURE PrettyPrintType( PCCOR_SIGNATURE typePtr, // type to convert, CQuickBytes *out, // where to put the pretty printed string - IMDInternalImport *pIMDI, // ptr to IMDInternal class with ComSig + IMetaDataImport *pIMDI, // ptr to IMetaDataImport class with ComSig DWORD formatFlags = FormatILDasm); const char* PrettyPrintClass( CQuickBytes *out, // where to put the pretty printed string mdToken tk, // The class token to look up - IMDInternalImport *pIMDI, // ptr to IMDInternalImport class with ComSig + IMetaDataImport *pIMDI, // ptr to IMetaDataImport class with ComSig DWORD formatFlags = FormatILDasm); // We have a proliferation of functions that translate a (module/token) pair to @@ -901,26 +97,5 @@ void PrettyPrintClassFromToken( size_t cbName, // the capacity of the buffer DWORD formatFlags = FormatCSharp); // the format flags for the types -inline HRESULT GetMDInternalFromImport(IMetaDataImport* pIMDImport, IMDInternalImport **ppIMDI) -{ - HRESULT hresult = E_FAIL; - IUnknown *pUnk = NULL; - IMetaDataHelper *pIMDH = NULL; - - IfErrGoTo(pIMDImport->QueryInterface(IID_IMetaDataHelper, (void**)&pIMDH), Cleanup); - pUnk = pIMDH->GetCachedInternalInterface(FALSE); - if (pUnk == NULL) - goto Cleanup; - IfErrGoTo(pUnk->QueryInterface(IID_IMDInternalImport, (void**)ppIMDI), Cleanup); - -Cleanup: - if (pUnk) - pUnk->Release(); - if (pIMDH != NULL) - pIMDH->Release(); - - return hresult; -} - #endif diff --git a/src/SOS/Strike/strike.cpp b/src/SOS/Strike/strike.cpp index 6738487df..c0ce606a0 100644 --- a/src/SOS/Strike/strike.cpp +++ b/src/SOS/Strike/strike.cpp @@ -12853,10 +12853,8 @@ public: ToRelease pMDUnknown; ToRelease pMD; - ToRelease pMDInternal; IfFailRet(pModule->GetMetaDataInterface(IID_IMetaDataImport, &pMDUnknown)); IfFailRet(pMDUnknown->QueryInterface(IID_IMetaDataImport, (LPVOID*) &pMD)); - IfFailRet(GetMDInternalFromImport(pMD, &pMDInternal)); mdTypeDef typeDef; IfFailRet(pClass->GetToken(&typeDef)); diff --git a/src/SOS/Strike/util.h b/src/SOS/Strike/util.h index 944dfcb78..d24c9f657 100644 --- a/src/SOS/Strike/util.h +++ b/src/SOS/Strike/util.h @@ -43,8 +43,6 @@ typedef LPSTR LPUTF8; DECLARE_HANDLE(OBJECTHANDLE); -struct IMDInternalImport; - #if defined(_TARGET_WIN64_) #define WIN64_8SPACES " " #define WIN86_8SPACES "" @@ -1400,8 +1398,6 @@ void NameForToken_s(DWORD_PTR ModuleAddr, mdTypeDef mb, __out_ecount (capacity_m bool bClassName=true); HRESULT NameForToken_s(mdTypeDef mb, IMetaDataImport *pImport, __out_ecount (capacity_mdName) WCHAR *mdName, size_t capacity_mdName, bool bClassName); -HRESULT NameForTokenNew_s(mdTypeDef mb, IMDInternalImport *pImport, __out_ecount (capacity_mdName) WCHAR *mdName, size_t capacity_mdName, - bool bClassName); void vmmap(); void vmstat(); @@ -3153,4 +3149,5 @@ private: HRESULT PrintCurrentInternalFrame(); }; +#include "sigparser.h" #endif // __util_h__