Exemple #1
0
        private void InterpretUShort(int table_id, MetadataStream m)
        {
            m.table_column_sizes[table_id].Add(2);

            m.table_templates[table_id].Add(new MetadataStream.FieldTemplate
            {
                EntryType = MetadataStream.FieldTemplate.FieldType.Int16
            });
        }
Exemple #2
0
 internal Interactive(metadata.MetadataStream metadata, libtysila5.target.Target target)
 {
     s.m = new InteractiveMetadataStream {
         m = metadata
     };
     t      = target;
     corlib = new InteractiveMetadataStream {
         m = metadata.al.GetAssembly("mscorlib")
     };
 }
Exemple #3
0
        private static void load_mscorlib()
        {
            var str = AssemblyLoader.LoadAssembly("mscorlib");

            metadata.PEFile pef = new metadata.PEFile();
            var             m   = pef.Parse(str, AssemblyLoader);

            AssemblyLoader.AddToCache(m, "mscorlib");
            mscorlib = m;
            BinaryAssemblyLoader.ptr_cache[(ulong)OtherOperations.GetStaticObjectAddress("mscorlib")] = m;
        }
Exemple #4
0
        public void WriteToOutput(binary_library.IBinaryFile of,
                                  metadata.MetadataStream ms, target.Target t,
                                  binary_library.ISection rd = null)
        {
            if (str_tab.Count == 0)
            {
                return;
            }

            if (rd == null)
            {
                rd = of.GetRDataSection();
            }
            rd.Align(t.GetCTSize(ir.Opcode.ct_object));

            var stab_lab = of.CreateSymbol();

            stab_lab.Name       = Label;
            stab_lab.ObjectType = binary_library.SymbolObjectType.Object;
            stab_lab.Offset     = (ulong)rd.Data.Count;
            stab_lab.Type       = binary_library.SymbolType.Weak;
            rd.AddSymbol(stab_lab);

            int stab_base = rd.Data.Count;

            foreach (byte b in str_tab)
            {
                rd.Data.Add(b);
            }

            foreach (var kvp in sig_metadata_addrs)
            {
                var reloc = of.CreateRelocation();
                reloc.DefinedIn = rd;
                reloc.Type      = t.GetDataToDataReloc();
                reloc.Addend    = 0;

                if (sig_metadata_addends.ContainsKey(kvp.Key))
                {
                    reloc.Addend = sig_metadata_addends[kvp.Key];
                }

                var md_lab = of.CreateSymbol();
                md_lab.Name       = kvp.Value;
                md_lab.ObjectType = binary_library.SymbolObjectType.Object;

                reloc.References = md_lab;
                reloc.Offset     = (ulong)(kvp.Key + stab_base);
                of.AddRelocation(reloc);
            }

            stab_lab.Size = rd.Data.Count - (int)stab_lab.Offset;
        }
Exemple #5
0
        private int GetModIdx(MetadataStream m, List <MetadataStream> mods)
        {
            for (int i = 0; i < mods.Count; i++)
            {
                if (mods[i].Equals(m))
                {
                    return(i);
                }
            }
            var ret = mods.Count;

            mods.Add(m);
            return(ret);
        }
Exemple #6
0
        private void InterpretGuidIndex(int table_id, MetadataStream m)
        {
            if (m.wide_guid)
            {
                m.table_column_sizes[table_id].Add(4);
            }
            else
            {
                m.table_column_sizes[table_id].Add(2);
            }

            m.table_templates[table_id].Add(new MetadataStream.FieldTemplate
            {
                EntryType = MetadataStream.FieldTemplate.FieldType.Guid
            });
        }
Exemple #7
0
        private int GetMaxIndex(MetadataStream m, int[] tables)
        {
            int max = 0;

            foreach (int i in tables)
            {
                if (i >= 0)
                {
                    if (m.table_rows[i] > max)
                    {
                        max = m.table_rows[i];
                    }
                }
            }
            return(max);
        }
Exemple #8
0
        private void InterpretSimpleIndex(int table_id, MetadataStream m, int v)
        {
            if (m.table_rows[v] < 65536)
            {
                m.table_column_sizes[table_id].Add(2);
            }
            else
            {
                m.table_column_sizes[table_id].Add(4);
            }

            m.table_templates[table_id].Add(new MetadataStream.FieldTemplate
            {
                EntryType   = MetadataStream.FieldTemplate.FieldType.SimpleIndex,
                SimpleIndex = v
            });
        }
