Пример #1
0
 /// <summary>Looks for a ArrayType matching the given OperandInfo.
 /// OperandInfo.oit must be OperandInfoT.ArrayType</summary>
 /// <param name="oi">The ArrayType specifying the searched Array.</param>
 /// <returns>Returns the ArrayType if found, otherwise null</returns>
 private object ResAElement(OperandInfo oi)
 {
     // TODO: uhm yes
     Log.Write(Log.Level.Warning, "Array deref not implemented");
     return(null);
 }
Пример #2
0
        // SAVE METHODS ******************************************************

        /// <summary>Saves the current reference list of this ILM into a xml parent node.
        /// If an entry is not resolved it will copy the raw data read back again.</summary>
        /// <param name="output">The parent node for the new reference nodes</param>
        public bool Save(XmlNode output)
        {
            XmlNode xM  = output.InsertCompressedElement(SST.MethodReference);
            XmlNode xF  = output.InsertCompressedElement(SST.FieldReference);
            XmlNode xT  = output.InsertCompressedElement(SST.TypeReference);
            XmlNode xCS = output.InsertCompressedElement(SST.CallSite);

            bool allOk = true;

            for (int i = 0; i < MemberList.Length; i++)
            {
                OperandInfo oi = MemberList[i];
                switch (oi.oit)
                {
                case OperandInfoT.ParameterDefinition:
                case OperandInfoT.ParameterReference:
                    Log.Write(Log.Level.Warning, $"PT resolving is obsolete: {oi}");
                    //todo reenable
                    if (oi.resolved)
                    {
                        Reference(((ParameterReference)oi.operand).ParameterType);
                    }
                    else
                    {
                        Log.Write(Log.Level.Error, "ParameterDef/Ref cannot be raw saved");
                        allOk = false;
                    }
                    break;

                case OperandInfoT.MethodDefinition:
                case OperandInfoT.MethodReference:
                case OperandInfoT.GenericInstanceMethod:
                    if (oi.resolved)
                    {
                        GenMChild(xM, (MethodReference)oi.operand, i);
                    }
                    else
                    {
                        xM.AppendClonedChild(oi.rawData);
                    }
                    break;

                case OperandInfoT.FieldDefinition:
                case OperandInfoT.FieldReference:
                    if (oi.resolved)
                    {
                        GenFChild(xF, (FieldReference)MemberList[i].operand, i);
                    }
                    else
                    {
                        xF.AppendClonedChild(oi.rawData);
                    }
                    break;

                case OperandInfoT.TypeDefinition:
                case OperandInfoT.TypeReference:
                case OperandInfoT.GenericInstanceType:
                case OperandInfoT.GenericParameter:
                    if (oi.resolved)
                    {
                        GenTChild(xT, (TypeReference)MemberList[i].operand, i);
                    }
                    else
                    {
                        xT.AppendClonedChild(oi.rawData);
                    }
                    break;

                case OperandInfoT.VariableDefinition:
                case OperandInfoT.VariableReference:
                    Log.Write(Log.Level.Warning, $"VD resolving is obsolete: {oi}");
                    //todo reenable
                    if (oi.resolved)
                    {
                        Reference(((VariableReference)oi.operand).VariableType);
                    }
                    else
                    {
                        Log.Write(Log.Level.Info, "VariableDef/Ref cannot be raw saved");
                        allOk = false;
                    }
                    break;

                case OperandInfoT.ArrayType:
                    if (oi.resolved)
                    {
                        GenAChild(xT, (ArrayType)MemberList[i].operand, i);
                    }
                    else
                    {
                        xT.AppendClonedChild(oi.rawData);
                    }
                    break;

                case OperandInfoT.CallSite:
                    if (oi.resolved)
                    {
                        XmlNode xElem = xCS.InsertCompressedElement(i);
                        xElem.CreateAttribute(SST.Name, ((CallSite)MemberList[i].operand).FullName);
                        Log.Write(Log.Level.Error, $"Unhandled CallSite: {oi}");
                        allOk = false;
                    }
                    else
                    {
                        xCS.AppendClonedChild(oi.rawData);
                    }
                    break;

                default:
                    Log.Write(Log.Level.Error, $"Not saved Member Entry: {oi}");
                    allOk = false;
                    break;
                }
            }

            MergeDoubleElements();

            return(allOk);
        }
