diff --git a/src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.Imports.cs b/src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.Imports.cs index dfc35c9..e682558 100644 --- a/src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.Imports.cs +++ b/src/SharpEmu.Core/Cpu/Native/DirectExecutionBackend.Imports.cs @@ -482,6 +482,8 @@ public sealed partial class DirectExecutionBackend catch (Exception ex) { LastError = $"HLE dispatch error for {importStubEntry.Nid}: {ex.GetType().Name}: {ex.Message}"; + Console.Error.WriteLine($"[LOADER][ERROR] {LastError}"); + Console.Error.WriteLine($"[LOADER][ERROR] {ex.StackTrace}"); cpuContext[CpuRegister.Rax] = 18446744071562199298uL; return 18446744071562199298uL; } @@ -533,12 +535,8 @@ public sealed partial class DirectExecutionBackend $"ret=0x{returnRip:X16}"); } - var previousImportCallFrame = GuestThreadExecution.EnterImportCallFrame( - returnRip, - (ulong)argPackPtr + 104uL, - ActiveGuestReturnSlotAddress); int returnValue; - try + if (IsNoBlockLeafImport(importStubEntry.Nid)) { cpuContext.ClearRaxWriteFlag(); returnValue = export.Function(cpuContext); @@ -547,9 +545,25 @@ public sealed partial class DirectExecutionBackend cpuContext[CpuRegister.Rax] = unchecked((ulong)returnValue); } } - finally + else { - GuestThreadExecution.RestoreImportCallFrame(previousImportCallFrame); + var previousImportCallFrame = GuestThreadExecution.EnterImportCallFrame( + returnRip, + (ulong)argPackPtr + 104uL, + ActiveGuestReturnSlotAddress); + try + { + cpuContext.ClearRaxWriteFlag(); + returnValue = export.Function(cpuContext); + if (!cpuContext.WasRaxWritten) + { + cpuContext[CpuRegister.Rax] = unchecked((ulong)returnValue); + } + } + finally + { + GuestThreadExecution.RestoreImportCallFrame(previousImportCallFrame); + } } if (returnValue != (int)OrbisGen2Result.ORBIS_GEN2_OK) @@ -594,6 +608,28 @@ public sealed partial class DirectExecutionBackend return true; } + private static bool IsNoBlockLeafImport(string nid) => + nid is + "8aI7R7WaOlc" or // sceAmprCommandBufferConstructor + "a8uLzYY--tM" or // sceAmprAprCommandBufferConstructor + "Qs1xtplKo0U" or // sceAmprAprCommandBufferDestructor + "GuchCTefuZw" or // sceAmprCommandBufferDestructor + "N-FSPA4S3nI" or // sceAmprCommandBufferSetBuffer + "baQO9ez2gL4" or // sceAmprCommandBufferReset + "ULvXMDz56po" or // sceAmprCommandBufferClearBuffer + "mQ16-QdKv7k" or // sceAmprAprCommandBufferReadFile + "vWU-odnS+fU" or // sceAmprMeasureCommandSizeReadFile + "sSAUCCU1dv4" or // sceAmprMeasureCommandSizeWriteKernelEventQueue_04_00 + "C+IEj+BsAFM" or // sceAmprMeasureCommandSizeWriteAddressOnCompletion + "tZDDEo2tE5k" or // sceAmprCommandBufferGetSize + "GnxKOHEawhk" or // sceAmprCommandBufferGetCurrentOffset + "H896Pt-yB4I" or // sceAmprCommandBufferWriteKernelEventQueue_04_00 + "sJXyWHjP-F8" or // sceAmprCommandBufferWriteAddressOnCompletion + "ASoW5WE-UPo" or // sceKernelAprSubmitCommandBufferAndGetResult + "rqwFKI4PAiM" or // sceKernelAprWaitCommandBuffer + "eE4Szl8sil8" or // sceKernelAprSubmitCommandBuffer + "qvMUCyyaCSI"; // sceKernelAprSubmitCommandBufferAndGetId + private bool ShouldLogImportResult(string nid, OrbisGen2Result result) { var expectedFileProbeMiss = @@ -602,7 +638,10 @@ public sealed partial class DirectExecutionBackend var expectedTimedWaitTimeout = string.Equals(nid, "27bAgiJmOh0", StringComparison.Ordinal) && unchecked((int)result) == 60; - if (!expectedFileProbeMiss && !expectedTimedWaitTimeout) + var expectedMutexTrylockBusy = + string.Equals(nid, "K-jXhbt2gn4", StringComparison.Ordinal) && + result == OrbisGen2Result.ORBIS_GEN2_ERROR_BUSY; + if (!expectedFileProbeMiss && !expectedTimedWaitTimeout && !expectedMutexTrylockBusy) { return true; } @@ -684,7 +723,11 @@ public sealed partial class DirectExecutionBackend "Vo5V8KAwCmk" or // sceSystemServiceHideSplashScreen "TywrFKCoLGY" or // sceSaveDataInitialize3 "dyIhnXq-0SM" or // sceSaveDataDirNameSearch + "ERKzksauAJA" or // sceSaveDataDialogGetStatus + "KK3Bdg1RWK0" or // sceSaveDataDialogUpdateStatus + "en7gNVnh878" or // sceSaveDataDialogIsReadyToDisplay "jO8DM8oyego" or // sceNpEntitlementAccessInitialize + "TFyU+KFBv54" or // sceNpEntitlementAccessGetAddcontEntitlementInfoList "27bAgiJmOh0" or // pthread_cond_timedwait "iQw3iQPhvUQ" or // sceNetCtlCheckCallback "Q2V+iqvjgC0" or // vsnprintf