Пример #1
0
        private void EmitProtectedRegionTable()
        {
            var trace = CreateTraceLog("Regions");

            var protectedRegionTableSymbol = MethodCompiler.Linker.DefineSymbol(Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName, SectionKind.ROData, NativeAlignment, 0);
            var writer = new EndianAwareBinaryWriter(protectedRegionTableSymbol.Stream, Architecture.Endianness);

            int sectioncount = 0;

            // 1. Number of Regions (filled in later)
            writer.Write((uint)0);

            foreach (var region in MethodCompiler.ProtectedRegions)
            {
                var handler = (uint)MethodCompiler.GetPosition(region.Handler.HandlerStart);

                trace?.Log($"Handler: {region.Handler.TryStart.ToString("X4")} to {region.Handler.TryEnd.ToString("X4")} Handler: {region.Handler.HandlerStart.ToString("X4")} Offset: [{handler.ToString("X4")}]");

                var sections = new List <Tuple <int, int> >();

                foreach (var block in region.IncludedBlocks)
                {
                    // Check if block continues to exist
                    if (!BasicBlocks.Contains(block))
                    {
                        continue;
                    }

                    int start = MethodCompiler.GetPosition(block.Label);
                    int end   = MethodCompiler.GetPosition(block.Label + 0x0F000000);

                    trace?.Log($"   Block: {block} [{start.ToString()}-{end.ToString()}]");

                    AddSection(sections, start, end);
                }

                foreach (var s in sections)
                {
                    int start = s.Item1;
                    int end   = s.Item2;

                    sectioncount++;

                    var name = Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName + "$" + sectioncount.ToString();
                    var protectedRegionDefinition = CreateProtectedRegionDefinition(name, (uint)start, (uint)end, handler, region.Handler.ExceptionHandlerType, region.Handler.Type);
                    MethodCompiler.Linker.Link(LinkType.AbsoluteAddress, NativePatchType, protectedRegionTableSymbol, writer.Position, protectedRegionDefinition, 0);
                    writer.WriteZeroBytes(TypeLayout.NativePointerSize);

                    trace?.Log($"     Section: [{start.ToString()}-{end.ToString()}]");
                }
            }

            // 1. Number of Regions (now put the real number)
            writer.Position = 0;
            writer.Write(sectioncount);
        }