public ByteBuffer PatchRawMethodBody(MethodDefinition method, CodeWriter writer, out MethodSymbols symbols) { var buffer = new ByteBuffer (); symbols = new MethodSymbols (method.Name); this.method = method; reader.context = method; MoveTo (method.RVA); var flags = ReadByte (); MetadataToken local_var_token; switch (flags & 0x3) { case 0x2: // tiny buffer.WriteByte (flags); local_var_token = MetadataToken.Zero; symbols.code_size = flags >> 2; PatchRawCode (buffer, symbols.code_size, writer); break; case 0x3: // fat base.position--; PatchRawFatMethod (buffer, symbols, writer, out local_var_token); break; default: throw new NotSupportedException (); } var symbol_reader = reader.module.SymbolReader; if (symbol_reader != null && writer.metadata.write_symbols) { symbols.method_token = GetOriginalToken (writer.metadata, method); symbols.local_var_token = local_var_token; symbol_reader.Read (symbols); } return buffer; }
void PatchRawCode(ByteBuffer buffer, int code_size, CodeWriter writer) { var metadata = writer.metadata; buffer.WriteBytes (ReadBytes (code_size)); var end = buffer.position; buffer.position -= code_size; while (buffer.position < end) { OpCode opcode; var il_opcode = buffer.ReadByte (); if (il_opcode != 0xfe) { opcode = OpCodes.OneByteOpCode [il_opcode]; } else { var il_opcode2 = buffer.ReadByte (); opcode = OpCodes.TwoBytesOpCode [il_opcode2]; } switch (opcode.OperandType) { case OperandType.ShortInlineI: case OperandType.ShortInlineBrTarget: case OperandType.ShortInlineVar: case OperandType.ShortInlineArg: buffer.position += 1; break; case OperandType.InlineVar: case OperandType.InlineArg: buffer.position += 2; break; case OperandType.InlineBrTarget: case OperandType.ShortInlineR: case OperandType.InlineI: buffer.position += 4; break; case OperandType.InlineI8: case OperandType.InlineR: buffer.position += 8; break; case OperandType.InlineSwitch: var length = buffer.ReadInt32 (); buffer.position += length * 4; break; case OperandType.InlineString: var @string = GetString (new MetadataToken (buffer.ReadUInt32 ())); buffer.position -= 4; buffer.WriteUInt32 ( new MetadataToken ( TokenType.String, metadata.user_string_heap.GetStringIndex (@string)).ToUInt32 ()); break; case OperandType.InlineSig: var call_site = GetCallSite (new MetadataToken (buffer.ReadUInt32 ())); buffer.position -= 4; buffer.WriteUInt32 (writer.GetStandAloneSignature (call_site).ToUInt32 ()); break; case OperandType.InlineTok: case OperandType.InlineType: case OperandType.InlineMethod: case OperandType.InlineField: var provider = reader.LookupToken (new MetadataToken (buffer.ReadUInt32 ())); buffer.position -= 4; buffer.WriteUInt32 (metadata.LookupToken (provider).ToUInt32 ()); break; } } }
void PatchRawFatMethod(ByteBuffer buffer, MethodSymbols symbols, CodeWriter writer, out MetadataToken local_var_token) { var flags = ReadUInt16 (); buffer.WriteUInt16 (flags); buffer.WriteUInt16 (ReadUInt16 ()); symbols.code_size = ReadInt32 (); buffer.WriteInt32 (symbols.code_size); local_var_token = ReadToken (); if (local_var_token.RID > 0) { var variables = symbols.variables = ReadVariables (local_var_token); buffer.WriteUInt32 (variables != null ? writer.GetStandAloneSignature (symbols.variables).ToUInt32 () : 0); } else buffer.WriteUInt32 (0); PatchRawCode (buffer, symbols.code_size, writer); if ((flags & 0x8) != 0) PatchRawSection (buffer, writer.metadata); }
public ByteBuffer PatchRawMethodBody(MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token) { var position = MoveTo (method); var buffer = new ByteBuffer (); var flags = ReadByte (); switch (flags & 0x3) { case 0x2: // tiny buffer.WriteByte (flags); local_var_token = MetadataToken.Zero; code_size = flags >> 2; PatchRawCode (buffer, code_size, writer); break; case 0x3: // fat Advance (-1); PatchRawFatMethod (buffer, writer, out code_size, out local_var_token); break; default: throw new NotSupportedException (); } MoveBackTo (position); return buffer; }
void Initialize() { m_mdWriter = new MetadataWriter ( m_mod.Assembly, m_mod.Image.MetadataRoot, m_structureWriter.Assembly.Kind, m_mod.Assembly.Runtime, m_structureWriter.GetWriter ()); m_tableWriter = m_mdWriter.GetTableVisitor (); m_rowWriter = m_tableWriter.GetRowVisitor () as MetadataRowWriter; m_sigWriter = new SignatureWriter (m_mdWriter); m_codeWriter = new CodeWriter (this, m_mdWriter.CilWriter); m_typeDefStack = new ArrayList (); m_methodStack = new ArrayList (); m_fieldStack = new ArrayList (); m_genericParamStack = new ArrayList (); m_typeSpecCache = new Hashtable (); m_methodIndex = 1; m_fieldIndex = 1; m_paramIndex = 1; m_eventIndex = 1; m_propertyIndex = 1; m_constWriter = new MemoryBinaryWriter (); }
public static byte[] ToBytes(MethodDefinition method) { CodeWriter cw = new CodeWriter(method); return cw.WriteMethodBody(); }
void PatchRawCode(ByteBuffer buffer, int code_size, CodeWriter writer) { var metadata = writer.metadata; buffer.WriteBytes(ReadBytes(code_size)); var end = buffer.position; buffer.position -= code_size; while (buffer.position < end) { OpCode opcode; var il_opcode = buffer.ReadByte(); if (il_opcode != 0xfe) { opcode = OpCodes.OneByteOpCode[il_opcode]; } else { var il_opcode2 = buffer.ReadByte(); opcode = OpCodes.TwoBytesOpCode[il_opcode2]; } switch (opcode.OperandType) { case OperandType.ShortInlineI: case OperandType.ShortInlineBrTarget: case OperandType.ShortInlineVar: case OperandType.ShortInlineArg: buffer.position += 1; break; case OperandType.InlineVar: case OperandType.InlineArg: buffer.position += 2; break; case OperandType.InlineBrTarget: case OperandType.ShortInlineR: case OperandType.InlineI: buffer.position += 4; break; case OperandType.InlineI8: case OperandType.InlineR: buffer.position += 8; break; case OperandType.InlineSwitch: var length = buffer.ReadInt32(); buffer.position += length * 4; break; case OperandType.InlineString: var @string = GetString(new MetadataToken(buffer.ReadUInt32())); buffer.position -= 4; buffer.WriteUInt32( new MetadataToken( TokenType.String, metadata.user_string_heap.GetStringIndex(@string)).ToUInt32()); break; case OperandType.InlineSig: var call_site = GetCallSite(new MetadataToken(buffer.ReadUInt32())); buffer.position -= 4; buffer.WriteUInt32(writer.GetStandAloneSignature(call_site).ToUInt32()); break; case OperandType.InlineTok: case OperandType.InlineType: case OperandType.InlineMethod: case OperandType.InlineField: var provider = reader.LookupToken(new MetadataToken(buffer.ReadUInt32())); buffer.position -= 4; buffer.WriteUInt32(metadata.LookupToken(provider).ToUInt32()); break; } } }
private void WriteOperand(Instruction instruction) { OpCode opCode = instruction.opcode; OperandType operandType = opCode.OperandType; if (operandType == OperandType.InlineNone) { return; } object obj = instruction.operand; if (obj == null) { throw new ArgumentException(); } switch (operandType) { case OperandType.InlineBrTarget: { Instruction instruction1 = (Instruction)obj; base.WriteInt32(this.GetTargetOffset(instruction1) - (instruction.Offset + opCode.Size + 4)); return; } case OperandType.InlineField: case OperandType.InlineMethod: case OperandType.InlineTok: case OperandType.InlineType: { this.WriteMetadataToken(this.metadata.LookupToken((IMetadataTokenProvider)obj)); return; } case OperandType.InlineI: { base.WriteInt32((int)obj); return; } case OperandType.InlineI8: { base.WriteInt64((long)obj); return; } case OperandType.InlineNone: case OperandType.InlinePhi: { throw new ArgumentException(); } case OperandType.InlineR: { base.WriteDouble((double)obj); return; } case OperandType.InlineSig: { this.WriteMetadataToken(this.GetStandAloneSignature((Mono.Cecil.CallSite)obj)); return; } case OperandType.InlineString: { this.WriteMetadataToken(new MetadataToken(Mono.Cecil.TokenType.String, this.GetUserStringIndex((string)obj))); return; } case OperandType.InlineSwitch: { Instruction[] instructionArray = (Instruction[])obj; base.WriteInt32((int)instructionArray.Length); int offset = instruction.Offset + opCode.Size + 4 * ((int)instructionArray.Length + 1); for (int i = 0; i < (int)instructionArray.Length; i++) { base.WriteInt32(this.GetTargetOffset(instructionArray[i]) - offset); } return; } case OperandType.InlineVar: { base.WriteInt16((short)CodeWriter.GetVariableIndex((VariableDefinition)obj)); return; } case OperandType.InlineArg: { base.WriteInt16((short)this.GetParameterIndex((ParameterDefinition)obj)); return; } case OperandType.ShortInlineBrTarget: { Instruction instruction2 = (Instruction)obj; base.WriteSByte((sbyte)(this.GetTargetOffset(instruction2) - (instruction.Offset + opCode.Size + 1))); return; } case OperandType.ShortInlineI: { if (opCode == OpCodes.Ldc_I4_S) { base.WriteSByte((sbyte)obj); return; } base.WriteByte((byte)obj); return; } case OperandType.ShortInlineR: { base.WriteSingle((float)obj); return; } case OperandType.ShortInlineVar: { base.WriteByte((byte)CodeWriter.GetVariableIndex((VariableDefinition)obj)); return; } case OperandType.ShortInlineArg: { base.WriteByte((byte)this.GetParameterIndex((ParameterDefinition)obj)); return; } default: { throw new ArgumentException(); } } }