Skip to content

Commit bbdfe2a

Browse files
authored
Merge pull request #1764 from JetBrains/corDebugElementTypes
Handle some other COR_ELEMENT_TYPES to avoid exceptions in ReadType
2 parents 1ed52e6 + 24d3bcf commit bbdfe2a

File tree

3 files changed

+90
-17
lines changed

3 files changed

+90
-17
lines changed

CorApi/ICorDebugWrappers.cs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ public enum CorDebugUserState
156156
USER_UNSAFE_POINT = 0x80
157157
}
158158

159-
// [Xamarin] Expression evaluator.
160-
[CLSCompliant(true)]
159+
// [Xamarin] Expression evaluator.
160+
[CLSCompliant (true)]
161161
[Flags]
162162
public enum CorElementType
163163
{
@@ -171,7 +171,7 @@ public enum CorElementType
171171
ELEMENT_TYPE_CMOD_REQD = 0x1f,
172172
ELEMENT_TYPE_END = 0,
173173
ELEMENT_TYPE_FNPTR = 0x1b,
174-
ELEMENT_TYPE_GENERICINST = 0x15,
174+
ELEMENT_TYPE_GENERICINST = 0x15,
175175
ELEMENT_TYPE_I = 0x18,
176176
ELEMENT_TYPE_I1 = 4,
177177
ELEMENT_TYPE_I2 = 6,
@@ -180,13 +180,13 @@ public enum CorElementType
180180
ELEMENT_TYPE_INTERNAL = 0x21,
181181
ELEMENT_TYPE_MAX = 0x22,
182182
ELEMENT_TYPE_MODIFIER = 0x40,
183-
ELEMENT_TYPE_MVAR = 0x1e,
183+
ELEMENT_TYPE_MVAR = 0x1e,
184184
ELEMENT_TYPE_OBJECT = 0x1c,
185-
ELEMENT_TYPE_PINNED = 0x45,
185+
ELEMENT_TYPE_PINNED = 0x05 | ELEMENT_TYPE_MODIFIER,
186186
ELEMENT_TYPE_PTR = 15,
187187
ELEMENT_TYPE_R4 = 12,
188188
ELEMENT_TYPE_R8 = 13,
189-
ELEMENT_TYPE_SENTINEL = 0x41,
189+
ELEMENT_TYPE_SENTINEL = 0x01 | ELEMENT_TYPE_MODIFIER,
190190
ELEMENT_TYPE_STRING = 14,
191191
ELEMENT_TYPE_SZARRAY = 0x1d,
192192
ELEMENT_TYPE_TYPEDBYREF = 0x16,
@@ -196,8 +196,37 @@ public enum CorElementType
196196
ELEMENT_TYPE_U4 = 9,
197197
ELEMENT_TYPE_U8 = 11,
198198
ELEMENT_TYPE_VALUETYPE = 0x11,
199-
ELEMENT_TYPE_VAR = 0x13,
200-
ELEMENT_TYPE_VOID = 1
199+
ELEMENT_TYPE_VAR = 0x13,
200+
ELEMENT_TYPE_VOID = 1,
201+
202+
203+
// from corpriv.h (CoreCLR sources)
204+
205+
// ZAPSIG types
206+
// ZapSig encoding for ELEMENT_TYPE_VAR and ELEMENT_TYPE_MVAR. It is always followed
207+
// by the RID of a GenericParam token, encoded as a compressed integer.
208+
ELEMENT_TYPE_VAR_ZAPSIG = 0x3b,
209+
210+
// ZapSig encoding for an array MethodTable to allow it to remain such after decoding
211+
// (rather than being transformed into the TypeHandle representing that array)
212+
//
213+
// The element is always followed by ELEMENT_TYPE_SZARRAY or ELEMENT_TYPE_ARRAY
214+
ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG = 0x3c,
215+
216+
// ZapSig encoding for native value types in IL stubs. IL stub signatures may contain
217+
// ELEMENT_TYPE_INTERNAL followed by ParamTypeDesc with ELEMENT_TYPE_VALUETYPE element
218+
// type. It acts like a modifier to the underlying structure making it look like its
219+
// unmanaged view (size determined by unmanaged layout, blittable, no GC pointers).
220+
//
221+
// ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG is used when encoding such types to NGEN images.
222+
// The signature looks like this: ET_NATIVE_VALUETYPE_ZAPSIG ET_VALUETYPE <token>.
223+
// See code:ZapSig.GetSignatureForTypeHandle and code:SigPointer.GetTypeHandleThrowing
224+
// where the encoding/decoding takes place.
225+
ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG = 0x3d,
226+
227+
ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for [mscorlib]System.__Canon
228+
ELEMENT_TYPE_MODULE_ZAPSIG = 0x3f, // zapsig encoding for external module id#
229+
201230
}
202231

203232
#region Top-level interfaces

CorApi2/Extensions/MetadataExtensions.cs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,13 @@ static MetadataHelperFunctionsExtensions ()
136136
CoreTypes.Add (CorElementType.ELEMENT_TYPE_U, typeof (UIntPtr));
137137
}
138138

