A collection of IName instances that represent names that are commonly used during compilation.
Inheritance: INameTable
Exemplo n.º 1
0
 public Checker(TextWriter tw)
 {
   this.tw = tw;
   this.nt = new NameTable();
   this.host1 = new SanitizerHostEnvironment(nt);
   this.host2 = new SanitizerHostEnvironment(nt);
 }
Exemplo n.º 2
0
        public PostCompiler(PostCompilerArgs postCompilerArgs, ILogger log)
        {
            this.log = log;

            if (postCompilerArgs.AreValid())
            {
                var nameTable = new NameTable();
                host = new PeReader.DefaultHost(nameTable);

                sharpMockCore = host.LoadUnitFrom(
                            System.Reflection.Assembly.GetExecutingAssembly().Location
                        );
                sharpMockDelegateTypes = sharpMockCore as IAssembly;

                host.Errors += host_Errors;
            }

            this.postCompilerArgs = postCompilerArgs;

            #if DEBUG && LAUNCH_DEBUGGER
            System.Diagnostics.Debugger.Launch();
            #endif
        }
Exemplo n.º 3
0
        public static void Main(string[] args)
        {
            string seeds = null;
            string contracts = null;
            string facadePath = null;
            Version assemblyFileVersion = null;
            bool clearBuildAndRevision = false;
            bool ignoreMissingTypes = false;
            bool buildDesignTimeFacades = false;
            string inclusionContracts = null;
            ErrorTreatment seedLoadErrorTreatment = ErrorTreatment.Default;
            ErrorTreatment contractLoadErrorTreatment = ErrorTreatment.Default;
            string[] seedTypePreferencesUnsplit = null;
            bool forceZeroVersionSeeds = false;
            bool producePdb = true;
            string partialFacadeAssemblyPath = null;

            bool parsingSucceeded = CommandLineParser.ParseForConsoleApplication((parser) =>
            {
                parser.DefineQualifier("facadePath", ref facadePath, "Path to output the facades.");
                parser.DefineQualifier("seeds", ref seeds, "Path to the seed assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineQualifier("contracts", ref contracts, "Path to the contract assemblies. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineOptionalQualifier("assemblyFileVersion", ref assemblyFileVersion, "Override the AssemblyFileVersion attribute from the contract with the given version for the generated facade.");
                parser.DefineOptionalQualifier("clearBuildAndRevision", ref clearBuildAndRevision, "Generate facade assembly version x.y.0.0 for contract version x.y.z.w");
                parser.DefineOptionalQualifier("ignoreMissingTypes", ref ignoreMissingTypes, "Ignore types that cannot be found in the seed assemblies. This is not recommended but is sometimes helpful while hacking around or trying to produce partial facades.");
                parser.DefineOptionalQualifier("designTime", ref buildDesignTimeFacades, "Enable design-time facade generation (marks facades with reference assembly flag and attribute).");
                parser.DefineOptionalQualifier("include", ref inclusionContracts, "Add types from these contracts to the facades. Can contain multiple assemblies or directories delimited by ',' or ';'.");
                parser.DefineOptionalQualifier("seedError", ref seedLoadErrorTreatment, "Error handling for seed assembly load failure.");
                parser.DefineOptionalQualifier("contractError", ref seedLoadErrorTreatment, "Error handling for contract assembly load failure.");
                parser.DefineOptionalQualifier("preferSeedType", ref seedTypePreferencesUnsplit, "Set which seed assembly to choose for a given type when it is defined in more than one assembly. Format: FullTypeName=PreferredSeedAssemblyName");
                parser.DefineOptionalQualifier("forceZeroVersionSeeds", ref forceZeroVersionSeeds, "Forces all seed assembly versions to 0.0.0.0, regardless of their true version.");
                parser.DefineOptionalQualifier("partialFacadeAssemblyPath", ref partialFacadeAssemblyPath, "Specifies the path to a single partial facade assembly, into which appropriate type forwards will be added to satisfy the given contract. If this option is specified, only a single partial assembly and a single contract may be given.");
                parser.DefineOptionalQualifier("producePdb", ref producePdb, "Specifices if a PDB file should be produced for the resulting partial facade.");
            }, args);

            if (!parsingSucceeded)
            {
                return;
            }

            CommandLineTraceHandler.Enable();

            if (!Directory.Exists(facadePath))
                Directory.CreateDirectory(facadePath);

            var nameTable = new NameTable();
            var internFactory = new InternFactory();

            try
            {
                Dictionary<string, string> seedTypePreferences = ParseSeedTypePreferences(seedTypePreferencesUnsplit);

                using (var contractHost = new HostEnvironment(nameTable, internFactory))
                using (var seedHost = new HostEnvironment(nameTable, internFactory))
                {
                    contractHost.LoadErrorTreatment = contractLoadErrorTreatment;
                    seedHost.LoadErrorTreatment = seedLoadErrorTreatment;

                    var contractAssemblies = LoadAssemblies(contractHost, contracts);
                    IReadOnlyDictionary<string, IEnumerable<string>> docIdTable = GenerateDocIdTable(contractAssemblies, inclusionContracts);

                    IAssembly[] seedAssemblies = LoadAssemblies(seedHost, seeds).ToArray();

                    IAssemblyReference seedCoreAssemblyRef = ((Microsoft.Cci.Immutable.PlatformType)seedHost.PlatformType).CoreAssemblyRef;

                    if (forceZeroVersionSeeds)
                    {
                        // Create a deep copier, copy the seed assemblies, and zero out their versions.
                        var copier = new MetadataDeepCopier(seedHost);

                        for (int i = 0; i < seedAssemblies.Length; i++)
                        {
                            var mutableSeed = copier.Copy(seedAssemblies[i]);
                            mutableSeed.Version = new Version(0, 0, 0, 0);
                            // Copy the modified seed assembly back.
                            seedAssemblies[i] = mutableSeed;

                            if (mutableSeed.Name.UniqueKey == seedCoreAssemblyRef.Name.UniqueKey)
                            {
                                seedCoreAssemblyRef = mutableSeed;
                            }
                        }
                    }

                    var typeTable = GenerateTypeTable(seedAssemblies);
                    var facadeGenerator = new FacadeGenerator(seedHost, contractHost, docIdTable, typeTable, seedTypePreferences, clearBuildAndRevision, buildDesignTimeFacades, assemblyFileVersion);

                    if (partialFacadeAssemblyPath != null)
                    {
                        if (contractAssemblies.Count() != 1)
                        {
                            throw new FacadeGenerationException(
                                "When partialFacadeAssemblyPath is specified, only exactly one corresponding contract assembly can be specified.");
                        }

                        IAssembly contractAssembly = contractAssemblies.First();
                        IAssembly partialFacadeAssembly = seedHost.LoadAssembly(partialFacadeAssemblyPath);
                        if (contractAssembly.Name != partialFacadeAssembly.Name
                            || contractAssembly.Version != partialFacadeAssembly.Version
                            || contractAssembly.GetPublicKeyToken() != partialFacadeAssembly.GetPublicKeyToken())
                        {
                            throw new FacadeGenerationException(
                                string.Format("The partial facade assembly's name, version, and public key token must exactly match the contract to be filled. Contract: {0}, Facade: {1}",
                                    contractAssembly.AssemblyIdentity,
                                    partialFacadeAssembly.AssemblyIdentity));
                        }

                        Assembly filledPartialFacade = facadeGenerator.GenerateFacade(contractAssembly, seedCoreAssemblyRef, ignoreMissingTypes, overrideContractAssembly: partialFacadeAssembly);

                        string pdbLocation = null;

                        if (producePdb)
                        {
                            string pdbFolder = Path.GetDirectoryName(partialFacadeAssemblyPath);
                            pdbLocation = Path.Combine(pdbFolder, contractAssembly.Name + ".pdb");
                            if (producePdb && !File.Exists(pdbLocation))
                            {
                                pdbLocation = null;
                                Trace.TraceWarning("No PDB file present for un-transformed partial facade. No PDB will be generated.");
                            }
                        }

                        OutputFacadeToFile(facadePath, seedHost, filledPartialFacade, contractAssembly, pdbLocation);
                    }
                    else
                    {
                        foreach (var contract in contractAssemblies)
                        {
                            Assembly facade = facadeGenerator.GenerateFacade(contract, seedCoreAssemblyRef, ignoreMissingTypes);
                            if (facade == null)
                            {
#if !COREFX
                                Debug.Assert(Environment.ExitCode != 0);
#endif
                                continue;
                            }

                            OutputFacadeToFile(facadePath, seedHost, facade, contract);
                        }
                    }
                }
            }
            catch (FacadeGenerationException ex)
            {
                Trace.TraceError(ex.Message);
#if !COREFX
                Debug.Assert(Environment.ExitCode != 0);
#endif
            }
        }
Exemplo n.º 4
0
        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);
                }
            }
        }
