public override bool IsActiveFor(AssemblyDefinition assembly) { #if XAMARIN_NO_TLS return(false); #else #if MONOMAC // this is only supported on the profiles where we ship mono (not classic with a system mono) if (!(Profile.Current is MacMobileProfile)) { return(false); } #endif if (assembly.Name.Name != (Profile.Current as BaseProfile).ProductAssembly) { return(false); } // process only assemblies where the linker is enabled (e.g. --linksdk, --linkskip) return(Annotations.GetAction(assembly) == AssemblyAction.Link); #endif }
void SweepAssembly(AssemblyDefinition assembly) { if (Annotations.GetAction(assembly) != AssemblyAction.Link) { return; } if (!IsMarkedAssembly(assembly)) { RemoveAssembly(assembly); return; } var types = new List <TypeDefinition> (); foreach (TypeDefinition type in assembly.MainModule.Types) { if (Annotations.IsMarked(type)) { SweepType(type); types.Add(type); continue; } if (type.Name == "<Module>") { types.Add(type); } else { ElementRemoved(type); } } assembly.MainModule.Types.Clear(); foreach (TypeDefinition type in types) { assembly.MainModule.Types.Add(type); } }
protected void ProcessAssemblyAction(AssemblyDefinition assembly) { switch (Annotations.GetAction(assembly)) { case AssemblyAction.AddBypassNGenUsed: Annotations.SetAction(assembly, AssemblyAction.AddBypassNGen); goto case AssemblyAction.AddBypassNGen; case AssemblyAction.AddBypassNGen: // FIXME: AddBypassNGen is just wrong, it should not be action as we need to // turn it to Action.Save here to e.g. correctly update debug symbols if (!Context.KeepTypeForwarderOnlyAssemblies || BypassNGenToSave.Contains(assembly)) { goto case AssemblyAction.Save; } break; case AssemblyAction.CopyUsed: AssemblyAction assemblyAction = AssemblyAction.Copy; if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders(assembly)) { assemblyAction = AssemblyAction.Save; } Annotations.SetAction(assembly, assemblyAction); break; case AssemblyAction.Copy: break; case AssemblyAction.Link: SweepAssembly(assembly); break; case AssemblyAction.Save: SweepTypeForwarders(assembly); break; } }
protected void ProcessAssemblyAction(AssemblyDefinition assembly) { switch (Annotations.GetAction(assembly)) { case AssemblyAction.Link: if (!IsMarkedAssembly(assembly)) { RemoveAssembly(assembly); return; } break; case AssemblyAction.AddBypassNGenUsed: if (!IsMarkedAssembly(assembly)) { RemoveAssembly(assembly); } else { Annotations.SetAction(assembly, AssemblyAction.AddBypassNGen); } return; case AssemblyAction.CopyUsed: if (!IsMarkedAssembly(assembly)) { RemoveAssembly(assembly); } else { Annotations.SetAction(assembly, AssemblyAction.Copy); } return; default: return; } SweepAssembly(assembly); }
protected override void ProcessAssembly(AssemblyDefinition assembly) { base.ProcessAssembly(assembly); if (Annotations.GetAction(assembly) == AssemblyAction.Delete) { return; } #if !NET if (skip_sdk_assemblies && Profile.IsSdkAssembly(assembly)) { return; } #endif if (!assembly.MainModule.HasTypes) { return; } var hasSymbols = false; if (assembly.MainModule.HasModuleReferences) { hasSymbols = true; } else if (assembly.MainModule.HasTypeReference(Namespaces.Foundation + ".FieldAttribute")) { hasSymbols = true; } if (!hasSymbols) { return; } foreach (var type in assembly.MainModule.Types) { ProcessType(type); } }
protected override void ProcessAssembly(AssemblyDefinition assembly) { if (assembly.Name.Name == "mscorlib" || assembly.Name.Name == "smcs") { return; } if (Annotations.GetAction(assembly) != AssemblyAction.Link) { return; } Report("in assembly {0}", assembly.Name); foreach (ModuleDefinition module in assembly.Modules) { foreach (TypeDefinition type in module.Types) { CheckType(type); } } }
protected override void Process() { assemblies = Context.Annotations.GetAssemblies().ToArray(); foreach (var assembly in assemblies) { RemoveUnmarkedAssembly(assembly); } foreach (var assembly in assemblies) { if (Annotations.GetAction(assembly) == AssemblyAction.Delete) { UpdateAssembliesReferencingRemovedAssembly(assembly); } } foreach (var assembly in assemblies) { ProcessAssemblyAction(assembly); } }
void OutputAssembly(AssemblyDefinition assembly) { string directory = Context.OutputDirectory; //CopyConfigFileIfNeeded (assembly, directory); switch (Annotations.GetAction(assembly)) { case AssemblyAction.Link: if (assembly.FullName == Globals.Context.TargetAssembly.FullName) { Globals.Context.TargetAssembly = assembly; } //assembly.Write (GetAssemblyFileName (assembly, directory), SaveSymbols (assembly)); break; case AssemblyAction.Copy: CloseSymbols(assembly); //CopyAssembly (GetOriginalAssemblyFileInfo (assembly), directory, Context.LinkSymbols); break; case AssemblyAction.Delete: CloseSymbols(assembly); Globals.Context.MarkedAssemblies.Add(assembly.FullName); var target = GetAssemblyFileName(assembly, directory); if (File.Exists(target)) { File.Delete(target); File.Delete(target + ".mdb"); File.Delete(GetConfigFile(target)); } break; default: CloseSymbols(assembly); break; } }
protected override void ProcessAssembly(AssemblyDefinition assembly) { if (!Annotations.HasAction(assembly)) { return; } var action = Annotations.GetAction(assembly); if (action == AssemblyAction.Skip || action == AssemblyAction.Delete) { return; } var fileName = assembly.Name.Name + ".dll"; if (MonoAndroidHelper.IsFrameworkAssembly(fileName) && !MonoAndroidHelper.FrameworkEmbeddedJarLookupTargets.Contains(fileName)) { return; } bool assembly_modified = false; foreach (var mod in assembly.Modules) { foreach (var r in mod.Resources.ToArray()) { if (ShouldStripResource(r)) { Context.LogMessage(" Stripped {0} from {1}", r.Name, fileName); mod.Resources.Remove(r); assembly_modified = true; } } } if (assembly_modified && action == AssemblyAction.Copy) { Annotations.SetAction(assembly, AssemblyAction.Save); } }
void SweepAssembly(AssemblyDefinition assembly) { if (Annotations.GetAction(assembly) != AssemblyAction.Link) { return; } foreach (var type in assembly.MainModule.Types) { if (Annotations.IsMarked(type)) { bool isComObject = false; TypeReference parentType = type.BaseType; while (parentType != null && parentType.FullName != "System.Object" && parentType is TypeDefinition) { if (parentType.FullName == "SharpDX.ComObject") { isComObject = true; break; } parentType = ((TypeDefinition)parentType).BaseType; } if (isComObject) { foreach (var methodDefinition in type.Methods) { if (methodDefinition.IsConstructor && methodDefinition.Parameters.Count == 1 && methodDefinition.Parameters[0].ParameterType.FullName == "System.IntPtr") { Context.Annotations.Mark(methodDefinition); Context.Annotations.SetAction(methodDefinition, MethodAction.Parse); } } } continue; } } }
void OutputAssembly(AssemblyDefinition assembly) { string directory = Context.OutputDirectory; CopyConfigFileIfNeeded(assembly, directory); switch (Annotations.GetAction(assembly)) { case AssemblyAction.Save: case AssemblyAction.Link: case AssemblyAction.AddBypassNGen: Context.Tracer.AddDependency(assembly); WriteAssembly(assembly, directory); break; case AssemblyAction.Copy: Context.Tracer.AddDependency(assembly); CloseSymbols(assembly); CopyAssembly(GetOriginalAssemblyFileInfo(assembly), directory, Context.LinkSymbols); break; case AssemblyAction.Delete: CloseSymbols(assembly); var target = GetAssemblyFileName(assembly, directory); if (File.Exists(target)) { File.Delete(target); File.Delete(target + ".mdb"); File.Delete(Path.ChangeExtension(target, "pdb")); File.Delete(GetConfigFile(target)); } break; default: CloseSymbols(assembly); break; } }
void SweepReferences(AssemblyDefinition assembly, AssemblyDefinition target) { if (assembly == target) { return; } var references = assembly.MainModule.AssemblyReferences; for (int i = 0; i < references.Count; i++) { var reference = references [i]; var r = Context.Resolver.Resolve(reference); if (!AreSameReference(r.Name, target.Name)) { continue; } references.RemoveAt(i); // Removing the reference does not mean it will be saved back to disk! // That depends on the AssemblyAction set for the `assembly` switch (Annotations.GetAction(assembly)) { case AssemblyAction.Copy: // Copy means even if "unlinked" we still want that assembly to be saved back // to disk (OutputStep) without the (removed) reference Annotations.SetAction(assembly, AssemblyAction.Save); ResolveAllTypeReferences(assembly); break; case AssemblyAction.Save: case AssemblyAction.Link: ResolveAllTypeReferences(assembly); break; } return; } }
protected override void ProcessAssembly(AssemblyDefinition assembly) { if (!Annotations.HasAction(assembly)) { Annotations.SetAction(assembly, AssemblyAction.Skip); } bool changed = FixAbstractMethods(assembly); if (changed) { Context.SafeReadSymbols(assembly); AssemblyAction action = Annotations.HasAction(assembly) ? Annotations.GetAction(assembly) : AssemblyAction.Skip; if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) { Annotations.SetAction(assembly, AssemblyAction.Save); } var td = AbstractMethodErrorConstructor.DeclaringType.Resolve(); Annotations.Mark(td); Annotations.SetPreserve(td, TypePreserve.Nothing); Annotations.AddPreservedMethod(td, AbstractMethodErrorConstructor.Resolve()); } }
void OutputAssembly(AssemblyDefinition assembly) { string directory = Context.OutputDirectory; CopyConfigFileIfNeeded(assembly, directory); var action = Annotations.GetAction(assembly); Context.LogMessage($"Output action: {action,8} assembly: {assembly}"); switch (action) { case AssemblyAction.Save: case AssemblyAction.Link: case AssemblyAction.AddBypassNGen: WriteAssembly(assembly, directory); CopySatelliteAssembliesIfNeeded(assembly, directory); assembliesWritten.Add(GetOriginalAssemblyFileInfo(assembly).Name); break; case AssemblyAction.Copy: CloseSymbols(assembly); CopyAssembly(assembly, directory); CopySatelliteAssembliesIfNeeded(assembly, directory); assembliesWritten.Add(GetOriginalAssemblyFileInfo(assembly).Name); break; case AssemblyAction.Delete: CloseSymbols(assembly); DeleteAssembly(assembly, directory); break; default: CloseSymbols(assembly); break; } }
void OutputAssembly(AssemblyDefinition assembly) { string directory = Context.OutputDirectory; CopyConfigFileIfNeeded(assembly, directory); var action = Annotations.GetAction(assembly); Context.LogMessage(MessageImportance.Low, $"Output action: {action,8} assembly: {assembly}"); switch (action) { case AssemblyAction.Save: case AssemblyAction.Link: case AssemblyAction.AddBypassNGen: Context.Tracer.AddDependency(assembly); WriteAssembly(assembly, directory); CopySatelliteAssembliesIfNeeded(assembly, directory); break; case AssemblyAction.Copy: Context.Tracer.AddDependency(assembly); CloseSymbols(assembly); CopyAssembly(assembly, directory); CopySatelliteAssembliesIfNeeded(assembly, directory); break; case AssemblyAction.Delete: CloseSymbols(assembly); DeleteAssembly(assembly, directory); break; default: CloseSymbols(assembly); break; } }
protected override void ProcessAssembly(AssemblyDefinition assembly) { if (!Annotations.HasAction(assembly)) { Annotations.SetAction(assembly, AssemblyAction.Skip); } if (Profile.IsSdkAssembly(assembly) || Profile.IsProductAssembly(assembly)) { return; } bool changed = false; foreach (var type in assembly.MainModule.Types) { if (MightNeedFix(type)) { changed |= FixAbstractMethods(type); } } if (changed) { Context.SafeReadSymbols(assembly); AssemblyAction action = Annotations.HasAction(assembly) ? Annotations.GetAction(assembly) : AssemblyAction.Skip; if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) { Annotations.SetAction(assembly, AssemblyAction.Save); } var td = AbstractMethodErrorConstructor.DeclaringType.Resolve(); Annotations.Mark(td); Annotations.SetPreserve(td, TypePreserve.Nothing); Annotations.AddPreservedMethod(td, AbstractMethodErrorConstructor.Resolve()); } }
void SweepReferences(AssemblyDefinition assembly, AssemblyDefinition target) { var references = assembly.MainModule.AssemblyReferences; for (int i = 0; i < references.Count; i++) { var reference = references [i]; if (!AreSameReference(reference, target.Name)) { continue; } references.RemoveAt(i); // Removing the reference does not mean it will be saved back to disk! // That depends on the AssemblyAction set for the `assembly` if (Annotations.GetAction(assembly) == AssemblyAction.Copy) { // Copy means even if "unlinked" we still want that assembly to be saved back // to disk (OutputStep) without the (removed) reference Annotations.SetAction(assembly, AssemblyAction.Save); } return; } }
protected override void EndProcess() { if (!need_https) { return; } var mono_security = Context.Resolve("Mono.Security"); if (mono_security == null) { return; } if (Annotations.GetAction(mono_security) != AssemblyAction.Link) { return; } var xml_preserve = CreatePreserveStep(); Context.Pipeline.AddStepAfter(typeof(PreserveHttps), xml_preserve); // Context.Pipeline.AddStepAfter (xml_preserve, new PreserveCrypto ()); }
SortedDictionary <TypeDefinition, IList> /*,List<IAnnotationProvider>>*/ ScanAssembly(AssemblyDefinition assembly) { if (Annotations.GetAction(assembly) != AssemblyAction.Link) { return(null); } SortedDictionary <TypeDefinition, IList> members_used = new SortedDictionary <TypeDefinition, IList> (new TypeComparer()); foreach (TypeDefinition type in assembly.MainModule.Types) { IList used_providers = FilterPublicMembers(ScanType(type)); if (used_providers.Count > 0) { members_used [type] = used_providers; } else if (IsInternal(type, true) && Annotations.IsMarked(type)) { throw new NotSupportedException(String.Format("The type {0} is used while its API is not", type.ToString())); } } return(members_used); }
public override bool IsActiveFor(AssemblyDefinition assembly) { return(Annotations.GetAction(assembly) == AssemblyAction.Link); }
void SweepAssembly(AssemblyDefinition assembly) { switch (Annotations.GetAction(assembly)) { case AssemblyAction.Link: if (!IsMarkedAssembly(assembly)) { RemoveAssembly(assembly); return; } break; case AssemblyAction.AddBypassNGenUsed: if (!IsMarkedAssembly(assembly)) { RemoveAssembly(assembly); } else { Annotations.SetAction(assembly, AssemblyAction.AddBypassNGen); } return; case AssemblyAction.CopyUsed: if (!IsMarkedAssembly(assembly)) { RemoveAssembly(assembly); } else { Annotations.SetAction(assembly, AssemblyAction.Copy); } return; default: return; } var types = new List <TypeDefinition> (); foreach (TypeDefinition type in assembly.MainModule.Types) { if (Annotations.IsMarked(type)) { SweepType(type); types.Add(type); continue; } if (type.Name == "<Module>") { types.Add(type); } else { ElementRemoved(type); } } assembly.MainModule.Types.Clear(); foreach (TypeDefinition type in types) { assembly.MainModule.Types.Add(type); } SweepResources(assembly); }
public override bool IsActiveFor(AssemblyDefinition assembly) { return(!Profile.IsSdkAssembly(assembly) && Annotations.GetAction(assembly) == AssemblyAction.Link); }
protected override void Process(MethodDefinition method) { if (!context.Annotations.IsMarked(method)) { return; } if (!method.HasBody) { return; } var body = method.Body; if (!body.HasExceptionHandlers) { return; } var anyFilterClauses = false; foreach (var eh in body.ExceptionHandlers) { if (eh.HandlerType == ExceptionHandlerType.Filter) { anyFilterClauses = true; string msg; PropertyDefinition property; if (method.IsSpecialName && ((property = method.GetPropertyByAccessor()) != null)) { msg = String.Format(Errors.MT2105_E, method.DeclaringType.FullName, property.Name, eh.HandlerType); } else { msg = String.Format(Errors.MT2105_F, method.DeclaringType.FullName, method.Name, eh.HandlerType); } DerivedLinkContext.Exceptions.Add(ErrorHelper.CreateWarning(Options.Application, 2105, method, msg)); break; } } if (!anyFilterClauses) { return; } body = new MethodBody(method); var il = body.GetILProcessor(); il.Emit(OpCodes.Ldstr, "This method contains IL not supported when compiled to bitcode."); if (nse_ctor_def == null) { var nse = DerivedLinkContext.Corlib.MainModule.GetType("System", "NotSupportedException"); foreach (var ctor in nse.GetConstructors()) { if (!ctor.HasParameters) { continue; } var parameters = ctor.Parameters; if (parameters.Count != 1) { continue; } if (!parameters [0].ParameterType.Is("System", "String")) { continue; } nse_ctor_def = ctor; context.Annotations.Mark(ctor); break; } nse_ctors = new Dictionary <ModuleDefinition, MethodReference> (); } MethodReference nse_ctor; if (!nse_ctors.TryGetValue(method.Module, out nse_ctor)) { nse_ctors [method.Module] = nse_ctor = method.Module.ImportReference(nse_ctor_def); // We're processing all assemblies, not linked assemblies, so // make sure we're saving any changes to non-linked assemblies as well. var assembly = method.Module.Assembly; var action = Annotations.GetAction(assembly); switch (action) { case AssemblyAction.Link: case AssemblyAction.Save: break; default: Annotations.SetAction(assembly, AssemblyAction.Save); break; } } il.Emit(OpCodes.Newobj, nse_ctor); il.Emit(OpCodes.Throw); method.Body = body; }
private void EnsureBypassNGenAttribute(ModuleDefinition targetModule) { if (bypassNGenAttribute != null) { return; } ModuleDefinition corelibMainModule = coreLibAssembly.MainModule; TypeReference bypassNGenAttributeRef = new TypeReference("System.Runtime", "BypassNGenAttribute", corelibMainModule, targetModule.TypeSystem.CoreLibrary); TypeDefinition bypassNGenAttributeDef = corelibMainModule.MetadataResolver.Resolve(bypassNGenAttributeRef); MethodDefinition bypassNGenAttributeDefaultConstructor = null; if (bypassNGenAttributeDef == null) { // System.Runtime.BypassNGenAttribute is not found in corelib. Add it. TypeReference systemAttributeRef = new TypeReference("System", "Attribute", corelibMainModule, targetModule.TypeSystem.CoreLibrary); TypeReference systemAttribute = corelibMainModule.MetadataResolver.Resolve(systemAttributeRef); systemAttribute = corelibMainModule.ImportReference(systemAttribute); if (systemAttribute == null) { throw new System.ApplicationException("System.Attribute is not found in " + targetModule.TypeSystem.CoreLibrary.Name); } MethodReference systemAttributeDefaultConstructorRef = new MethodReference(".ctor", corelibMainModule.TypeSystem.Void, systemAttributeRef); MethodReference systemAttributeDefaultConstructor = corelibMainModule.MetadataResolver.Resolve(systemAttributeDefaultConstructorRef); systemAttributeDefaultConstructor = corelibMainModule.ImportReference(systemAttributeDefaultConstructor); if (systemAttributeDefaultConstructor == null) { throw new System.ApplicationException("System.Attribute has no default constructor"); } bypassNGenAttributeDef = new TypeDefinition("System.Runtime", "BypassNGenAttribute", TypeAttributes.NotPublic | TypeAttributes.Sealed, systemAttribute); coreLibAssembly.MainModule.Types.Add(bypassNGenAttributeDef); if (Annotations.GetAction(coreLibAssembly) == AssemblyAction.Copy) { Annotations.SetAction(coreLibAssembly, AssemblyAction.Save); } const MethodAttributes ctorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; bypassNGenAttributeDefaultConstructor = new MethodDefinition(".ctor", ctorAttributes, coreLibAssembly.MainModule.TypeSystem.Void); var instructions = bypassNGenAttributeDefaultConstructor.Body.Instructions; instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Call, systemAttributeDefaultConstructor)); instructions.Add(Instruction.Create(OpCodes.Ret)); bypassNGenAttributeDef.Methods.Add(bypassNGenAttributeDefaultConstructor); } else { foreach (MethodDefinition method in bypassNGenAttributeDef.Methods) { if (method.IsConstructor && !method.IsStatic && !method.HasParameters) { bypassNGenAttributeDefaultConstructor = method; break; } } if (bypassNGenAttributeDefaultConstructor == null) { throw new System.ApplicationException("System.Runtime.BypassNGenAttribute has no default constructor"); } } MethodReference defaultConstructorReference = targetModule.ImportReference(bypassNGenAttributeDefaultConstructor); bypassNGenAttribute = new CustomAttribute(defaultConstructorReference); }
void UpdateAssemblyReferencesToRemovedAssemblies(AssemblyDefinition assembly) { var action = Annotations.GetAction(assembly); switch (action) { case AssemblyAction.Skip: case AssemblyAction.Delete: case AssemblyAction.Link: case AssemblyAction.Save: return; case AssemblyAction.Copy: case AssemblyAction.CopyUsed: case AssemblyAction.AddBypassNGen: case AssemblyAction.AddBypassNGenUsed: foreach (var reference in assembly.MainModule.AssemblyReferences) { AssemblyDefinition ad = Context.Resolver.Resolve(reference); if (ad == null) { continue; } RemoveUnmarkedAssembly(ad); if (Annotations.GetAction(ad) != AssemblyAction.Delete) { continue; } // Assembly was removed in the output but it's referenced by // other assembly with action which does not update references switch (action) { case AssemblyAction.CopyUsed: case AssemblyAction.Copy: // // Assembly has a reference to another assembly which has been fully removed. This can // happen when for example the reference assembly is 'copy-used' and it's not needed. // // or // // Assembly can contain type references with // type forwarders to deleted assembly (facade) when // facade assemblies are not kept. For that reason we need to // rewrite the copy to save to update the scopes not to point // forwarding assembly (facade). // // foo.dll -> facade.dll -> lib.dll // copy | copy (delete) | link // Annotations.SetAction(assembly, AssemblyAction.Save); continue; case AssemblyAction.AddBypassNGenUsed: Annotations.SetAction(assembly, AssemblyAction.AddBypassNGen); goto case AssemblyAction.AddBypassNGen; case AssemblyAction.AddBypassNGen: BypassNGenToSave.Add(assembly); continue; } } break; default: throw new ArgumentOutOfRangeException(action.ToString()); } }
void SweepReferences(AssemblyDefinition assembly, AssemblyDefinition referenceToRemove) { if (assembly == referenceToRemove) { return; } bool reference_removed = false; var references = assembly.MainModule.AssemblyReferences; for (int i = 0; i < references.Count; i++) { var reference = references [i]; AssemblyDefinition ad = Context.Resolver.Resolve(reference); if (ad == null || !AreSameReference(ad.Name, referenceToRemove.Name)) { continue; } ReferenceRemoved(assembly, reference); references.RemoveAt(i--); reference_removed = true; } if (reference_removed) { switch (Annotations.GetAction(assembly)) { case AssemblyAction.CopyUsed: if (IsUsedAssembly(assembly)) { goto case AssemblyAction.Copy; } break; case AssemblyAction.Copy: // // Assembly has a reference to another assembly which has been fully removed. This can // happen when for example the reference assembly is 'copy-used' and it's not needed. // // or // // Assembly can contain type references with // type forwarders to deleted assembly (facade) when // facade assemblies are not kept. For that reason we need to // rewrite the copy to save to update the scopes not to point // forwarding assembly (facade). // // foo.dll -> facade.dll -> lib.dll // copy | copy (delete) | link // Annotations.SetAction(assembly, AssemblyAction.Save); break; case AssemblyAction.AddBypassNGenUsed: if (IsUsedAssembly(assembly)) { Annotations.SetAction(assembly, AssemblyAction.AddBypassNGen); goto case AssemblyAction.AddBypassNGen; } break; case AssemblyAction.AddBypassNGen: BypassNGenToSave.Add(assembly); break; } } }
// If certain conditions are met, we can optimize away the code for the dynamic registrar. bool RequiresDynamicRegistrar(AssemblyDefinition assembly, bool warnIfRequired) { // We know that the SDK assemblies we ship don't use the methods we're looking for. if (Profile.IsSdkAssembly(assembly)) { return(false); } // The product assembly itself is safe as long as it's linked if (Profile.IsProductAssembly(assembly)) { if (Annotations.GetAction(assembly) != AssemblyAction.Link) { return(false); } PlatformAssembly = assembly; } // Can't touch the forbidden fruit in the product assembly unless there's a reference to it var hasProductReference = false; foreach (var ar in assembly.MainModule.AssemblyReferences) { if (!Profile.IsProductAssembly(ar.Name)) { continue; } hasProductReference = true; break; } if (!hasProductReference) { return(false); } // Check if the assembly references any methods that require the dynamic registrar var productAssemblyName = PlatformAssemblyName; var requires = false; foreach (var mr in assembly.MainModule.GetMemberReferences()) { if (mr.DeclaringType == null || string.IsNullOrEmpty(mr.DeclaringType.Namespace)) { continue; } var scope = mr.DeclaringType.Scope; var name = string.Empty; switch (scope.MetadataScopeType) { case MetadataScopeType.ModuleDefinition: name = ((ModuleDefinition)scope).Assembly.Name.Name; break; default: name = scope.Name; break; } if (name != productAssemblyName) { continue; } switch (mr.DeclaringType.Namespace) { case "ObjCRuntime": switch (mr.DeclaringType.Name) { case "Runtime": switch (mr.Name) { case "ConnectMethod": // Req 1: Nobody must call Runtime.ConnectMethod. if (warnIfRequired) { Warn(assembly, mr); } requires = true; break; case "RegisterAssembly": // Req 3: Nobody must call Runtime.RegisterAssembly if (warnIfRequired) { Warn(assembly, mr); } requires = true; break; } break; case "BlockLiteral": switch (mr.Name) { case "SetupBlock": case "SetupBlockUnsafe": // Req 2: Nobody must call BlockLiteral.SetupBlock[Unsafe]. // // Fortunately the linker is able to rewrite calls to SetupBlock[Unsafe] to call // SetupBlockImpl (which doesn't need the dynamic registrar), which means we only have // to look in assemblies that aren't linked. if (Annotations.GetAction(assembly) == AssemblyAction.Link && Optimizations.OptimizeBlockLiteralSetupBlock == true) { break; } if (warnIfRequired) { Warn(assembly, mr); } requires = true; break; } break; case "TypeConverter": switch (mr.Name) { case "ToManaged": // Req 4: Nobody must call TypeConverter.ToManaged if (warnIfRequired) { Warn(assembly, mr); } requires = true; break; } break; } break; } } return(requires); }
void SweepReferences(AssemblyDefinition assembly, AssemblyDefinition target) { if (assembly == target) { return; } var references = assembly.MainModule.AssemblyReferences; for (int i = 0; i < references.Count; i++) { var reference = references [i]; AssemblyDefinition r = Context.Resolver.Resolve(reference); if (r == null) { continue; } if (!AreSameReference(r.Name, target.Name)) { continue; } ReferenceRemoved(assembly, reference); // removal from `references` requires an adjustment to `i` references.RemoveAt(i--); // Removing the reference does not mean it will be saved back to disk! // That depends on the AssemblyAction set for the `assembly` switch (Annotations.GetAction(assembly)) { case AssemblyAction.Copy: // We need to save the assembly if a reference was removed, otherwise we can end up // with an assembly that references an assembly that no longer exists Annotations.SetAction(assembly, AssemblyAction.Save); // Copy means even if "unlinked" we still want that assembly to be saved back // to disk (OutputStep) without the (removed) reference if (!Context.KeepTypeForwarderOnlyAssemblies) { ResolveAllTypeReferences(assembly); } break; case AssemblyAction.CopyUsed: if (IsMarkedAssembly(assembly) && !Context.KeepTypeForwarderOnlyAssemblies) { Annotations.SetAction(assembly, AssemblyAction.Save); ResolveAllTypeReferences(assembly); } break; case AssemblyAction.Save: case AssemblyAction.Link: case AssemblyAction.AddBypassNGen: case AssemblyAction.AddBypassNGenUsed: if (!Context.KeepTypeForwarderOnlyAssemblies) { ResolveAllTypeReferences(assembly); } break; } } }
protected virtual bool IgnoreScope(IMetadataScope scope) { AssemblyDefinition assembly = ResolveAssembly(scope); return(Annotations.GetAction(assembly) != AssemblyAction.Link); }
void SweepReferences(AssemblyDefinition assembly, AssemblyDefinition target) { if (assembly == target) { return; } var references = assembly.MainModule.AssemblyReferences; for (int i = 0; i < references.Count; i++) { var reference = references [i]; AssemblyDefinition r = null; try { r = Context.Resolver.Resolve(reference); } catch (AssemblyResolutionException) { continue; } if (!AreSameReference(r.Name, target.Name)) { continue; } ReferenceRemoved(assembly, references [i]); references.RemoveAt(i); // Removing the reference does not mean it will be saved back to disk! // That depends on the AssemblyAction set for the `assembly` switch (Annotations.GetAction(assembly)) { case AssemblyAction.Copy: // Copy means even if "unlinked" we still want that assembly to be saved back // to disk (OutputStep) without the (removed) reference if (!Context.KeepTypeForwarderOnlyAssemblies) { Annotations.SetAction(assembly, AssemblyAction.Save); ResolveAllTypeReferences(assembly); } break; case AssemblyAction.CopyUsed: if (IsMarkedAssembly(assembly) && !Context.KeepTypeForwarderOnlyAssemblies) { Annotations.SetAction(assembly, AssemblyAction.Save); ResolveAllTypeReferences(assembly); } break; case AssemblyAction.Save: case AssemblyAction.Link: case AssemblyAction.AddBypassNGen: case AssemblyAction.AddBypassNGenUsed: if (!Context.KeepTypeForwarderOnlyAssemblies) { ResolveAllTypeReferences(assembly); } break; } return; } }