mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 21:38:52 +00:00
.
This commit is contained in:
parent
bbb8265166
commit
feef7db59a
1 changed files with 35 additions and 34 deletions
|
|
@ -1,4 +1,4 @@
|
|||
//#define VMT_DEBUG
|
||||
//#define VMT_DEBUG
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
|
@ -21,6 +21,7 @@ using Cosmos.IL2CPU.Plugs;
|
|||
using Cosmos.IL2CPU.X86.IL;
|
||||
using Mono.Cecil;
|
||||
using XSharp.Compiler;
|
||||
using static XSharp.Compiler.XSRegisters;
|
||||
using Add = Cosmos.Assembler.x86.Add;
|
||||
using Call = Cosmos.Assembler.x86.Call;
|
||||
using FieldInfo = Cosmos.IL2CPU.X86.IL.FieldInfo;
|
||||
|
|
@ -160,14 +161,14 @@ namespace Cosmos.IL2CPU
|
|||
if (DebugEnabled && StackCorruptionDetection)
|
||||
{
|
||||
// if StackCorruption detection is active, we're also going to emit a stack overflow detection
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EAX), "Before_Kernel_Stack");
|
||||
XS.Compare(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EAX), "Before_Kernel_Stack");
|
||||
XS.Compare(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.ESP));
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.LessThan, DestinationLabel = mCurrentMethodLabel + ".StackOverflowCheck_End" };
|
||||
new ClearInterruptFlag();
|
||||
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
||||
new Call { DestinationLabel = mCurrentMethodLabel + ".StackOverflowCheck_GetAddress" };
|
||||
new Label(mCurrentMethodLabel + ".StackOverflowCheck_GetAddress");
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||
new Call { DestinationLabel = "DebugStub_SendStackOverflowOccurred" };
|
||||
new Halt();
|
||||
|
|
@ -183,18 +184,18 @@ namespace Cosmos.IL2CPU
|
|||
var xName = DataMember.FilterStringForIncorrectChars("CCTOR_CALLED__" + LabelName.GetFullName(aMethod.MethodBase.DeclaringType));
|
||||
var xAsmMember = new DataMember(xName, (byte)0);
|
||||
Assembler.DataMembers.Add(xAsmMember);
|
||||
new Compare { DestinationRef = ElementReference.New(xName), DestinationIsIndirect = true, Size = 8, SourceValue = 1 };
|
||||
XS.Compare(xName, 1, destinationIsIndirect: true, size: RegisterSize.Byte8);
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = ".BeforeQuickReturn" };
|
||||
new Mov { DestinationRef = ElementReference.New(xName), DestinationIsIndirect = true, Size = 8, SourceValue = 1 };
|
||||
XS.Set(xName, 1, destinationIsIndirect: true, size: RegisterSize.Byte8);
|
||||
new Jump { DestinationLabel = ".AfterCCTorAlreadyCalledCheck" };
|
||||
new Label(".BeforeQuickReturn");
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.ECX), 0);
|
||||
XS.Set(OldToNewRegister(RegistersEnum.ECX), 0);
|
||||
new Return { };
|
||||
new Label(".AfterCCTorAlreadyCalledCheck");
|
||||
}
|
||||
|
||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||
|
||||
if (DebugMode == DebugMode.Source)
|
||||
{
|
||||
|
|
@ -343,7 +344,7 @@ namespace Cosmos.IL2CPU
|
|||
};
|
||||
}
|
||||
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.ECX), 0);
|
||||
XS.Set(OldToNewRegister(RegistersEnum.ECX), 0);
|
||||
var xTotalArgsSize = (from item in aMethod.MethodBase.GetParameters()
|
||||
select (int)ILOp.Align(ILOp.SizeOfType(item.ParameterType), 4)).Sum();
|
||||
if (!aMethod.MethodBase.IsStatic)
|
||||
|
|
@ -386,7 +387,7 @@ namespace Cosmos.IL2CPU
|
|||
var xOffset = GetResultCodeOffset(xReturnSize, (uint)xTotalArgsSize);
|
||||
for (int i = 0; i < ((int)(xReturnSize/4)); i++)
|
||||
{
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||
new Mov { DestinationReg = RegistersEnum.EBP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xOffset + ((i + 0) * 4)), SourceReg = RegistersEnum.EAX };
|
||||
}
|
||||
// extra stack space is the space reserved for example when a "public static int TestMethod();" method is called, 4 bytes is pushed, to make room for result;
|
||||
|
|
@ -405,13 +406,13 @@ namespace Cosmos.IL2CPU
|
|||
|
||||
if (xLocalsSize >= 256)
|
||||
{
|
||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 255);
|
||||
XS.Add(OldToNewRegister(RegistersEnum.ESP), 255);
|
||||
xLocalsSize -= 255;
|
||||
}
|
||||
}
|
||||
if (xLocalsSize > 0)
|
||||
{
|
||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), xLocalsSize);
|
||||
XS.Add(OldToNewRegister(RegistersEnum.ESP), xLocalsSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -419,21 +420,21 @@ namespace Cosmos.IL2CPU
|
|||
{
|
||||
// if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
|
||||
// if not, we should somehow break here.
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBX), XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Compare(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.EBX));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EBX), OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Compare(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.EBX));
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabelExc + "__2" };
|
||||
new ClearInterruptFlag();
|
||||
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
||||
new Call { DestinationLabel = xLabelExc + ".MethodFooterStackCorruptionCheck_Break_on_location" };
|
||||
new Label(xLabelExc + ".MethodFooterStackCorruptionCheck_Break_on_location");
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||
new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
|
||||
new Halt();
|
||||
}
|
||||
new Label(xLabelExc + "__2");
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||
var xRetSize = ((int)xTotalArgsSize) - ((int)xReturnSize);
|
||||
if (xRetSize < 0)
|
||||
{
|
||||
|
|
@ -858,7 +859,7 @@ namespace Cosmos.IL2CPU
|
|||
var xSize = X86.IL.Call.GetStackSizeToReservate(aTargetMethod.MethodBase);
|
||||
if (xSize > 0)
|
||||
{
|
||||
XS.Sub(XSRegisters.OldToNewRegister(RegistersEnum.ESP), xSize);
|
||||
XS.Sub(OldToNewRegister(RegistersEnum.ESP), xSize);
|
||||
}
|
||||
new Call { DestinationLabel = ILOp.GetMethodLabel(aTargetMethod) };
|
||||
var xMethodInfo = aMethod.MethodBase as SysReflection.MethodInfo;
|
||||
|
|
@ -879,7 +880,7 @@ namespace Cosmos.IL2CPU
|
|||
}
|
||||
for (int i = 0; i < xResultSize / 4; i++)
|
||||
{
|
||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4);
|
||||
XS.Add(OldToNewRegister(RegistersEnum.ESP), 4);
|
||||
}
|
||||
}, aNextLabel);
|
||||
}
|
||||
|
|
@ -909,8 +910,8 @@ namespace Cosmos.IL2CPU
|
|||
{
|
||||
XS.Comment("---------------------------------------------------------");
|
||||
new Label(InitVMTCodeLabel);
|
||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||
mSequences = new DebugInfo.SequencePoint[0];
|
||||
|
||||
var xSetTypeInfoRef = VTablesImplRefs.SetTypeInfoRef;
|
||||
|
|
@ -1166,7 +1167,7 @@ namespace Cosmos.IL2CPU
|
|||
#endif
|
||||
|
||||
new Label("_END_OF_" + InitVMTCodeLabel);
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||
new Return();
|
||||
}
|
||||
|
||||
|
|
@ -1373,8 +1374,8 @@ namespace Cosmos.IL2CPU
|
|||
// at the time the datamembers for literal strings are created, the type id for string is not yet determined.
|
||||
// for now, we fix this at runtime.
|
||||
new Label(InitStringIDsLabel);
|
||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||
new Mov { DestinationReg = RegistersEnum.EAX, SourceRef = ElementReference.New(ILOp.GetTypeIDLabel(typeof(String))), SourceIsIndirect = true };
|
||||
new Mov { DestinationRef = ElementReference.New("static_field__System_String_Empty"), DestinationIsIndirect = true, SourceRef = ElementReference.New(LdStr.GetContentsArrayName("")) };
|
||||
|
||||
|
|
@ -1398,12 +1399,12 @@ namespace Cosmos.IL2CPU
|
|||
new Mov { DestinationRef = ElementReference.New(xDataMember.Name), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||
}
|
||||
Assembler.WriteDebugVideo("Done");
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||
new Return();
|
||||
|
||||
new Label(CosmosAssembler.EntryPointName);
|
||||
XS.Push(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBP), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Push(OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EBP), OldToNewRegister(RegistersEnum.ESP));
|
||||
new Call { DestinationLabel = InitVMTCodeLabel };
|
||||
Assembler.WriteDebugVideo("Initializing string IDs.");
|
||||
new Call { DestinationLabel = InitStringIDsLabel };
|
||||
|
|
@ -1418,7 +1419,7 @@ namespace Cosmos.IL2CPU
|
|||
new Label(xCurLabel);
|
||||
X86.IL.Call.DoExecute(Assembler, null, aEntrypoint.DeclaringType.BaseType.GetMethod("Start"), null, xCurLabel, CosmosAssembler.EntryPointName + ".AfterStart", DebugEnabled);
|
||||
new Label(CosmosAssembler.EntryPointName + ".AfterStart");
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EBP));
|
||||
new Return();
|
||||
|
||||
if (ShouldOptimize)
|
||||
|
|
@ -1510,19 +1511,19 @@ namespace Cosmos.IL2CPU
|
|||
|
||||
// if debugstub is active, emit a stack corruption detection. at this point EBP and ESP should have the same value.
|
||||
// if not, we should somehow break here.
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EBX), XSRegisters.OldToNewRegister(RegistersEnum.EBP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.ESP));
|
||||
XS.Set(OldToNewRegister(RegistersEnum.EBX), OldToNewRegister(RegistersEnum.EBP));
|
||||
if (xStackDifference != 0)
|
||||
{
|
||||
XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.EAX), xStackDifference.Value);
|
||||
XS.Add(OldToNewRegister(RegistersEnum.EAX), xStackDifference.Value);
|
||||
}
|
||||
XS.Compare(XSRegisters.OldToNewRegister(RegistersEnum.EAX), XSRegisters.OldToNewRegister(RegistersEnum.EBX));
|
||||
XS.Compare(OldToNewRegister(RegistersEnum.EAX), OldToNewRegister(RegistersEnum.EBX));
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = xLabel + ".StackCorruptionCheck_End" };
|
||||
new ClearInterruptFlag();
|
||||
// don't remove the call. It seems pointless, but we need it to retrieve the EIP value
|
||||
new Call { DestinationLabel = xLabel + ".StackCorruptionCheck_GetAddress" };
|
||||
new Label(xLabel + ".StackCorruptionCheck_GetAddress");
|
||||
XS.Pop(XSRegisters.OldToNewRegister(RegistersEnum.EAX));
|
||||
XS.Pop(OldToNewRegister(RegistersEnum.EAX));
|
||||
new Mov { DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = RegistersEnum.EAX };
|
||||
new Call { DestinationLabel = "DebugStub_SendStackCorruptionOccurred" };
|
||||
new Halt();
|
||||
|
|
|
|||
Loading…
Reference in a new issue