Exemplo n.º 5
0
 internal SanitizerHostEnvironment(NameTable nameTable)
   : base(nameTable, new InternFactory(), 4, null, true)
 {
   this.peReader = new PeReader(this);
 }
Exemplo n.º 6
0
    static void Main(string[] args) {
      var nameTable = new NameTable();
      using (var host = new PeReader.DefaultHost(nameTable)) {
        var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

        var assembly = new Assembly() {
          Name = nameTable.GetNameFor("hello"),
          ModuleName = nameTable.GetNameFor("hello.exe"),
          PlatformType = host.PlatformType,
          Kind = ModuleKind.ConsoleApplication,
          RequiresStartupStub = host.PointerSize == 4,
          TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion,
        };
        assembly.AssemblyReferences.Add(coreAssembly);

        var rootUnitNamespace = new RootUnitNamespace();
        assembly.UnitNamespaceRoot = rootUnitNamespace;
        rootUnitNamespace.Unit = assembly;

        var moduleClass = new NamespaceTypeDefinition() {
          ContainingUnitNamespace = rootUnitNamespace,
          InternFactory = host.InternFactory,
          IsClass = true,
          Name = nameTable.GetNameFor("<Module>"),
        };
        assembly.AllTypes.Add(moduleClass);

        var testClass = new NamespaceTypeDefinition() {
          ContainingUnitNamespace = rootUnitNamespace,
          InternFactory = host.InternFactory,
          IsClass = true,
          IsPublic = true,
          Methods = new List<IMethodDefinition>(1),
          Name = nameTable.GetNameFor("Test"),
        };
        rootUnitNamespace.Members.Add(testClass);
        assembly.AllTypes.Add(testClass);
        testClass.BaseClasses = new List<ITypeReference>() { host.PlatformType.SystemObject };

        var mainMethod = new MethodDefinition() {
          ContainingTypeDefinition = testClass,
          InternFactory = host.InternFactory,
          IsCil = true,
          IsStatic = true,
          Name = nameTable.GetNameFor("Main"),
          Type = host.PlatformType.SystemVoid,
          Visibility = TypeMemberVisibility.Public,
        };
        assembly.EntryPoint = mainMethod;
        testClass.Methods.Add(mainMethod);

        var ilGenerator = new ILGenerator(host, mainMethod);

        var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console");
        var writeLine = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString);

        ilGenerator.Emit(OperationCode.Ldstr, "hello");
        ilGenerator.Emit(OperationCode.Call, writeLine);
        ilGenerator.Emit(OperationCode.Ret);

        var body = new ILGeneratorMethodBody(ilGenerator, true, 1, mainMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
        mainMethod.Body = body;

        using (var peStream = File.Create("hello.exe")) {
          PeWriter.WritePeToStream(assembly, host, peStream);
        }
      }
    }
