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; *is_read_only = mount->read_only;
} }
// Nothing to do if getting the mount itself.
const auto corrected_path_sanitized = RemoveTrailingSlashes(corrected_path); const auto corrected_path_sanitized = RemoveTrailingSlashes(corrected_path);
if (corrected_path_sanitized == mount->mount) { std::filesystem::path host_path = mount->host_path;
return mount->host_path;
}
// Remove device (e.g /app0) from path to retrieve relative path. // Update folder is either mount + "-UPDATE" or mount + "-patch"
const auto rel_path = std::string_view{corrected_path}.substr(mount->mount.size() + 1);
std::filesystem::path host_path = mount->host_path / rel_path;
std::filesystem::path patch_path = mount->host_path; std::filesystem::path patch_path = mount->host_path;
patch_path += "-UPDATE"; patch_path += "-UPDATE";
if (!std::filesystem::exists(patch_path)) { if (!std::filesystem::exists(patch_path)) {
patch_path = mount->host_path; patch_path = mount->host_path;
patch_path += "-patch"; patch_path += "-patch";
} }
patch_path /= rel_path;
// Mods folder can only be at mount + "-mods"
std::filesystem::path mods_path = mount->host_path; std::filesystem::path mods_path = mount->host_path;
mods_path += "-mods"; 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; mods_path /= rel_path;
if (path_type == HostPathType::Mod) { 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) { void RegisterlibSceLibcInternalStr(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("5Xa2ACNECdo", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcpy_s); LIB_FUNCTION("5Xa2ACNECdo", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcpy_s);
LIB_FUNCTION("K+gcnFFJKVc", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strcat_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_strcmp);
LIB_FUNCTION("Ovb2dSJOAuE", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncmp); LIB_FUNCTION("aesyjrHVWy4", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncmp);
LIB_FUNCTION("j4ViWNHEgww", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strlen); LIB_FUNCTION("j4ViWNHEgww", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strlen);
LIB_FUNCTION("6sJWiWSRuqk", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncpy); LIB_FUNCTION("6sJWiWSRuqk", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncpy);
LIB_FUNCTION("YNzNkJzYqEg", "libSceLibcInternal", 1, "libSceLibcInternal", internal_strncpy_s); 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, bool Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Module* m,
Loader::SymbolRecord* return_info) { Loader::SymbolRecord* return_info) {
const auto ids = Common::SplitString(name, '#'); const auto ids = Common::SplitString(name, '#');
@ -362,10 +354,16 @@ bool Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Modul
return true; return true;
} }
// Check if it an export function // Check if it an exported function from one of our loaded libraries
const auto* p = FindExportedModule(*module, *library); for (const auto& mod : m_modules) {
if (p && p->export_sym.GetSize() > 0) { if (!std::ranges::contains(mod->GetExportLibs(), *library) ||
record = p->export_sym.FindSymbol(sr); !std::ranges::contains(mod->GetExportModules(), *module)) {
continue;
}
if (mod->export_sym.GetSize() == 0) {
continue;
}
record = mod->export_sym.FindSymbol(sr);
if (record) { if (record) {
*return_info = *record; *return_info = *record;
return true; return true;

View File

@ -155,8 +155,6 @@ public:
void DebugDump(); void DebugDump();
private: private:
const Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l);
MemoryManager* memory; MemoryManager* memory;
Libraries::Kernel::Thread main_thread; Libraries::Kernel::Thread main_thread;
std::mutex mutex; 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 u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set = // OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)); 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 // FIXME this needs control flow because it currently executes both atomics
const auto result = ctx.OpSelect( 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 u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set = // OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)); 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 // FIXME this needs control flow because it currently executes both atomics
const auto result = ctx.OpSelect( 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 u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set = // OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)); 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( const auto result = ctx.OpSelect(
ctx.F32[1], sign_bit_set, 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 u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto sign_bit_set = // OpSelect requires a bool condition; produce one by comparing the sign bit to 0.
ctx.OpBitFieldUExtract(ctx.U32[1], u32_value, ctx.ConstU32(31u), ctx.ConstU32(1u)); 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( const auto result = ctx.OpSelect(
ctx.F32[1], sign_bit_set, ctx.F32[1], sign_bit_set,