mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-25 20:28:48 +08:00
[HLE] Resolve Lunar Lander's remaining unresolved imports
With the threading rework letting Lunar Lander Beyond run ~8x further (800K -> 6.7M imports), five previously-unreached imports surfaced. All resolved -> zero unresolved NIDs: - unlink (VAzswvTOCzI): POSIX alias of sceKernelUnlink. - sceAgcDriverGetEqContextId (Zw7uUVPulbw): returns a single stable driver eq-context id (1); events are keyed on (equeue, ident, filter) so one id satisfies the contract. - sceImeKeyboardGetInfo (VkqLPArfFdc): zeroes the info struct (no keyboard connected) and returns OK. - sceSysmoduleGetModuleInfoForUnwind (4fU5yvOkVG4): delegates to the existing sceKernelGetModuleInfoForUnwind (same contract, Gen5 module surface). - _is_signal_return (crb5j7mkk1c): libc unwinder predicate; guest signal returns use no guest-visible trampoline, so always false. Lunar now reaches its next wall (a C++ exception-unwind loop, 0 DCBs) with no unresolved imports; the other games are unaffected (additive exports). 349 Libs tests pass.
This commit is contained in:
@@ -2622,6 +2622,32 @@ public static partial class AgcExports
|
||||
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK);
|
||||
}
|
||||
|
||||
// Hands the game the driver-side context id its GPU event-queue packets
|
||||
// reference. We key events purely on (equeue, ident, filter), so a single
|
||||
// stable id satisfies the contract; the game only checks the call
|
||||
// succeeded and threads the id back through later driver calls.
|
||||
[SysAbiExport(
|
||||
Nid = "Zw7uUVPulbw",
|
||||
ExportName = "sceAgcDriverGetEqContextId",
|
||||
Target = Generation.Gen5,
|
||||
LibraryName = "libSceAgcDriver")]
|
||||
public static int DriverGetEqContextId(CpuContext ctx)
|
||||
{
|
||||
var contextIdAddress = ctx[CpuRegister.Rdi];
|
||||
if (contextIdAddress == 0)
|
||||
{
|
||||
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
if (!TryWriteUInt32(ctx, contextIdAddress, 1))
|
||||
{
|
||||
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
TraceAgc($"agc.driver_get_eq_context_id out=0x{contextIdAddress:X16} -> 1");
|
||||
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK);
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "DL2RXaXOy88",
|
||||
ExportName = "sceAgcDriverDeleteEqEvent",
|
||||
|
||||
@@ -43,4 +43,25 @@ public static class ImeExports
|
||||
ctx[CpuRegister.Rax] = 0;
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
// No hardware keyboard is ever connected; zero the caller's info struct so
|
||||
// it reads as "not connected" rather than uninitialized stack.
|
||||
[SysAbiExport(
|
||||
Nid = "VkqLPArfFdc",
|
||||
ExportName = "sceImeKeyboardGetInfo",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libSceIme")]
|
||||
public static int ImeKeyboardGetInfo(CpuContext ctx)
|
||||
{
|
||||
var infoAddress = ctx[CpuRegister.Rsi] != 0 ? ctx[CpuRegister.Rsi] : ctx[CpuRegister.Rdi];
|
||||
if (infoAddress != 0)
|
||||
{
|
||||
Span<byte> info = stackalloc byte[0x40];
|
||||
info.Clear();
|
||||
_ = ctx.Memory.TryWrite(infoAddress, info);
|
||||
}
|
||||
|
||||
ctx[CpuRegister.Rax] = 0;
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1819,6 +1819,15 @@ public static partial class KernelMemoryCompatExports
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
// POSIX alias; same Orbis result convention as the other posix-named
|
||||
// file exports in this module (mkdir/rmdir/open).
|
||||
[SysAbiExport(
|
||||
Nid = "VAzswvTOCzI",
|
||||
ExportName = "unlink",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libKernel")]
|
||||
public static int PosixUnlink(CpuContext ctx) => KernelUnlink(ctx);
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "AUXVxWeJU-A",
|
||||
ExportName = "sceKernelUnlink",
|
||||
|
||||
@@ -1302,6 +1302,30 @@ public static class KernelRuntimeCompatExports
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
// Same (pc, flags, out-info) contract as sceKernelGetModuleInfoForUnwind,
|
||||
// surfaced through libSceSysmodule on Gen5; the unwinder threads whichever
|
||||
// one the module's libc was linked against.
|
||||
[SysAbiExport(
|
||||
Nid = "4fU5yvOkVG4",
|
||||
ExportName = "sceSysmoduleGetModuleInfoForUnwind",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libSceSysmodule")]
|
||||
public static int SysmoduleGetModuleInfoForUnwind(CpuContext ctx) => KernelGetModuleInfoForUnwind(ctx);
|
||||
|
||||
// libc unwinder predicate: is this PC the kernel signal-return trampoline?
|
||||
// Guest signal returns do not run through a guest-visible trampoline here,
|
||||
// so no PC is ever one — report false and let the frame unwind normally.
|
||||
[SysAbiExport(
|
||||
Nid = "crb5j7mkk1c",
|
||||
ExportName = "_is_signal_return",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libc")]
|
||||
public static int IsSignalReturn(CpuContext ctx)
|
||||
{
|
||||
ctx[CpuRegister.Rax] = 0;
|
||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "nu4a0-arQis",
|
||||
ExportName = "sceKernelAioInitializeParam",
|
||||
|
||||
Reference in New Issue
Block a user