private static List <SEHBlock> ReadSehBlocks(BufferedBinaryReader reader) { const int FatSize = 24; const int TinySize = 12; var blocks = new List <SEHBlock>(); bool next = true; while (next) { // Goto 4 byte boundary (each section has to start at 4 byte boundary) reader.Align4(); uint header = reader.ReadUInt32(); var sf = (SectionFlags)(header & 0xFF); int size = (int)(header >> 8); //in bytes if ((sf & SectionFlags.OptILTable) != 0) { } else if ((sf & SectionFlags.FatFormat) == 0) { // tiny header size &= 0xFF; // 1 byte size (filter out the padding) int n = size / TinySize; for (int i = 0; i < n; ++i) { var block = new SEHBlock(reader, false); blocks.Add(block); } } else { //make sure this is an exception block , otherwise skip if ((sf & SectionFlags.EHTable) != 0) { int n = size / FatSize; for (int i = 0; i < n; ++i) { var block = new SEHBlock(reader, true); blocks.Add(block); } } else { reader.Position += size; } } next = (sf & SectionFlags.MoreSects) != 0; } return(blocks); }
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 HandlerBlock CreateHandlerBlock(IMethod method, IMethodContext context, IInstructionList code, SEHBlock block) { switch (block.Type) { case SEHFlags.Catch: { int token = block.Value; var type = context.ResolveType(method, token); if (!HasGenericExceptions && type.IsGenericContext()) { _genericFlags |= GenericFlags.HasGenericExceptions; } var h = new HandlerBlock(BlockType.Catch) { ExceptionType = type }; return(h); } case SEHFlags.Filter: { var h = new HandlerBlock(BlockType.Filter) { FilterIndex = code.GetOffsetIndex(block.Value) }; return(h); } case SEHFlags.Finally: return(new HandlerBlock(BlockType.Finally)); case SEHFlags.Fault: return(new HandlerBlock(BlockType.Fault)); default: throw new IndexOutOfRangeException(); } }