From 83085124d5cc7b3b33a22c8fa766871bb5e56be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Wed, 9 Aug 2017 22:49:23 +0100 Subject: [PATCH] g3 --- .../Cosmos.TestRunner.Core.csproj | 21 ++ .../DefaultEngineConfiguration.cs | 2 +- .../Cosmos.TestRunner.Core/Engine.Helpers.cs | 28 ++- .../Cosmos.TestRunner.Core/Engine.Run.cs | 4 + .../Cosmos.TestRunner.csproj | 1 + .../Cosmos.Build.MSBuild/Cosmos.targets | 19 +- .../Cosmos.Build.MSBuild/TheRingMaster.cs | 17 +- .../Cosmos.System2/Cosmos.System2.csproj | 4 - Cosmos/source/TheRingMaster/Program.cs | 182 +++++++++++++++++- .../source/TheRingMaster/TheRingMaster.csproj | 9 + 10 files changed, 267 insertions(+), 20 deletions(-) diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj b/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj index ece01df5d..9fdd386f8 100644 --- a/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj +++ b/Cosmos/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj @@ -6,6 +6,27 @@ ..\..\Cosmos.snk + + + Engine.cs + + + Engine.cs + + + Engine.cs + + + Engine.cs + + + Engine.cs + + + Engine.cs + + + diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs b/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs index 86e43ff88..5aca1e30d 100644 --- a/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs +++ b/Cosmos/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs @@ -28,7 +28,7 @@ namespace Cosmos.TestRunner.Core engine.DebugIL2CPU = false; engine.TraceAssembliesLevel = TraceAssemblies.User; //engine.EnableStackCorruptionChecks = false; - engine.KernelPkg = "X86G3"; + engine.KernelPkg = "X86"; engine.EnableStackCorruptionChecks = true; engine.StackCorruptionChecksLevel = StackCorruptionDetectionLevel.AllInstructions; diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs index 40cb3d4b8..659406201 100644 --- a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs +++ b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs @@ -163,6 +163,30 @@ namespace Cosmos.TestRunner.Core RunObjDump(CosmosPaths.Build, workingDir, kernelFileName, OutputHandler.LogError, OutputHandler.LogMessage); } + private void RunTheRingMaster(string kernelFileName) + { + var xArgs = new List() { kernelFileName }; + + bool xUsingUserKit = false; + string xTheRingMasterPath = Path.Combine(FindCosmosRoot(), "source", "TheRingMaster"); + if (!Directory.Exists(xTheRingMasterPath)) + { + xUsingUserKit = true; + xTheRingMasterPath = Path.Combine(GetCosmosUserkitFolder(), "Build", "TheRingMaster"); + } + + if (xUsingUserKit) + { + RunProcess("TheRingMaster.exe", xTheRingMasterPath, xArgs); + } + else + { + xArgs.Insert(0, "run"); + xArgs.Insert(1, "--no-build"); + RunProcess("dotnet", xTheRingMasterPath, xArgs); + } + } + private void RunIL2CPU(string kernelFileName, string outputFile) { References = new List() { kernelFileName }; @@ -227,8 +251,8 @@ namespace Cosmos.TestRunner.Core else { xArgs.Insert(0, "run"); - xArgs.Insert(3, "--no-build"); - xArgs.Insert(4, " -- "); + xArgs.Insert(1, "--no-build"); + xArgs.Insert(2, " -- "); RunProcess("dotnet", xIL2CPUPath, xArgs, true); } } diff --git a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs index 08611bd9a..b3881310c 100644 --- a/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs +++ b/Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Run.cs @@ -20,6 +20,10 @@ namespace Cosmos.TestRunner.Core var xTempObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.o"); var xIsoFile = Path.Combine(mBaseWorkingDirectory, "Kernel.iso"); + if (KernelPkg == "X86") + { + RunTask("TheRingMaster", () => RunTheRingMaster(assemblyFileName)); + } RunTask("IL2CPU", () => RunIL2CPU(assemblyFileName, xAssemblyFile)); RunTask("Nasm", () => RunNasm(xAssemblyFile, xObjectFile, configuration.IsELF)); if (configuration.IsELF) diff --git a/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj b/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj index cfc09c67f..400e445aa 100644 --- a/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj +++ b/Cosmos/Tests/Cosmos.TestRunner/Cosmos.TestRunner.csproj @@ -11,6 +11,7 @@ + diff --git a/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets b/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets index fb7964650..0879d43ca 100644 --- a/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets +++ b/Cosmos/source/Cosmos.Build.MSBuild/Cosmos.targets @@ -1,12 +1,12 @@ - + False True False true - + $(AppData)\Cosmos User Kit $(CosmosDir)\Build\Tools @@ -44,7 +44,7 @@ - + @@ -54,8 +54,15 @@ + + + @@ -75,7 +82,7 @@ - + - + diff --git a/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs b/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs index cb715b778..2ed18e891 100644 --- a/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs +++ b/Cosmos/source/Cosmos.Build.MSBuild/TheRingMaster.cs @@ -2,14 +2,13 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Reflection; using Microsoft.Build.Framework; using Cosmos.Build.Common; namespace Cosmos.Build.MSBuild { - public class RingCheck : BaseToolTask + public class TheRingMaster : BaseToolTask { [Required] public string KernelAssemblyPath { get; set; } @@ -21,7 +20,19 @@ namespace Cosmos.Build.MSBuild public override bool Execute() { - return ExecuteTool(WorkingDir, Path.Combine(CosmosPaths.Build, "RingCheck", "RingCheck.exe"), KernelAssemblyPath, "Ring Check"); + var xSW = Stopwatch.StartNew(); + + try + { + Log.LogMessage(MessageImportance.High, $"Invoking TheRingMaster.exe {KernelAssemblyPath}"); + return ExecuteTool(WorkingDir, Path.Combine(CosmosPaths.Build, "TheRingMaster", "TheRingMaster.exe"), KernelAssemblyPath, "The Ring Master"); + } + finally + { + xSW.Stop(); + Log.LogMessage(MessageImportance.High, $"TheRingMaster invoked with KernelAssemblyPath = '{KernelAssemblyPath}'"); + Log.LogMessage(MessageImportance.High, "TheRingMaster task took {0}", xSW.Elapsed); + } } } } diff --git a/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj b/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj index cab278f1e..2f7f6b016 100644 --- a/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj +++ b/Cosmos/source/Cosmos.System2/Cosmos.System2.csproj @@ -15,8 +15,4 @@ - - - - diff --git a/Cosmos/source/TheRingMaster/Program.cs b/Cosmos/source/TheRingMaster/Program.cs index bb5b52f43..7cc9596fc 100644 --- a/Cosmos/source/TheRingMaster/Program.cs +++ b/Cosmos/source/TheRingMaster/Program.cs @@ -1,19 +1,193 @@ using System; -using System.Text; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; + +using Cosmos.Build.Common; namespace TheRingMaster { - class Program + public class Program { - static void Main(string[] args) + static Dictionary RingCache = new Dictionary(); + static string KernelDir; + + public static void Main(string[] args) { if (args.Length != 1) { + Console.WriteLine("ARGS:"); + + foreach (var xArg in args) + { + Console.WriteLine(xArg); + } + Console.WriteLine("Usage: theringmaster "); return; } - var xKernelAssemblyPath = args[1]; + var xKernelAssemblyPath = args[0]; + + if (!File.Exists(xKernelAssemblyPath)) + { + throw new FileNotFoundException("Kernel Assembly not found! Path: '" + xKernelAssemblyPath + "'"); + } + + KernelDir = Path.GetDirectoryName(xKernelAssemblyPath); + AssemblyLoadContext.Default.Resolving += Default_Resolving; + + var xKernelAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(xKernelAssemblyPath); + CheckRings(xKernelAssembly, "Application"); + + void CheckRings(Assembly aAssembly, string aRing, string aSourceAssemblyName = null) + { + RingCache.TryGetValue(aAssembly, out var xRing); + + if (xRing == null) + { + var xManifestName = aAssembly.GetManifestResourceNames() + .Where(n => n == aAssembly.GetName().Name + ".Cosmos.cfg") + .SingleOrDefault(); + + if (xManifestName != null) + { + Dictionary xCfg; + + using (var xManifestStream = aAssembly.GetManifestResourceStream(xManifestName)) + { + xCfg = ParseCfg(xManifestStream); + } + + if (xCfg == null) + { + throw new Exception("Invalid Cosmos configuration! Resource name: " + xManifestName); + } + + xCfg.TryGetValue("Ring", out xRing); + + if (!new string[] { "CPU", "Platform", "HAL", "System", "Application", /*"Plug",*/ "Debug" }.Contains(xRing)) + { + throw new Exception("Unknown ring! Ring: " + xRing); + } + } + + if (xRing == null) + { + xRing = "External"; + } + } + + RingCache.Add(aAssembly, xRing); + + // Check Rings + + bool xValid = false; + + // Same rings + // OR + // External ring, can be referenced by any ring + // OR + // One of the assemblies is Debug + if (aRing == xRing || xRing == "External" || aRing == "Debug" || xRing == "Debug") + { + xValid = true; + } + + if (!xValid) + { + switch (aRing) + { + case "Application" when xRing == "System": + case "System" when xRing == "HAL": + case "Platform" when xRing == "CPU": + case "Platform" when xRing == "HAL": + //case "Plug" when xRing == "System": + return; + } + } + + if (!xValid) + { + var xExceptionMessage = "Invalid rings! Source assembly: " + (aSourceAssemblyName ?? "(no assembly)") + + ": Ring " + aRing + "; Referenced assembly: " + aAssembly.GetName().Name + + ": Ring " + xRing; + + throw new Exception(xExceptionMessage); + } + + foreach (var xReference in aAssembly.GetReferencedAssemblies()) + { + try + { + CheckRings(AssemblyLoadContext.Default.LoadFromAssemblyName(xReference), xRing, aAssembly.GetName().Name); + } + catch (FileNotFoundException) + { + } + } + } + } + + private static Assembly Default_Resolving(AssemblyLoadContext aContext, AssemblyName aAssemblyName) + { + Assembly xAssembly = null; + + if (ResolveAssemblyForDir(KernelDir, out xAssembly)) + { + return xAssembly; + } + + if (ResolveAssemblyForDir(CosmosPaths.Kernel, out xAssembly)) + { + return xAssembly; + } + + return xAssembly; + + bool ResolveAssemblyForDir(string aDir, out Assembly aAssembly) + { + aAssembly = null; + + var xFiles = Directory.GetFiles(aDir, aAssemblyName.Name + ".*", SearchOption.TopDirectoryOnly); + + if (xFiles.Any(f => Path.GetExtension(f) == ".dll")) + { + aAssembly = aContext.LoadFromAssemblyPath(xFiles.Where(f => Path.GetExtension(f) == ".dll").Single()); + } + + if (xFiles.Any(f => Path.GetExtension(f) == ".exe")) + { + aAssembly = aContext.LoadFromAssemblyPath(xFiles.Where(f => Path.GetExtension(f) == ".exe").Single()); + } + + return aAssembly != null; + } + } + + static Dictionary ParseCfg(Stream aStream) + { + var xCfg = new Dictionary(); + + using (var xReader = new StreamReader(aStream)) + { + while (xReader.Peek() >= 0) + { + var xLine = xReader.ReadLine(); + + if (!xLine.Contains(':') || xLine.Count(c => c == ':') > 1) + { + return null; + } + + var xProperty = xLine.Split(':'); + xCfg.Add(xProperty[0].Trim(), xProperty[1].Trim()); + } + } + + return xCfg; } } } diff --git a/Cosmos/source/TheRingMaster/TheRingMaster.csproj b/Cosmos/source/TheRingMaster/TheRingMaster.csproj index d9499d41a..6c9fd7dce 100644 --- a/Cosmos/source/TheRingMaster/TheRingMaster.csproj +++ b/Cosmos/source/TheRingMaster/TheRingMaster.csproj @@ -2,6 +2,15 @@ netcoreapp1.0 + Exe + + + + + + + +