A dozen changes; new HLEs, AV fixes, ELF loader fixes, new return codes, etc.

This commit is contained in:
ParantezTech
2026-03-14 20:38:25 +03:00
parent 028494a83b
commit 1f71c970d9
21 changed files with 2291 additions and 216 deletions
+130
View File
@@ -0,0 +1,130 @@
// Copyright (C) 2026 SharpEmu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
using System.Runtime.InteropServices;
using System.Text;
namespace SharpEmu.HLE;
public static class HleDataSymbols
{
private const string StackChkGuardNid = "f7uOxY9mM1U";
private const string ProgNameNid = "djxxOmW6-aw";
private const string LibcNeedFlagNid = "P330P3dFF68";
private const string LibcInternalNeedFlagNid = "ZT4ODD2Ts9o";
private const int ProgNameMaxBytes = 511;
private const ulong StackChkGuardValue = 0xC0DEC0DECAFEBABEUL;
private static readonly object _gate = new();
private static readonly nint _stackChkGuardAddress = Allocate(sizeof(ulong) * 2);
private static readonly nint _progNameBufferAddress = Allocate(ProgNameMaxBytes + 1);
private static readonly nint _progNamePointerAddress = Allocate(nint.Size);
private static readonly nint _libcNeedFlagAddress = Allocate(sizeof(uint));
private static readonly nint _libcInternalNeedFlagAddress = Allocate(sizeof(uint));
static HleDataSymbols()
{
if (_stackChkGuardAddress != 0)
{
Marshal.WriteInt64(_stackChkGuardAddress, unchecked((long)StackChkGuardValue));
Marshal.WriteInt64(
IntPtr.Add(_stackChkGuardAddress, sizeof(ulong)),
unchecked((long)StackChkGuardValue));
}
if (_libcNeedFlagAddress != 0)
{
Marshal.WriteInt32(_libcNeedFlagAddress, 1);
}
if (_libcInternalNeedFlagAddress != 0)
{
Marshal.WriteInt32(_libcInternalNeedFlagAddress, 1);
}
ConfigureProcessImageName("eboot.bin");
}
public static IEnumerable<string> EnumerateKnownNids()
{
yield return StackChkGuardNid;
yield return ProgNameNid;
yield return LibcNeedFlagNid;
yield return LibcInternalNeedFlagNid;
}
public static void ConfigureProcessImageName(string? processImageName)
{
var effectiveName = string.IsNullOrWhiteSpace(processImageName)
? "eboot.bin"
: processImageName;
var encodedName = Encoding.UTF8.GetBytes(effectiveName);
var byteCount = Math.Min(encodedName.Length, ProgNameMaxBytes);
lock (_gate)
{
if (_progNameBufferAddress == 0 || _progNamePointerAddress == 0)
{
return;
}
for (var i = 0; i <= ProgNameMaxBytes; i++)
{
Marshal.WriteByte(_progNameBufferAddress, i, 0);
}
Marshal.Copy(encodedName, 0, _progNameBufferAddress, byteCount);
WritePointer(_progNamePointerAddress, _progNameBufferAddress);
}
}
public static bool TryGetAddress(string nid, out ulong address)
{
var pointer = nid switch
{
StackChkGuardNid => _stackChkGuardAddress,
ProgNameNid => _progNamePointerAddress,
LibcNeedFlagNid => _libcNeedFlagAddress,
LibcInternalNeedFlagNid => _libcInternalNeedFlagAddress,
_ => 0,
};
if (pointer == 0)
{
address = 0;
return false;
}
address = unchecked((ulong)pointer);
return true;
}
private static nint Allocate(int size)
{
try
{
var memory = Marshal.AllocHGlobal(size);
for (var i = 0; i < size; i++)
{
Marshal.WriteByte(memory, i, 0);
}
return memory;
}
catch
{
return 0;
}
}
private static void WritePointer(nint target, nint value)
{
if (nint.Size == sizeof(int))
{
Marshal.WriteInt32(target, value.ToInt32());
return;
}
Marshal.WriteInt64(target, value.ToInt64());
}
}
+2
View File
@@ -17,5 +17,7 @@ public interface IModuleManager
bool TryGetExportByName(string exportName, out ExportedFunction export);
bool TryDispatch(string nid, CpuContext context, out OrbisGen2Result result);
OrbisGen2Result Dispatch(string nid, CpuContext context);
}
+12 -3
View File
@@ -93,6 +93,12 @@ public sealed class ModuleManager : IModuleManager
}
public OrbisGen2Result Dispatch(string nid, CpuContext context)
{
TryDispatch(nid, context, out var result);
return result;
}
public bool TryDispatch(string nid, CpuContext context, out OrbisGen2Result result)
{
ArgumentException.ThrowIfNullOrWhiteSpace(nid);
ArgumentNullException.ThrowIfNull(context);
@@ -100,13 +106,15 @@ public sealed class ModuleManager : IModuleManager
if (!_dispatchTable.TryGetValue(nid, out var function) || !_exportTable.TryGetValue(nid, out var export))
{
context[CpuRegister.Rax] = unchecked((ulong)(int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND);
return OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
result = OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
return false;
}
if ((export.Target & context.TargetGeneration) == 0)
{
context[CpuRegister.Rax] = unchecked((ulong)(int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND);
return OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
result = OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
return false;
}
context.ClearRaxWriteFlag();
@@ -117,7 +125,8 @@ public sealed class ModuleManager : IModuleManager
context[CpuRegister.Rax] = unchecked((ulong)ret);
}
return (OrbisGen2Result)ret;
result = (OrbisGen2Result)ret;
return true;
}
private static Delegate CreateHandler(Type ownerType, MethodInfo method, IDictionary<Type, object> instances)
+5
View File
@@ -45,6 +45,11 @@ public enum OrbisGen2Result : int
/// </summary>
ORBIS_GEN2_ERROR_BUSY = unchecked((int)0x80020010),
/// <summary>
/// Indicates that the operation should be retried later.
/// </summary>
ORBIS_GEN2_ERROR_TRY_AGAIN = unchecked((int)0x80020023),
/// <summary>
/// Indicates that behavior is recognized but not implemented yet.
/// </summary>