139-
internal static void ReadMethodSignature (IMetadataImport importer, Instantiation instantiation, ref IntPtr pData, out CorCallingConvention cconv, out Type retType, out List<Type> argTypes)
139+
internal static void ReadMethodSignature (IMetadataImport importer, Instantiation instantiation, ref IntPtr pData, out CorCallingConvention cconv, out Type retType, out List<Type> argTypes, out int sentinelIndex)
140140
{
141141
cconv = MetadataHelperFunctions.CorSigUncompressCallingConv (ref pData);
142142
uint numArgs = 0;
143143
// FIXME: Use number of <T>s.
144144
uint types = 0;
145+
sentinelIndex = -1;
145146
if ((cconv & CorCallingConvention.Generic) == CorCallingConvention.Generic)
146147
types = MetadataHelperFunctions.CorSigUncompressData (ref pData);
147148

@@ -150,8 +151,25 @@ internal static void ReadMethodSignature (IMetadataImport importer, Instantiatio
150151

151152
retType = ReadType (importer, instantiation, ref pData);
152153
argTypes = new List<Type> ();
153-
for (int n = 0; n < numArgs; n++)
154+
for (int n = 0; n < numArgs; n++) {
155+
CorElementType elemType;
156+
unsafe {
157+
var pByte = (byte*) pData;
158+
var b = *pByte;
159+
elemType = (CorElementType) b;
160+
161+
if (elemType == CorElementType.ELEMENT_TYPE_SENTINEL) {
162+
// the case when SENTINEL is presented in a separate position, so we have to increment the pointer
163+
sentinelIndex = n;
164+
pData = (IntPtr) (pByte + 1);
165+
}
166+
else if ((elemType & CorElementType.ELEMENT_TYPE_SENTINEL) == CorElementType.ELEMENT_TYPE_SENTINEL) {
167+
// SENTINEL is just a flag on element type, so we haven't to promote the pointer
168+
sentinelIndex = n;
169+
}
170+
}
154171
argTypes.Add (ReadType (importer, instantiation, ref pData));
172+
}
155173
}
156174

157175
static Type ReadType (IMetadataImport importer, Instantiation instantiation, ref IntPtr pData)
@@ -163,6 +181,10 @@ static Type ReadType (IMetadataImport importer, Instantiation instantiation, ref
163181
pData = (IntPtr) (pBytes + 1);
164182
}
165183

184+
if ((et & CorElementType.ELEMENT_TYPE_SENTINEL) == CorElementType.ELEMENT_TYPE_SENTINEL) {
185+
et ^= CorElementType.ELEMENT_TYPE_SENTINEL; // substract SENTINEL bits from element type to get clean ET
186+
}
187+
166188
switch (et)
167189
{
168190
case CorElementType.ELEMENT_TYPE_VOID: return typeof (void);
@@ -252,13 +274,26 @@ static Type ReadType (IMetadataImport importer, Instantiation instantiation, ref
252274
CorCallingConvention cconv;
253275
Type retType;
254276
List<Type> argTypes;
255-
ReadMethodSignature (importer, instantiation, ref pData, out cconv, out retType, out argTypes);
277+
int sentinelIndex;
278+
ReadMethodSignature (importer, instantiation, ref pData, out cconv, out retType, out argTypes, out sentinelIndex);
256279
return MetadataExtensions.MakeDelegate (retType, argTypes);
257280
}
258281

259282
case CorElementType.ELEMENT_TYPE_CMOD_REQD:
260-
case CorElementType.ELEMENT_TYPE_CMOD_OPT:
283+
case CorElementType.ELEMENT_TYPE_CMOD_OPT: {
284+
uint token = MetadataHelperFunctions.CorSigUncompressToken (ref pData);
285+
return new MetadataType (importer, (int) token);
286+
}
287+
288+
case CorElementType.ELEMENT_TYPE_INTERNAL:
289+
return typeof(object); // hack to avoid the exceptions. CLR spec says that this type should never occurs, but it occurs sometimes, mystics
290+
291+
case CorElementType.ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG:
292+
case CorElementType.ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG:
261293
return ReadType (importer, instantiation, ref pData);
294+
295+
case CorElementType.ELEMENT_TYPE_CANON_ZAPSIG:
296+
return typeof(object); // this is representation of __Canon type, but it's inaccessible, using object instead
262297
}
263298
throw new NotSupportedException ("Unknown sig element type: " + et);
264299
}

CorApi2/Metadata/CorMetadata.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ internal MetadataMethodInfo(IMetadataImport importer, int methodToken, Instantia
304304

305305
// [Xamarin] Expression evaluator.
306306
CorCallingConvention callingConv;
307-
MetadataHelperFunctionsExtensions.ReadMethodSignature (importer, instantiation, ref ppvSigBlob, out callingConv, out m_retType, out m_argTypes);
307+
MetadataHelperFunctionsExtensions.ReadMethodSignature (importer, instantiation, ref ppvSigBlob, out callingConv, out m_retType, out m_argTypes, out m_sentinelIndex);
308308
m_name = szMethodName.ToString();
309309
m_methodAttributes = (MethodAttributes)pdwAttr;
310310
}
@@ -456,15 +456,24 @@ public string[] GetGenericArgumentNames()
456456
return MetadataHelperFunctions.GetGenericArgumentNames(m_importer,m_methodToken);
457457
}
458458

459+
public int VarargStartIndex
460+
{
461+
get
462+
{
463+
return m_sentinelIndex;
464+
}
465+
}
466+
459467
private IMetadataImport m_importer;
460468
private string m_name;
461469
private int m_classToken;
462470
private int m_methodToken;
463471
private MethodAttributes m_methodAttributes;
464-
// [Xamarin] Expression evaluator.
465-
private List<Type> m_argTypes;
466-
private Type m_retType;
467-
private object[] m_customAttributes;
472+
// [Xamarin] Expression evaluator.
473+
private List<Type> m_argTypes;
474+
private Type m_retType;
475+
private object[] m_customAttributes;
476+
private int m_sentinelIndex;
468477
}
469478

470479
public enum MetadataTokenType

0 commit comments

Comments
 (0)