[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:
Gutemberg Ribeiro
2026-07-19 04:11:05 +01:00
parent 3d4a8803f5
commit 22a7ca97ed
4 changed files with 80 additions and 0 deletions
+26
View File
@@ -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",
+21
View File
@@ -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",