/// <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); }
// 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); }
/// <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); }
/// <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); }