예제 #1
0
        void WriteExceptionHandlerCollection(ExceptionHandlerCollection seh)
        {
            m_codeWriter.QuadAlign();

            if (seh.Count < 0x15 && !IsFat(seh))
            {
                m_codeWriter.Write((byte)MethodDataSection.EHTable);
                m_codeWriter.Write((byte)(seh.Count * 12 + 4));
                m_codeWriter.Write(new byte [2]);
                foreach (ExceptionHandler eh in seh)
                {
                    m_codeWriter.Write((ushort)eh.Type);
                    m_codeWriter.Write((ushort)eh.TryStart.Offset);
                    m_codeWriter.Write((byte)(eh.TryEnd.Offset - eh.TryStart.Offset));
                    m_codeWriter.Write((ushort)eh.HandlerStart.Offset);
                    m_codeWriter.Write((byte)GetLength(eh.HandlerStart, eh.HandlerEnd, seh.Container.Instructions));
                    WriteHandlerSpecific(eh);
                }
            }
            else
            {
                m_codeWriter.Write((byte)(MethodDataSection.FatFormat | MethodDataSection.EHTable));
                WriteFatBlockSize(seh);
                foreach (ExceptionHandler eh in seh)
                {
                    m_codeWriter.Write((uint)eh.Type);
                    m_codeWriter.Write((uint)eh.TryStart.Offset);
                    m_codeWriter.Write((uint)(eh.TryEnd.Offset - eh.TryStart.Offset));
                    m_codeWriter.Write((uint)eh.HandlerStart.Offset);
                    m_codeWriter.Write((uint)GetLength(eh.HandlerStart, eh.HandlerEnd, seh.Container.Instructions));
                    WriteHandlerSpecific(eh);
                }
            }
        }
예제 #2
0
        public uint AddResource(byte [] data)
        {
            uint offset = (uint)m_resWriter.BaseStream.Position;

            m_resWriter.Write(data.Length);
            m_resWriter.Write(data);
            m_resWriter.QuadAlign();
            return(offset);
        }
예제 #3
0
        public override void TerminateMethodBody(MethodBody body)
        {
            long pos = m_binaryWriter.BaseStream.Position;

            if (body.HasVariables || body.HasExceptionHandlers ||
                m_codeWriter.BaseStream.Length >= 64 || body.MaxStack > 8)
            {
                MethodHeader header = MethodHeader.FatFormat;
                if (body.InitLocals)
                {
                    header |= MethodHeader.InitLocals;
                }
                if (body.HasExceptionHandlers)
                {
                    header |= MethodHeader.MoreSects;
                }

                m_binaryWriter.Write((byte)header);
                m_binaryWriter.Write((byte)0x30);                   // (header size / 4) << 4
                m_binaryWriter.Write((short)body.MaxStack);
                m_binaryWriter.Write((int)m_codeWriter.BaseStream.Length);
                // the token should be zero if there are no variables
                int token = body.HasVariables ? ((int)TokenType.Signature | body.LocalVarToken) : 0;
                m_binaryWriter.Write(token);

                if (body.HasExceptionHandlers)
                {
                    WriteExceptionHandlerCollection(body.ExceptionHandlers);
                }
            }
            else
            {
                m_binaryWriter.Write((byte)((byte)MethodHeader.TinyFormat |
                                            m_codeWriter.BaseStream.Length << 2));
            }

            m_binaryWriter.Write(m_codeWriter);
            m_binaryWriter.QuadAlign();

            m_reflectWriter.MetadataWriter.AddData(
                (int)(m_binaryWriter.BaseStream.Position - pos));
        }
예제 #4
0
        public override void VisitMetadataRoot(MetadataRoot root)
        {
            WriteMemStream(m_cilWriter);
            WriteMemStream(m_fieldDataWriter);
            m_resStart = (uint)m_binaryWriter.BaseStream.Position;
            WriteMemStream(m_resWriter);
            m_resSize = (uint)(m_binaryWriter.BaseStream.Position - m_resStart);

            // for now, we only reserve the place for the strong name signature
            if ((m_assembly.Name.Flags & AssemblyFlags.PublicKey) > 0)
            {
                m_snsStart = (uint)m_binaryWriter.BaseStream.Position;
                m_snsSize  = GetStrongNameSignatureSize();
                m_binaryWriter.Write(new byte [m_snsSize]);
                m_binaryWriter.QuadAlign();
            }

            // save place for debug header
            if (m_imgWriter.GetImage().DebugHeader != null)
            {
                m_debugHeaderStart = (uint)m_binaryWriter.BaseStream.Position;
                m_binaryWriter.Write(new byte [m_imgWriter.GetImage().DebugHeader.GetSize()]);
                m_binaryWriter.QuadAlign();
            }

            m_mdStart = (uint)m_binaryWriter.BaseStream.Position;

            if (m_stringWriter.BaseStream.Length > 1)
            {
                CreateStream(MetadataStream.Strings);
                SetHeapSize(root.Streams.StringsHeap, m_stringWriter, 0x01);
                m_stringWriter.QuadAlign();
            }

            if (m_guidWriter.BaseStream.Length > 0)
            {
                CreateStream(MetadataStream.GUID);
                SetHeapSize(root.Streams.GuidHeap, m_guidWriter, 0x02);
            }

            if (m_blobWriter.BaseStream.Length > 1)
            {
                CreateStream(MetadataStream.Blob);
                SetHeapSize(root.Streams.BlobHeap, m_blobWriter, 0x04);
                m_blobWriter.QuadAlign();
            }

            if (m_usWriter.BaseStream.Length > 2)
            {
                CreateStream(MetadataStream.UserStrings);
                m_usWriter.QuadAlign();
            }

            m_root.Header.MajorVersion = 1;
            m_root.Header.MinorVersion = 1;

            switch (m_runtime)
            {
            case TargetRuntime.NET_1_0:
                m_root.Header.Version = "v1.0.3705";
                break;

            case TargetRuntime.NET_1_1:
                m_root.Header.Version = "v1.1.4322";
                break;

            case TargetRuntime.NET_2_0:
                m_root.Header.Version = "v2.0.50727";
                break;

            case TargetRuntime.NET_4_0:
                m_root.Header.Version = "v4.0.30319";
                break;
            }

            m_root.Streams.TablesHeap.Tables.Accept(m_tableWriter);

            if (m_tWriter.BaseStream.Length == 0)
            {
                m_root.Streams.Remove(m_root.Streams.TablesHeap.GetStream());
            }
        }
예제 #5
0
 public void AddFieldInitData(byte [] data)
 {
     m_fieldDataWriter.Write(data);
     m_fieldDataWriter.QuadAlign();
 }