Пример #3
0
        /// <summary>Looks for a TypeReference matching the given OperandInfo.
        /// OperandInfo.oit must be OperandInfoT.TypeReference</summary>
        /// <param name="oi">The OperandInfo specifying the searched Type.</param>
        /// <returns>Returns the TypeReference if found, otherwise null</returns>
        private object ResTElement(OperandInfo oi)
        {
            XmlNode xDataNode = oi.rawData;

            Mono.Collections.Generic.Collection <TypeDefinition> searchCollection;

            string name = xDataNode.GetAttribute(SST.Name);

            if (string.IsNullOrEmpty(name))
            {
                oi.Status = ResolveStatus.SaveFileError; Log.Write(Log.Level.Error, $"\"{xDataNode.Name}\" has No Name"); return(null);
            }

            string namesp = string.Empty;
            // TODO enable namespace comparison, atm the algorithm will always take the first element.

            bool   isGeneric;
            bool   isGenericInstance;
            bool   isNested;
            bool   noNamespaceGiven = false;
            string genericvalstr;

            string[] genericValues;

            // 1] search in
            #region search_in
            string nestedin = xDataNode.GetAttribute(SST.NestedIn);
            if (string.IsNullOrEmpty(nestedin))             // type is module subtype
            {
                isNested = false;

                string module = xDataNode.GetAttribute(SST.Module);
                if (string.IsNullOrEmpty(module))
                {
                    oi.Status = ResolveStatus.SaveFileError; return(null);
                }

                namesp = xDataNode.GetAttribute(SST.Namespace);
                if (string.IsNullOrEmpty(namesp))
                {
                    noNamespaceGiven = true;
                    Log.Write(Log.Level.Careful, "No Namespace defined! Will use first matching Item(!)");
                }

                ModuleDefinition ModDef = null;
                if (dataStruct.AssemblyDefinition.MainModule.Name == module)
                {
                    ModDef = dataStruct.AssemblyDefinition.MainModule;
                }
                else
                {
                    try
                    {
                        // fix if ns not found
                        foreach (AssemblyNameReference anr in dataStruct.AssemblyDefinition.MainModule.AssemblyReferences)
                        {
                            if (anr.Name == module)
                            {
                                AssemblyDefinition AssDef = dataStruct.AssemblyDefinition.MainModule.AssemblyResolver.Resolve(anr);
                                ModDef = AssDef.MainModule;
                                break;
                            }
                        }
                        if (ModDef == null)
                        {
                            oi.Status = ResolveStatus.ReferenceNotFound; Log.Write(Log.Level.Error, $"ModuleDefinition \"{module}\" not found"); return(null);
                        }
                    }
                    catch
                    {
                        oi.Status = ResolveStatus.ReferenceNotFound;
                        Log.Write(Log.Level.Error, $"Assembly \"{module}\" is missing");
                        return(null);
                    }
                }

                searchCollection = ModDef.Types;
            }
            else             // type is nested
            {
                isNested = true;

                TypeDefinition nestintyp = Resolve(nestedin.ToBaseInt()) as TypeDefinition;
                if (nestintyp == null)
                {
                    oi.Status = ResolveStatus.ReferenceNotFound; Log.Write(Log.Level.Error, $"Nestparent \"{nestedin}\" not found"); return(null);
                }

                searchCollection = nestintyp.NestedTypes;
            }
            #endregion

            // 2] search generics
            #region search_generics
            if (xDataNode.GetAttribute(SST.Generics, out genericvalstr))
            {
                genericValues = genericvalstr.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                isGeneric     = genericValues.Length != 0;
                if (isGeneric)
                {
                    isGenericInstance = !genericvalstr.Contains('%');                            // TDOD: check if this is true
                }
                else
                {
                    isGenericInstance = false;
                }
            }
            else
            {
                isGeneric         = false;
                isGenericInstance = false;
                genericValues     = null;
            }
            #endregion

            // 3] compare
            #region compare
            foreach (TypeDefinition typdef in searchCollection)
            {
                // TODO: find out what !-beginning params mean

                if (typdef.Name == name && (isNested || noNamespaceGiven || typdef.Namespace == namesp))
                {
                    if (isGeneric)
                    {
                        if (isGenericInstance)
                        {
                            // TODO: either find one or create new (better not new, because new will be a diferent object from the cecil existing)
                            // also deref elements not starting with $ and check if they match
                            // another problem is that this part will never be reached because GITs aren't stored in the searchCollection
                            // think about a solution later
                            continue;
                        }
                        else
                        {
                            if (typdef.GenericParameters.Count != genericValues.Length)
                            {
                                continue;
                            }
                        }
                    }

                    Type t = typdef.GetType();
                    if (!Enum.TryParse(t.Name, out oi.oit))
                    {
                        Log.Write(Log.Level.Warning, $"OperandInfoType \"{t.Name}\" was not found");
                    }
                    oi.operand = typdef;
                    oi.Status  = ResolveStatus.Resolved;
                    return(typdef);
                }
            }
            #endregion

            Log.Write(Log.Level.Error, $"TypeDefinition \"{name}\" coundn't be found in the Module");
            return(null);
        }
Пример #4
0
        /// <summary>Looks for a MethodReference matching the given OperandInfo.
        /// OperandInfo.oit must be OperandInfoT.MethodReference</summary>
        /// <param name="oi">The OperandInfo specifying the searched Method.</param>
        /// <returns>Returns the MethodReference if found, otherwise null</returns>
        private object ResMElement(OperandInfo oi)
        {
            XmlNode xDataNode = oi.rawData;

            string name = xDataNode.GetAttribute(SST.Name);
            string type = xDataNode.GetAttribute(SST.Type);

            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(type))
            {
                oi.Status = ResolveStatus.SaveFileError;
                Log.Write(Log.Level.Error, $"\"{xDataNode.Name}\" has no Name or Parenttype");
                return(null);
            }

            bool   isGeneric;
            bool   isGenericInstance;
            string genericvalstr;

            string[] genericValues;

            // 1] search in
            #region search_in
            TypeDefinition typdef = Resolve(type.ToBaseInt()) as TypeDefinition;
            if (typdef == null)
            {
                oi.Status = ResolveStatus.ReferenceNotFound; Log.Write(Log.Level.Error, $"Type \"{name}\" couldn't be resolved"); return(null);
            }
            #endregion

            // 2] search generics
            #region search_generics
            if (xDataNode.GetAttribute(SST.Generics, out genericvalstr))
            {
                genericValues = genericvalstr.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                isGeneric     = genericValues.Length != 0;
                if (isGeneric)
                {
                    isGenericInstance = !genericvalstr.Contains('%');                            // TDOD: check if this is true
                }
                else
                {
                    isGenericInstance = false;
                }
            }
            else
            {
                isGeneric         = false;
                isGenericInstance = false;
                genericValues     = null;
            }
            #endregion

            // 3] compare
            #region compare
            foreach (MethodReference metdef in typdef.Methods)
            {
                if (metdef.Name == name)
                {
                    if (isGeneric)
                    {
                        if (isGenericInstance)
                        {
                            // TODO: same as ResTElement
                        }
                        else
                        {
                            if (metdef.GenericParameters.Count != genericValues.Length)
                            {
                                continue;
                            }
                        }
                    }

                    Type t = metdef.GetType();
                    if (!Enum.TryParse(t.Name, out oi.oit))
                    {
                        Log.Write(Log.Level.Warning, $"OperandInfoType \"{t.Name}\" not found");
                    }
                    oi.operand = metdef;
                    oi.Status  = ResolveStatus.Resolved;
                    return(metdef);
                }
            }
            #endregion

            Log.Write(Log.Level.Error, $"MethodDefinition \"{name}\" couldn't be found in Type \"{typdef.Name}\"");
            return(null);
        }