initial commit

This commit is contained in:
ParantezTech
2026-03-11 15:48:28 +03:00
commit 4d73f469bc
92 changed files with 166746 additions and 0 deletions
+275
View File
@@ -0,0 +1,275 @@
// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using System.Runtime.InteropServices;
namespace SharpEmu.Core.Cpu.Native;
public static unsafe class JitStubs
{
public const int XsaveBufferSize = 2688;
public const ulong XsaveChkGuard = 0xDeadBeef5533CCAAu;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct JmpWithIndex
{
private fixed byte _code[16];
public static ReadOnlySpan<byte> Template => new byte[]
{
0x68, 0x00, 0x00, 0x00, 0x00, // push <index>
0xE9, 0x00, 0x00, 0x00, 0x00, // jmp <handler>
0x90, 0x90, 0x90, 0x90, 0x90, 0x90 // nop padding
};
public static int Size => 16;
public void Initialize()
{
fixed (byte* code = _code)
{
Template.CopyTo(new Span<byte>(code, 16));
}
}
public void SetIndex(uint index)
{
fixed (byte* code = _code)
{
*(uint*)(code + 1) = index;
}
}
public void SetHandler(void* handler)
{
fixed (byte* code = _code)
{
var funcAddr = (long)handler;
var ripAddr = (long)(code + 10); // After push + jmp
var offset64 = funcAddr - ripAddr;
var offset32 = (uint)(ulong)offset64;
*(uint*)(code + 6) = offset32;
}
}
public byte* GetCodePointer()
{
fixed (byte* code = _code)
{
return code;
}
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Call9
{
private fixed byte _code[9];
public static ReadOnlySpan<byte> Template => new byte[]
{
0xE8, 0x00, 0x00, 0x00, 0x00, // call func
0x48, 0x89, 0xC0, // mov rax,rax
0x90 // nop
};
public static int Size => 9;
public void Initialize()
{
fixed (byte* code = _code)
{
Template.CopyTo(new Span<byte>(code, 9));
}
}
public void SetFunc(void* func)
{
fixed (byte* code = _code)
{
var funcAddr = (long)func;
var ripAddr = (long)(code + 5); // After call instruction
var offset64 = funcAddr - ripAddr;
var offset32 = (uint)(ulong)offset64;
*(uint*)(code + 1) = offset32;
}
}
public byte* GetCodePointer()
{
fixed (byte* code = _code)
{
return code;
}
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct JmpRax
{
private fixed byte _code[12];
public static ReadOnlySpan<byte> Template => new byte[]
{
0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // movabs rax,<addr>
0xFF, 0xE0 // jmp rax
};
public static int Size => 12;
public void Initialize()
{
fixed (byte* code = _code)
{
Template.CopyTo(new Span<byte>(code, 12));
}
}
public void SetTarget(void* target)
{
fixed (byte* code = _code)
{
*(ulong*)(code + 2) = (ulong)target;
}
}
public byte* GetCodePointer()
{
fixed (byte* code = _code)
{
return code;
}
}
}
public static class SafeCall
{
public static ReadOnlySpan<byte> Template => new byte[]
{
0x51,
0x52,
0x41, 0x50,
0x41, 0x51,
0x41, 0x52,
0x41, 0x53,
0x57,
0x56,
0x48, 0xBF, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
0x48, 0xBE, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
0x48, 0xB9, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
0xB0, 0x01,
0x86, 0x07,
0x84, 0xC0,
0x75, 0xF8,
0xB8, 0xFF, 0xFF, 0xFF, 0xFF,
0xBA, 0xFF, 0xFF, 0xFF, 0xFF,
0x0F, 0xAE, 0x26,
0x48, 0x83, 0xEC, 0x08,
0xFF, 0xD1,
0x48, 0x83, 0xC4, 0x08,
0x48, 0x89, 0xC1,
0xB8, 0xFF, 0xFF, 0xFF, 0xFF,
0xBA, 0xFF, 0xFF, 0xFF, 0xFF,
0x0F, 0xAE, 0x2E,
0x48, 0x89, 0xC8,
0xC6, 0x07, 0x00,
0x5E,
0x5F,
0x41, 0x5B,
0x41, 0x5A,
0x41, 0x59,
0x41, 0x58,
0x5A,
0x59,
0xC3
};
public static int Size => Template.Length; // 0x6c = 108 bytes
}
public static ReadOnlySpan<byte> TlsAccessPattern => new byte[]
{
0x64, 0x48, 0x8B, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00
};
public static void CreateJmpWithIndex(byte* location, uint index, void* handler)
{
var code = location;
code[0] = 0x68;
*(uint*)(code + 1) = index;
code[5] = 0xE9;
var handlerAddr = (long)handler;
var ripAddr = (long)(code + 10); // After push + jmp
var offset64 = handlerAddr - ripAddr;
*(uint*)(code + 6) = (uint)(ulong)offset64;
for (int i = 10; i < 16; i++)
{
code[i] = 0x90;
}
}
public static void CreateCall9(byte* location, void* func)
{
var code = location;
code[0] = 0xE8;
var funcAddr = (long)func;
var ripAddr = (long)(code + 5);
var offset64 = funcAddr - ripAddr;
*(uint*)(code + 1) = (uint)(ulong)offset64;
code[5] = 0x48;
code[6] = 0x89;
code[7] = 0xC0;
code[8] = 0x90;
}
public static void CreateJmpRax(byte* location, void* target)
{
var code = location;
code[0] = 0x48;
code[1] = 0xB8;
*(ulong*)(code + 2) = (ulong)target;
code[10] = 0xFF;
code[11] = 0xE0;
}
public static List<nint> FindTlsAccessPatterns(byte* start, int length)
{
var results = new List<nint>();
var pattern = TlsAccessPattern;
var end = start + length - pattern.Length;
for (var ptr = start; ptr < end; ptr++)
{
if (MatchesPattern(ptr, pattern))
{
results.Add((nint)ptr);
}
}
return results;
}
private static bool MatchesPattern(byte* ptr, ReadOnlySpan<byte> pattern)
{
for (var i = 0; i < pattern.Length; i++)
{
if (ptr[i] != pattern[i])
return false;
}
return true;
}
}