Exemple #9
0
        private void InterpretCodedIndex(int table_id, MetadataStream m,
                                         MetadataStream.CodedIndexTemplate ci)
        {
            int maxindex = GetMaxIndex(m, ci.Members);

            if (maxindex >= (1 << (16 - ci.TagBits)))
            {
                m.table_column_sizes[table_id].Add(4);
            }
            else
            {
                m.table_column_sizes[table_id].Add(2);
            }

            m.table_templates[table_id].Add(new MetadataStream.FieldTemplate
            {
                EntryType     = MetadataStream.FieldTemplate.FieldType.CodedIndex,
                CodedTemplate = ci
            });
        }
Exemple #10
0
        public void WriteToOutput(binary_library.IBinaryFile of,
                                  metadata.MetadataStream ms, target.Target t)
        {
            var rd = of.GetRDataSection();

            rd.Align(t.GetCTSize(ir.Opcode.ct_object));

            var stab_lab = GetStringTableSymbol(of);

            stab_lab.Name       = Label;
            stab_lab.ObjectType = binary_library.SymbolObjectType.Object;
            stab_lab.Offset     = (ulong)rd.Data.Count;
            stab_lab.Type       = binary_library.SymbolType.Global;
            rd.AddSymbol(stab_lab);

            int stab_base = rd.Data.Count;

            foreach (byte b in str_tab)
            {
                rd.Data.Add(b);
            }

            var str_lab = of.CreateSymbol();

            str_lab.Name       = StringObject.m.MangleType(StringObject);
            str_lab.ObjectType = binary_library.SymbolObjectType.Object;

            foreach (var str_addr in str_addrs.Values)
            {
                var reloc = of.CreateRelocation();
                reloc.DefinedIn  = rd;
                reloc.Type       = t.GetDataToDataReloc();
                reloc.Addend     = 0;
                reloc.References = str_lab;
                reloc.Offset     = (ulong)(str_addr + stab_base);
                of.AddRelocation(reloc);
            }

            stab_lab.Size = rd.Data.Count - (int)stab_lab.Offset;
        }
Exemple #11
0
 internal SeqPt(MetadataStream mstream)
 {
     m = mstream;
 }
Exemple #12
0
 /**<summary>Add an already loaded assembly to the cache</summary> */
 public virtual void AddToCache(MetadataStream m, string name)
 {
     cache[name] = m;
 }
Exemple #13
0
        public void AddSignature(List <byte> sig, List <MetadataStream> mods)
        {
            switch (stype)
            {
            case SpecialType.None:
            {
                bool has_gtparams = true;
                if (gtparams == null || gtparams.Length == 0)
                {
                    has_gtparams = false;
                }

                if (has_gtparams)
                {
                    sig.Add(0x15);
                }

                // emit as simple typedef signature
                var simple = SimpleType;
                if (simple != 0)
                {
                    sig.Add((byte)simple);
                }
                else
                {
                    if (IsValueType)
                    {
                        sig.Add(0x31);
                    }
                    else
                    {
                        sig.Add(0x32);
                    }
                    uint mod_tok = (uint)GetModIdx(m, mods);
                    sig.AddRange(MetadataStream.SigWriteUSCompressed(mod_tok));
                    uint tok = m.MakeCodedIndexEntry(MetadataStream.tid_TypeDef,
                                                     tdrow, m.TypeDefOrRef);
                    sig.AddRange(MetadataStream.SigWriteUSCompressed(tok));
                }

                if (has_gtparams)
                {
                    sig.AddRange(MetadataStream.SigWriteUSCompressed((uint)gtparams.Length));
                    foreach (var x in gtparams)
                    {
                        x.AddSignature(sig, mods);
                    }
                }
            }
            break;

            case SpecialType.SzArray:
                sig.Add(0x1d);
                other.AddSignature(sig, mods);
                break;

            case SpecialType.Boxed:
                other.AddSignature(sig, mods);
                break;

            case SpecialType.Ptr:
                sig.Add(0x0f);
                other.AddSignature(sig, mods);
                break;

            case SpecialType.MPtr:
                sig.Add(0x10);
                other.AddSignature(sig, mods);
                break;

            case SpecialType.Array:
                sig.Add(0x14);
                other.AddSignature(sig, mods);
                sig.AddRange(MetadataStream.SigWriteUSCompressed((uint)arr_rank));
                sig.AddRange(MetadataStream.SigWriteUSCompressed((uint)arr_sizes.Length));
                foreach (var item in arr_sizes)
                {
                    sig.AddRange(MetadataStream.SigWriteUSCompressed((uint)item));
                }
                sig.AddRange(MetadataStream.SigWriteUSCompressed((uint)arr_lobounds.Length));
                foreach (var item in arr_lobounds)
                {
                    sig.AddRange(MetadataStream.SigWriteUSCompressed((uint)item));
                }
                break;

            default:
                throw new NotImplementedException();
            }
        }