Exemplo n.º 7
0
        public static int Main(string[] args)
        {
            ParseCommandLine(args);
            CommandLineTraceHandler.Enable();

            if (s_listRules)
            {
                CompositionHost c = GetCompositionHost();
                ExportCciSettings.StaticSettings = CciComparers.Default.GetEqualityComparer<ITypeReference>();

                var rules = c.GetExports<IDifferenceRule>();

                foreach (var rule in rules.Select(r => r.GetType().Name).OrderBy(r => r))
                {
                    Console.WriteLine(rule);
                }

                return 0;
            }

            using (TextWriter output = GetOutput())
            {
                if (DifferenceWriter.ExitCode != 0)
                    return 0;

                if (output != Console.Out)
                    Trace.Listeners.Add(new TextWriterTraceListener(output) { Filter = new EventTypeFilter(SourceLevels.Error | SourceLevels.Warning) });
                try
                {
                    BaselineDifferenceFilter filter = GetBaselineDifferenceFilter();
                    NameTable sharedNameTable = new NameTable();
                    HostEnvironment contractHost = new HostEnvironment(sharedNameTable);
                    contractHost.UnableToResolve += new EventHandler<UnresolvedReference<IUnit, AssemblyIdentity>>(contractHost_UnableToResolve);
                    contractHost.ResolveAgainstRunningFramework = s_resolveFx;
                    contractHost.UnifyToLibPath = s_unifyToLibPaths;
                    contractHost.AddLibPaths(HostEnvironment.SplitPaths(s_contractLibDirs));
                    IEnumerable<IAssembly> contractAssemblies = contractHost.LoadAssemblies(s_contractSet, s_contractCoreAssembly);

                    if (s_ignoreDesignTimeFacades)
                        contractAssemblies = contractAssemblies.Where(a => !a.IsFacade());

                    HostEnvironment implHost = new HostEnvironment(sharedNameTable);
                    implHost.UnableToResolve += new EventHandler<UnresolvedReference<IUnit, AssemblyIdentity>>(implHost_UnableToResolve);
                    implHost.ResolveAgainstRunningFramework = s_resolveFx;
                    implHost.UnifyToLibPath = s_unifyToLibPaths;
                    implHost.AddLibPaths(HostEnvironment.SplitPaths(s_implDirs));
                    if (s_warnOnMissingAssemblies)
                        implHost.LoadErrorTreatment = ErrorTreatment.TreatAsWarning;

                    // The list of contractAssemblies already has the core assembly as the first one (if _contractCoreAssembly was specified).
                    IEnumerable<IAssembly> implAssemblies = implHost.LoadAssemblies(contractAssemblies.Select(a => a.AssemblyIdentity), s_warnOnIncorrectVersion);

                    // Exit after loading if the code is set to non-zero
                    if (DifferenceWriter.ExitCode != 0)
                        return 0;

                    ICciDifferenceWriter writer = GetDifferenceWriter(output, filter);
                    writer.Write(s_implDirs, implAssemblies, s_contractSet, contractAssemblies);
                    return 0;
                }
                catch (FileNotFoundException)
                {
                    // FileNotFoundException will be thrown by GetBaselineDifferenceFilter if it doesn't find the baseline file
                    // OR if GetComparers doesn't find the remap file.
                    return 2;
                }                
            }
        }