예제 #1
0
        void ReadProperties()
        {
            if (!m_tHeap.HasTable(PropertyTable.RId))
            {
                m_properties = new PropertyDefinition [0];
                return;
            }

            PropertyTable    propsTable = m_tableReader.GetPropertyTable();
            PropertyMapTable pmapTable  = m_tableReader.GetPropertyMapTable();

            m_properties = new PropertyDefinition [propsTable.Rows.Count];
            for (int i = 0; i < pmapTable.Rows.Count; i++)
            {
                PropertyMapRow pmapRow = pmapTable [i];
                if (pmapRow.Parent == 0)
                {
                    continue;
                }

                TypeDefinition owner = GetTypeDefAt(pmapRow.Parent);

                GenericContext context = new GenericContext(owner);

                int start = (int)pmapRow.PropertyList, last = propsTable.Rows.Count + 1, end;
                if (i < pmapTable.Rows.Count - 1)
                {
                    end = (int)pmapTable [i + 1].PropertyList;
                }
                else
                {
                    end = last;
                }

                if (end > last)
                {
                    end = last;
                }

                for (int j = start; j < end; j++)
                {
                    PropertyRow        prow = propsTable [j - 1];
                    PropertySig        psig = m_sigReader.GetPropSig(prow.Type);
                    PropertyDefinition pdef = new PropertyDefinition(
                        m_root.Streams.StringsHeap [prow.Name],
                        GetTypeRefFromSig(psig.Type, context),
                        prow.Flags);
                    pdef.MetadataToken = MetadataToken.FromMetadataRow(TokenType.Property, j - 1);

                    pdef.PropertyType = GetModifierType(psig.CustomMods, pdef.PropertyType);

                    if (!IsDeleted(pdef))
                    {
                        owner.Properties.Add(pdef);
                    }

                    m_properties [j - 1] = pdef;
                }
            }
        }
        void PatchMethods()
        {
            MethodTable methodTable = (MethodTable)stripped_tables [MethodTable.RId];

            if (methodTable == null)
            {
                return;
            }

            RVA method_rva = RVA.Zero;

            for (int i = 0; i < methodTable.Rows.Count; i++)
            {
                MethodRow methodRow = methodTable[i];

                MetadataToken methodToken = MetadataToken.FromMetadataRow(TokenType.Method, i);

                MethodDefinition method = (MethodDefinition)assembly.MainModule.LookupByToken(methodToken);

                method_rva = method_rva != RVA.Zero
                                        ? method_rva
                                        : reflection_writer.CodeWriter.WriteMethodBody(method);

                methodRow.RVA = method_rva;
            }
        }
        void ReadMethods()
        {
            if (!m_tHeap.HasTable(MethodTable.RId))
            {
                m_meths = new MethodDefinition [0];
                return;
            }

            MethodTable mTable = m_tableReader.GetMethodTable();

            m_meths = new MethodDefinition [mTable.Rows.Count];
            for (int i = 0; i < mTable.Rows.Count; i++)
            {
                MethodRow        mRow = mTable [i];
                MethodDefinition meth = new MethodDefinition(
                    m_root.Streams.StringsHeap [mRow.Name],
                    mRow.Flags);
                meth.RVA            = mRow.RVA;
                meth.ImplAttributes = mRow.ImplFlags;

                meth.MetadataToken = MetadataToken.FromMetadataRow(TokenType.Method, i);

                m_meths [i] = meth;
            }
        }