Exemple #14
0
        private void InterpretSchema(int table_id, MetadataStream m)
        {
            m.table_column_sizes[table_id]   = new List <int>();
            m.table_column_offsets[table_id] = new List <int>();
            m.table_templates[table_id]      = new List <MetadataStream.FieldTemplate>();
            switch (table_id)
            {
            case 0x20:
                // Assembly
                InterpretUInt(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUInt(table_id, m);
                InterpretBlobIndex(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretStringIndex(table_id, m);
                break;

            case 0x22:
                // AssemblyOS
                InterpretUInt(table_id, m);
                InterpretUInt(table_id, m);
                InterpretUInt(table_id, m);
                break;

            case 0x21:
                // AssemblyProcessor
                InterpretUInt(table_id, m);
                break;

            case 0x23:
                // AssemblyRef
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUInt(table_id, m);
                InterpretBlobIndex(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x25:
                // AssemblyRefOS
                InterpretUInt(table_id, m);
                InterpretUInt(table_id, m);
                InterpretUInt(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.AssemblyRef]);
                break;

            case 0x24:
                // AssemblyRefProcessor
                InterpretUInt(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.AssemblyRef]);
                break;

            case 0x0f:
                // ClassLayout
                InterpretUShort(table_id, m);
                InterpretUInt(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.TypeDef]);
                break;

            case 0x0b:
                // Constant
                InterpretUShort(table_id, m);
                InterpretCodedIndex(table_id, m, m.HasConstant);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x0c:
                // CustomAttribute
                InterpretCodedIndex(table_id, m, m.HasCustomAttribute);
                InterpretCodedIndex(table_id, m, m.CustomAttributeType);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x0e:
                // DeclSecurity
                InterpretUShort(table_id, m);
                InterpretCodedIndex(table_id, m, m.HasDeclSecurity);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x12:
                // EventMap
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.TypeDef]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.Event]);
                break;

            case 0x14:
                // Event
                InterpretUShort(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretCodedIndex(table_id, m, m.TypeDefOrRef);
                break;

            case 0x27:
                // ExportedType
                InterpretUInt(table_id, m);
                InterpretUInt(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretCodedIndex(table_id, m, m.Implementation);
                break;

            case 0x04:
                // Field
                InterpretUShort(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x10:
                // FieldLayout
                InterpretUInt(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.Field]);
                break;

            case 0x0d:
                // FieldMarshal
                InterpretCodedIndex(table_id, m, m.HasFieldMarshal);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x1d:
                // FieldRVA
                InterpretUInt(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.Field]);
                break;

            case 0x26:
                // File
                InterpretUInt(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x2a:
                // GenericParam
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretCodedIndex(table_id, m, m.TypeOrMethodDef);
                InterpretStringIndex(table_id, m);
                break;

            case 0x2c:
                // GenericParamConstraint
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.GenericParam]);
                InterpretCodedIndex(table_id, m, m.TypeDefOrRef);
                break;

            case 0x1c:
                // ImplMap
                InterpretUShort(table_id, m);
                InterpretCodedIndex(table_id, m, m.MemberForwarded);
                InterpretStringIndex(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.ModuleRef]);
                break;

            case 0x09:
                // InterfaceImpl
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.TypeDef]);
                InterpretCodedIndex(table_id, m, m.TypeDefOrRef);
                break;

            case 0x28:
                // ManifestResource
                InterpretUInt(table_id, m);
                InterpretUInt(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretCodedIndex(table_id, m, m.Implementation);
                break;

            case 0x0a:
                // MemberRef
                InterpretCodedIndex(table_id, m, m.MemberRefParent);
                InterpretStringIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x06:
                // MethodDef
                InterpretUInt(table_id, m);
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.Param]);
                break;

            case 0x19:
                // MethodImpl
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.TypeDef]);
                InterpretCodedIndex(table_id, m, m.MethodDefOrRef);
                InterpretCodedIndex(table_id, m, m.MethodDefOrRef);
                break;

            case 0x18:
                // MethodSemantics
                InterpretUShort(table_id, m);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.MethodDef]);
                InterpretCodedIndex(table_id, m, m.HasSemantics);
                break;

            case 0x2b:
                // MethodSpec
                InterpretCodedIndex(table_id, m, m.MethodDefOrRef);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x00:
                // Module
                InterpretUShort(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretGuidIndex(table_id, m);
                InterpretGuidIndex(table_id, m);
                InterpretGuidIndex(table_id, m);
                break;

            case 0x1a:
                // ModuleRef
                InterpretStringIndex(table_id, m);
                break;

            case 0x29:
                // NestedClass
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.TypeDef]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.TypeDef]);
                break;

            case 0x08:
                // Param
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretStringIndex(table_id, m);
                break;

            case 0x17:
                // Property
                InterpretUShort(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x15:
                // PropertyMap
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.TypeDef]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.Property]);
                break;

            case 0x11:
                // StandAloneSig
                InterpretBlobIndex(table_id, m);
                break;

            case 0x02:
                // TypeDef
                InterpretUInt(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretStringIndex(table_id, m);
                InterpretCodedIndex(table_id, m, m.TypeDefOrRef);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.Field]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.MethodDef]);
                break;

            case 0x01:
                // TypeRef
                InterpretCodedIndex(table_id, m, m.ResolutionScope);
                InterpretStringIndex(table_id, m);
                InterpretStringIndex(table_id, m);
                break;

            case 0x1b:
                // TypeSpec
                InterpretBlobIndex(table_id, m);
                break;

            case 0x30:
                // Document
                InterpretBlobIndex(table_id, m);
                InterpretGuidIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                InterpretGuidIndex(table_id, m);
                break;

            case 0x31:
                // MethodDebugInformation
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.Document]);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x32:
                // LocalScope
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.MethodDef]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.ImportScope]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.LocalVariable]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.LocalConstant]);
                InterpretUInt(table_id, m);
                InterpretUInt(table_id, m);
                break;

            case 0x33:
                // LocalVariable
                InterpretUShort(table_id, m);
                InterpretUShort(table_id, m);
                InterpretStringIndex(table_id, m);
                break;

            case 0x34:
                // LocalConstant
                InterpretStringIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x35:
                // ImportScope
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.ImportScope]);
                InterpretBlobIndex(table_id, m);
                break;

            case 0x36:
                // StateMachineMethod
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.MethodDef]);
                InterpretSimpleIndex(table_id, m, m.TableIDs[MetadataStream.TableId.MethodDef]);
                break;

            case 0x37:
                // CustomDebugInformation
                InterpretCodedIndex(table_id, m, m.HasCustomDebugInformation);
                InterpretGuidIndex(table_id, m);
                InterpretBlobIndex(table_id, m);
                break;

            default:
                throw new Exception("Unsupported metadata table type: " + table_id.ToString());
            }

            int row_size = 0;

            foreach (int sz in m.table_column_sizes[table_id])
            {
                m.table_column_offsets[table_id].Add(row_size);
                row_size += sz;
            }
            m.table_entry_size[table_id] = row_size;
        }
