protected virtual LinkContext GetContext () { LinkContext context = new LinkContext (_pipeline); context.OutputDirectory = GetOutputPath (); context.CoreAction = AssemblyAction.Copy; return context; }
public static void ProcessLibrary(LinkContext context, AssemblyDefinition assembly) { SetAction (context, assembly, AssemblyAction.Copy); foreach (TypeDefinition type in assembly.MainModule.Types) MarkType (context, type); }
public void Process (LinkContext context) { _context = context; Initialize (); Process (); }
void ProcessAssemblies (LinkContext context, XPathNodeIterator iterator) { while (iterator.MoveNext ()) { AssemblyDefinition assembly = GetAssembly (context, GetFullName (iterator.Current)); ProcessTypes (assembly, iterator.Current.SelectChildren ("type", _ns)); ProcessNamespaces (assembly, iterator.Current.SelectChildren ("namespace", _ns)); } }
static AssemblyDefinition GetAssembly(LinkContext context, string assemblyName) { AssemblyNameReference reference = AssemblyNameReference.Parse (assemblyName); AssemblyDefinition assembly; assembly = context.Resolve (reference); ProcessReferences (assembly, context); return assembly; }
static void MarkType (LinkContext context, TypeDefinition type) { context.Annotations.Mark (type); if (type.HasFields) MarkFields (context, type.Fields); if (type.HasMethods) MarkMethods (context, type.Methods); if (type.HasNestedTypes) foreach (var nested in type.NestedTypes) MarkType (context, nested); }
public override void Process(LinkContext context) { foreach(var assembly in context.GetAssemblies()) { foreach (TypeDefinition type in assembly.MainModule.Types) { if (type.IsSerializable) //The C# [Serializable] attribute, does not map to an IL attribute. in IL "serializable" is an IL level thing. { Annotations.SetPreserve(type,TypePreserve.Fields); } } } }
public void Process (LinkContext context) { _context = context; if (!ConditionToProcess ()) return; Process (); foreach (AssemblyDefinition assembly in context.GetAssemblies ()) ProcessAssembly (assembly); EndProcess (); }
public override void Process(LinkContext context) { if (_assembly != null) { context.SafeLoadSymbols (_assembly); context.Resolver.CacheAssembly (_assembly); } _assembly = _assembly ?? context.Resolve (_file); switch (_assembly.Kind) { case AssemblyKind.Dll: ProcessLibrary (_assembly); return; default: ProcessExecutable (_assembly); return; } }
static void MarkFields(LinkContext context, ICollection fields) { foreach (FieldDefinition field in fields) context.Annotations.Mark (field); }
public FlowAnnotations(LinkContext context) { _context = context; _hierarchyInfo = new TypeHierarchyCache(context); }
static void Run(Pipeline pipeline, LinkContext context) { pipeline.Process(context); }
protected ProcessLinkerXmlBase(LinkContext context, XPathDocument document, string xmlDocumentLocation) { _context = context; _document = document; _xmlDocumentLocation = xmlDocumentLocation; }
protected override AssemblyDefinition GetAssembly(LinkContext context, AssemblyNameReference assemblyName) { return(context.GetLoadedAssembly(assemblyName.Name)); }
public abstract void Initialize(LinkContext context, MarkContext markContext);
/// <summary> /// Compiles the item /// </summary> /// <param name="linkContext"></param> virtual public void Compile(LinkContext linkContext) { throw new CompileException(Error.InvalidGroupForCompile); }
/// <summary> /// Performs packing. /// </summary> public void Run() { // Steps // 1) Mono.Cecil: Determine assembly dependencies // 2) ILMerge: Merge exe into a single assembly // 3) Mono.Linker var includeMergeListRegex = new string[] { @"SharpDX\..*" }; // Step 1 : Mono.Cecil: Determine assembly dependencies var assembly = AssemblyDefinition.ReadAssembly(MainAssembly); var corlib = (AssemblyNameReference)assembly.MainModule.TypeSystem.Corlib; bool isNet40 = corlib.Version.Major == 4; var paths = new List <string>(); var fromDirectory = Path.GetDirectoryName(assembly.MainModule.FullyQualifiedName); // Load SharpDX assemblies AddAssemblies(assembly, paths, fromDirectory, includeMergeListRegex); // Load assemblies to link foreach (var assemblyToLinkName in AssembliesToLink) { var assemblyToLink = AssemblyDefinition.ReadAssembly(assemblyToLinkName); paths.Add(assemblyToLink.MainModule.FullyQualifiedName); } // Step 2: ILMerge: Merge exe into a single assembly var merge = new ILMerge(); String[] files = paths.ToArray(); if (!Directory.Exists(OutputDirectory)) { Directory.CreateDirectory(OutputDirectory); } //Here we get the first file name (which was the .exe file) and use that // as the output String strOutputFile = System.IO.Path.GetFileName(files[0]); merge.OutputFile = OutputDirectory + "\\" + strOutputFile; merge.SetInputAssemblies(files); merge.DebugInfo = false; merge.CopyAttributes = true; merge.AllowMultipleAssemblyLevelAttributes = true; merge.XmlDocumentation = false; // Special case for v4 framework // See http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx if (isNet40) { // Retrieve the install root path for the framework string installRoot = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\.NetFramework", false).GetValue("InstallRoot").ToString(); var directorties = Directory.GetDirectories(installRoot, "v4.*"); if (directorties.Length == 0) { UsageError(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Cannot found any .Net 4.0 directory from [{0}] ", installRoot)); } merge.SetTargetPlatform("v4", directorties[0]); } merge.Merge(); // Step 3: Mono.Linker if (!NoLinker) { var pipeline = GetStandardPipeline(); var context = new LinkContext(pipeline) { CoreAction = AssemblyAction.Skip, OutputDirectory = OutputDirectory }; context.OutputDirectory = OutputDirectory; var mainAssemblyDirectory = new DirectoryInfo(Path.GetDirectoryName(Path.GetFullPath(MainAssembly))); context.Resolver.AddSearchDirectory(mainAssemblyDirectory.FullName); // Load assembly merged previously by ILMerge var mergedAssemblyDefinition = context.Resolve(merge.OutputFile); // Create Mono.Linker default pipeline pipeline = GetStandardPipeline(); pipeline.PrependStep(new ResolveFromAssemblyStep(mergedAssemblyDefinition)); // Add custom step for ComObject constructors pipeline.AddStepBefore(typeof(SweepStep), new ComObjectStep()); pipeline.Process(context); } Console.WriteLine("Assembly successfully packed to [{0}]", merge.OutputFile); }
public ReflectionMarker(LinkContext context, MarkStep markStep, bool enabled) { _context = context; _markStep = markStep; _enabled = enabled; }
public static bool IsInternalized(LinkContext context, IMetadataTokenProvider provider) { var annotations = context.Annotations.GetCustomAnnotations(_internalizedKey); return(annotations.ContainsKey(provider)); }
public static void Internalized(LinkContext context, IMetadataTokenProvider provider) { var annotations = context.Annotations.GetCustomAnnotations(_internalizedKey); annotations [provider] = _internalizedKey; }
public virtual void Process(LinkContext context) { _context = context; foreach (AssemblyDefinition assembly in _context.GetAssemblies ()) ProcessAssembly (assembly); DumpXml (); }
public virtual void Initialize(LinkContext context) { this.context = context; }
protected virtual void RunTest(string testCase) { _testCase = testCase; _context = GetContext (); }
/// <summary> /// Compiles the token; in general a single token doesn't mean enough by /// itself to be compilable, but give them the option /// </summary> /// <param name="linkContext"></param> public virtual void Compile(LinkContext linkContext) { throw new CompileException(Error.TokenCannotBeCompiled); }
public override void Process(LinkContext context) { XPathNavigator nav = _document.CreateNavigator (); nav.MoveToFirstChild (); ProcessAssemblies (context, nav.SelectChildren ("assembly", _ns)); }
public void Process(LinkContext context) { var profile = (Profile.Current as BaseProfile); AssemblyDefinition assembly; if (!context.TryGetLinkedAssembly(profile.ProductAssembly, out assembly)) { return; } HashSet <string> namespaces = new HashSet <string> (); foreach (TypeDefinition type in assembly.MainModule.Types) { namespaces.Add(type.Namespace); } // clean NSObject from loading them var nsobject = assembly.MainModule.GetType(Namespaces.Foundation + ".NSObject"); var nsobject_cctor = nsobject.GetTypeConstructor(); var instructions = nsobject_cctor.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { Instruction ins = instructions [i]; if (ins.OpCode.Code != Code.Ldstr) { continue; } // To be safe we only remove the ones we know about *and* // only when we know the namespace is not being used by the app // Based on the list from xamcore/src/Foundation/NSObjectMac.cs bool remove_dlopen = false; string targetNamespace; if (NamespaceMapping.TryGetValue(ins.Operand as string, out targetNamespace)) { remove_dlopen = !namespaces.Contains(targetNamespace); } #if DEBUG else { string libname = ins.Operand as string; if (libname.StartsWith("/", StringComparison.Ordinal)) { Console.WriteLine("Unprocessed library / namespace {0}", libname); } } #endif if (remove_dlopen) { FieldDefinition f = Nop(ins); if (f != null) { i += 3; nsobject.Fields.Remove(f); } } } }
public void Process(LinkContext context) { throw null; }
static void MarkMethods(LinkContext context, ICollection methods) { foreach (MethodDefinition method in methods) MarkMethod (context, method, MethodAction.ForceParse); }
protected ProcessLinkerXmlBase(LinkContext context, XPathDocument document, EmbeddedResource resource, AssemblyDefinition resourceAssembly, string xmlDocumentLocation) : this(context, document, xmlDocumentLocation) { _resource = resource ?? throw new ArgumentNullException(nameof(resource)); _resourceAssembly = resourceAssembly ?? throw new ArgumentNullException(nameof(resourceAssembly)); }
static void TryReadSymbols(LinkContext context, AssemblyDefinition assembly) { context.SafeReadSymbols (assembly); }
public abstract void Process (LinkContext context);
public void Setup() { var ctx = new LinkContext(null, new ConsoleLogger(), string.Empty); store = new AnnotationStore(ctx); }
static void SetAction(LinkContext context, AssemblyDefinition assembly, AssemblyAction action) { TryReadSymbols (context, assembly); context.Annotations.SetAction (assembly, action); }
public void Process(LinkContext context) { }
public JsonFlowAnnotationSource(LinkContext context, string jsonFile) { Initialize(context, jsonFile); }
protected override void AddXmlDependencyRecorder(LinkContext context, string file) { // Don't try to open the output file for writing - just pretend it exists. Context.Tracer.AddRecorder(MockXmlDependencyRecorder.Singleton); }
static void MarkMethod(LinkContext context, MethodDefinition method, MethodAction action) { context.Annotations.Mark (method); context.Annotations.SetAction (method, action); }
public LinkAttributesParser(LinkContext context, Stream documentStream, string xmlDocumentLocation) : base(context, documentStream, xmlDocumentLocation) { }
public LinkAttributesParser(LinkContext context, Stream documentStream, EmbeddedResource resource, AssemblyDefinition resourceAssembly, string xmlDocumentLocation = "<unspecified>") : base(context, documentStream, resource, resourceAssembly, xmlDocumentLocation) { }
public void Process(LinkContext context) { Driver.Watch(message, 2); }
static void TryReadSymbols(LinkContext context, AssemblyDefinition assembly) { context.SafeReadSymbols(assembly); }
public void Process (LinkContext context) { assemblies = context.GetAssemblies (); foreach (var assembly in assemblies) SweepAssembly (assembly); }
protected static void SetAction(LinkContext context, AssemblyDefinition assembly, AssemblyAction action) { TryReadSymbols(context, assembly); context.Annotations.SetAction(assembly, action); }
public static void ProcessLibrary(LinkContext context, AssemblyDefinition assembly, RootVisibility rootVisibility = RootVisibility.Any) { var action = rootVisibility == RootVisibility.Any ? AssemblyAction.Copy : AssemblyAction.Link; SetAction(context, assembly, action); context.Annotations.Push(assembly); foreach (TypeDefinition type in assembly.MainModule.Types) { MarkType(context, type, rootVisibility); } if (assembly.MainModule.HasExportedTypes) { foreach (var exported in assembly.MainModule.ExportedTypes) { bool isForwarder = exported.IsForwarder; var declaringType = exported.DeclaringType; while (!isForwarder && (declaringType != null)) { isForwarder = declaringType.IsForwarder; declaringType = declaringType.DeclaringType; } if (!isForwarder) { continue; } TypeDefinition resolvedExportedType = null; try { resolvedExportedType = exported.Resolve(); } catch (AssemblyResolutionException) { continue; } if (resolvedExportedType == null) { // // It's quite common for assemblies to have broken exported types // // One source of them is from native csc which added all nested types of // type-forwarded types automatically including private ones. // // Next source of broken type-forwarders is from custom metadata writers which // simply write bogus information. // // Both cases are bugs not on our end but we still want to link all assemblies // especially when such types cannot be used anyway // if (context.LogInternalExceptions) { System.Console.WriteLine($"Cannot find declaration of exported type '{exported}' from the assembly '{assembly}'"); } continue; } context.Resolve(resolvedExportedType.Scope); MarkType(context, resolvedExportedType, rootVisibility); context.Annotations.Mark(exported); if (context.KeepTypeForwarderOnlyAssemblies) { context.Annotations.Mark(assembly.MainModule); } } } context.Annotations.Pop(); }
static void ProcessReferences(AssemblyDefinition assembly, LinkContext context) { foreach (AssemblyNameReference name in assembly.MainModule.AssemblyReferences) context.Resolve (name); }
public FlowAnnotations(LinkContext context, CustomAttributeSource annotationSource) { _source = annotationSource; _context = context; }
static void ProcessReferences(AssemblyDefinition assembly, LinkContext context) { context.ResolveReferences(assembly); }
private void Initialize(LinkContext context, string jsonFile) { // Need "using" because JsonDocument won't close this as part of Dispose(). using FileStream jsonFileStream = File.OpenRead(jsonFile); // We only support UTF-8 using JsonDocument jsonDoc = JsonDocument.Parse(jsonFileStream, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip }); // TODO: need to also check the document is structurally sound. foreach (var assemblyElement in jsonDoc.RootElement.EnumerateObject()) { var assembly = context.Resolve(new AssemblyNameReference(assemblyElement.Name, new Version())); if (assembly == null) { context.LogMessage($"Assembly {assemblyElement.Name} couldn't be resolved"); continue; } foreach (var ns in assemblyElement.Value.EnumerateObject()) { string namespaceName = ns.Name; foreach (var typeElement in ns.Value.EnumerateObject()) { string typeName = typeElement.Name; var type = assembly.MainModule.GetType(namespaceName, typeName); if (type == null) { context.LogMessage($"Type {namespaceName}.{typeName} couldn't be resolved"); continue; } foreach (var member in typeElement.Value.EnumerateObject()) { string memberName = member.Name; // Technically, '(' is a valid character in both method and field names, // but the existing PreserveDependencyAttribute parser has a limitation in supporting // that anyway, so we will use '(' to distinguish methods from fields/properties. if (memberName.Contains("(")) { // This is a method // Parser uses same format as PreserveDependencyAttribute string[] signature = null; memberName = memberName.Replace(" ", ""); var sign_start = memberName.IndexOf('('); var sign_end = memberName.LastIndexOf(')'); if (sign_start > 0 && sign_end > sign_start) { var parameters = memberName.Substring(sign_start + 1, sign_end - sign_start - 1); signature = string.IsNullOrEmpty(parameters) ? Array.Empty <string> () : parameters.Split(','); memberName = memberName.Substring(0, sign_start); } MethodDefinition method = null; foreach (var candidate in type.Methods) { if (candidate.Name != memberName) { continue; } if (signature != null) { if (candidate.Parameters.Count != signature.Length) { continue; } bool sigMatch = true; for (int i = 0; i < candidate.Parameters.Count; i++) { if (candidate.Parameters[i].ParameterType.FullName != signature[i].ToCecilName()) { sigMatch = false; break; } } if (!sigMatch) { continue; } } if (method != null) { context.LogMessage($"Multiple matches for method {memberName}"); } method = candidate; } if (method == null) { context.LogMessage($"No match for {memberName}"); continue; } DynamicallyAccessedMemberKinds returnAnnotation = 0; var parameterAnnotations = new ArrayBuilder <(string ParamName, DynamicallyAccessedMemberKinds Annotation)> (); foreach (var parameter in member.Value.EnumerateObject()) { if (parameter.Name == "return") { returnAnnotation = ParseKinds(parameter.Value); } else { DynamicallyAccessedMemberKinds paramAnnotation = ParseKinds(parameter.Value); if (paramAnnotation != 0) { parameterAnnotations.Add((parameter.Name, paramAnnotation)); } } } if (returnAnnotation != 0 || parameterAnnotations.Count > 0) { _methods[method] = new AnnotatedMethod(returnAnnotation, parameterAnnotations.ToArray()); } } else { // This is a field or property FieldDefinition field = null; foreach (var candidate in type.Fields) { if (candidate.Name != memberName) { continue; } // IL allows overloaded fields, but not worth adding messages for that... field = candidate; break; } if (field != null) { DynamicallyAccessedMemberKinds fieldAnnotation = ParseKinds(member.Value); if (fieldAnnotation != 0) { _fields[field] = fieldAnnotation; } continue; } PropertyDefinition property = null; foreach (var candidate in type.Properties) { if (candidate.Name != memberName) { continue; } // IL allows overloaded properties, but not worth adding messages for that... property = candidate; break; } if (property != null) { DynamicallyAccessedMemberKinds propertyAnnotation = ParseKinds(member.Value); if (propertyAnnotation != 0) { _properties[property] = propertyAnnotation; } } if (field == null && property == null) { context.LogMessage($"No match for field or property {memberName}"); } } } } } } }
// Extension method to avoid conditional code for files shared between // .NET linker and Legacy (where LinkContext doesn't implement IMetadataResolver). // This doesn't actually use the LinkContext. public static TypeDefinition Resolve(this LinkContext context, TypeReference type) { return(type.Resolve()); }
public void Initialize(LinkContext context, MarkContext markContext) { _context = context; markContext.RegisterMarkTypeAction(ProcessType); markContext.RegisterMarkMethodAction(CheckForSerializerActivation); }