Check for reads/writes outside of the address space, optimize translation with a tail call
This commit is contained in:
parent
7685062655
commit
b4f3ffad61
1 changed files with 28 additions and 12 deletions
|
@ -43,18 +43,20 @@ namespace ChocolArm64.Memory
|
||||||
|
|
||||||
private Dictionary<int, ArmMonitor> Monitors;
|
private Dictionary<int, ArmMonitor> Monitors;
|
||||||
|
|
||||||
|
private ConcurrentDictionary<long, IntPtr> ObservedPages;
|
||||||
|
|
||||||
public IntPtr Ram { get; private set; }
|
public IntPtr Ram { get; private set; }
|
||||||
|
|
||||||
private byte* RamPtr;
|
private byte* RamPtr;
|
||||||
|
|
||||||
private byte*** PageTable;
|
private byte*** PageTable;
|
||||||
|
|
||||||
private ConcurrentDictionary<long, IntPtr> ObservedPages;
|
|
||||||
|
|
||||||
public AMemory(IntPtr Ram)
|
public AMemory(IntPtr Ram)
|
||||||
{
|
{
|
||||||
Monitors = new Dictionary<int, ArmMonitor>();
|
Monitors = new Dictionary<int, ArmMonitor>();
|
||||||
|
|
||||||
|
ObservedPages = new ConcurrentDictionary<long, IntPtr>();
|
||||||
|
|
||||||
this.Ram = Ram;
|
this.Ram = Ram;
|
||||||
|
|
||||||
RamPtr = (byte*)Ram;
|
RamPtr = (byte*)Ram;
|
||||||
|
@ -65,8 +67,6 @@ namespace ChocolArm64.Memory
|
||||||
{
|
{
|
||||||
PageTable[L0] = null;
|
PageTable[L0] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObservedPages = new ConcurrentDictionary<long, IntPtr>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveMonitor(AThreadState State)
|
public void RemoveMonitor(AThreadState State)
|
||||||
|
@ -445,25 +445,33 @@ namespace ChocolArm64.Memory
|
||||||
long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask;
|
long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask;
|
||||||
long L1 = (Position >> PTLvl1Bit) & PTLvl1Mask;
|
long L1 = (Position >> PTLvl1Bit) & PTLvl1Mask;
|
||||||
|
|
||||||
|
long Old = Position;
|
||||||
|
|
||||||
byte** Lvl1 = PageTable[L0];
|
byte** Lvl1 = PageTable[L0];
|
||||||
|
|
||||||
|
if ((Position >> (PTLvl0Bit + PTLvl0Bits)) != 0)
|
||||||
|
{
|
||||||
|
goto Unmapped;
|
||||||
|
}
|
||||||
|
|
||||||
if (Lvl1 == null)
|
if (Lvl1 == null)
|
||||||
{
|
{
|
||||||
return HandleNullPte(Position);
|
goto Unmapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
long Old = Position;
|
|
||||||
|
|
||||||
Position &= PageMask;
|
Position &= PageMask;
|
||||||
|
|
||||||
byte* Ptr = Lvl1[L1];
|
byte* Ptr = Lvl1[L1];
|
||||||
|
|
||||||
if (Ptr == null)
|
if (Ptr == null)
|
||||||
{
|
{
|
||||||
return HandleNullPte(Old);
|
goto Unmapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ptr + Position;
|
return Ptr + Position;
|
||||||
|
|
||||||
|
Unmapped:
|
||||||
|
return HandleNullPte(Old);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte* HandleNullPte(long Position)
|
private byte* HandleNullPte(long Position)
|
||||||
|
@ -483,25 +491,33 @@ namespace ChocolArm64.Memory
|
||||||
long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask;
|
long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask;
|
||||||
long L1 = (Position >> PTLvl1Bit) & PTLvl1Mask;
|
long L1 = (Position >> PTLvl1Bit) & PTLvl1Mask;
|
||||||
|
|
||||||
|
long Old = Position;
|
||||||
|
|
||||||
byte** Lvl1 = PageTable[L0];
|
byte** Lvl1 = PageTable[L0];
|
||||||
|
|
||||||
|
if ((Position >> (PTLvl0Bit + PTLvl0Bits)) != 0)
|
||||||
|
{
|
||||||
|
goto Unmapped;
|
||||||
|
}
|
||||||
|
|
||||||
if (Lvl1 == null)
|
if (Lvl1 == null)
|
||||||
{
|
{
|
||||||
return HandleNullPteWrite(Position);
|
goto Unmapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
long Old = Position;
|
|
||||||
|
|
||||||
Position &= PageMask;
|
Position &= PageMask;
|
||||||
|
|
||||||
byte* Ptr = Lvl1[L1];
|
byte* Ptr = Lvl1[L1];
|
||||||
|
|
||||||
if (Ptr == null)
|
if (Ptr == null)
|
||||||
{
|
{
|
||||||
return HandleNullPteWrite(Old);
|
goto Unmapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ptr + Position;
|
return Ptr + Position;
|
||||||
|
|
||||||
|
Unmapped:
|
||||||
|
return HandleNullPteWrite(Old);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte* HandleNullPteWrite(long Position)
|
private byte* HandleNullPteWrite(long Position)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue