Merge pull request #21558 from hrydgard/kernel-snprintf

Rough implementation of sysclib_snprintf (kernel function)
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-04-14 13:45:01 -06:00
commit fcca1445c3
3 files changed
+32 -16

No files matched your search

+7 -5
View File
@@ -70,6 +70,8 @@ static PluginInfo ReadPluginIni(const std::string &subdir, IniFile &ini) {
info.memory = 0;
options->Get("version", &info.version);
options->Get("memory", &info.memory);
// TODO: Why this specific limit?
if (info.memory > 93) {
ERROR_LOG(Log::System, "Plugin memory too high, using 93 MB");
info.memory = 93;
@@ -184,23 +186,23 @@ bool Load(PSPModule *pluginWaitingModule, SceUID threadID) {
for (const std::string &filename : prxPlugins) {
if (!g_Config.bEnablePlugins) {
WARN_LOG(Log::System, "Plugins are disabled, ignoring enabled plugin %s", filename.c_str());
WARN_LOG(Log::System, "Plugins are disabled, ignoring enabled plugin '%s'", filename.c_str());
continue;
}
std::string error_string = "";
SceUID module = KernelLoadModule(filename, &error_string);
if (!error_string.empty() || module < 0) {
ERROR_LOG(Log::System, "Unable to load plugin %s (module %d): '%s'", filename.c_str(), module, error_string.c_str());
ERROR_LOG(Log::System, "Unable to load plugin '%s' (module %d): '%s'", filename.c_str(), module, error_string.c_str());
continue;
}
int ret = __KernelStartModule(module, 0, 0, 0, nullptr, nullptr);
if (ret < 0) {
ERROR_LOG(Log::System, "Unable to start plugin %s: %08x", filename.c_str(), ret);
ERROR_LOG(Log::System, "Unable to start plugin '%s': %08x", filename.c_str(), ret);
} else {
std::string shortName = Path(filename).GetFilename();
g_OSD.Show(OSDType::MESSAGE_SUCCESS, ApplySafeSubstitutions(sy->T("Loaded plugin: %1"), shortName), 6.0f);
g_OSD.Show(OSDType::MESSAGE_SUCCESS, ApplySafeSubstitutions(sy->T("Loaded plugin: '%1'"), shortName), 6.0f);
started = true;
pluginWaitingModule->startingPlugins.push_back(module);
u32 error;
@@ -208,7 +210,7 @@ bool Load(PSPModule *pluginWaitingModule, SceUID threadID) {
plugin_module->pluginWaitingThread = threadID;
}
INFO_LOG(Log::System, "Loaded plugin: %s", filename.c_str());
INFO_LOG(Log::System, "Loaded plugin: '%s'", filename.c_str());
}
std::lock_guard<std::mutex> guard(g_inputMutex);
+24 -10
View File
@@ -721,13 +721,8 @@ static int sysclib_memcmp(u32 dst, u32 src, u32 size) {
}
}
static int sysclib_snprintf(u32 dst, int size, u32 fmt) {
return hleLogError(Log::sceKernel, 0, "UNIMPL");
}
static int sysclib_sprintf(u32 dst, u32 fmt) {
DEBUG_LOG(Log::sceKernel, "Not fully implemented: sysclib_sprintf(dst=%08x, fmt=%08x)", dst, fmt);
// NOTE: This doesn't yet obey the limit parameter, needed for correct snprintf behavior.
static int sysclib_sprintf_impl(u32 dst, int limit, u32 fmt, int paramOffset) {
if (!Memory::IsValidNullTerminatedString(fmt)) {
ERROR_LOG(Log::sceKernel, "sysclib_sprintf bad fmt");
return 0;
@@ -748,7 +743,7 @@ static int sysclib_sprintf(u32 dst, u32 fmt) {
bool processing_specifier = false;
std::string specifier = "";
int bytes_to_read = 0;
int arg_idx = 0;
int arg_idx = paramOffset;
std::string result = "";
for (const char *c = Memory::GetCharPointerUnchecked(fmt); *c != '\0'; c++) {
if (!processing_specifier) {
@@ -866,14 +861,33 @@ static int sysclib_sprintf(u32 dst, u32 fmt) {
}
}
VERBOSE_LOG(Log::sceKernel, "sysclib_sprintf result string has length %d, content:", (int)result.length());
const size_t retval = result.size();
// Implement the snprintf length check.
if (limit != 0 && result.length() >= limit) {
result.resize(limit - 1);
}
VERBOSE_LOG(Log::sceKernel, "sysclib_sprintf result string has length %d (retval: %d), content:", (int)result.length(), (int)retval);
VERBOSE_LOG(Log::sceKernel, "%s", result.c_str());
// Since this is a sprintf function and not an actual printf, we don't log to the Sprintf log.
// INFO_LOG(Log::Printf, "%s", result.c_str());
if (!Memory::IsValidRange(dst, (u32)result.length() + 1)) {
ERROR_LOG(Log::sceKernel, "sysclib_sprintf result string is too long or dst is invalid");
return 0;
}
memcpy((char *)Memory::GetPointerUnchecked(dst), result.c_str(), (int)result.length() + 1);
return (int)result.length();
return (int)retval;
}
static int sysclib_sprintf(u32 dst, u32 fmt) {
DEBUG_LOG(Log::sceKernel, "Not fully implemented: sysclib_sprintf(dst=%08x, fmt=%08x)", dst, fmt);
return hleLogDebug(Log::sceKernel, sysclib_sprintf_impl(dst, 0, fmt, 0));
}
static int sysclib_snprintf(u32 dst, int size, u32 fmt) {
DEBUG_LOG(Log::sceKernel, "Not fully implemented: sysclib_snprintf(dst=%08x, fmt=%08x)", dst, fmt);
return hleLogDebug(Log::sceKernel, sysclib_sprintf_impl(dst, size, fmt, 1));
}
static u32 sysclib_memset(u32 destAddr, int data, int size) {
+1 -1
View File
@@ -2639,7 +2639,6 @@ const HLEFunction ModuleMgrForUser[] = {
{0XFBE27467, nullptr, "ModuleMgrForUser_FBE27467", '?', "" },
};
const HLEFunction ModuleMgrForKernel[] = {
{0x50F0C1EC, &WrapU_UUUUU<sceKernelStartModule>, "sceKernelStartModule", 'v', "xxxxx", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED | HLE_KERNEL_SYSCALL },
{0x977DE386, &WrapU_CUU<sceKernelLoadModule>, "sceKernelLoadModule", 'x', "sxx", HLE_KERNEL_SYSCALL },
@@ -2649,6 +2648,7 @@ const HLEFunction ModuleMgrForKernel[] = {
{0x748CBED9, &WrapU_UU<sceKernelQueryModuleInfo>, "sceKernelQueryModuleInfo", 'x', "xx", HLE_KERNEL_SYSCALL },
{0x644395E2, &WrapU_UUU<sceKernelGetModuleIdList>, "sceKernelGetModuleIdList", 'x', "xxx", HLE_KERNEL_SYSCALL },
{0X2E0911AA, &WrapU_U<sceKernelUnloadModule>, "sceKernelUnloadModule", 'x', "x" , HLE_KERNEL_SYSCALL },
{0xD675EBB8, &WrapU_UUU<sceKernelSelfStopUnloadModule>, "sceKernelSelfStopUnloadModule", 'x', "xxx", HLE_KERNEL_SYSCALL },
};
void Register_ModuleMgrForUser() {