feat: auto set runtime internal stubs and syscalls on recompiled code

This commit is contained in:
Ran-j
2026-01-27 17:12:35 -03:00
parent 7b3fee9247
commit b1f86a7597
6 changed files with 254 additions and 146 deletions
+10 -5
View File
@@ -37,13 +37,14 @@ file(GLOB_RECURSE PS2RECOMP_HEADERS
"include/*.h"
"include/*.hpp"
)
add_executable(ps2recomp ${PS2RECOMP_SOURCES})
add_library(ps2_recomp STATIC ${PS2RECOMP_SOURCES})
target_include_directories(ps2recomp PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/../ps2xRuntime/include
${elfio_SOURCE_DIR}
)
@@ -51,7 +52,11 @@ target_include_directories(ps2_recomp PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${elfio_SOURCE_DIR}
)
target_include_directories(ps2_recomp PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../ps2xRuntime/include
)
target_link_libraries(ps2recomp PRIVATE
fmt::fmt
toml11::toml11
@@ -61,7 +66,7 @@ target_link_libraries(ps2_recomp PUBLIC
fmt::fmt
toml11::toml11
)
install(TARGETS ps2recomp ps2_recomp
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
+46 -2
View File
@@ -1,5 +1,6 @@
#include "ps2recomp/ps2_recompiler.h"
#include "ps2recomp/instructions.h"
#include "ps2_runtime_calls.h"
#include <iostream>
#include <fstream>
#include <sstream>
@@ -15,6 +16,28 @@ namespace fs = std::filesystem;
namespace ps2recomp
{
namespace
{
enum class StubTarget
{
Unknown,
Syscall,
Stub
};
StubTarget resolveStubTarget(const std::string &name)
{
if (ps2_runtime_calls::isSyscallName(name))
{
return StubTarget::Syscall;
}
if (ps2_runtime_calls::isStubName(name))
{
return StubTarget::Stub;
}
return StubTarget::Unknown;
}
}
PS2Recompiler::PS2Recompiler(const std::string &configPath)
: m_configManager(configPath)
@@ -234,7 +257,22 @@ namespace ps2recomp
std::string generatedName = m_codeGenerator->getGeneratedFunctionName(function);
std::stringstream stub;
stub << "void " << generatedName
<< "(uint8_t* rdram, R5900Context* ctx, PS2Runtime *runtime) { ps2_syscalls::TODO(rdram, ctx, runtime); }";
<< "(uint8_t* rdram, R5900Context* ctx, PS2Runtime *runtime) { ";
switch (resolveStubTarget(function.name))
{
case StubTarget::Syscall:
stub << "ps2_syscalls::" << function.name << "(rdram, ctx, runtime); ";
break;
case StubTarget::Stub:
stub << "ps2_stubs::" << function.name << "(rdram, ctx, runtime); ";
break;
default:
stub << "ps2_syscalls::TODO(rdram, ctx, runtime); ";
break;
}
stub << "}";
m_generatedStubs[function.start] = stub.str();
}
}
@@ -250,6 +288,7 @@ namespace ps2recomp
combinedOutput << "#include \"ps2_runtime.h\"\n";
combinedOutput << "#include \"ps2_recompiled_stubs.h\"\n";
combinedOutput << "#include \"ps2_syscalls.h\"\n";
combinedOutput << "#include \"ps2_stubs.h\"\n";
if (m_bootstrapInfo.valid)
{
combinedOutput << "\n"
@@ -315,7 +354,12 @@ namespace ps2recomp
{
if (function.isStub)
{
code = m_generatedStubs[function.start];
std::stringstream stubFile;
stubFile << "#include \"ps2_runtime.h\"\n";
stubFile << "#include \"ps2_syscalls.h\"\n";
stubFile << "#include \"ps2_stubs.h\"\n\n";
stubFile << m_generatedStubs[function.start] << "\n";
code = stubFile.str();
}
else
{
+147
View File
@@ -0,0 +1,147 @@
#pragma once
// I know ugly, but will work for now.
#define PS2_SYSCALL_LIST(X) \
X(FlushCache) \
X(ResetEE) \
X(SetMemoryMode) \
\
X(CreateThread) \
X(DeleteThread) \
X(StartThread) \
X(ExitThread) \
X(ExitDeleteThread) \
X(TerminateThread) \
X(SuspendThread) \
X(ResumeThread) \
X(GetThreadId) \
X(ReferThreadStatus) \
X(SleepThread) \
X(WakeupThread) \
X(iWakeupThread) \
X(ChangeThreadPriority) \
X(RotateThreadReadyQueue) \
X(ReleaseWaitThread) \
X(iReleaseWaitThread) \
\
X(CreateSema) \
X(DeleteSema) \
X(SignalSema) \
X(iSignalSema) \
X(WaitSema) \
X(PollSema) \
X(iPollSema) \
X(ReferSemaStatus) \
X(iReferSemaStatus) \
\
X(CreateEventFlag) \
X(DeleteEventFlag) \
X(SetEventFlag) \
X(iSetEventFlag) \
X(ClearEventFlag) \
X(iClearEventFlag) \
X(WaitEventFlag) \
X(PollEventFlag) \
X(iPollEventFlag) \
X(ReferEventFlagStatus) \
X(iReferEventFlagStatus) \
\
X(SetAlarm) \
X(iSetAlarm) \
X(CancelAlarm) \
X(iCancelAlarm) \
\
X(EnableIntc) \
X(DisableIntc) \
X(EnableDmac) \
X(DisableDmac) \
\
X(SifStopModule) \
X(SifLoadModule) \
X(SifInitRpc) \
X(SifBindRpc) \
X(SifCallRpc) \
X(SifRegisterRpc) \
X(SifCheckStatRpc) \
X(SifSetRpcQueue) \
X(SifRemoveRpcQueue) \
X(SifRemoveRpc) \
X(sceSifCallRpc) \
X(sceSifSendCmd) \
X(_sceRpcGetPacket) \
\
X(fioOpen) \
X(fioClose) \
X(fioRead) \
X(fioWrite) \
X(fioLseek) \
X(fioMkdir) \
X(fioChdir) \
X(fioRmdir) \
X(fioGetstat) \
X(fioRemove) \
\
X(GsSetCrt) \
X(GsGetIMR) \
X(GsPutIMR) \
X(GsSetVideoMode) \
\
X(GetOsdConfigParam) \
X(SetOsdConfigParam) \
X(GetRomName) \
X(SifLoadElfPart) \
X(sceSifLoadModule) \
\
X(SetupThread) \
X(QueryBootMode) \
X(GetThreadTLS) \
X(RegisterExitHandler)
// Stubs
#define PS2_STUB_LIST(X) \
X(malloc) \
X(free) \
X(calloc) \
X(realloc) \
X(memcpy) \
X(memset) \
X(memmove) \
X(memcmp) \
\
X(strcpy) \
X(strncpy) \
X(strlen) \
X(strcmp) \
X(strncmp) \
X(strcat) \
X(strncat) \
X(strchr) \
X(strrchr) \
X(strstr) \
\
X(printf) \
X(sprintf) \
X(snprintf) \
X(puts) \
X(fopen) \
X(fclose) \
X(fread) \
X(fwrite) \
X(fprintf) \
X(fseek) \
X(ftell) \
X(fflush) \
\
X(sqrt) \
X(sin) \
X(cos) \
X(tan) \
X(atan2) \
X(pow) \
X(exp) \
X(log) \
X(log10) \
X(ceil) \
X(floor) \
X(fabs)
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <string_view>
#include "ps2_call_list.h"
namespace ps2_runtime_calls
{
inline constexpr std::string_view kSyscallNames[] = {
#define PS2_SYSCALL_NAME(name) std::string_view{#name},
PS2_SYSCALL_LIST(PS2_SYSCALL_NAME)
#undef PS2_SYSCALL_NAME
};
inline constexpr std::string_view kStubNames[] = {
#define PS2_STUB_NAME(name) std::string_view{#name},
PS2_STUB_LIST(PS2_STUB_NAME)
#undef PS2_STUB_NAME
};
inline bool isSyscallName(std::string_view name)
{
for (auto entry : kSyscallNames)
{
if (entry == name)
{
return true;
}
}
return false;
}
inline bool isStubName(std::string_view name)
{
for (auto entry : kStubNames)
{
if (entry == name)
{
return true;
}
}
return false;
}
}
+4 -50
View File
@@ -2,60 +2,14 @@
#define PS2_STUBS_H
#include "ps2_runtime.h"
#include "ps2_call_list.h"
#include <cstdint>
namespace ps2_stubs
{
// Memory operations
void malloc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void free(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void calloc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void realloc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void memcpy(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void memset(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void memmove(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void memcmp(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
// String operations
void strcpy(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strncpy(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strlen(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strcmp(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strncmp(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strcat(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strncat(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strchr(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strrchr(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void strstr(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
// I/O operations
void printf(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void sprintf(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void snprintf(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void puts(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fopen(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fclose(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fwrite(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fprintf(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fseek(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ftell(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fflush(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
// Math functions
void sqrt(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void sin(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void cos(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void tan(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void atan2(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void pow(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void exp(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void log(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void log10(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ceil(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void floor(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fabs(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
#define PS2_DECLARE_STUB(name) void name(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
PS2_STUB_LIST(PS2_DECLARE_STUB)
#undef PS2_DECLARE_STUB
void TODO(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
}
+4 -89
View File
@@ -2,6 +2,7 @@
#define PS2_SYSCALLS_H
#include "ps2_runtime.h"
#include "ps2_call_list.h"
#include <mutex>
#include <atomic>
@@ -26,95 +27,9 @@ static std::mutex g_sys_fd_mutex;
namespace ps2_syscalls
{
void FlushCache(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ResetEE(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SetMemoryMode(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void CreateThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void DeleteThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void StartThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ExitThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ExitDeleteThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void TerminateThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SuspendThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ResumeThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void GetThreadId(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ReferThreadStatus(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SleepThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void WakeupThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iWakeupThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ChangeThreadPriority(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void RotateThreadReadyQueue(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ReleaseWaitThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iReleaseWaitThread(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void CreateSema(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void DeleteSema(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SignalSema(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iSignalSema(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void WaitSema(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void PollSema(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iPollSema(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ReferSemaStatus(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iReferSemaStatus(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void CreateEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void DeleteEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SetEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iSetEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ClearEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iClearEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void WaitEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void PollEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iPollEventFlag(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void ReferEventFlagStatus(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iReferEventFlagStatus(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SetAlarm(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iSetAlarm(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void CancelAlarm(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void iCancelAlarm(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void EnableIntc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void DisableIntc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void EnableDmac(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void DisableDmac(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifStopModule(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifLoadModule(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifInitRpc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifBindRpc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifCallRpc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifRegisterRpc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifCheckStatRpc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifSetRpcQueue(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifRemoveRpcQueue(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifRemoveRpc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void sceSifCallRpc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void sceSifSendCmd(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void _sceRpcGetPacket(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioOpen(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioClose(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioRead(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioWrite(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioLseek(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioMkdir(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioChdir(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioRmdir(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioGetstat(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void fioRemove(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void GsSetCrt(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void GsGetIMR(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void GsPutIMR(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void GsSetVideoMode(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void GetOsdConfigParam(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SetOsdConfigParam(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void GetRomName(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void SifLoadElfPart(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
void sceSifLoadModule(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
#define PS2_DECLARE_SYSCALL(name) void name(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
PS2_SYSCALL_LIST(PS2_DECLARE_SYSCALL)
#undef PS2_DECLARE_SYSCALL
void TODO(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime);
}