Exemple #15
0
        public MetadataStream Parse(DataInterface file, AssemblyLoader al, bool fail_refs = true, bool is_pdb = false)
        {
            var m = new MetadataStream();

            m.al = al;

            long mroot_offset;

            if (is_pdb)
            {
                mroot_offset = 0;
                pdbf         = true;
            }
            else
            {
                pefh = new PE_File_Header();

                uint pefh_start = file.ReadUInt(0x3c) + 4;
                uint pesig      = file.ReadUInt((int)pefh_start - 4);
                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: PE Signature: " + pesig.ToString("X8"));
                pefh.NumberOfSections = file.ReadUShort((int)pefh_start + 2);
                pefh.Sections         = new SectionHeader[pefh.NumberOfSections];
                TimeSpan t = new TimeSpan(0, 0, (int)(file.ReadUInt((int)pefh_start + 4) & 0x7fffffff));    // csc /deterministic sets top bit - ignore for timestamp purposes
                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: t: " + ((int)file.ReadUInt((int)pefh_start + 4)).ToString());
                pefh.TimeDateStamp = new DateTime(1970, 1, 1) + t;
                pefh.OptHeaderSize = file.ReadUShort((int)pefh_start + 16);
                if (pefh.OptHeaderSize < 224)
                {
                    throw new Exception("PE optional header too small");
                }
                pefh.Chars = file.ReadUShort((int)pefh_start + 18);
                if ((pefh.Chars & 0x3) != 0x2)
                {
                    System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: Invalid PE file header characteristics: " + pefh.Chars.ToString());
                    System.Diagnostics.Debugger.Break();
                    throw new Exception("Invalid PE file header characteristics");
                }

                int    pe32plusoffset = 0;
                ushort magic          = file.ReadUShort((int)pefh_start + 20);
                if (magic == 0x20b)
                {
                    pe32plusoffset = 16;
                }

                pefh.CliHeader      = new DataDir();
                pefh.CliHeader.RVA  = file.ReadUInt((int)pefh_start + 228 + pe32plusoffset);
                pefh.CliHeader.Size = file.ReadUInt((int)pefh_start + 232 + pe32plusoffset);

                // Read the section headers
                uint sections_start = pefh_start + 20 + pefh.OptHeaderSize;
                for (uint i = 0; i < pefh.NumberOfSections; i++)
                {
                    uint s_start = sections_start + i * 40;
                    pefh.Sections[i] = new SectionHeader();

                    char[] w_str = new char[9];
                    for (int j = 0; j < 8; j++)
                    {
                        w_str[j] = (char)file.ReadByte((int)s_start + j);
                    }
                    w_str[8] = '\0';

                    pefh.Sections[i].Name = new String(w_str);
                    pefh.Sections[i].Name = pefh.Sections[i].Name.Remove(pefh.Sections[i].Name.IndexOf("\0"));
                    System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: section name: " + pefh.Sections[i].Name + "\n");

                    pefh.Sections[i].VSize    = file.ReadUInt((int)s_start + 8);
                    pefh.Sections[i].VAddress = file.ReadUInt((int)s_start + 12);
                    pefh.Sections[i].PSize    = file.ReadUInt((int)s_start + 16);
                    pefh.Sections[i].PAddress = file.ReadUInt((int)s_start + 20);

                    pefh.Sections[i].Chars = file.ReadUInt((int)s_start + 36);
                }

                // Read the Cli header
                if (pefh.CliHeader.RVA == 0)
                {
                    return(null);
                }
                long clih_offset = ResolveRVA(pefh.CliHeader.RVA);


                clih = new Cli_Header();
                clih.Metadata.RVA    = file.ReadUInt((int)clih_offset + 8);
                clih.Metadata.Size   = file.ReadUInt((int)clih_offset + 12);
                clih.EntryPointToken = file.ReadUInt((int)clih_offset + 20);
                clih.Resources.RVA   = file.ReadUInt((int)clih_offset + 24);
                clih.Resources.Size  = file.ReadUInt((int)clih_offset + 28);

                m.entry_point_token = clih.EntryPointToken;

                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: CLI header parsed");

                // First, read the metadata root
                mroot_offset = ResolveRVA(clih.Metadata.RVA);
            }
            uint sig = file.ReadUInt((int)mroot_offset);

            if (sig != 0x424A5342)
            {
                throw new Exception("Invalid metadata root");
            }
            uint vstr_len = file.ReadUInt((int)mroot_offset + 12);

            m.VersionString = ReadSZ(file, (int)mroot_offset + 16);
            ushort nstr = file.ReadUShort((int)mroot_offset + 16 +
                                          (int)vstr_len + 2);

            int cur_offset = (int)mroot_offset + 16 + (int)vstr_len + 4;

            // Now, read the stream headers
            for (ushort i = 0; i < nstr; i++)
            {
                StreamHeader sh = new StreamHeader();
                sh.Offset     = file.ReadUInt(cur_offset);
                sh.FileOffset = ResolveRVA((is_pdb ? 0 : clih.Metadata.RVA) + sh.Offset);
                sh.Size       = file.ReadUInt(cur_offset + 4);

                cur_offset += 8;
                StringBuilder sb = new StringBuilder();
                while (true)
                {
                    byte strb = file.ReadByte(cur_offset++);
                    if (strb == 0)
                    {
                        break;
                    }
                    else
                    {
                        sb.Append((char)strb);
                    }
                }
                while ((cur_offset & 0x3) != 0)
                {
                    cur_offset++;
                }

                sh.Name = sb.ToString();

                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: stream name: " + sh.Name);

                sh.di = file.Clone((int)sh.FileOffset);

                if (sh.Name == "#Strings")
                {
                    m.sh_string = sh;
                }
                else if (sh.Name == "#US")
                {
                    m.sh_us = sh;
                }
                else if (sh.Name == "#GUID")
                {
                    m.sh_guid = sh;
                }
                else if (sh.Name == "#Blob")
                {
                    m.sh_blob = sh;
                }
                else if (sh.Name == "#~")
                {
                    m.sh_tables = sh;
                }
                else if (sh.Name == "#Pdb")
                {
                    m.sh_pdb = sh;
                }
                else
                {
                    System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: unknown table \"" + sh.Name + "\"");
                    throw new Exception("Unknown metadata table");
                }
            }

            // Parse tables
            if (m.sh_tables != null)
            {
                var di  = m.sh_tables.di;
                var maj = di.ReadByte(4);
                var min = di.ReadByte(5);
                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: parsing tables");
                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: metadata table schema v" + maj.ToString() + "." + min.ToString());

                // Determine size of indices into the heaps
                var heapsizes = di.ReadByte(6);
                if ((heapsizes & 0x1) == 0x1)
                {
                    m.wide_string = true;
                }
                if ((heapsizes & 0x2) == 0x2)
                {
                    m.wide_guid = true;
                }
                if ((heapsizes & 0x4) == 0x4)
                {
                    m.wide_blob = true;
                }

                // Get list of valid tables
                var        valid        = di.ReadULong(8);
                int        valid_count  = 0;
                List <int> valid_tables = new List <int>();
                for (int i = 0; i < 64; i++)
                {
                    if (((valid >> i) & 0x1) == 0x1)
                    {
                        m.valid_tables[i] = true;
                        valid_count++;
                        valid_tables.Add(i);
                    }
                }

                // Get number of rows in each table
                int table_id = 0;
                foreach (var valid_table in valid_tables)
                {
                    m.table_rows[valid_table] = (int)di.ReadUInt(24 + 4 * table_id++);
                }

                // Interpret the schema of each table
                foreach (var valid_table in valid_tables)
                {
                    InterpretSchema(valid_table, m);
                }

                // Determine start offsets of each table
                int offset = 24 + 4 * valid_count;
                foreach (var valid_table in valid_tables)
                {
                    m.table_offsets[valid_table] = offset;
                    offset += m.table_rows[valid_table] * m.table_entry_size[valid_table];
                }
            }

            m.pef  = this;
            m.file = file;

            /* Get this assembly name */
            if (m.table_rows[MetadataStream.tid_Assembly] == 1)
            {
                m.assemblyName = m.GetStringEntry(MetadataStream.tid_Assembly, 1, 7);

                // Handle dotnet coreclr mscorlib having a different name
                if (m.assemblyName == "System.Private.CoreLib")
                {
                    m.assemblyName = "mscorlib";
                }

                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: current assembly is " + m.assemblyName);
            }

            /* Load up all referenced assemblies */
            m.referenced_assemblies = new MetadataStream[m.table_rows[MetadataStream.tid_AssemblyRef]];
            for (int i = 1; i <= m.table_rows[MetadataStream.tid_AssemblyRef]; i++)
            {
                var ass_name = m.GetStringEntry(MetadataStream.tid_AssemblyRef, i, 6);
                var maj      = (int)m.GetIntEntry(MetadataStream.tid_AssemblyRef, i, 0);
                var min      = (int)m.GetIntEntry(MetadataStream.tid_AssemblyRef, i, 1);
                var build    = (int)m.GetIntEntry(MetadataStream.tid_AssemblyRef, i, 2);
                var rev      = (int)m.GetIntEntry(MetadataStream.tid_AssemblyRef, i, 3);

                if (ass_name == "netstandard")
                {
                    ass_name = "mscorlib";
                    maj      = -1;
                }

                System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: loading referenced assembly " + ass_name);

                if ((m.referenced_assemblies[i - 1] = al.GetAssembly(ass_name, maj, min, build, rev)) == null && fail_refs)
                {
                    var ale = new AssemblyLoadException();
                    ale.ReferencedAssembly = new AssemblyLoadException.ALEAssembly
                    {
                        Name     = ass_name,
                        Major    = maj,
                        Minor    = min,
                        Revision = rev,
                        Build    = build
                    };
                    ale.CurrentAssembly = new AssemblyLoadException.ALEAssembly
                    {
                        Name     = m.AssemblyName,
                        Major    = m.MajorVersion,
                        Minor    = m.MinorVersion,
                        Revision = m.RevisionVersion,
                        Build    = m.BuildVersion
                    };

                    foreach (var la in al.LoadedAssemblies)
                    {
                        var cla = al.GetAssembly(la);

                        var clale = new AssemblyLoadException.ALEAssembly
                        {
                            Name     = cla.AssemblyName,
                            Major    = cla.MajorVersion,
                            Minor    = cla.MinorVersion,
                            Revision = cla.RevisionVersion,
                            Build    = cla.BuildVersion
                        };
                        ale.CurrentlyLoadedAssemblies.Add(clale);
                    }
                    throw ale;
                }
            }

            m.PatchMethodDefOwners();
            m.PatchFieldDefOwners();
            m.PatchFieldRVAs();
            m.PatchClassLayouts();
            m.PatchFieldConstants();
            m.PatchGTypes();
            if (m.assemblyName == "mscorlib")
            {
                m.is_corlib = true;
                m.PatchSimpleTypes();
            }
            m.PatchNestedTypes();
            m.PatchCustomAttrs();

            m.LoadBuiltinTypes();

            System.Diagnostics.Debugger.Log(0, "metadata", "PEFile.Parse: parsing complete");

            /* Load up a .pdb sidecar file if necessary */
            if (m.sh_pdb != null)
            {
                m.pdb = m;
            }
            else
            {
                var fname = file.Name;
                if (fname != null)
                {
                    if (fname.EndsWith(".dll") || fname.EndsWith(".exe"))
                    {
                        fname = fname.Substring(0, fname.Length - 4);
                    }
                    var pdbf = al.LoadAssembly(fname + ".pdb");
                    if (pdbf != null)
                    {
                        var pef = new metadata.PEFile();
                        try
                        {
                            m.pdb = pef.Parse(pdbf, al, true, true);
                        }
                        catch (Exception)
                        {
                            m.pdb = null;
                        }
                    }
                }
            }

            return(m);
        }
