mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-18 02:51:59 +00:00
core: page-aware TryReadUtf8Z and unify exit/_exit handling (#57)
Read guest C strings in page-bounded chunks without heap allocations. Return false when the buffer fills without a null terminator. Route exit and _exit through RequestProcessExit.
This commit is contained in:
@@ -52,14 +52,7 @@ public static class KernelExports
|
|||||||
ExportName = "exit",
|
ExportName = "exit",
|
||||||
Target = Generation.Gen4 | Generation.Gen5,
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
LibraryName = "libKernel")]
|
LibraryName = "libKernel")]
|
||||||
public static int Exit(CpuContext ctx)
|
public static int Exit(CpuContext ctx) => RequestProcessExit(ctx, "exit");
|
||||||
{
|
|
||||||
var status = unchecked((int)ctx[CpuRegister.Rdi]);
|
|
||||||
Console.Error.WriteLine($"[LOADER][INFO] exit(status={status})");
|
|
||||||
GuestThreadExecution.RequestCurrentEntryExit("exit", status);
|
|
||||||
ctx[CpuRegister.Rax] = unchecked((ulong)status);
|
|
||||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SysAbiExport(
|
[SysAbiExport(
|
||||||
Nid = "XKRegsFpEpk",
|
Nid = "XKRegsFpEpk",
|
||||||
@@ -172,11 +165,7 @@ public static class KernelExports
|
|||||||
ExportName = "_exit",
|
ExportName = "_exit",
|
||||||
Target = Generation.Gen4 | Generation.Gen5,
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
LibraryName = "libKernel")]
|
LibraryName = "libKernel")]
|
||||||
public static int UnderscoreExit(CpuContext ctx)
|
public static int UnderscoreExit(CpuContext ctx) => RequestProcessExit(ctx, "_exit");
|
||||||
{
|
|
||||||
_ = ctx;
|
|
||||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SysAbiExport(
|
[SysAbiExport(
|
||||||
Nid = "Ac86z8q7T8A",
|
Nid = "Ac86z8q7T8A",
|
||||||
@@ -437,4 +426,13 @@ public static class KernelExports
|
|||||||
{
|
{
|
||||||
return string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_PTHREADS"), "1", StringComparison.Ordinal);
|
return string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_PTHREADS"), "1", StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int RequestProcessExit(CpuContext ctx, string syscallName)
|
||||||
|
{
|
||||||
|
var status = unchecked((int)ctx[CpuRegister.Rdi]);
|
||||||
|
Console.Error.WriteLine($"[LOADER][INFO] {syscallName}(status={status})");
|
||||||
|
GuestThreadExecution.RequestCurrentEntryExit(syscallName, status);
|
||||||
|
ctx[CpuRegister.Rax] = unchecked((ulong)status);
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1469,26 +1469,42 @@ public static class KernelRuntimeCompatExports
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bytes = new List<byte>(Math.Min(maxLength, 64));
|
const int pageSize = 4096;
|
||||||
Span<byte> one = stackalloc byte[1];
|
const int inlineChunkSize = 64;
|
||||||
for (var i = 0; i < maxLength; i++)
|
Span<byte> buffer = stackalloc byte[Math.Min(maxLength, 512)];
|
||||||
|
var length = 0;
|
||||||
|
|
||||||
|
for (var offset = 0; offset < maxLength && length < buffer.Length;)
|
||||||
{
|
{
|
||||||
if (!ctx.Memory.TryRead(address + (ulong)i, one))
|
var current = address + (ulong)offset;
|
||||||
|
var pageRemaining = pageSize - (int)(current & (pageSize - 1));
|
||||||
|
var chunkSize = Math.Min(
|
||||||
|
buffer.Length - length,
|
||||||
|
Math.Min(maxLength - offset, Math.Min(inlineChunkSize, pageRemaining)));
|
||||||
|
|
||||||
|
if (chunkSize <= 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (one[0] == 0)
|
var chunk = buffer.Slice(length, chunkSize);
|
||||||
|
if (!ctx.Memory.TryRead(current, chunk))
|
||||||
{
|
{
|
||||||
value = Encoding.UTF8.GetString(bytes.ToArray());
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nulIndex = chunk.IndexOf((byte)0);
|
||||||
|
if (nulIndex >= 0)
|
||||||
|
{
|
||||||
|
value = Encoding.UTF8.GetString(buffer[..(length + nulIndex)]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes.Add(one[0]);
|
length += chunkSize;
|
||||||
|
offset += chunkSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = Encoding.UTF8.GetString(bytes.ToArray());
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ulong GetTlsScratchAddress(CpuContext ctx, ulong offset)
|
private static ulong GetTlsScratchAddress(CpuContext ctx, ulong offset)
|
||||||
|
|||||||
Reference in New Issue
Block a user