/// <summary> /// Initialize non-generic R2RMethods with method signatures from MethodDefHandle, and runtime function indices from MethodDefEntryPoints /// </summary> private void ParseMethodDefEntrypoints(bool[] isEntryPoint) { if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS)) { return; } int methodDefEntryPointsRVA = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS].RelativeVirtualAddress; int methodDefEntryPointsOffset = GetOffset(methodDefEntryPointsRVA); NativeArray methodEntryPoints = new NativeArray(Image, (uint)methodDefEntryPointsOffset); uint nMethodEntryPoints = methodEntryPoints.GetCount(); for (uint rid = 1; rid <= nMethodEntryPoints; rid++) { int offset = 0; if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset)) { EntityHandle methodHandle = MetadataTokens.MethodDefinitionHandle((int)rid); int runtimeFunctionId; FixupCell[] fixups; GetRuntimeFunctionIndexFromOffset(offset, out runtimeFunctionId, out fixups); R2RMethod method = new R2RMethod(R2RMethods.Count, this.MetadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixups: fixups); if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= isEntryPoint.Length) { throw new BadImageFormatException("EntryPointRuntimeFunctionId out of bounds"); } isEntryPoint[method.EntryPointRuntimeFunctionId] = true; R2RMethods.Add(method); } } }
public RuntimeFunction( int id, int startRva, int endRva, int unwindRva, int codeOffset, R2RMethod method, BaseUnwindInfo unwindInfo, BaseGcInfo gcInfo, EHInfo ehInfo, DebugInfo debugInfo) { Id = id; StartAddress = startRva; UnwindRVA = unwindRva; Method = method; UnwindInfo = unwindInfo; DebugInfo = debugInfo; if (endRva != -1) { Size = endRva - startRva; } else if (unwindInfo is x86.UnwindInfo) { Size = (int)((x86.UnwindInfo)unwindInfo).FunctionLength; } else if (unwindInfo is Arm.UnwindInfo) { Size = (int)((Arm.UnwindInfo)unwindInfo).FunctionLength; } else if (unwindInfo is Arm64.UnwindInfo) { Size = (int)((Arm64.UnwindInfo)unwindInfo).FunctionLength; } else if (gcInfo != null) { Size = gcInfo.CodeLength; } else { Size = -1; } CodeOffset = codeOffset; method.GcInfo = gcInfo; EHInfo = ehInfo; }
public InstanceMethod(byte bucket, R2RMethod method) { Bucket = bucket; Method = method; }
/// <summary> /// Initialize generic method instances with argument types and runtime function indices from InstanceMethodEntrypoints /// </summary> private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint) { if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS)) { return; } R2RSection instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS]; int instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress); NativeParser parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset); NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser, (uint)(instMethodEntryPointsOffset + instMethodEntryPointSection.Size)); NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries(); NativeParser curParser = allEntriesEnum.GetNext(); while (!curParser.IsNull()) { SignatureDecoder decoder = new SignatureDecoder(_assemblyResolver, this, (int)curParser.Offset); MetadataReader mdReader = MetadataReader; string owningType = null; uint methodFlags = decoder.ReadUInt(); if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { mdReader = decoder.GetMetadataReaderFromModuleOverride(); owningType = decoder.ReadTypeSignatureNoEmit(); } if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0) { throw new NotImplementedException(); } EntityHandle methodHandle; int rid = (int)decoder.ReadUInt(); if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken) != 0) { methodHandle = MetadataTokens.MemberReferenceHandle(rid); } else { methodHandle = MetadataTokens.MethodDefinitionHandle(rid); } string[] methodTypeArgs = null; if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0) { uint typeArgCount = decoder.ReadUInt(); methodTypeArgs = new string[typeArgCount]; for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++) { methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignatureNoEmit(); } } string constrainedType = null; if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0) { constrainedType = decoder.ReadTypeSignatureNoEmit(); } int runtimeFunctionId; FixupCell[] fixups; GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixups); R2RMethod method = new R2RMethod( R2RMethods.Count, mdReader == null ? MetadataReader : mdReader, methodHandle, runtimeFunctionId, owningType, constrainedType, methodTypeArgs, fixups); if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length) { isEntryPoint[method.EntryPointRuntimeFunctionId] = true; } R2RMethods.Add(method); InstanceMethods.Add(new InstanceMethod(curParser.LowHashcode, method)); curParser = allEntriesEnum.GetNext(); } }