private static TryCatchBlock CreateTryBlock(ILStream code, int tryOffset, int tryLength) { int entryIndex = code.GetOffsetIndex(tryOffset); int exitIndex = GetIndex(code, tryOffset, tryLength); var tryBlock = new TryCatchBlock { EntryPoint = code[entryIndex], ExitPoint = code[exitIndex] }; return(tryBlock); }
private static int GetIndex(ILStream code, int offset, int length) { int index = code.GetOffsetIndex(offset + length); if (index == code.Count - 1) { return(index); } index--; return(index >= 0 ? index : code.Count - 1); }
public void SetupInstructions(ILStream code) { Code = code; for (int i = EntryIndex; i <= ExitIndex; ++i) { var instr = code[i]; if (instr.SehBlock == null) { instr.SehBlock = this; VisitInstruction(instr); } } }
private static void SetupInstructions(ILStream code, Block block) { foreach (var kid in block.Kids) { SetupInstructions(code, kid); } var tryBlock = block as TryCatchBlock; if (tryBlock != null) { foreach (var h in tryBlock.Handlers.Cast <HandlerBlock>()) { SetupInstructions(code, h); } } block.SetupInstructions(code); }
private ILStream ReadCode(IMethod method, IMethodContext context, BufferedBinaryReader reader, int codeSize) { var list = new ILStream(); var startPos = reader.Position; int offset = 0; while (offset < codeSize) { var pos = reader.Position; var instr = ReadInstruction(method, context, reader, startPos); var size = reader.Position - pos; offset += (int)size; instr.Index = list.Count; list.Add(instr); if (!HasGenericInstructions && instr.IsGenericContext) { _genericFlags |= GenericFlags.HasGenericInstructions; } } return(list); }
private static TryCatchBlock EnshureTryBlock(IList <SEHBlock> blocks, int i, TryCatchBlock tryBlock, ILStream code, SEHBlock block, ICollection <TryCatchBlock> list) { if (tryBlock == null) { tryBlock = CreateTryBlock(code, block.TryOffset, block.TryLength); list.Add(tryBlock); } else { var prev = blocks[i - 1]; if (prev.TryOffset != block.TryOffset || prev.TryLength != block.TryLength) { tryBlock = CreateTryBlock(code, block.TryOffset, block.TryLength); list.Add(tryBlock); } } return(tryBlock); }
private IReadOnlyList <TryCatchBlock> TranslateSehBlocks(IMethod method, IMethodContext context, IList <SEHBlock> blocks, ILStream code) { var list = new List <TryCatchBlock>(); var handlers = new BlockList(); TryCatchBlock tryBlock = null; int n = blocks.Count; for (int i = 0; i < n; ++i) { var block = blocks[i]; tryBlock = EnshureTryBlock(blocks, i, tryBlock, code, block, list); var handler = CreateHandlerBlock(method, context, code, block); int entryIndex = code.GetOffsetIndex(block.HandlerOffset); int exitIndex = GetIndex(code, block.HandlerOffset, block.HandlerLength); handler.EntryPoint = code[entryIndex]; handler.ExitPoint = code[exitIndex]; tryBlock.Handlers.Add(handler); handlers.Add(handler); } //set parents for (int i = 0; i < list.Count; ++i) { var block = list[i]; var parent = FindParent(list, block); if (parent != null) { parent.Add(block); list.RemoveAt(i); --i; } } foreach (var block in list) { SetupInstructions(code, block); } return(list.AsReadOnlyList()); }
public MethodBody(IMethod method, IMethodContext context, BufferedBinaryReader reader) { if (method == null) { throw new ArgumentNullException("method"); } if (context == null) { throw new ArgumentNullException("context"); } if (reader == null) { throw new ArgumentNullException("reader"); } _method = method; int lsb = reader.ReadUInt8(); var flags = (MethodBodyFlags)lsb; _maxStackSize = 8; var format = flags & MethodBodyFlags.FormatMask; List <SEHBlock> sehBlocks = null; switch (format) { case MethodBodyFlags.FatFormat: { byte msb = reader.ReadUInt8(); int dwordMultipleSize = (msb & 0xF0) >> 4; Debug.Assert(dwordMultipleSize == 3); // the fat header is 3 dwords _maxStackSize = reader.ReadUInt16(); int codeSize = reader.ReadInt32(); int localSig = reader.ReadInt32(); flags = (MethodBodyFlags)((msb & 0x0F) << 8 | lsb); _code = ReadCode(method, context, reader, codeSize); if ((flags & MethodBodyFlags.MoreSects) != 0) { sehBlocks = ReadSehBlocks(reader); } bool hasGenericVars; _vars = context.ResolveLocalVariables(method, localSig, out hasGenericVars); if (hasGenericVars) { _genericFlags |= GenericFlags.HasGenericVars; } } break; case MethodBodyFlags.TinyFormat: case MethodBodyFlags.TinyFormat1: { int codeSize = (lsb >> 2); _code = ReadCode(method, context, reader, codeSize); } break; default: throw new NotSupportedException("Not supported method body format!"); } TranslateOffsets(); if (sehBlocks != null) { _protectedBlocks = TranslateSehBlocks(method, context, sehBlocks, _code); } context.LinkDebugInfo(this); }