internal void AddSecurityTransparencyAttribute(List <ICustomAttribute> list, SecurityTransparencyStatus securityTransparencyStatus, ITypeReference containingType) { Microsoft.Cci.MethodReference ctor = null; switch (securityTransparencyStatus) { case SecurityTransparencyStatus.Critical: ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecurityCriticalAttribute, //FindType("System.Security.SecurityCriticalAttribute"), CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0); break; case SecurityTransparencyStatus.SafeCritical: ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecuritySafeCriticalAttribute, //FindType("System.Security.SecuritySafeCriticalAttribute"), CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0); break; case SecurityTransparencyStatus.Transparent: break; } if (ctor != null) { CustomAttribute securityAttribute = new CustomAttribute(); securityAttribute.Constructor = ctor; list.Add(Rewrite(securityAttribute)); } }
private void AddFaaAttributeIfNeeded(Element element, List <ICustomAttribute> attributes, ITypeReference containingType) { if (element != null && element.IsFriendAccessAllowed)//typeHasFaaAttribute(attributes, containingType)) { List <INamedTypeDefinition> types = new List <INamedTypeDefinition>(this.host.FindAssembly(this.host.CoreAssemblySymbolicIdentity).GetAllTypes()); if (types == null || !types.Any()) { return; //Couldn't find any type on the assembly } IEnumerable <INamedTypeDefinition> faaAttributeType = types.Where(t => t.Name.Value == "FriendAccessAllowedAttribute"); if (!faaAttributeType.Any()) { return; //Unable to find the FriendAccessAllowedAttribute } var faaAttributeResult = faaAttributeType.FirstOrDefault(); if (!Util.HasAttribute(attributes, faaAttributeResult)) { Microsoft.Cci.MethodReference faaCtor = new Microsoft.Cci.MethodReference(this.host, faaAttributeResult, CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0); CustomAttribute faaAttribute = new CustomAttribute(); faaAttribute.Constructor = faaCtor; attributes.Add(Rewrite(faaAttribute)); } } }
protected void AppendEmitExceptionThrow(ILGenerator generator) { var systemExceptionTypeReference = GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Exception"); IMethodReference exceptionConstructor = new Microsoft.Cci.MethodReference( host, systemExceptionTypeReference, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0); generator.Emit(OperationCode.Newobj, exceptionConstructor); generator.Emit(OperationCode.Throw); }
private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace) { var contractTypeName = this.host.NameTable.GetNameFor("Contract"); var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts"); Microsoft.Cci.MethodReference compilerGeneratedCtor = new Microsoft.Cci.MethodReference( this.host, this.compilerGeneratedAttributeType, CallingConvention.HasThis, this.systemVoidType, this.host.NameTable.Ctor, 0); CustomAttribute compilerGeneratedAttribute = new CustomAttribute(); compilerGeneratedAttribute.Constructor = compilerGeneratedCtor; var contractsNs = new NestedUnitNamespace() { ContainingUnitNamespace = unitNamespace, Name = contractNamespaceName, }; NamespaceTypeDefinition result = new NamespaceTypeDefinition() { // NB: The string name must be kept in sync with the code that recognizes contract // methods!! Name = contractTypeName, Attributes = new List <ICustomAttribute> { compilerGeneratedAttribute }, BaseClasses = new List <ITypeReference> { this.systemObjectType }, ContainingUnitNamespace = contractsNs, InternFactory = this.host.InternFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, Layout = LayoutKind.Auto, StringFormat = StringFormatKind.Ansi, }; return(result); }
private void AddInterceptionTargets() { host.LoadUnit(host.CoreAssemblySymbolicIdentity); foreach (var method in registry.GetRegisteredReferences(ReplaceableReferenceTypes.Method)) { var methodInfo = method as ReplaceableMethodInfo; var fullNamespace = methodInfo.DeclaringType.Namespace; var fullNamespaceWithType = methodInfo.DeclaringType.FullName; log.WriteTrace("Adding interception target for '{0}'.", fullNamespaceWithType); fakeNamespace.AddNamespaces(fullNamespace); fakeNamespace.AddClass(fullNamespace, methodInfo.DeclaringType.Name); var reflector = new UnitReflector(host); var methodType = reflector.Get(methodInfo.ReturnType.FullName); var actualMethod = methodInfo.Name == ".ctor" ? reflector.From(fullNamespaceWithType).GetConstructor(methodInfo.Parameters.Select(p => reflector.Get(p.ParameterType.FullName)).ToArray()) : reflector.From(fullNamespaceWithType).GetMethod(methodInfo.Name, methodInfo.Parameters.Select(p => reflector.Get(p.ParameterType.FullName)).ToArray()); var methodClass = fakeNamespace.Classes[fullNamespaceWithType]; var methodName = methodInfo.Name == ".ctor" ? "<constructor>" : methodInfo.Name; var fakeMethod = methodClass.AddPublicStaticMethod(methodName, methodType, host); // if it's an instance method, we add a parameter at the end for the target ushort extraParameters = 0; if (!actualMethod.ResolvedMethod.IsStatic && !actualMethod.ResolvedMethod.IsConstructor) { fakeMethod.AddParameter(0, "target", actualMethod.ContainingType, host, false, false); extraParameters = 1; } foreach (var parameter in actualMethod.Parameters) { fakeMethod.AddParameter((ushort)(parameter.Index + extraParameters), "p" + parameter.Index, parameter.Type, host, parameter.IsByReference/*IsOut*/, parameter.IsByReference); } if (actualMethod.ResolvedMethod.IsConstructor) { fakeMethod.Type = actualMethod.ResolvedMethod.ContainingTypeDefinition; } var customAttribute = new CustomAttribute(); customAttribute.Constructor = new UnitReflector(host) .From<SharpMockGeneratedAttribute>().GetConstructor(Type.EmptyTypes); fakeMethod.Attributes = new List<ICustomAttribute>(); fakeMethod.Attributes.Add(customAttribute); fakeMethod.Body = GetBody(fakeMethod, actualMethod); var parameterTypes = new List<ITypeDefinition>(); foreach (var param in fakeMethod.Parameters) { parameterTypes.Add(param.Type.ResolvedType); } var fakeCallReference = new Microsoft.Cci.MethodReference(host, fakeMethod.ContainingTypeDefinition, fakeMethod.CallingConvention, fakeMethod.Type, fakeMethod.Name, 0, parameterTypes.ToArray()); registry.RegisterReplacement(method, fakeCallReference); } foreach (var field in registry.GetRegisteredReferences(ReplaceableReferenceTypes.FieldAccessor)) { var fieldReplacementBuilder = new FieldAccessorSourceWriter(fakeNamespace, host, log, field as ReplaceableFieldInfo); var fakeCallReference = fieldReplacementBuilder.GetReference(); registry.RegisterReplacement(field, fakeCallReference); } foreach (var field in registry.GetRegisteredReferences(ReplaceableReferenceTypes.FieldAssignment)) { var fieldReplacementBuilder = new FieldAssignmentSourceWriter(fakeNamespace, host, log, field as ReplaceableFieldInfo); var fakeCallReference = fieldReplacementBuilder.GetReference(); registry.RegisterReplacement(field, fakeCallReference); } }
private IMethodDefinition GetOrCreateFinalizer(ITypeDefinition type) { Contract.Requires(type != null); Contract.Requires(type != Dummy.Type); Contract.Ensures(Contract.Result <IMethodDefinition>() != null); Contract.Ensures(Contract.Result <IMethodDefinition>() != Dummy.Method); var finalizer = TypeHelper.GetMethod(type, base.host.NameTable.GetNameFor("Finalize")); if (finalizer == Dummy.Method) { // create a method: virtual void Finalize() finalizer = new MethodDefinition() { IsVirtual = true, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = type, InternFactory = host.InternFactory, IsCil = true, IsStatic = false, Name = base.host.NameTable.GetNameFor("Finalize"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Family, }; // create a list of operations that holds (i) call to baseclass finalize if there is one and (ii) a return statement. var ops = new List <IOperation>(); // call base class Finalize method var baseClass = GetBaseClass(type); var baseClassFinalize = new Microsoft.Cci.MethodReference( base.host, baseClass, CallingConvention.HasThis, base.host.PlatformType.SystemVoid, base.host.NameTable.GetNameFor("Finalize"), 0 ); ops.Add(new Operation() { Location = Dummy.Location, Offset = 0, OperationCode = OperationCode.Ldarg_0, Value = null }); ops.Add(new Operation() { Location = Dummy.Location, Offset = 0, OperationCode = OperationCode.Call, Value = baseClassFinalize }); ops.Add(new Operation() { Location = Dummy.Location, Offset = 0, OperationCode = OperationCode.Ret, Value = null }); // create a method body with that single operation and no exception information var body = new MethodBody { LocalsAreZeroed = false, LocalVariables = null, MaxStack = 0, MethodDefinition = finalizer, OperationExceptionInformation = new List <IOperationExceptionInformation>(0), Operations = ops, PrivateHelperTypes = null }; // update the method definition and the body to point to each other. body.MethodDefinition = finalizer; ((MethodDefinition)finalizer).Body = body; // add it to this typeDefinition var containingType = type as NamedTypeDefinition; if (containingType != null) { if (containingType.Methods == null) { containingType.Methods = new List <IMethodDefinition>(); } containingType.Methods.Add(finalizer); } else { var nestedContainingType = type as NestedTypeDefinition; if (nestedContainingType != null) { if (nestedContainingType.Methods == null) { nestedContainingType.Methods = new List <IMethodDefinition>(); } nestedContainingType.Methods.Add(finalizer); } else { var specializedContainingType = type as SpecializedNestedTypeDefinition; if (specializedContainingType != null) { if (specializedContainingType.Methods == null) { specializedContainingType.Methods = new List <IMethodDefinition>(); } specializedContainingType.Methods.Add(finalizer); } else { Contract.Assert(false); } } } } return(finalizer); }
public void Compile(string fileName) { string appName = Path.GetFileNameWithoutExtension(fileName); string exeName = appName + ".exe"; string src = ""; using (TextReader file = new StreamReader(fileName)) { src = file.ReadToEnd(); } var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { // Load Mirage types IModule module = host.LoadUnitFrom("Mirage.dll") as IModule; if (module == null || module is Dummy) { return; } var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine"); var inputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput"); var outputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput"); // Create assembly var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor(appName), ModuleName = nameTable.GetNameFor(exeName), PlatformType = host.PlatformType, Kind = ModuleKind.ConsoleApplication, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); // Create namespace var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; // Create module class var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); // Create program class var programClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List<IMethodDefinition>(1), Name = nameTable.GetNameFor("Program"), }; programClass.BaseClasses = new List<ITypeReference>() { host.PlatformType.SystemObject }; rootUnitNamespace.Members.Add(programClass); // Add types to the assembly assembly.AllTypes.Add(machineType); foreach (var t in machineType.NestedTypes) { assembly.AllTypes.Add(t); } assembly.AllTypes.Add(inputType); assembly.AllTypes.Add(outputType); assembly.AllTypes.Add(programClass); // Create main method var mainMethod = new MethodDefinition() { ContainingTypeDefinition = programClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; programClass.Methods.Add(mainMethod); // Create constructors and methods IMethodReference machineConstructor = new Microsoft.Cci.MethodReference( host, machineType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); IMethodReference inputConstructor = new Microsoft.Cci.MethodReference( host, inputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType); IMethodReference outputConstructor = new Microsoft.Cci.MethodReference( host, outputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType); var opIncPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers")); var opDecPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers")); var opIncHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer")); var opDecHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer")); var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer")); var opLoadHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer")); var opDragLoPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer")); var opXchPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers")); var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear")); var opAdd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add")); var opDec = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec")); var opNot = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not")); var opAnd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And")); var opOr = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or")); var opXor = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor")); var opSal = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal")); var opSar = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar")); var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString); var opInput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type); var opOutput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type); var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz")); // Create program code var labels = new Stack<ILGeneratorLabel>(100); var ilGenerator = new ILGenerator(host, mainMethod); ilGenerator.Emit(OperationCode.Newobj, machineConstructor); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Newobj, inputConstructor); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Newobj, outputConstructor); ilGenerator.Emit(OperationCode.Stloc_2); int pc = 0; while (pc < src.Length) { char opcode = src[pc++]; switch (opcode) { case '>': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncPointers); break; case '<': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecPointers); break; case ']': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer); break; case '[': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer); break; case '#': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer); break; case '$': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer); break; case '=': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer); break; case '%': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXchPointers); break; case '_': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opClear); break; case '+': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAdd); break; case '-': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDec); break; case '~': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opNot); break; case '&': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAnd); break; case '|': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opOr); break; case '^': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXor); break; case '*': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSal); break; case '/': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSar); break; case '(': int dataStart = pc; int dataEnd = dataStart; while (src[pc++] != ')') { dataEnd = pc; } ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart)); ilGenerator.Emit(OperationCode.Callvirt, opLoadData); break; case '?': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Call, inputCast); ilGenerator.Emit(OperationCode.Callvirt, opInput); break; case '!': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Call, outputCast); ilGenerator.Emit(OperationCode.Callvirt, opOutput); break; case '{': var cycleStart = new ILGeneratorLabel(); var cycleEnd = new ILGeneratorLabel(); labels.Push(cycleStart); labels.Push(cycleEnd); ilGenerator.Emit(OperationCode.Br, cycleEnd); ilGenerator.MarkLabel(cycleStart); break; case '}': ilGenerator.MarkLabel(labels.Pop()); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opJz); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Ceq); ilGenerator.Emit(OperationCode.Stloc_3); ilGenerator.Emit(OperationCode.Ldloc_3); ilGenerator.Emit(OperationCode.Brtrue, labels.Pop()); break; default: break; } } ilGenerator.Emit(OperationCode.Ret); mainMethod.Body = new ILGeneratorMethodBody( ilGenerator, true, 8, mainMethod, new List<ILocalDefinition>() { new LocalDefinition() { Type = machineType }, new LocalDefinition() { Type = inputType }, new LocalDefinition() { Type = outputType }, new LocalDefinition() { Type = host.PlatformType.SystemInt32 }, }, Enumerable<ITypeDefinition>.Empty ); using (var peStream = File.Create(exeName)) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
private NamespaceTypeDefinition CreateContractClass(UnitNamespace unitNamespace) { var contractTypeName = this.host.NameTable.GetNameFor("Contract"); var contractNamespaceName = this.host.NameTable.GetNameFor("System.Diagnostics.Contracts"); Microsoft.Cci.MethodReference compilerGeneratedCtor = new Microsoft.Cci.MethodReference( this.host, this.compilerGeneratedAttributeType, CallingConvention.HasThis, this.systemVoidType, this.host.NameTable.Ctor, 0); CustomAttribute compilerGeneratedAttribute = new CustomAttribute(); compilerGeneratedAttribute.Constructor = compilerGeneratedCtor; var contractsNs = new NestedUnitNamespace() { ContainingUnitNamespace = unitNamespace, Name = contractNamespaceName, }; NamespaceTypeDefinition result = new NamespaceTypeDefinition() { // NB: The string name must be kept in sync with the code that recognizes contract // methods!! Name = contractTypeName, Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute }, BaseClasses = new List<ITypeReference>{ this.systemObjectType }, ContainingUnitNamespace = contractsNs, InternFactory = this.host.InternFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, Layout = LayoutKind.Auto, StringFormat = StringFormatKind.Ansi, }; return result; }
private IMethodDefinition GetOrCreateFinalizer(ITypeDefinition type) { Contract.Requires(type != null); Contract.Requires(type != Dummy.Type); Contract.Ensures(Contract.Result<IMethodDefinition>() != null); Contract.Ensures(Contract.Result<IMethodDefinition>() != Dummy.Method); var finalizer = TypeHelper.GetMethod(type, base.host.NameTable.GetNameFor("Finalize")); if (finalizer == Dummy.Method) { // create a method: virtual void Finalize() finalizer = new MethodDefinition() { IsVirtual = true, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = type, InternFactory = host.InternFactory, IsCil = true, IsStatic = false, Name = base.host.NameTable.GetNameFor("Finalize"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Family, }; // create a list of operations that holds (i) call to baseclass finalize if there is one and (ii) a return statement. var ops = new List<IOperation>(); // call base class Finalize method var baseClass = GetBaseClass(type); var baseClassFinalize = new Microsoft.Cci.MethodReference( base.host, baseClass, CallingConvention.HasThis, base.host.PlatformType.SystemVoid, base.host.NameTable.GetNameFor("Finalize"), 0 ); ops.Add(new Operation() { Location = Dummy.Location, Offset = 0, OperationCode = OperationCode.Ldarg_0, Value = null }); ops.Add(new Operation() { Location = Dummy.Location, Offset = 0, OperationCode = OperationCode.Call, Value = baseClassFinalize }); ops.Add(new Operation() { Location = Dummy.Location, Offset = 0, OperationCode = OperationCode.Ret, Value = null }); // create a method body with that single operation and no exception information var body = new MethodBody { LocalsAreZeroed = false, LocalVariables = null, MaxStack = 0, MethodDefinition = finalizer, OperationExceptionInformation = new List<IOperationExceptionInformation>(0), Operations = ops, PrivateHelperTypes = null }; // update the method definition and the body to point to each other. body.MethodDefinition = finalizer; ((MethodDefinition)finalizer).Body = body; // add it to this typeDefinition var containingType = type as NamedTypeDefinition; if (containingType != null) { if (containingType.Methods == null) containingType.Methods = new List<IMethodDefinition>(); containingType.Methods.Add(finalizer); } else { var nestedContainingType = type as NestedTypeDefinition; if (nestedContainingType != null) { if (nestedContainingType.Methods == null) nestedContainingType.Methods = new List<IMethodDefinition>(); nestedContainingType.Methods.Add(finalizer); } else { var specializedContainingType = type as SpecializedNestedTypeDefinition; if (specializedContainingType != null) { if (specializedContainingType.Methods == null) specializedContainingType.Methods = new List<IMethodDefinition>(); specializedContainingType.Methods.Add(finalizer); } else { Contract.Assert(false); } } } } return finalizer; }
public void Compile(string fileName) { string appName = Path.GetFileNameWithoutExtension(fileName); string exeName = appName + ".exe"; string src = ""; using (TextReader file = new StreamReader(fileName)) { src = file.ReadToEnd(); } var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { // Load Mirage types IModule module = host.LoadUnitFrom("Mirage.dll") as IModule; if (module == null || module is Dummy) { return; } var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine"); var inputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput"); var outputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput"); // Create assembly var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor(appName), ModuleName = nameTable.GetNameFor(exeName), PlatformType = host.PlatformType, Kind = ModuleKind.ConsoleApplication, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); // Create namespace var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; // Create module class var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); // Create program class var programClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Program"), }; programClass.BaseClasses = new List <ITypeReference>() { host.PlatformType.SystemObject }; rootUnitNamespace.Members.Add(programClass); // Add types to the assembly assembly.AllTypes.Add(machineType); foreach (var t in machineType.NestedTypes) { assembly.AllTypes.Add(t); } assembly.AllTypes.Add(inputType); assembly.AllTypes.Add(outputType); assembly.AllTypes.Add(programClass); // Create main method var mainMethod = new MethodDefinition() { ContainingTypeDefinition = programClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; programClass.Methods.Add(mainMethod); // Create constructors and methods IMethodReference machineConstructor = new Microsoft.Cci.MethodReference( host, machineType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); IMethodReference inputConstructor = new Microsoft.Cci.MethodReference( host, inputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType); IMethodReference outputConstructor = new Microsoft.Cci.MethodReference( host, outputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType); var opIncPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers")); var opDecPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers")); var opIncHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer")); var opDecHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer")); var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer")); var opLoadHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer")); var opDragLoPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer")); var opXchPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers")); var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear")); var opAdd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add")); var opDec = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec")); var opNot = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not")); var opAnd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And")); var opOr = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or")); var opXor = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor")); var opSal = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal")); var opSar = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar")); var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString); var opInput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type); var opOutput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type); var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz")); // Create program code var labels = new Stack <ILGeneratorLabel>(100); var ilGenerator = new ILGenerator(host, mainMethod); ilGenerator.Emit(OperationCode.Newobj, machineConstructor); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Newobj, inputConstructor); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Newobj, outputConstructor); ilGenerator.Emit(OperationCode.Stloc_2); int pc = 0; while (pc < src.Length) { char opcode = src[pc++]; switch (opcode) { case '>': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncPointers); break; case '<': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecPointers); break; case ']': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer); break; case '[': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer); break; case '#': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer); break; case '$': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer); break; case '=': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer); break; case '%': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXchPointers); break; case '_': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opClear); break; case '+': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAdd); break; case '-': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDec); break; case '~': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opNot); break; case '&': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAnd); break; case '|': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opOr); break; case '^': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXor); break; case '*': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSal); break; case '/': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSar); break; case '(': int dataStart = pc; int dataEnd = dataStart; while (src[pc++] != ')') { dataEnd = pc; } ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart)); ilGenerator.Emit(OperationCode.Callvirt, opLoadData); break; case '?': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Call, inputCast); ilGenerator.Emit(OperationCode.Callvirt, opInput); break; case '!': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Call, outputCast); ilGenerator.Emit(OperationCode.Callvirt, opOutput); break; case '{': var cycleStart = new ILGeneratorLabel(); var cycleEnd = new ILGeneratorLabel(); labels.Push(cycleStart); labels.Push(cycleEnd); ilGenerator.Emit(OperationCode.Br, cycleEnd); ilGenerator.MarkLabel(cycleStart); break; case '}': ilGenerator.MarkLabel(labels.Pop()); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opJz); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Ceq); ilGenerator.Emit(OperationCode.Stloc_3); ilGenerator.Emit(OperationCode.Ldloc_3); ilGenerator.Emit(OperationCode.Brtrue, labels.Pop()); break; default: break; } } ilGenerator.Emit(OperationCode.Ret); mainMethod.Body = new ILGeneratorMethodBody( ilGenerator, true, 8, mainMethod, new List <ILocalDefinition>() { new LocalDefinition() { Type = machineType }, new LocalDefinition() { Type = inputType }, new LocalDefinition() { Type = outputType }, new LocalDefinition() { Type = host.PlatformType.SystemInt32 }, }, Enumerable <ITypeDefinition> .Empty ); using (var peStream = File.Create(exeName)) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
internal void AddSecurityTransparencyAttribute(List<ICustomAttribute> list, SecurityTransparencyStatus securityTransparencyStatus, ITypeReference containingType) { Microsoft.Cci.MethodReference ctor = null; switch (securityTransparencyStatus) { case SecurityTransparencyStatus.Critical: ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecurityCriticalAttribute,//FindType("System.Security.SecurityCriticalAttribute"), CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0); break; case SecurityTransparencyStatus.SafeCritical: ctor = new Microsoft.Cci.MethodReference(this.host, containingType.PlatformType.SystemSecuritySecuritySafeCriticalAttribute,//FindType("System.Security.SecuritySafeCriticalAttribute"), CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0); break; case SecurityTransparencyStatus.Transparent: break; } if (ctor != null) { CustomAttribute securityAttribute = new CustomAttribute(); securityAttribute.Constructor = ctor; list.Add(Rewrite(securityAttribute)); } }
private void AddFaaAttributeIfNeeded(Element element, List<ICustomAttribute> attributes, ITypeReference containingType) { if (element != null && element.IsFriendAccessAllowed)//typeHasFaaAttribute(attributes, containingType)) { List<INamedTypeDefinition> types = new List<INamedTypeDefinition>(this.host.FindAssembly(this.host.CoreAssemblySymbolicIdentity).GetAllTypes()); if (types == null || !types.Any()) return; //Couldn't find any type on the assembly IEnumerable<INamedTypeDefinition> faaAttributeType = types.Where(t => t.Name.Value == "FriendAccessAllowedAttribute"); if (!faaAttributeType.Any()) return; //Unable to find the FriendAccessAllowedAttribute var faaAttributeResult = faaAttributeType.FirstOrDefault(); if (!Util.HasAttribute(attributes, faaAttributeResult)) { Microsoft.Cci.MethodReference faaCtor = new Microsoft.Cci.MethodReference(this.host, faaAttributeResult, CallingConvention.HasThis, this.host.PlatformType.SystemVoid, this.host.NameTable.Ctor, 0); CustomAttribute faaAttribute = new CustomAttribute(); faaAttribute.Constructor = faaCtor; attributes.Add(Rewrite(faaAttribute)); } } }
public override void TraverseChildren(IMethodCall methodCall) { var resolvedMethod = Sink.Unspecialize(methodCall.MethodToCall).ResolvedMethod; var methodName = Microsoft.Cci.MemberHelper.GetMethodSignature(resolvedMethod); if (methodName.Equals("System.Object.GetHashCode") || methodName.Equals("System.Object.ToString")) { base.TraverseChildren(methodCall); return; } bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_"); bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_"); if (isEventAdd || isEventRemove) { base.TraverseChildren(methodCall); return; } if (!methodCall.IsVirtualCall) { base.TraverseChildren(methodCall); return; } var containingType = TypeHelper.UninstantiateAndUnspecialize(methodCall.MethodToCall.ContainingType); List <ITypeReference> subTypesOfContainingType; if (!this.subTypes.TryGetValue(containingType, out subTypesOfContainingType)) { base.TraverseChildren(methodCall); return; } Contract.Assert(0 < subTypesOfContainingType.Count); Contract.Assert(!methodCall.IsStaticCall); Contract.Assert(!resolvedMethod.IsConstructor); var overrides = FindOverrides(containingType, resolvedMethod); bool same = true; foreach (var o in overrides) { IMethodDefinition resolvedOverride = Sink.Unspecialize(o.Item2).ResolvedMethod; if (resolvedOverride != resolvedMethod) { same = false; } } if (!(containingType.ResolvedType.IsInterface) && (0 == overrides.Count || same)) { base.TraverseChildren(methodCall); return; } Contract.Assume(1 <= overrides.Count); var getType = new Microsoft.Cci.MethodReference( this.sink.host, this.sink.host.PlatformType.SystemObject, CallingConvention.HasThis, this.sink.host.PlatformType.SystemType, this.sink.host.NameTable.GetNameFor("GetType"), 0); var op_Type_Equality = new Microsoft.Cci.MethodReference( this.sink.host, this.sink.host.PlatformType.SystemType, CallingConvention.Default, this.sink.host.PlatformType.SystemBoolean, this.sink.host.NameTable.GetNameFor("op_Equality"), 0, this.sink.host.PlatformType.SystemType, this.sink.host.PlatformType.SystemType); // Depending on whether the method is a void method or not // Turn into expression: // (o.GetType() == typeof(T1)) ? ((T1)o).M(...) : ( (o.GetType() == typeof(T2)) ? ((T2)o).M(...) : ... // Or turn into statements: // if (o.GetType() == typeof(T1)) ((T1)o).M(...) else if ... var turnIntoStatements = resolvedMethod.Type.TypeCode == PrimitiveTypeCode.Void; IStatement elseStatement = null; IExpression elseValue = new MethodCall() { Arguments = new List <IExpression>(methodCall.Arguments), IsStaticCall = false, IsVirtualCall = false, MethodToCall = methodCall.MethodToCall, ThisArgument = methodCall.ThisArgument, Type = methodCall.Type, }; if (turnIntoStatements) { elseStatement = new ExpressionStatement() { Expression = elseValue, } } ; Conditional ifConditional = null; ConditionalStatement ifStatement = null; foreach (var typeMethodPair in overrides) { var t = typeMethodPair.Item1; var m = typeMethodPair.Item2; if (m.IsGeneric) { var baseMethod = m.ResolvedMethod; m = new GenericMethodInstanceReference() { CallingConvention = baseMethod.CallingConvention, ContainingType = baseMethod.ContainingTypeDefinition, GenericArguments = new List <ITypeReference>(IteratorHelper.GetConversionEnumerable <IGenericMethodParameter, ITypeReference>(baseMethod.GenericParameters)), GenericMethod = baseMethod, InternFactory = this.sink.host.InternFactory, Name = baseMethod.Name, Parameters = baseMethod.ParameterCount == 0 ? null : new List <IParameterTypeInformation>(baseMethod.Parameters), Type = baseMethod.Type, }; } var cond = new MethodCall() { Arguments = new List <IExpression>() { new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = false, MethodToCall = getType, ThisArgument = methodCall.ThisArgument, }, new TypeOf() { TypeToGet = t, }, }, IsStaticCall = true, IsVirtualCall = false, MethodToCall = op_Type_Equality, Type = this.sink.host.PlatformType.SystemBoolean, }; Expression thenValue = new MethodCall() { Arguments = new List <IExpression>(methodCall.Arguments), IsStaticCall = false, IsVirtualCall = false, MethodToCall = m, ThisArgument = methodCall.ThisArgument, Type = m.Type, }; thenValue = new Conversion() { Type = m.Type, TypeAfterConversion = methodCall.Type, ValueToConvert = thenValue, }; if (turnIntoStatements) { ifStatement = new ConditionalStatement() { Condition = cond, FalseBranch = elseStatement, TrueBranch = new ExpressionStatement() { Expression = thenValue, }, }; elseStatement = ifStatement; } else { ifConditional = new Conditional() { Condition = cond, ResultIfFalse = elseValue, ResultIfTrue = thenValue, }; elseValue = ifConditional; } } if (turnIntoStatements) { Contract.Assume(ifStatement != null); this.StmtTraverser.Traverse(ifStatement); } else { Contract.Assume(ifConditional != null); base.Traverse(ifConditional); } return; }