diff --git a/source/Cosmos.Core_Plugs/CosmosRuntimeType.cs b/source/Cosmos.Core/CosmosRuntimeType.cs
similarity index 99%
rename from source/Cosmos.Core_Plugs/CosmosRuntimeType.cs
rename to source/Cosmos.Core/CosmosRuntimeType.cs
index 6957a714a0..a12633ea50 100644
--- a/source/Cosmos.Core_Plugs/CosmosRuntimeType.cs
+++ b/source/Cosmos.Core/CosmosRuntimeType.cs
@@ -1,7 +1,6 @@
using System;
using System.Globalization;
using System.Reflection;
-using Cosmos.IL2CPU;
namespace Cosmos.Core
{
diff --git a/source/Cosmos.Core/Memory/HeapLarge.cs b/source/Cosmos.Core/Memory/HeapLarge.cs
index 7436f0e86d..f69296b21b 100644
--- a/source/Cosmos.Core/Memory/HeapLarge.cs
+++ b/source/Cosmos.Core/Memory/HeapLarge.cs
@@ -35,8 +35,8 @@ public static void Init()
var xPtr = (uint*)RAT.AllocPages(aType, xPages);
if (xPtr == null)
{
- Debugger.SendKernelPanic(0x67); // out of pages
- while (true) { }
+ Debugger.DoFail(0x67); // out of pages
+
}
xPtr[0] = xPages * RAT.PageSize - PrefixBytes; // Allocated data size
xPtr[1] = aSize; // Actual data size
@@ -52,7 +52,13 @@ public static void Init()
/// Thrown if page type is not found.
public static void Free(void* aPtr)
{
+ var heapObject = (uint*)aPtr;
var xPageIdx = RAT.GetFirstRATIndex(aPtr);
+ if (heapObject[-4] == 0 && xPageIdx == 0)
+ {
+ // The object is not allocated
+ return;
+ }
RAT.Free(xPageIdx);
}
}
diff --git a/source/Cosmos.Core/Memory/HeapSmall.cs b/source/Cosmos.Core/Memory/HeapSmall.cs
index 664458f130..a965e81198 100644
--- a/source/Cosmos.Core/Memory/HeapSmall.cs
+++ b/source/Cosmos.Core/Memory/HeapSmall.cs
@@ -230,8 +230,7 @@ private static void AddRootSMTBlock(SMTPage* aPage, uint aSize)
// we cant later add a block with a size smaller than an earlier block. That would break the algorithm
Debugger.DoSendNumber(aSize);
Debugger.DoSendNumber(ptr->Size);
- Debugger.SendKernelPanic(0x83);
- while (true) { }
+ Debugger.DoFail(0x83);
}
if (ptr->Size == 0)
@@ -367,8 +366,7 @@ static void CreatePage(SMTPage* aPage, uint aItemSize)
smtBlock = NextFreeBlock();
if (smtBlock == null)
{
- Debugger.SendKernelPanic(0x93);
- while (true) { };
+ Debugger.DoFail(0x93);
}
}
@@ -389,6 +387,28 @@ static void CreatePage(SMTPage* aPage, uint aItemSize)
smtBlock->PagePtr = xPtr;
}
+
+
+ ///
+ /// Get the first block for this size, which has space left to allocate to And get the root block
+ ///
+ /// The size
+ /// the Output block
+ /// The parent of the block
+ private static RootSMTBlock* GetFirstWithSpaceAndParent(uint aSize, out SMTBlock* block)
+ {
+ var page = SMT;
+ RootSMTBlock* rootblock = null;
+ do
+ {
+ rootblock = GetFirstBlock(page, aSize);
+ block = GetFirstWithSpace(aSize, rootblock);
+
+ page = page->Next;
+ } while (rootblock == null && page != null);
+ return rootblock;
+ }
+
///
/// Alloc memory block, of a given size.
///
@@ -396,22 +416,22 @@ static void CreatePage(SMTPage* aPage, uint aItemSize)
/// Byte pointer to the start of the block.
public static byte* Alloc(ushort aSize)
{
- var pageBlock = GetFirstWithSpace(aSize);
+ var smtblock = GetFirstWithSpaceAndParent(aSize, out SMTBlock* pageBlock);
if (pageBlock == null) // This happens when the page is full and we need to allocate a new page for this size
{
- CreatePage(GetLastPage(), GetRoundedSize(aSize));
+ CreatePage(GetLastPage(), smtblock->Size);
pageBlock = GetFirstWithSpace(aSize);
if (pageBlock == null)
{
//this means that we cant allocate another page
- Debugger.SendKernelPanic(0x121);
+ Debugger.DoAssert(0x121);
}
}
//now find position in the block
- ushort* page = (ushort*)pageBlock->PagePtr;
- uint elementSize = GetRoundedSize(aSize) + PrefixItemBytes;
- uint positions = RAT.PageSize / elementSize;
+ var page = (ushort*)pageBlock->PagePtr;
+ var elementSize = smtblock->Size + PrefixItemBytes;
+ var positions = RAT.PageSize / elementSize;
for (int i = 0; i < positions; i++)
{
if (page[i * elementSize / 2] == 0)
@@ -434,8 +454,8 @@ static void CreatePage(SMTPage* aPage, uint aItemSize)
// if we get here, RAM is corrupted, since we know we had a space but it turns out we didnt
Debugger.DoSendNumber((uint)pageBlock);
Debugger.DoSendNumber(aSize);
- Debugger.SendKernelPanic(0x122);
- while (true) { }
+ Debugger.DoFail(0x122);
+ return null;
}
///
@@ -449,9 +469,10 @@ public static void Free(void* aPtr)
if (size == 0)
{
// double free, this object has already been freed
- Debugger.DoBochsBreak();
+ //Debugger.DoBochsBreak();
Debugger.DoSendNumber((uint)heapObject);
- Debugger.SendKernelPanic(0x99);
+ Debugger.DoAssert(true, 0x99, true);
+ return;
}
var allocated = (uint*)aPtr;
@@ -483,7 +504,7 @@ public static void Free(void* aPtr)
{
blockPtr = blockPtr->NextBlock;
}
- if(blockPtr->PagePtr == allocatedOnPage)
+ if (blockPtr != null && blockPtr->PagePtr == allocatedOnPage)
{
break;
}
@@ -495,8 +516,7 @@ public static void Free(void* aPtr)
// this shouldnt happen
Debugger.DoSendNumber((uint)aPtr);
Debugger.DoSendNumber((uint)SMT);
- Debugger.SendKernelPanic(0x98);
- while (true) { }
+ Debugger.DoFail(0x98);
}
blockPtr->SpacesLeft++;
}
@@ -559,4 +579,5 @@ private static int GetAllocatedObjectCount(SMTPage* aPage, uint aSize)
#endregion
}
+
}
diff --git a/source/Cosmos.Core/Memory/RAT.cs b/source/Cosmos.Core/Memory/RAT.cs
index b62c8c3a8f..3b6e5a87c5 100644
--- a/source/Cosmos.Core/Memory/RAT.cs
+++ b/source/Cosmos.Core/Memory/RAT.cs
@@ -123,8 +123,9 @@ public static void Init(byte* aStartPtr, uint aSize)
if (aSize % PageSize != 0)
{
- Debugger.DoSendNumber(aSize % PageSize);
- Debugger.SendKernelPanic(11);
+
+ Debugger.DoSendNumber((aSize % PageSize));
+ Debugger.DoAssert(11);
throw new Exception("RAM size must be page aligned.");
}
diff --git a/source/Cosmos.Core/VTablesImpl.cs b/source/Cosmos.Core/VTablesImpl.cs
index e18833f923..dba15fd835 100644
--- a/source/Cosmos.Core/VTablesImpl.cs
+++ b/source/Cosmos.Core/VTablesImpl.cs
@@ -1,9 +1,5 @@
using System;
-using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Cosmos.Debug.Kernel;
namespace Cosmos.Core
@@ -158,8 +154,7 @@ public static uint GetMethodAddressForType(uint aType, uint aMethodId)
EnableDebug = true;
DebugHex("Type", aType);
DebugHex("MethodId", aMethodId);
- Debugger.SendKernelPanic(KernelPanics.VMT_TypeIdInvalid);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_TypeIdInvalid);
}
var xCurrentType = aType;
do
@@ -172,15 +167,13 @@ public static uint GetMethodAddressForType(uint aType, uint aMethodId)
{
EnableDebug = true;
DebugHex("MethodIndexes is null for type", aType);
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodIndexesNull);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_MethodIndexesNull);
}
if (xCurrentTypeInfo.MethodAddresses == null)
{
EnableDebug = true;
DebugHex("MethodAddresses is null for type", aType);
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodAddressesNull);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_MethodAddressesNull);
}
for (int i = 0; i < xCurrentTypeInfo.MethodIndexes.Length; i++)
@@ -198,9 +191,8 @@ public static uint GetMethodAddressForType(uint aType, uint aMethodId)
DebugHex("MethodCount", xCurrentTypeInfo.MethodCount);
DebugHex("MethodAddresses.Length", (uint)xCurrentTypeInfo.MethodAddresses.Length);
Debug("Method found, but address is invalid!");
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodFoundButAddressInvalid);
- while (true)
- ;
+ Debugger.DoFail(KernelPanics.VMT_MethodFoundButAddressInvalid);
+
}
Debug("Found.");
return xResult;
@@ -220,8 +212,7 @@ public static uint GetMethodAddressForType(uint aType, uint aMethodId)
DebugHex("MethodId", aMethodId);
Debug("Not FOUND!");
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodNotFound);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_MethodNotFound);
throw new Exception("Cannot find virtual method!");
}
@@ -254,8 +245,8 @@ public static uint GetDeclaringTypeOfMethodForType(uint aType, uint aMethodId)
DebugHex("MethodId", aMethodId);
Debug("Not FOUND Declaring TYPE!");
Debugger.DoBochsBreak();
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodNotFound);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_MethodNotFound);
+ return 0;
}
public static uint GetMethodAddressForInterfaceType(uint aType, uint aInterfaceMethodId)
@@ -265,8 +256,7 @@ public static uint GetMethodAddressForInterfaceType(uint aType, uint aInterfaceM
EnableDebug = true;
DebugHex("Type", aType);
DebugHex("InterfaceMethodId", aInterfaceMethodId);
- Debugger.SendKernelPanic(KernelPanics.VMT_TypeIdInvalid);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_TypeIdInvalid);
}
var xTypeInfo = mTypes[aType];
@@ -275,16 +265,14 @@ public static uint GetMethodAddressForInterfaceType(uint aType, uint aInterfaceM
{
EnableDebug = true;
DebugHex("InterfaceMethodIndexes is null for type", aType);
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodIndexesNull);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_MethodIndexesNull);
}
if (xTypeInfo.TargetMethodIndexes == null)
{
EnableDebug = true;
DebugHex("TargetMethodIndexes is null for type", aType);
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodAddressesNull);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_MethodAddressesNull);
}
for (int i = 0; i < xTypeInfo.InterfaceMethodIndexes.Length; i++)
@@ -302,8 +290,8 @@ public static uint GetMethodAddressForInterfaceType(uint aType, uint aInterfaceM
DebugHex("InterfaceMethodId", aInterfaceMethodId);
Debug("Not FOUND!");
- Debugger.SendKernelPanic(KernelPanics.VMT_MethodNotFound);
- while (true) ;
+ Debugger.DoFail(KernelPanics.VMT_MethodNotFound);
+ return 0;
}
///
diff --git a/source/Cosmos.Core_Plugs/System/ArrayImpl.cs b/source/Cosmos.Core_Plugs/System/ArrayImpl.cs
index 290fa494d2..e66d8d8d14 100644
--- a/source/Cosmos.Core_Plugs/System/ArrayImpl.cs
+++ b/source/Cosmos.Core_Plugs/System/ArrayImpl.cs
@@ -118,7 +118,7 @@ public static unsafe object GetValue(Array aThis, params int[] aIndices)
}
[PlugMethod(Signature = "System_Void__System_Array_SetValue_System_Object__System_Int32_")]
- public static unsafe void SetValue([ObjectPointerAccess] uint* aThis, uint aValue, int aIndex)
+ public static unsafe void SetValue([ObjectPointerAccess] uint* aThis, [ObjectPointerAccess] uint* aValue, int aIndex)
{
aThis = (uint*) aThis[0];
aThis += 3;
@@ -128,16 +128,16 @@ public static unsafe void SetValue([ObjectPointerAccess] uint* aThis, uint aValu
switch (xElementSize)
{
case 1:
- *(byte*) aThis = (byte) aValue;
+ *(byte*) aThis = (byte) *aValue;
return;
case 2:
- *(ushort*) aThis = (ushort) aValue;
+ *(ushort*) aThis = (ushort) *aValue;
return;
case 3:
- *(uint*) aThis = (uint) aValue;
+ *(uint*) aThis = (uint) *aValue;
return;
case 4:
- *(uint*) aThis = (uint) aValue;
+ *(uint*) aThis = (uint) *aValue;
return;
}
throw new NotSupportedException("SetValue not supported in this situation!");
diff --git a/source/Cosmos.Debug.Hosts/VMware.cs b/source/Cosmos.Debug.Hosts/VMware.cs
index d90e82ba7b..12826eb84d 100644
--- a/source/Cosmos.Debug.Hosts/VMware.cs
+++ b/source/Cosmos.Debug.Hosts/VMware.cs
@@ -9,9 +9,12 @@
//using Vestris.VMWareLib;
using Cosmos.Build.Common;
+using System.Linq;
-namespace Cosmos.Debug.Hosts {
- public class VMware : Host {
+namespace Cosmos.Debug.Hosts
+{
+ public class VMware : Host
+ {
protected VMwareEdition mEdition;
protected string mDir;
protected string mVmxPath;
@@ -21,27 +24,33 @@ public class VMware : Host {
protected string mPlayerPath;
protected string mHarddisk;
- public VMware(Dictionary aParams, bool aUseGDB,string harddisk = "Filesystem.vmdk") : base(aParams, aUseGDB) {
+ public VMware(Dictionary aParams, bool aUseGDB, string harddisk = "Filesystem.vmdk") : base(aParams, aUseGDB)
+ {
mHarddisk = harddisk;
mDir = Path.Combine(CosmosPaths.Build, @"VMWare\Workstation\");
mVmxPath = Path.Combine(mDir, @"Debug.vmx");
mWorkstationPath = GetPathname("VMware Workstation", "vmware.exe");
mPlayerPath = GetPathname("VMware Player", "vmplayer.exe");
- if (mWorkstationPath == null && mPlayerPath == null) {
+ if (mWorkstationPath == null && mPlayerPath == null)
+ {
throw new Exception("VMware not found.");
}
string xFlavor = aParams[BuildPropertyNames.VMwareEditionString].ToUpper();
mEdition = VMwareEdition.Player;
- if (xFlavor == "WORKSTATION") {
+ if (xFlavor == "WORKSTATION")
+ {
mEdition = VMwareEdition.Workstation;
}
// Try alternate if selected one is not installed
- if (mEdition == VMwareEdition.Player && mPlayerPath == null && mWorkstationPath != null) {
+ if (mEdition == VMwareEdition.Player && mPlayerPath == null && mWorkstationPath != null)
+ {
mEdition = VMwareEdition.Workstation;
- } else if (mEdition == VMwareEdition.Workstation && mWorkstationPath == null) {
+ }
+ else if (mEdition == VMwareEdition.Workstation && mWorkstationPath == null)
+ {
mEdition = VMwareEdition.Player;
}
}
@@ -54,11 +63,15 @@ public VMware(Dictionary aParams, bool aUseGDB,string harddisk =
// }
//}
- protected string GetPathname(string aKey, string aEXE) {
- using (var xRegKey = Registry.LocalMachine.OpenSubKey(@"Software\WOW6432Node\VMware, Inc.\" + aKey, false)) {
- if (xRegKey != null) {
+ protected string GetPathname(string aKey, string aEXE)
+ {
+ using (var xRegKey = Registry.LocalMachine.OpenSubKey(@"Software\WOW6432Node\VMware, Inc.\" + aKey, false))
+ {
+ if (xRegKey != null)
+ {
string xResult = Path.Combine(((string)xRegKey.GetValue("InstallPath")), aEXE);
- if (File.Exists(xResult)) {
+ if (File.Exists(xResult))
+ {
return xResult;
}
}
@@ -66,24 +79,31 @@ protected string GetPathname(string aKey, string aEXE) {
}
}
- public override void Start() {
+ public override void Start()
+ {
Cleanup();
CreateDebugVmx();
// Target exe or file
mProcess = new Process();
var xPSI = mProcess.StartInfo;
- if (mEdition == VMwareEdition.Player) {
+ if (mEdition == VMwareEdition.Player)
+ {
xPSI.FileName = mPlayerPath;
- } else {
+ }
+ else
+ {
xPSI.FileName = mWorkstationPath;
}
var xArgSB = new StringBuilder();
string xVmxPath = "\"" + mVmxPath + "\"";
- if (mEdition == VMwareEdition.Player) {
+ if (mEdition == VMwareEdition.Player)
+ {
xPSI.Arguments = xVmxPath;
- } else {
+ }
+ else
+ {
// -x: Auto power on VM. Must be small x, big X means something else.
// -q: Close VMWare when VM is powered off.
// Options must come beore the vmx, and cannot use shellexecute
@@ -129,7 +149,8 @@ private void ExitCallback(object sender, EventArgs e)
}
}
- public override void Stop() {
+ public override void Stop()
+ {
if (null != mProcess)
{
try
@@ -152,15 +173,19 @@ public override void Stop() {
Cleanup();
}
- protected void DeleteFiles(string aPath, string aPattern) {
+ protected void DeleteFiles(string aPath, string aPattern)
+ {
var xFiles = Directory.GetFiles(aPath, aPattern);
- foreach (var xFile in xFiles) {
+ foreach (var xFile in xFiles)
+ {
File.Delete(xFile);
}
}
- protected void Cleanup() {
- try {
+ protected void Cleanup()
+ {
+ try
+ {
string xPath = Path.GetDirectoryName(mVmxPath);
// Delete old Debug.vmx and other files that might be left over from previous run.
// Especially important with newer versions of VMWare player which defaults to suspend
@@ -178,50 +203,66 @@ protected void Cleanup() {
File.Delete(Path.Combine(xPath, "vmware-0.log"));
File.Delete(Path.Combine(xPath, "vmware-1.log"));
File.Delete(Path.Combine(xPath, "vmware-2.log"));
- } catch (Exception) {
+ }
+ catch (Exception)
+ {
// Ignore errors, users can stop VS while VMware is still running and files will be locked.
}
}
- protected void CreateDebugVmx() {
+ protected void CreateDebugVmx()
+ {
// VMWare doesn't like to boot a read only VMX.
// We also need to make changes based on project / debug settings.
// Finally we do not want to create VCS checkins based on local user changes.
// Because of this we use Cosmos.vmx as a template and output a Debug.vmx on every run.
- using (var xSrc = new StreamReader(File.Open(Path.Combine(mDir, "Cosmos.vmx"), FileMode.OpenOrCreate))) {
- try {
+ using (var xSrc = new StreamReader(File.Open(Path.Combine(mDir, "Cosmos.vmx"), FileMode.OpenOrCreate)))
+ {
+ try
+ {
// Write out Debug.vmx
- using (var xDest = new StreamWriter(File.Open(mVmxPath, FileMode.Create))) {
+ using (var xDest = new StreamWriter(File.Open(mVmxPath, FileMode.Create)))
+ {
string xLine;
- while ((xLine = xSrc.ReadLine()) != null) {
+ while ((xLine = xSrc.ReadLine()) != null)
+ {
var xParts = xLine.Split('=');
- if (xParts.Length == 2) {
+ if (xParts.Length == 2)
+ {
string xName = xParts[0].Trim();
string xValue = xParts[1].Trim();
- if ((xName == "uuid.location") || (xName == "uuid.bios")) {
+ if ((xName == "uuid.location") || (xName == "uuid.bios"))
+ {
// We delete uuid entries so VMWare doesnt ask the user "Did you move or copy" the file
xValue = null;
- } else if (xName == "ide1:0.fileName")
+ }
+ else if (xName == "ide1:0.fileName")
{
// Set the ISO file for booting
xValue = "\"" + mParams["ISOFile"] + "\"";
- } else if (xName == "ide0:0.fileName") {
+ }
+ else if (xName == "ide0:0.fileName")
+ {
xValue = "\"" + mHarddisk + "\"";
- } else if (xName == "nvram") {
+ }
+ else if (xName == "nvram")
+ {
// Point it to an initially non-existent nvram.
// This has the effect of disabling PXE so the boot is faster.
xValue = "\"Debug.nvram\"";
}
- if (xValue != null) {
+ if (xValue != null)
+ {
xDest.WriteLine(xName + " = " + xValue);
}
}
}
- if (mUseGDB) {
+ if (mUseGDB)
+ {
xDest.WriteLine();
xDest.WriteLine("debugStub.listen.guest32 = \"TRUE\"");
xDest.WriteLine("debugStub.hideBreakpoints = \"TRUE\"");
@@ -229,8 +270,11 @@ protected void CreateDebugVmx() {
xDest.WriteLine("debugStub.listen.guest32.remote = \"TRUE\"");
}
}
- } catch (IOException ex) {
- if (ex.Message.Contains(Path.GetFileName(mDir))) {
+ }
+ catch (IOException ex)
+ {
+ if (ex.Message.Contains(Path.GetFileName(mDir)))
+ {
throw new Exception("The VMware image " + mDir + " is still in use. Please exit current Vmware session with Cosmos and try again.", ex);
}
throw;
diff --git a/source/Cosmos.Debug.Kernel.Plugs.Asm/DebuggerAsm.cs b/source/Cosmos.Debug.Kernel.Plugs.Asm/DebuggerAsm.cs
index 95fadc540d..fa5039d526 100644
--- a/source/Cosmos.Debug.Kernel.Plugs.Asm/DebuggerAsm.cs
+++ b/source/Cosmos.Debug.Kernel.Plugs.Asm/DebuggerAsm.cs
@@ -60,6 +60,15 @@ public static void SendKernelPanic(uint id)
new LiteralAssemblerCode("%endif");
}
+
+ [Inline]
+ public static void SendCoreDump()
+ {
+ new LiteralAssemblerCode("%ifdef DEBUGSTUB");
+ new LiteralAssemblerCode("Call DebugStub_SendCoreDump");
+ new LiteralAssemblerCode("%endif");
+ }
+
[PlugMethod(Assembler = typeof(DoRealHalt))]
public static void DoRealHalt() { }
diff --git a/source/Cosmos.Debug.Kernel/Debugger.cs b/source/Cosmos.Debug.Kernel/Debugger.cs
index c94095ece2..9dda28dc20 100644
--- a/source/Cosmos.Debug.Kernel/Debugger.cs
+++ b/source/Cosmos.Debug.Kernel/Debugger.cs
@@ -1,278 +1,366 @@
-using System.Diagnostics;
-
-namespace Cosmos.Debug.Kernel
-{
- ///
- /// Provides a simplified interface for creating new instances of the
- /// class.
- ///
- public static class DebuggerFactory
- {
- ///
- /// Whether the created instances should output
- /// the given log inputs to the display console.
- ///
- public static bool WriteToConsole = false;
-
- ///
- /// Creates a new instance.
- ///
- /// The virtual compile-time ring the debugger is operating in.
- /// The section the debugger refers to.
- public static Debugger CreateDebugger(string section = "")
- {
- if (WriteToConsole)
- {
- return new ConsoleDebugger(section);
- }
- else
- {
- return new Debugger(section);
- }
- }
- }
-
- ///
- /// Represents a categorized remote debugger, capable of communicating
- /// with an external host machine, including virtualizers.
- ///
- public class Debugger
- {
- ///
- /// Creates a new instance of the class.
- ///
- /// The virtual compile-time ring the debugger is operating in.
- /// The section the debugger refers to.
- public Debugger(string section)
- {
- Section = section;
- }
-
- ///
- /// The section the debugger refers to.
- ///
- public string Section { get; }
-
- ///
- /// Triggers a software breakpoint.
- ///
- public void Break() { }
-
- ///
- /// Triggers a Bochs breakpoint.
- ///
- public static void DoBochsBreak() { }
-
- internal static void DoRealHalt() { }
-
- private static unsafe void ActualSend(int aLength, char* aText) { }
-
- ///
- /// Sends the pointer of the given object to any connected debugging hosts.
- ///
- public void SendPtr(object obj) { }
-
- ///
- /// Sends a 32-bit unsigned integer to connected debugging hosts.
- ///
- public static void DoSendNumber(uint number) { }
-
- ///
- /// Sends a 32-bit signed integer to connected debugging hosts.
- ///
- public static void DoSendNumber(int number) { }
-
- ///
- /// Sends a 64-bit unsigned integer to connected debugging hosts.
- ///
- public static void DoSendNumber(ulong number) { }
-
- ///
- /// Sends a 64-bit signed integer to connected debugging hosts.
- ///
- public static void DoSendNumber(long number) { }
-
- ///
- /// Sends a 32-bit floating-point number to connected debugging hosts.
- ///
- public static void DoSendNumber(float number) { }
-
- ///
- /// Sends a 64-bit floating-point number to connected debugging hosts.
- ///
- public static void DoSendNumber(double number) { }
-
- ///
- public void SendNumber(uint number) => DoSendNumber(number);
-
- ///
- public void SendNumber(int number) => DoSendNumber(number);
-
- ///
- public void SendNumber(ulong number) => DoSendNumber(number);
-
- ///
- public void SendNumber(long number) => DoSendNumber(number);
-
- ///
- public void SendNumber(float number) => DoSendNumber(number);
-
- ///
- public void SendNumber(double number) => DoSendNumber(number);
-
- public unsafe void SendChannelCommand(byte aChannel, byte aCommand, byte[] aData)
- {
- fixed (byte* xPtr = &aData[0])
- {
- SendChannelCommand(aChannel, aCommand, aData.Length, xPtr);
- }
- }
-
- ///
- /// Sends a command and its associated data to the given debug channel.
- ///
- /// The channel to send the data to.
- /// The numeric command.
- /// The amount of bytes in the data associated with the command.
- /// The data associated with the command
- public static unsafe void SendChannelCommand(byte channel, byte command, int byteCount, byte* data) { }
-
- ///
- /// Sends a command to the given debug channel.
- ///
- /// The channel to send the data to.
- /// The numeric command.
- public static void SendChannelCommand(byte channel, byte command) { }
-
- internal static void DoSend(string aText) { }
-
- internal static void DoSend(string[] aStringArray)
- {
- for (int i = 0; i < aStringArray.Length; ++i)
- {
- DoSend(aStringArray[i]);
- }
- }
-
- ///
- /// Sends a kernel panic error code to connected debugging hosts.
- ///
- public static void SendKernelPanic(uint id) { }
-
- ///
- /// Sends the given string to connected debugging hosts.
- ///
- /// The text/message to send.
- public void Send(string text) => DoSend(text);
-
- ///
- /// Sends multiple strings to connected debugging hosts.
- ///
- /// The strings to send.
- public void Send(string[] stringArray) => DoSend(stringArray);
-
- ///
- /// Sends the given message to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(string text) => DoSend(text);
-
- ///
- /// Sends the given strings to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(string[] stringArray) => DoSend(stringArray);
-
- ///
- /// Sends the given 32-bit unsigned integer to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(uint number) => DoSendNumber(number);
-
- ///
- /// Sends the given 32-bit signed integer to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(int number) => DoSendNumber(number);
-
- ///
- /// Sends the given 64-bit unsigned integer to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(ulong number) => DoSendNumber(number);
-
- ///
- /// Sends the given 64-bit signed integer to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(long number) => DoSendNumber(number);
-
- ///
- /// Sends the given 32-bit floating-point number to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(float number) => DoSendNumber(number);
-
- ///
- /// Sends the given 64-bit floating-point number to all connected debugging hosts.
- ///
- [Conditional("COSMOSDEBUG")]
- public virtual void SendInternal(double number) => DoSendNumber(number);
-
- //public void OldSend(string aText) {
- // // TODO: Need to fix this so it can send empty strings.
- // // Sending empty strings locks it up right now
- // if (aText.Length == 0)
- // {
- // return;
- // }
-
- // var xChars = aText.ToCharArray();
- // fixed (char* xPtr = &xChars[0])
- // {
- // ActualSend(xChars.Length, xPtr);
- // }
- //}
-
- ///
- /// Displays a message box on connected debugging hosts.
- ///
- /// The length of the C-string.
- /// The text to display in the message box, as a C-string.
- public unsafe void SendMessageBox(int length, char* text) { } // Plugged
-
- ///
- /// Displays a message box on connected debugging hosts.
- ///
- /// The text to display.
- public unsafe void SendMessageBox(string text)
- {
- // TODO: Need to fix this so it can send empty strings.
- // Sending empty strings locks it up right now
- if (text.Length == 0)
- {
- return;
- }
-
- var xChars = text.ToCharArray();
- fixed (char* xPtr = &xChars[0])
- {
- SendMessageBox(xChars.Length, xPtr);
- }
- }
-
- private int FromHex(string p)
- {
- p = p.ToLower();
- string hex = "0123456789abcdef";
-
- int ret = 0;
-
- for (int i = 0; i < p.Length; i++)
- {
- ret = ret * 16 + hex.IndexOf(p[i]);
- }
- return ret;
- }
- }
+using System.Diagnostics;
+
+namespace Cosmos.Debug.Kernel
+{
+
+
+ ///
+ /// Provides a simplified interface for creating new instances of the
+ /// class.
+ ///
+ public static class DebuggerFactory
+ {
+ ///
+ /// Whether the created instances should output
+ /// the given log inputs to the display console.
+ ///
+ public static bool WriteToConsole = false;
+
+ ///
+ /// Creates a new instance.
+ ///
+ /// The virtual compile-time ring the debugger is operating in.
+ /// The section the debugger refers to.
+ public static Debugger CreateDebugger(string section = "")
+ {
+ if (WriteToConsole)
+ {
+ return new ConsoleDebugger(section);
+ }
+ else
+ {
+ return new Debugger(section);
+ }
+ }
+ }
+
+ public class Debugger
+ {
+ public static bool IgnoreAssert = false;
+ ///
+ /// Creates a new instance of the class.
+ ///
+ /// The virtual compile-time ring the debugger is operating in.
+ /// The section the debugger refers to.
+ public Debugger(string section)
+ {
+ Section = section;
+ }
+
+ ///
+ /// The section the debugger refers to.
+ ///
+ public string Section { get; }
+
+ #region Break
+ public void Break() { }
+
+ public static void DoBochsBreak() { }
+
+ internal static void DoRealHalt() { }
+ #endregion
+
+ private static unsafe void ActualSend(int aLength, char* aText) { }
+
+ ///
+ /// Sends the pointer of the given object to any connected debugging hosts.
+ ///
+ public void SendPtr(object obj) { }
+
+ ///
+ /// Sends a 32-bit unsigned integer to connected debugging hosts.
+ ///
+ public static void DoSendNumber(uint number) { }
+
+ ///
+ /// Sends a 32-bit signed integer to connected debugging hosts.
+ ///
+ public static void DoSendNumber(int number) { }
+
+ ///
+ /// Sends a 64-bit unsigned integer to connected debugging hosts.
+ ///
+ public static void DoSendNumber(ulong number) { }
+
+ ///
+ /// Sends a 64-bit signed integer to connected debugging hosts.
+ ///
+ public static void DoSendNumber(long number) { }
+
+ ///
+ /// Sends a 32-bit floating-point number to connected debugging hosts.
+ ///
+ public static void DoSendNumber(float number) { }
+
+ ///
+ /// Sends a 64-bit floating-point number to connected debugging hosts.
+ ///
+ public static void DoSendNumber(double number) { }
+
+ ///
+ public void SendNumber(uint number) => DoSendNumber(number);
+
+ ///
+ public void SendNumber(int number) => DoSendNumber(number);
+
+ ///
+ public void SendNumber(ulong number) => DoSendNumber(number);
+
+ ///
+ public void SendNumber(long number) => DoSendNumber(number);
+
+ ///
+ public void SendNumber(float number) => DoSendNumber(number);
+
+ ///
+ public void SendNumber(double number) => DoSendNumber(number);
+
+ public unsafe void SendChannelCommand(byte aChannel, byte aCommand, byte[] aData)
+ {
+ fixed (byte* xPtr = &aData[0])
+ {
+ SendChannelCommand(aChannel, aCommand, aData.Length, xPtr);
+ }
+ }
+
+ ///
+ /// Sends a command and its associated data to the given debug channel.
+ ///
+ /// The channel to send the data to.
+ /// The numeric command.
+ /// The amount of bytes in the data associated with the command.
+ /// The data associated with the command
+ public static unsafe void SendChannelCommand(byte channel, byte command, int byteCount, byte* data) { }
+
+ ///
+ /// Sends a command to the given debug channel.
+ ///
+ /// The channel to send the data to.
+ /// The numeric command.
+ public static void SendChannelCommand(byte channel, byte command) { }
+
+ internal static void DoSend(string aText) { }
+
+ internal static void DoSend(string[] aStringArray)
+ {
+ for (int i = 0; i < aStringArray.Length; ++i)
+ {
+ DoSend(aStringArray[i]);
+ }
+ }
+
+ #region Assert
+ private static void SendKernelPanic(uint id) { }
+
+ public static void SendCoreDump() { }
+
+ #region Assert Function
+
+ public static void DoAssert(int code)
+ {
+ DoAssert(true, code);
+ }
+
+ public static void DoAssert(bool condition)
+ {
+ DoAssert(condition, -1);
+ }
+
+ public static void DoAssert(bool condition, int code)
+ {
+ DoAssert(condition, code, false);
+ }
+ public static void DoAssert(bool condition, int code, string message)
+ {
+ DoAssert(condition, code, false, message);
+ }
+ public static void DoAssert(bool condition, bool DoBreak)
+ {
+ DoAssert(condition, -1, DoBreak, null);
+ }
+ public static void DoAssert(bool condition, bool DoBreak, string message)
+ {
+ DoAssert(condition, -1, DoBreak, message);
+ }
+
+ public static void DoAssert(bool condition, string message)
+ {
+ DoAssert(condition, -1, false, message);
+ }
+
+ public static void DoAssert(bool condition, int code, bool DoBreak)
+ {
+ DoAssert(condition, code, DoBreak, null);
+ }
+
+ public static void DoAssert(bool condition, int code, bool DoBreak, string message)
+ {
+ if (condition && !IgnoreAssert)
+ {
+ if (message != null) { DoSend(message); }
+ if (DoBreak)
+ {
+ DoBochsBreak();
+ }
+ if (code > -1)
+ {
+ SendKernelPanic((uint)code);
+ }
+ else { SendCoreDump(); }
+ }
+ }
+
+ [Conditional("COSMOSDEBUG")]
+ public virtual void Assert(bool condition) => DoAssert(condition);
+
+ [Conditional("COSMOSDEBUG")]
+ public virtual void Assert(bool condition, int code) => DoAssert(condition, code);
+
+ [Conditional("COSMOSDEBUG")]
+ public virtual void Assert(bool condition, int code, string message) => DoAssert(condition, code, message);
+ #endregion
+
+ #region Fail Function
+
+ public static void DoFail(uint code)
+ {
+ DoFail((int)code);
+ }
+
+ public static void DoFail(int code)
+ {
+ DoFail(code, null);
+ }
+
+ public static void DoFail(string message)
+ {
+ DoFail(-1, message);
+ }
+
+ public static void DoFail(int code, string message)
+ {
+ if (message != null) { DoSend(message); }
+ if (code > -1)
+ {
+ SendKernelPanic((uint)code);
+ }
+ else { SendCoreDump(); } // behave like assert function
+ // halt
+ while (true) { }
+ }
+ [Conditional("COSMOSDEBUG")]
+ public virtual void Fail(string message) => DoFail(message);
+ [Conditional("COSMOSDEBUG")]
+ public virtual void Fail(int code) => DoFail(code);
+ [Conditional("COSMOSDEBUG")]
+ public virtual void Fail(int code, string message) => DoFail(code, message);
+ #endregion
+
+ #endregion
+
+ #region Trace
+
+ public void Send(string aText) => DoSend(aText);
+
+ public void Send(string[] aStringArray) => DoSend(aStringArray);
+
+ ///
+ /// Sends the given message to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(string text) => DoSend(text);
+
+ ///
+ /// Sends the given strings to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(string[] stringArray) => DoSend(stringArray);
+
+ ///
+ /// Sends the given 32-bit unsigned integer to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(uint number) => DoSendNumber(number);
+
+ ///
+ /// Sends the given 32-bit signed integer to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(int number) => DoSendNumber(number);
+
+ ///
+ /// Sends the given 64-bit unsigned integer to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(ulong number) => DoSendNumber(number);
+
+ ///
+ /// Sends the given 64-bit signed integer to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(long number) => DoSendNumber(number);
+
+ ///
+ /// Sends the given 32-bit floating-point number to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(float number) => DoSendNumber(number);
+
+ ///
+ /// Sends the given 64-bit floating-point number to all connected debugging hosts.
+ ///
+ [Conditional("COSMOSDEBUG")]
+ public virtual void SendInternal(double number) => DoSendNumber(number);
+
+ //public void OldSend(string aText) {
+ // // TODO: Need to fix this so it can send empty strings.
+ // // Sending empty strings locks it up right now
+ // if (aText.Length == 0)
+ // {
+ // return;
+ // }
+
+ // var xChars = aText.ToCharArray();
+ // fixed (char* xPtr = &xChars[0])
+ // {
+ // ActualSend(xChars.Length, xPtr);
+ // }
+ //}
+
+ public unsafe void SendMessageBox(int aLength, char* aText) { } // Plugged
+
+ ///
+ /// Displays a message box on connected debugging hosts.
+ ///
+ /// The text to display.
+ public unsafe void SendMessageBox(string text)
+ {
+ // TODO: Need to fix this so it can send empty strings.
+ // Sending empty strings locks it up right now
+ if (text.Length == 0)
+ {
+ return;
+ }
+
+ var xChars = text.ToCharArray();
+ fixed (char* xPtr = &xChars[0])
+ {
+ SendMessageBox(xChars.Length, xPtr);
+ }
+ }
+ #endregion
+ private int FromHex(string p)
+ {
+ p = p.ToLower();
+ string hex = "0123456789abcdef";
+
+ int ret = 0;
+
+ for (int i = 0; i < p.Length; i++)
+ {
+ ret = ret * 16 + hex.IndexOf(p[i]);
+ }
+ return ret;
+ }
+ }
}
\ No newline at end of file
diff --git a/source/Cosmos.System2/FileSystem/Disk.cs b/source/Cosmos.System2/FileSystem/Disk.cs
index 29d9476b08..010f4cbdf8 100644
--- a/source/Cosmos.System2/FileSystem/Disk.cs
+++ b/source/Cosmos.System2/FileSystem/Disk.cs
@@ -74,6 +74,23 @@ public List Partitions
i++;
}
}
+ // Partitions is lost
+ if (converted.Count == 0)
+ {
+ int i = 0;
+ foreach (var item in FindLostPartitions())
+ {
+ var part = new ManagedPartition(item);
+ if (mountedPartitions[i] != null)
+ {
+ var data = mountedPartitions[i];
+ part.RootPath = data.RootPath;
+ part.MountedFS = data;
+ }
+ converted.Add(part);
+ i++;
+ }
+ }
return converted;
}
@@ -276,6 +293,20 @@ public void FormatPartition(int index, string format, bool quick = true)
}
}
+ private List FindLostPartitions()
+ {
+ List list = new();
+ foreach (var p in Partition.Partitions)
+ {
+ if (p.Host == Host)
+ {
+ // start mount
+ list.Add(p);
+ }
+ }
+ return list;
+ }
+
private readonly FileSystem[] mountedPartitions = new FileSystem[4];
///
diff --git a/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs b/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs
index ad5f17c39d..cb533099e6 100644
--- a/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs
+++ b/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs
@@ -676,7 +676,7 @@ void DbgCmdSimpleNumber(uint nr)
void DbgCmdKernelPanic(uint nr)
{
- AD7Util.ShowError("Kernel panic: 0x" + nr.ToString());
+ AD7Util.ShowError("Kernel panic: 0x" + nr.ToString("X").ToUpper());
}
void DbgCmdSimpleLongNumber(ulong nr)
diff --git a/source/Cosmos.VS.DebugEngine/Utilities/Extensions.cs b/source/Cosmos.VS.DebugEngine/Utilities/Extensions.cs
index 0da698e20a..85c6b71284 100644
--- a/source/Cosmos.VS.DebugEngine/Utilities/Extensions.cs
+++ b/source/Cosmos.VS.DebugEngine/Utilities/Extensions.cs
@@ -71,12 +71,8 @@ public static string GetFullName(this MethodBase aMethod)
return String.Intern(xBuilder.ToString());
}
- public static string GetFullName(this Type aType)
+ public static string GetFullName(this Type aType,bool checkParam=false)
{
- if (aType.IsGenericParameter)
- {
- return aType.FullName;
- }
var xSB = new StringBuilder();
if (aType.IsArray)
{
@@ -103,7 +99,24 @@ public static string GetFullName(this Type aType)
{
xSB.Append(aType.FullName);
}
- if (aType.IsGenericType)
+ if (aType.IsGenericParameter)
+ {
+ if (checkParam)
+ {
+ xSB.Append(aType.DeclaringType.FullName);
+ xSB.Append(aType.DeclaringMethod?.Name);
+ var paramss = aType.DeclaringMethod?.GetParameters();
+ if (paramss != null)
+ {
+ foreach (var item in paramss)
+ {
+ xSB.Append(GetFullName(item.ParameterType, false));
+ }
+ }
+ }
+ xSB.Append(aType.Name);
+ }
+ if (aType.IsGenericType && !aType.IsGenericTypeDefinition)
{
xSB.Append("<");
var xArgs = aType.GetGenericArguments();