예제 #1
0
        public override void Execute()
        {
            var configOptions = new WeaverConfigOptions(Config);
            var config        = new WeaverConfig(configOptions, ModuleDefinition);
            var context       = new ModuleWeavingContext(ModuleDefinition, config);

            foreach (var type in ModuleDefinition.GetTypes())
            {
                foreach (var method in type.Methods)
                {
                    try
                    {
                        if (!MethodWeaver.NeedsProcessing(context, method))
                        {
                            continue;
                        }

                        _log.Debug($"Processing: {method.FullName}");
                        new MethodWeaver(context, method).Process();
                    }
                    catch (WeavingException ex)
                    {
                        AddError(ex.Message, ex.SequencePoint);
                        InvalidateMethod(method, ex.Message);
                    }
                }

                if (type.IsInlineILTypeUsageDeep(context))
                {
                    AddError($"Reference to InlineIL found in type {type.FullName}. InlineIL should not be referenced in attributes/constraints, as its assembly reference will be removed.", null);
                }
            }

            RemoveLibReference(context);
        }
예제 #2
0
            static bool DoCheck(TypeReference typeRef, ModuleWeavingContext ctx)
            {
                switch (typeRef)
                {
                case GenericInstanceType t:
                    return(t.ElementType.IsInlineILTypeUsage(ctx) ||
                           t.GenericParameters.Any(i => i.IsInlineILTypeUsage(ctx)) ||
                           t.GenericArguments.Any(i => i.IsInlineILTypeUsage(ctx)));

                case GenericParameter t:
                    return(t.HasConstraints && t.Constraints.Any(c => c.IsInlineILTypeUsage(ctx)) ||
                           t.HasCustomAttributes && t.CustomAttributes.Any(i => i.IsInlineILTypeUsage(ctx)));

                case IModifierType t:
                    return(t.ElementType.IsInlineILTypeUsage(ctx) ||
                           t.ModifierType.IsInlineILTypeUsage(ctx));

                case FunctionPointerType t:
                    return(((IMethodSignature)t).IsInlineILTypeUsage(ctx));

                default:
                    return(typeRef.Scope?.MetadataScopeType == MetadataScopeType.AssemblyNameReference &&
                           typeRef.Scope.Name == "InlineIL");
                }
            }
예제 #3
0
        private void RemoveLibReference(ModuleWeavingContext context)
        {
            var libRef = ModuleDefinition.AssemblyReferences.FirstOrDefault(i => i.IsInlineILAssembly());

            if (libRef == null)
            {
                return;
            }

            var importScopes = new HashSet <ImportDebugInformation>();

            foreach (var method in ModuleDefinition.GetTypes().SelectMany(t => t.Methods))
            {
                foreach (var scope in method.DebugInformation.GetScopes())
                {
                    ProcessScope(scope);
                }
            }

            ModuleDefinition.AssemblyReferences.Remove(libRef);

            var copyLocalFilesToRemove = new HashSet <string>(StringComparer.OrdinalIgnoreCase)
            {
                libRef.Name + ".dll",
                libRef.Name + ".xml",
                libRef.Name + ".pdb" // We don't ship this, but future-proof that ;)
            };

            ReferenceCopyLocalPaths.RemoveAll(i => copyLocalFilesToRemove.Contains(Path.GetFileName(i)));

            _log.Debug("Removed reference to InlineIL");

            void ProcessScope(ScopeDebugInformation scope)
            {
                ProcessImportScope(scope.Import);

                if (scope.HasScopes)
                {
                    foreach (var childScope in scope.Scopes)
                    {
                        ProcessScope(childScope);
                    }
                }
            }

            void ProcessImportScope(ImportDebugInformation importScope)
            {
                if (importScope == null || !importScopes.Add(importScope))
                {
                    return;
                }

                importScope.Targets.RemoveWhere(t => t.AssemblyReference.IsInlineILAssembly() || t.Type.IsInlineILTypeUsage(context));
                ProcessImportScope(importScope.Parent);
            }
        }
예제 #4
0
 public MethodWeaver(ModuleWeavingContext context, MethodDefinition method, ILogger log)
 {
     _context        = context;
     _method         = method;
     _il             = new WeaverILProcessor(_method);
     _sequencePoints = new SequencePointMapper(_method, context.Config);
     _log            = new MethodWeaverLogger(log, _method);
     _labels         = new LabelMapper(_il, _log);
     _consumer       = new ArgumentConsumer(_il);
 }
예제 #5
0
    public void SingleMethod()
    {
        var assemblyPath = FixtureHelper.IsolateAssembly <StandardAssemblyToProcessReference>();
        var type         = typeof(MethodRefTestCases);
        var methodName   = nameof(MethodRefTestCases.ReturnMethodHandle);

        using var module = ModuleDefinition.ReadModule(assemblyPath);
        var weavingContext = new ModuleWeavingContext(module, new WeaverConfig(null, module));

        var typeDef   = module.GetTypes().Single(i => i.FullName == type.FullName);
        var methodDef = typeDef.Methods.Single(i => i.Name == methodName);

        new MethodWeaver(weavingContext, methodDef, NoOpLogger.Instance).Process();
    }
예제 #6
0
        public static bool IsInlineILTypeUsage(this TypeReference?type, ModuleWeavingContext context)
        {
            if (type == null)
            {
                return(false);
            }

            if (context.LibUsageTypeCache.TryGetValue(type, out var result))
            {
                return(result);
            }

            context.LibUsageTypeCache[type] = false;
            result = DoCheck(type, context);
            context.LibUsageTypeCache[type] = result;
            return(result);
예제 #7
0
    private static bool HasLibReference(ModuleWeavingContext context, MethodDefinition method, out Instruction?refInstruction)
    {
        refInstruction = null;

        if (method.IsInlineILTypeUsage(context))
        {
            return(true);
        }

        if (!method.HasBody)
        {
            return(false);
        }

        if (method.Body.HasVariables && method.Body.Variables.Any(i => i.VariableType.IsInlineILTypeUsage(context)))
        {
            return(true);
        }

        foreach (var instruction in method.Body.Instructions)
        {
            refInstruction = instruction;

            switch (instruction.Operand)
            {
            case MethodReference methodRef when methodRef.IsInlineILTypeUsage(context):
            case TypeReference typeRef when typeRef.IsInlineILTypeUsage(context):
            case FieldReference fieldRef when fieldRef.IsInlineILTypeUsage(context):
            case CallSite callSite when callSite.IsInlineILTypeUsage(context):
                return(true);
            }
        }

        refInstruction = null;
        return(false);
    }
예제 #8
0
 public static bool NeedsProcessing(ModuleWeavingContext context, MethodDefinition method)
 => HasLibReference(context, method, out _);