Exemple #16
0
        public SpecialMethods(metadata.MetadataStream m)
        {
            corlib = m.al.GetAssembly("mscorlib");
            var i  = corlib.GetTypeSpec("System", "Int32");
            var u  = corlib.GetTypeSpec("System", "UInt32");
            var I  = corlib.GetTypeSpec("System", "IntPtr");
            var o  = corlib.GetSimpleTypeSpec(0x1c);
            var s  = corlib.GetSimpleTypeSpec(0x0e);
            var a  = corlib.GetSimpleTypeSpec(0x04);
            var Pa = a.Pointer;
            var c  = corlib.GetSimpleTypeSpec(0x03);
            var Pc = c.Pointer;
            var Zc = c.SzArray;
            var Zo = o.SzArray;
            var Pv = m.SystemVoid.Type.Pointer;
            var d  = corlib.GetSimpleTypeSpec(0xd);

            gcmalloc = CreateMethodSignature(b, I,
                                             new metadata.TypeSpec[] { i });
            castclassex = CreateMethodSignature(b, o,
                                                new TypeSpec[] { I, I, i });
            throw_ = CreateMethodSignature(b, null,
                                           new TypeSpec[] { o });
            try_enter = CreateMethodSignature(b, null,
                                              new TypeSpec[] { I, I });
            catch_enter = CreateMethodSignature(b, null,
                                                new TypeSpec[] { I, I });
            leave = CreateMethodSignature(b, null,
                                          new TypeSpec[] { I });
            rethrow = CreateMethodSignature(b, null,
                                            new TypeSpec[] { });
            strlen = CreateMethodSignature(b, I,
                                           new TypeSpec[] { Pa });
            wcslen = CreateMethodSignature(b, I,
                                           new TypeSpec[] { Pc });
            memcpy = CreateMethodSignature(I,
                                           new TypeSpec[] { I, I, i });
            memset = CreateMethodSignature(I,
                                           new TypeSpec[] { I, i, i });
            invoke = CreateMethodSignature(o,
                                           new TypeSpec[] { Pv, Zo, Pv, u });

            inst_Rv_s = CreateMethodSignature(b, null,
                                              new TypeSpec[] { s }, true);
            inst_Rv_P0 = CreateMethodSignature(b, null,
                                               new TypeSpec[] { }, true);
            static_Rv_P0 = CreateMethodSignature(b, null,
                                                 new TypeSpec[] { }, false);
            static_Rv_P1Pv = CreateMethodSignature(b, null,
                                                   new TypeSpec[] { Pv }, false);

            string_ci = CreateMethodSignature(null,
                                              new TypeSpec[] { c, i }, true);
            string_Zc = CreateMethodSignature(null,
                                              new TypeSpec[] { Zc }, true);
            string_Pcii = CreateMethodSignature(null,
                                                new TypeSpec[] { Pc, i, i }, true);
            string_Pa = CreateMethodSignature(null,
                                              new TypeSpec[] { Pa }, true);
            string_Zcii = CreateMethodSignature(null,
                                                new TypeSpec[] { Zc, i, i }, true);
            string_Pc = CreateMethodSignature(null,
                                              new TypeSpec[] { Pc }, true);
            string_PaiiEncoding = CreateMethodSignature(null,
                                                        new TypeSpec[] { Pa, i, i, corlib.GetTypeSpec("System.Text", "Encoding") }, true);
            string_Paii = CreateMethodSignature(null,
                                                new TypeSpec[] { Pa, i, i }, true);

            type_from_vtbl = CreateMethodSignature(o, new TypeSpec[] { I });

            array_copyToManaged = CreateMethodSignature(null,
                                                        new TypeSpec[] { Pv, Pv, i, i }, false);

            debugger_Log = CreateMethodSignature(null,
                                                 new TypeSpec[] { i, s, s });

            rint = CreateMethodSignature(d, new TypeSpec[] { d });

            sh_blob = new BlobStream(b);

            al = m.al;

            SystemArray               = m.SystemArray;
            SystemByte                = m.SystemByte;
            SystemChar                = m.SystemChar;
            SystemDelegate            = m.SystemDelegate;
            SystemEnum                = m.SystemEnum;
            SystemInt16               = m.SystemInt16;
            SystemInt32               = m.SystemInt32;
            SystemInt64               = m.SystemInt64;
            SystemInt8                = m.SystemInt8;
            SystemIntPtr              = m.SystemIntPtr;
            SystemObject              = m.SystemObject;
            SystemRuntimeFieldHandle  = m.SystemRuntimeFieldHandle;
            SystemRuntimeMethodHandle = m.SystemRuntimeMethodHandle;
            SystemRuntimeTypeHandle   = m.SystemRuntimeTypeHandle;
            SystemString              = m.SystemString;
            SystemUInt16              = m.SystemUInt16;
            SystemUInt32              = m.SystemUInt32;
            SystemUInt64              = m.SystemUInt64;
            SystemValueType           = m.SystemValueType;
            SystemVoid                = m.SystemVoid;
        }