public ILToCilRecompiler(CilMethodBody methodBody, MetadataImage targetImage, IVMFunctionResolver exportResolver) { _context = new RecompilerContext(methodBody, targetImage, this, exportResolver); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow<EventAttributes, uint, uint> row) { return new EventDefinition(image, row); }
/// <summary> /// Reads a single by-reference type signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the signature is defined in.</param> /// <param name="reader">The reader to use.</param> /// <returns>The read signature.</returns> public static ByReferenceTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader) { return(FromReader(image, reader, new RecursionProtection())); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <FileSegment, MethodImplAttributes, MethodAttributes, uint, uint, uint> row) { return(new MethodDefinition(image, row)); }
public new static PointerTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader) { long position = reader.Position; return(new PointerTypeSignature(TypeSignature.FromReader(image, reader))); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, uint> row) { return(new FieldMarshal(image, row)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, uint> row) { return(new MethodSpecification(image, row)); }
private static IFrameLayout InferLayoutFromCallReference(MetadataImage image, FunctionReference reference) { // This is kind of a hack, but works perfectly fine for vanilla KoiVM. // // Vanilla KoiVM uses the calling convention where the caller cleans up the stack after the call. // The assumption is that each post-call code of the function is using the default calling convention is // in some variation of the following code: // // CALL ; Original call instruction. // // PUSHR_xxxx R0 ; Only present if the function returns something. // POP R0 // // PUSHR_DWORD SP ; Clean up of arguments on the stack. // PUSHI_DWORD <number of parameters> // ADD_DWORD // POP SP // // Note that forks can deviate from this. // // Find the POP SP instruction. bool returnsValue = false; int currentOffset = reference.Offset; ILInstruction instruction; do { if (!reference.Caller.Instructions.TryGetValue(currentOffset, out instruction)) { throw new FrameLayoutDetectionException( $"Could not infer the number of arguments of function_{reference.Callee.EntrypointAddress:X4} " + $"due to an incomplete or unsupported post-call of IL_{reference.Offset:X4} (function_{reference.Caller.EntrypointAddress:X4}).", new DisassemblyException( $"Offset IL_{currentOffset:X4} is not disassembled or does not belong to function_{reference.Caller.EntrypointAddress:X4}.")); } switch (instruction.OpCode.Code) { case ILCode.PUSHR_BYTE: case ILCode.PUSHR_WORD: case ILCode.PUSHR_DWORD: case ILCode.PUSHR_QWORD: case ILCode.PUSHR_OBJECT: if ((VMRegisters)instruction.Operand == VMRegisters.R0) { returnsValue = true; } break; } currentOffset += instruction.Size; } while (instruction.OpCode.Code != ILCode.POP || (VMRegisters)instruction.Operand != VMRegisters.SP); // The number of arguments pushed onto the stack is the number of values implicitly popped from the stack // at this POP SP instruction. int argumentCount = instruction.Annotation.InferredPopCount - 1; return(new DefaultFrameLayout( image, Enumerable.Repeat <TypeSignature>(null, argumentCount).ToList(), Array.Empty <TypeSignature>(), returnsValue ? image.TypeSystem.Object : image.TypeSystem.Void, false)); }
private static IFrameLayout InferLayoutFromLdftnReference(VMConstants constants, MetadataImage image, FunctionReference reference) { // LDFTN instructions reference a physical method, or an export defined in the export table containing // the signature of an intra-linked method. We can therefore reliably extract the necessary information // without too much guessing. var ldftn = reference.Caller.Instructions[reference.Offset]; var annotation = (LdftnAnnotation)ldftn.Annotation; var parameterTypes = new List <TypeSignature>(); TypeSignature returnType; bool hasThis; if (annotation.IsIntraLinked) { returnType = ((ITypeDefOrRef)image.ResolveMember(annotation.Signature.ReturnToken)) .ToTypeSignature(); foreach (var token in annotation.Signature.ParameterTokens) { parameterTypes.Add(((ITypeDefOrRef)image.ResolveMember(token)) .ToTypeSignature()); } hasThis = (annotation.Signature.Flags & constants.FlagInstance) != 0; } else { var methodSig = (MethodSignature)annotation.Method.Signature; foreach (var parameter in methodSig.Parameters) { parameterTypes.Add(parameter.ParameterType); } returnType = methodSig.ReturnType; hasThis = methodSig.HasThis; } return(new DefaultFrameLayout( image, parameterTypes, Array.Empty <TypeSignature>(), returnType, hasThis)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <ushort, GenericParameterAttributes, uint, uint> row) { return(new GenericParameter(image, row)); }
protected virtual MetadataBuffer CreateBuffer(MetadataImage image) { return(new MetadataBuffer(image)); }
/// <summary> /// Reads a single array type signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the array was defined in.</param> /// <param name="reader">The reader to use.</param> /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param> /// <returns>The read array.</returns> public static ArrayTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader, RecursionProtection protection) { var signature = new ArrayTypeSignature(TypeSignature.FromReader(image, reader, false, protection)); // Rank if (!reader.TryReadCompressedUInt32(out uint rank)) { return(signature); } // Sizes. if (!reader.TryReadCompressedUInt32(out uint numSizes)) { return(signature); } var sizes = new List <uint>(); for (int i = 0; i < numSizes; i++) { if (!reader.TryReadCompressedUInt32(out uint size)) { return(signature); } sizes.Add(size); } // Lower bounds. if (!reader.TryReadCompressedUInt32(out uint numLoBounds)) { return(signature); } var loBounds = new List <uint>(); for (int i = 0; i < numLoBounds; i++) { if (!reader.TryReadCompressedUInt32(out uint bound)) { return(signature); } loBounds.Add(bound); } // Create dimensions. for (int i = 0; i < rank; i++) { var dimension = new ArrayDimension(); if (i < numSizes) { dimension.Size = (int)sizes[i]; } if (i < numLoBounds) { dimension.LowerBound = (int)loBounds[i]; } signature.Dimensions.Add(dimension); } return(signature); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, uint> row) { throw new System.NotImplementedException(); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <ImplementationMapAttributes, uint, uint, uint> row) { return(new ImplementationMap(image, row)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, ManifestResourceAttributes, uint, uint> row) { return(new ManifestResource(image, row)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, uint> row) { return(new NestedClass(image, row)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint> row) { return(new AssemblyProcessor(image, row)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint> row) { return(new StandAloneSignature(image, row)); }
/// <summary> /// Reads a single annotated type signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the signature resides in.</param> /// <param name="reader">The reader to use.</param> /// <returns>The read signature.</returns> public static OptionalModifierSignature FromReader(MetadataImage image, IBinaryStreamReader reader) { return(FromReader(image, reader, new RecursionProtection())); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <ParameterAttributes, ushort, uint> row) { return(new ParameterDefinition(image, row)); }
/// <summary> /// Reads a single method signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the field is defined in.</param> /// <param name="reader">The reader to use.</param> /// <param name="readToEnd">Determines whether any extra data after the signature should be read and /// put into the <see cref="ExtendableBlobSignature.ExtraData"/> property.</param> /// <returns>The read signature.</returns> public new static MethodSignature FromReader(MetadataImage image, IBinaryStreamReader reader, bool readToEnd = false) { return(FromReader(image, reader, readToEnd, new RecursionProtection())); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, uint> row) { return(new PropertyMap(image, row)); }
public new static SzArrayTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader) { return(new SzArrayTypeSignature(TypeSignature.FromReader(image, reader))); }
private static object ReadValue(MetadataImage image, TypeSignature typeSignature, IBinaryStreamReader reader) { switch (typeSignature.ElementType) { case ElementType.Boolean: return(reader.ReadByte() == 1); case ElementType.Char: return((char)reader.ReadUInt16()); case ElementType.R4: return(reader.ReadSingle()); case ElementType.R8: return(reader.ReadDouble()); case ElementType.I1: return(reader.ReadSByte()); case ElementType.I2: return(reader.ReadInt16()); case ElementType.I4: return(reader.ReadInt32()); case ElementType.I8: return(reader.ReadInt64()); case ElementType.U1: return(reader.ReadByte()); case ElementType.U2: return(reader.ReadUInt16()); case ElementType.U4: return(reader.ReadUInt32()); case ElementType.U8: return(reader.ReadUInt64()); case ElementType.String: return(reader.ReadSerString()); case ElementType.Object: return(ReadValue(image, TypeSignature.ReadFieldOrPropType(image, reader), reader)); case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = image.MetadataResolver.ResolveType(typeSignature); if (enumTypeDef == null) { throw new MemberResolutionException(typeSignature); } if (enumTypeDef.IsEnum) { return(ReadValue(image, enumTypeDef.GetEnumUnderlyingType(), reader)); } break; } if (typeSignature.IsTypeOf("System", "Type")) { return(TypeSignature.FromAssemblyQualifiedName(image, reader.ReadSerString())); } throw new NotSupportedException("Unsupported element type " + typeSignature.ElementType); }
/// <summary> /// Reads a single boxed type signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the signature is defined in.</param> /// <param name="reader">The reader to use.</param> /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param> /// <returns>The read signature.</returns> public static BoxedTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader, RecursionProtection protection) { return(new BoxedTypeSignature(TypeSignature.FromReader(image, reader, false, protection))); }
public static ElementSignature FromReader(MetadataImage image, TypeSignature typeSignature, IBinaryStreamReader reader) { return(new ElementSignature(ReadValue(image, typeSignature, reader))); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <DataSegment, uint> row) { return(new FieldRva(image, row)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, uint> row) { return(new GenericParameterConstraint(image, row)); }
protected override IMetadataMember CreateMemberFromRow(MetadataImage image, MetadataRow <uint, uint, uint> row) { return(new MemberReference(image, row)); }
/// <summary> /// Reads a single generic parameter signature at the current position of the provided stream reader. /// </summary> /// <param name="image">The image the parameter was defined in.</param> /// <param name="reader">The reader to use.</param> /// <param name="parameterType">Determines whether the parameter signature is referencing a type parameter from the enclosing method or type.</param> /// <returns>The read signature.</returns> public static GenericParameterSignature FromReader(MetadataImage image, IBinaryStreamReader reader, GenericParameterType parameterType) { return(reader.TryReadCompressedUInt32(out uint index) ? new GenericParameterSignature(parameterType, (int)index) : null); }