예제 #4
0
        void ReadEvents()
        {
            if (!m_tHeap.HasTable(EventTable.RId))
            {
                m_events = new EventDefinition [0];
                return;
            }

            EventTable    evtTable  = m_tableReader.GetEventTable();
            EventMapTable emapTable = m_tableReader.GetEventMapTable();

            m_events = new EventDefinition [evtTable.Rows.Count];
            for (int i = 0; i < emapTable.Rows.Count; i++)
            {
                EventMapRow emapRow = emapTable [i];
                if (emapRow.Parent == 0)
                {
                    continue;
                }

                TypeDefinition owner   = GetTypeDefAt(emapRow.Parent);
                GenericContext context = new GenericContext(owner);

                int start = (int)emapRow.EventList, last = evtTable.Rows.Count + 1, end;
                if (i < (emapTable.Rows.Count - 1))
                {
                    end = (int)emapTable [i + 1].EventList;
                }
                else
                {
                    end = last;
                }

                if (end > last)
                {
                    end = last;
                }

                for (int j = start; j < end; j++)
                {
                    EventRow        erow = evtTable [j - 1];
                    EventDefinition edef = new EventDefinition(
                        m_root.Streams.StringsHeap [erow.Name],
                        GetTypeDefOrRef(erow.EventType, context), erow.EventFlags);
                    edef.MetadataToken = MetadataToken.FromMetadataRow(TokenType.Event, j - 1);

                    if (!IsDeleted(edef))
                    {
                        owner.Events.Add(edef);
                    }

                    m_events [j - 1] = edef;
                }
            }
        }
        void AddTypeRef(TypeRefTable typesRef, int i)
        {
            // Check if index has been already added.
            if (m_typeRefs [i] != null)
            {
                return;
            }

            TypeRefRow     type   = typesRef [i];
            IMetadataScope scope  = null;
            TypeReference  parent = null;

            if (type.ResolutionScope != MetadataToken.Zero)
            {
                switch (type.ResolutionScope.TokenType)
                {
                case TokenType.AssemblyRef:
                    scope = m_module.AssemblyReferences [(int)type.ResolutionScope.RID - 1];
                    break;

                case TokenType.ModuleRef:
                    scope = m_module.ModuleReferences [(int)type.ResolutionScope.RID - 1];
                    break;

                case TokenType.Module:
                    scope = m_module.Assembly.Modules [(int)type.ResolutionScope.RID - 1];
                    break;

                case TokenType.TypeRef:
                    AddTypeRef(typesRef, (int)type.ResolutionScope.RID - 1);
                    parent = GetTypeRefAt(type.ResolutionScope.RID);
                    scope  = parent.Scope;
                    break;
                }
            }

            TypeReference t = new TypeReference(
                m_root.Streams.StringsHeap [type.Name],
                m_root.Streams.StringsHeap [type.Namespace],
                scope);

            t.MetadataToken = MetadataToken.FromMetadataRow(TokenType.TypeRef, i);

            if (parent != null)
            {
                t.DeclaringType = parent;
            }

            m_typeRefs [i] = t;
            m_module.TypeReferences.Add(t);
        }
        void ReadAllFields()
        {
            TypeDefTable tdefTable = m_tableReader.GetTypeDefTable();

            if (!m_tHeap.HasTable(FieldTable.RId))
            {
                m_fields = new FieldDefinition [0];
                return;
            }

            FieldTable fldTable = m_tableReader.GetFieldTable();

            m_fields = new FieldDefinition [fldTable.Rows.Count];

            for (int i = 0; i < m_typeDefs.Length; i++)
            {
                TypeDefinition dec     = m_typeDefs [i];
                GenericContext context = new GenericContext(dec);

                int index = i, next;

                if (index == tdefTable.Rows.Count - 1)
                {
                    next = fldTable.Rows.Count + 1;
                }
                else
                {
                    next = (int)(tdefTable [index + 1]).FieldList;
                }

                for (int j = (int)tdefTable [index].FieldList; j < next; j++)
                {
                    FieldRow        frow = fldTable [j - 1];
                    FieldSig        fsig = m_sigReader.GetFieldSig(frow.Signature);
                    FieldDefinition fdef = new FieldDefinition(
                        m_root.Streams.StringsHeap [frow.Name],
                        this.GetTypeRefFromSig(fsig.Type, context), frow.Flags);
                    fdef.MetadataToken = MetadataToken.FromMetadataRow(TokenType.Field, j - 1);

                    if (fsig.CustomMods.Length > 0)
                    {
                        fdef.FieldType = GetModifierType(fsig.CustomMods, fdef.FieldType);
                    }

                    dec.Fields.Add(fdef);
                    m_fields [j - 1] = fdef;
                }
            }
        }
