diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index e694e636a..e9157d48a 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -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) { diff --git a/src/core/libraries/libc_internal/libc_internal_str.cpp b/src/core/libraries/libc_internal/libc_internal_str.cpp index a7997a193..e5c2e64bc 100644 --- a/src/core/libraries/libc_internal/libc_internal_str.cpp +++ b/src/core/libraries/libc_internal/libc_internal_str.cpp @@ -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); diff --git a/src/core/linker.cpp b/src/core/linker.cpp index edf5b6f36..720aa9650 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -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; diff --git a/src/core/linker.h b/src/core/linker.h index 895901f08..f210c2e57 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -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; diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp index 806169217..4273b8f0a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp @@ -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,