Upstreaming valid changes from others (#4469)

* Fix nids for strcmp vs strncmp

Co-Authored-By: m33ts4k0z <3597723+m33ts4k0z@users.noreply.github.com>

* Fix sign_bit_set logic

Co-Authored-By: m33ts4k0z <3597723+m33ts4k0z@users.noreply.github.com>

* Fix IterateDirectory on mounts

IterateDirectory would just retrieve the base path when trying to iterate /app0, since GetHostPath for the other path types would still return the base path.

Co-Authored-By: m33ts4k0z <3597723+m33ts4k0z@users.noreply.github.com>

* Fix function resolves

If multiple modules export the same library and module, then we would only check the first one we find for the symbol. This can end up breaking the font library stack

Co-Authored-By: m33ts4k0z <3597723+m33ts4k0z@users.noreply.github.com>

* Update fs.cpp

Co-Authored-By: m33ts4k0z <3597723+m33ts4k0z@users.noreply.github.com>

* Oops

---------

Co-authored-by: m33ts4k0z <3597723+m33ts4k0z@users.noreply.github.com>
This commit is contained in:
Stephen Miller 2026-05-24 01:42:31 -05:00 committed by GitHub
parent 19f299714a
commit e5c406d809
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 51 additions and 32 deletions

View File

@ -63,25 +63,36 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea
*is_read_only = mount->read_only;
}
// Nothing to do if getting the mount itself.
const auto corrected_path_sanitized = RemoveTrailingSlashes(corrected_path);
if (corrected_path_sanitized == mount->mount) {
return mount->host_path;
}
std::filesystem::path host_path = mount->host_path;
// Remove device (e.g /app0) from path to retrieve relative path.
const auto rel_path = std::string_view{corrected_path}.substr(mount->mount.size() + 1);
std::filesystem::path host_path = mount->host_path / rel_path;
// Update folder is either mount + "-UPDATE" or mount + "-patch"
std::filesystem::path patch_path = mount->host_path;
patch_path += "-UPDATE";
if (!std::filesystem::exists(patch_path)) {
patch_path = mount->host_path;
patch_path += "-patch";
}
patch_path /= rel_path;
// Mods folder can only be at mount + "-mods"
std::filesystem::path mods_path = mount->host_path;
mods_path += "-mods";
// If we're just retrieving the mount, return the correct mount path.
if (corrected_path_sanitized == mount->mount) {
if (path_type == HostPathType::Mod) {
return mods_path;
} else if (path_type == HostPathType::Patch) {
return patch_path;
} else {
return host_path;
}
}
// Remove device (e.g /app0) from path to retrieve relative path.
const auto rel_path = std::string_view{corrected_path}.substr(mount->mount.size() + 1);
host_path /= rel_path;
patch_path /= rel_path;
mods_path /= rel_path;
if (path_type == HostPathType::Mod) {

View File

@ -63,8 +63,8 @@ const char* PS4_SYSV_ABI internal_strchr(const char* str, int c) {
void RegisterlibSceLibcInternalStr(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("5Xa2ACNECdo", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcpy_s);
LIB_FUNCTION("K+gcnFFJKVc", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcat_s);
LIB_FUNCTION("aesyjrHVWy4", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcmp);
LIB_FUNCTION("Ovb2dSJOAuE", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncmp);
LIB_FUNCTION("Ovb2dSJOAuE", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcmp);
LIB_FUNCTION("aesyjrHVWy4", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncmp);
LIB_FUNCTION("j4ViWNHEgww", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strlen);
LIB_FUNCTION("6sJWiWSRuqk", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncpy);
LIB_FUNCTION("YNzNkJzYqEg", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncpy_s);

View File

@ -326,14 +326,6 @@ void Linker::Relocate(Module* module) {
});
}
const Module* Linker::FindExportedModule(const ModuleInfo& module, const LibraryInfo& library) {
const auto it = std::ranges::find_if(m_modules, [&](const auto& m) {
return std::ranges::contains(m->GetExportLibs(), library) &&
std::ranges::contains(m->GetExportModules(), module);
});
return it == m_modules.end() ? nullptr : it->get();
}
bool Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Module* m,
Loader::SymbolRecord* return_info) {
const auto ids = Common::SplitString(name, '#');
@ -362,10 +354,16 @@ bool Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Modul
return true;
}
// Check if it an export function
const auto* p = FindExportedModule(*module, *library);
if (p && p->export_sym.GetSize() > 0) {
record = p->export_sym.FindSymbol(sr);
// Check if it an exported function from one of our loaded libraries
for (const auto& mod : m_modules) {
if (!std::ranges::contains(mod->GetExportLibs(), *library) ||
!std::ranges::contains(mod->GetExportModules(), *module)) {
continue;
}
if (mod->export_sym.GetSize() == 0) {
continue;
}
record = mod->export_sym.FindSymbol(sr);
if (record) {
*return_info = *record;
return true;

View File

@ -155,8 +155,6 @@ public:
void DebugDump();
private:
const Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l);
MemoryManager* memory;
Libraries::Kernel::Thread main_thread;
std::mutex mutex;

View File

@ -252,8 +252,11 @@ Id EmitBufferAtomicFMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addre
}
const auto u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set =
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u));
// OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
const auto sign_bit_set = ctx.OpINotEqual(
ctx.U1[1],
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)),
ctx.u32_zero_value);
// FIXME this needs control flow because it currently executes both atomics
const auto result = ctx.OpSelect(
@ -287,8 +290,11 @@ Id EmitBufferAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addre
}
const auto u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set =
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u));
// OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
const auto sign_bit_set = ctx.OpINotEqual(
ctx.U1[1],
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)),
ctx.u32_zero_value);
// FIXME this needs control flow because it currently executes both atomics
const auto result = ctx.OpSelect(
@ -364,8 +370,11 @@ Id EmitImageAtomicFMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords
}
const auto u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set =
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u));
// OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
const auto sign_bit_set = ctx.OpINotEqual(
ctx.U1[1],
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)),
ctx.u32_zero_value);
const auto result = ctx.OpSelect(
ctx.F32[1], sign_bit_set,
@ -381,8 +390,11 @@ Id EmitImageAtomicFMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords
}
const auto u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set =
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u));
// OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
const auto sign_bit_set = ctx.OpINotEqual(
ctx.U1[1],
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)),
ctx.u32_zero_value);
const auto result = ctx.OpSelect(
ctx.F32[1], sign_bit_set,