예제 #7
0
        public override void VisitModuleReferenceCollection(ModuleReferenceCollection modules)
        {
            if (!m_tHeap.HasTable(ModuleRefTable.RId))
            {
                return;
            }

            ModuleRefTable mrTable = m_tableReader.GetModuleRefTable();

            for (int i = 0; i < mrTable.Rows.Count; i++)
            {
                ModuleRefRow    mrRow = mrTable [i];
                ModuleReference mod   = new ModuleReference(ReadString(mrRow.Name));
                mod.MetadataToken = MetadataToken.FromMetadataRow(TokenType.ModuleRef, i);
                modules.Add(mod);
            }
        }
        public TypeReference GetTypeSpecAt(uint rid, GenericContext context)
        {
            int           index = (int)rid - 1;
            TypeReference tspec = m_typeSpecs [index];

            if (tspec != null)
            {
                return(tspec);
            }

            TypeSpecTable tsTable = m_tableReader.GetTypeSpecTable();
            TypeSpecRow   tsRow   = tsTable [index];
            TypeSpec      ts      = m_sigReader.GetTypeSpec(tsRow.Signature);

            tspec = GetTypeRefFromSig(ts.Type, context);
            tspec.MetadataToken = MetadataToken.FromMetadataRow(TokenType.TypeSpec, index);
            m_typeSpecs [index] = tspec;

            return(tspec);
        }
        void ReadGenericParameters()
        {
            if (!m_tHeap.HasTable(GenericParamTable.RId))
            {
                return;
            }

            GenericParamTable gpTable = m_tableReader.GetGenericParamTable();

            m_genericParameters = new GenericParameter [gpTable.Rows.Count];
            for (int i = 0; i < gpTable.Rows.Count; i++)
            {
                GenericParamRow           gpRow = gpTable [i];
                IGenericParameterProvider owner;
                if (gpRow.Owner.TokenType == TokenType.Method)
                {
                    owner = GetMethodDefAt(gpRow.Owner.RID);
                }
                else if (gpRow.Owner.TokenType == TokenType.TypeDef)
                {
                    owner = GetTypeDefAt(gpRow.Owner.RID);
                }
                else
                {
                    throw new ReflectionException("Unknown owner type for generic parameter");
                }

                GenericParameter gp = new GenericParameter((int)gpRow.Number, owner);
                gp.Attributes    = gpRow.Flags;
                gp.Name          = MetadataRoot.Streams.StringsHeap [gpRow.Name];
                gp.MetadataToken = MetadataToken.FromMetadataRow(TokenType.GenericParam, i);

                owner.GenericParameters.Add(gp);
                m_genericParameters [i] = gp;
            }
        }
        void CompleteMethods()
        {
            TypeDefTable tdefTable = m_tableReader.GetTypeDefTable();

            if (!m_tHeap.HasTable(MethodTable.RId))
            {
                m_meths = new MethodDefinition [0];
                return;
            }

            MethodTable methTable  = m_tableReader.GetMethodTable();
            ParamTable  paramTable = m_tableReader.GetParamTable();

            if (!m_tHeap.HasTable(ParamTable.RId))
            {
                m_parameters = new ParameterDefinition [0];
            }
            else
            {
                m_parameters = new ParameterDefinition [paramTable.Rows.Count];
            }

            for (int i = 0; i < m_typeDefs.Length; i++)
            {
                TypeDefinition dec = m_typeDefs [i];

                int index = i, next;

                if (index == tdefTable.Rows.Count - 1)
                {
                    next = methTable.Rows.Count + 1;
                }
                else
                {
                    next = (int)(tdefTable [index + 1]).MethodList;
                }

                for (int j = (int)tdefTable [index].MethodList; j < next; j++)
                {
                    MethodRow        methRow = methTable [j - 1];
                    MethodDefinition mdef    = m_meths [j - 1];
                    if (mdef.IsConstructor)
                    {
                        dec.Constructors.Add(mdef);
                    }
                    else
                    {
                        dec.Methods.Add(mdef);
                    }
                    GenericContext context = new GenericContext(mdef);

                    MethodDefSig msig = m_sigReader.GetMethodDefSig(methRow.Signature);
                    mdef.HasThis           = msig.HasThis;
                    mdef.ExplicitThis      = msig.ExplicitThis;
                    mdef.CallingConvention = msig.MethCallConv;

                    int prms;
                    if (j == methTable.Rows.Count)
                    {
                        prms = m_parameters.Length + 1;
                    }
                    else
                    {
                        prms = (int)(methTable [j]).ParamList;
                    }

                    ParameterDefinition retparam = null;

                    //TODO: optimize this
                    ParamRow pRow  = null;
                    int      start = (int)methRow.ParamList - 1;

                    if (paramTable != null && start < prms - 1)
                    {
                        pRow = paramTable [start];
                    }

                    if (pRow != null && pRow.Sequence == 0)                       // ret type
                    {
                        retparam = new ParameterDefinition(
                            m_root.Streams.StringsHeap [pRow.Name],
                            0,
                            pRow.Flags,
                            null);
                        retparam.Method      = mdef;
                        m_parameters [start] = retparam;
                        start++;
                    }

                    for (int k = 0; k < msig.ParamCount; k++)
                    {
                        int pointer = start + k;

                        if (paramTable != null && pointer < prms - 1)
                        {
                            pRow = paramTable [pointer];
                        }

                        Param psig = msig.Parameters [k];

                        ParameterDefinition pdef;
                        if (pRow != null)
                        {
                            pdef = BuildParameterDefinition(
                                m_root.Streams.StringsHeap [pRow.Name],
                                pRow.Sequence, pRow.Flags, psig, context);
                            pdef.MetadataToken     = MetadataToken.FromMetadataRow(TokenType.Param, pointer);
                            m_parameters [pointer] = pdef;
                        }
                        else
                        {
                            pdef = BuildParameterDefinition(
                                string.Concat("A_", mdef.IsStatic ? k : k + 1),
                                k + 1, (ParamAttributes)0, psig, context);
                        }

                        pdef.Method = mdef;
                        mdef.Parameters.Add(pdef);
                    }

                    mdef.ReturnType = GetMethodReturnType(msig, context);
                    MethodReturnType mrt = mdef.ReturnType as MethodReturnType;
                    mrt.Method = mdef;
                    if (retparam != null)
                    {
                        mrt.Parameter = retparam;
                        mrt.Parameter.ParameterType = mrt.ReturnType;
                    }
                }
            }

            uint eprid = CodeReader.GetRid((int)m_reader.Image.CLIHeader.EntryPointToken);

            if (eprid > 0 && eprid <= m_meths.Length)
            {
                m_module.Assembly.EntryPoint = GetMethodDefAt(eprid);
            }
        }
        public override void VisitTypeDefinitionCollection(TypeDefinitionCollection types)
        {
            // type def reading
            TypeDefTable typesTable = m_tableReader.GetTypeDefTable();

            m_typeDefs = new TypeDefinition [typesTable.Rows.Count];
            for (int i = 0; i < typesTable.Rows.Count; i++)
            {
                TypeDefRow     type = typesTable [i];
                TypeDefinition t    = new TypeDefinition(
                    m_root.Streams.StringsHeap [type.Name],
                    m_root.Streams.StringsHeap [type.Namespace],
                    type.Flags);
                t.MetadataToken = MetadataToken.FromMetadataRow(TokenType.TypeDef, i);

                m_typeDefs [i] = t;
            }

            // nested types
            if (m_tHeap.HasTable(NestedClassTable.RId))
            {
                NestedClassTable nested = m_tableReader.GetNestedClassTable();
                for (int i = 0; i < nested.Rows.Count; i++)
                {
                    NestedClassRow row = nested [i];

                    TypeDefinition parent = GetTypeDefAt(row.EnclosingClass);
                    TypeDefinition child  = GetTypeDefAt(row.NestedClass);

                    parent.NestedTypes.Add(child);
                }
            }

            foreach (TypeDefinition type in m_typeDefs)
            {
                types.Add(type);
            }

            // type ref reading
            if (m_tHeap.HasTable(TypeRefTable.RId))
            {
                TypeRefTable typesRef = m_tableReader.GetTypeRefTable();

                m_typeRefs = new TypeReference [typesRef.Rows.Count];

                for (int i = 0; i < typesRef.Rows.Count; i++)
                {
                    AddTypeRef(typesRef, i);
                }
            }
            else
            {
                m_typeRefs = new TypeReference [0];
            }

            ReadTypeSpecs();
            ReadMethodSpecs();

            ReadMethods();
            ReadGenericParameters();

            // set base types
            for (int i = 0; i < typesTable.Rows.Count; i++)
            {
                TypeDefRow     type  = typesTable [i];
                TypeDefinition child = m_typeDefs [i];
                child.BaseType = GetTypeDefOrRef(type.Extends, new GenericContext(child));
            }

            CompleteMethods();
            ReadAllFields();
            ReadMemberReferences();
        }
        public MemberReference GetMemberRefAt(uint rid, GenericContext context)
        {
            int             index  = (int)rid - 1;
            MemberReference member = m_memberRefs [rid - 1];

            if (member != null)
            {
                return(member);
            }

            MemberRefTable mrTable = m_tableReader.GetMemberRefTable();
            MemberRefRow   mrefRow = mrTable [index];

            Signature sig = m_sigReader.GetMemberRefSig(mrefRow.Class.TokenType, mrefRow.Signature);

            switch (mrefRow.Class.TokenType)
            {
            case TokenType.TypeDef:
            case TokenType.TypeRef:
            case TokenType.TypeSpec:
                TypeReference  declaringType = GetTypeDefOrRef(mrefRow.Class, context);
                GenericContext nc            = context.Clone();

                if (declaringType is GenericInstanceType)
                {
                    TypeReference ct = declaringType;
                    while (ct is GenericInstanceType)
                    {
                        ct = (ct as GenericInstanceType).ElementType;
                    }

                    nc.Type          = ct;
                    nc.AllowCreation = ct.GetType() == typeof(TypeReference);
                }

                if (sig is FieldSig)
                {
                    FieldSig fs = sig as FieldSig;
                    member = new FieldReference(
                        m_root.Streams.StringsHeap [mrefRow.Name],
                        declaringType,
                        GetTypeRefFromSig(fs.Type, nc));
                }
                else
                {
                    string    name = m_root.Streams.StringsHeap [mrefRow.Name];
                    MethodSig ms   = sig as MethodSig;

                    MethodReference methref = new MethodReference(
                        name, ms.HasThis, ms.ExplicitThis, ms.MethCallConv);
                    methref.DeclaringType = declaringType;

                    if (sig is MethodDefSig)
                    {
                        int arity = (sig as MethodDefSig).GenericParameterCount;
                        for (int i = 0; i < arity; i++)
                        {
                            methref.GenericParameters.Add(new GenericParameter(i, methref));
                        }
                    }

                    nc.Method = methref;

                    methref.ReturnType = GetMethodReturnType(ms, nc);

                    methref.ReturnType.Method = methref;
                    for (int j = 0; j < ms.ParamCount; j++)
                    {
                        Param p = ms.Parameters [j];
                        ParameterDefinition pdef = BuildParameterDefinition(
                            string.Concat("A_", j), j, new ParamAttributes(), p, nc);
                        pdef.Method = methref;
                        methref.Parameters.Add(pdef);
                    }
                    member    = methref;
                    nc.Method = methref;
                }
                break;

            case TokenType.Method:
                // really not sure about this
                MethodDefinition methdef = GetMethodDefAt(mrefRow.Class.RID);
                member = new MethodReference(
                    methdef.Name, methdef.HasThis,
                    methdef.ExplicitThis, methdef.CallingConvention);
                member.DeclaringType = methdef.DeclaringType;
                break;

            case TokenType.ModuleRef:
                break;                 // TODO, implement that, or not
            }

            member.MetadataToken = MetadataToken.FromMetadataRow(TokenType.MemberRef, index);
            m_module.MemberReferences.Add(member);
            m_memberRefs [index] = member;

            return(member);
        }