/// <summary> /// Initialize the dependent architectures and runtimes. /// </summary> private static void InitializeTargets() { Phx.Targets.Architectures.Architecture msilArch = Phx.Targets.Architectures.Msil.Architecture.New(); Phx.Targets.Runtimes.Runtime win32MSILRuntime = Phx.Targets.Runtimes.Vccrt.Win.Msil.Runtime.New(msilArch); Phx.GlobalData.RegisterTargetArchitecture(msilArch); Phx.GlobalData.RegisterTargetRuntime(win32MSILRuntime); }
/// <summary> /// Instrument the assembly. /// </summary> /// <returns>Termination mode of the processing.</returns> public static Phx.Term.Mode Process() { string currentAssembly = Application.Input.GetValue(null); // Create the log file with details about the basic blocks using (LogWriter log = new LogWriter(Path.ChangeExtension(currentAssembly, "Coverage.xml"))) { log.Start(); Phx.Output.WriteLine("Instrumenting code coverage for " + currentAssembly + " ..."); log.StartAssembly(currentAssembly); // Get the architecture and runtime from the existing assembly Phx.PEModuleUnit oldModule = Phx.PEModuleUnit.Open(currentAssembly); Phx.Targets.Architectures.Architecture architecture = oldModule.Architecture; Phx.Targets.Runtimes.Runtime runtime = oldModule.Runtime; #if VS2010 string clrVersion = oldModule.ClrVersionString; #endif oldModule.Close(); oldModule.Delete(); // Create an empty program to contain the instrumented code Phx.Lifetime lifetime = Phx.Lifetime.New(Phx.LifetimeKind.Global, null); Phx.ProgramUnit program = Phx.ProgramUnit.New( lifetime, null, Phx.GlobalData.TypeTable, architecture, runtime); Phx.PEModuleUnit module = Phx.PEModuleUnit.New( lifetime, Phx.Name.New(lifetime, Path.GetFullPath(currentAssembly)), program, Phx.GlobalData.TypeTable, architecture, runtime); // Set to metadata version 2 if none was copied #if VS2010 if (clrVersion == null) { clrVersion = PreferredClrVersion; module.ClrVersionString = clrVersion; } #endif // Dev10 Phoenix seems to require this fix #if VS2010 module.RaiseMsilOnly = true; #endif // Create the phase list: // 1. For each function // a. Raise the binary executable code to LIR // b. Instrument function with code coverage calls // c. Encode the instrumented code // 2. Emit the instrumented program as a binary Phx.Phases.PhaseConfiguration phases = Phx.Phases.PhaseConfiguration.New(lifetime, "CodeCoverage Phases"); phases.PhaseList.AppendPhase(Phx.PE.ReaderPhase.New(phases)); Phx.Phases.PhaseList functionPhases = Phx.PE.UnitListPhaseList.New(phases, Phx.PE.UnitListWalkOrder.PrePass); functionPhases.AppendPhase(Phx.PE.RaiseIRPhase.New(phases, Phx.FunctionUnit.LowLevelIRBeforeLayoutFunctionUnitState)); functionPhases.AppendPhase(InstrumentPhase.New(phases, log)); functionPhases.AppendPhase(EncodePhase.New(phases)); functionPhases.AppendPhase(Phx.PE.DiscardIRPhase.New(phases)); phases.PhaseList.AppendPhase(functionPhases); phases.PhaseList.AppendPhase(EmitPhase.New(phases)); Phx.GlobalData.BuildPlugInPhases(phases); // Run Phoenix using our phases phases.PhaseList.DoPhaseList(module); // Close the log file log.EndAssembly(); log.Close(); } return(Phx.Term.Mode.Normal); }