diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index daa18c55bd..d97edf1da9 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -765,8 +765,12 @@ static void ppu_check_patch_spu_images(const ppu_segment& seg) if (g_cfg.core.spu_debug) { - fs::file dump_file(fs::get_cache_dir() + "/spu_progs/" + vfs::escape(name.substr(name.find_last_of('/') + 1)) + '_' + hash.substr(4) + ".elf", fs::rewrite); - obj.save(dump_file); + fs::pending_file temp(fs::get_cache_dir() + "/spu_progs/" + vfs::escape(name.substr(name.find_last_of('/') + 1)) + '_' + hash.substr(4) + ".elf"); + + if (!temp.file || !(temp.file.write(obj.save()), temp.commit())) + { + ppu_loader.error("Failed to dump SPU program from PPU executable: name='%s', hash=%s", name, hash); + } } // Try to patch each segment, will only succeed if the address exists in SPU local storage diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 87abffaeba..182d2e135f 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -4661,21 +4661,34 @@ bool spu_thread::capture_local_storage() const }; auto elf_path = get_filename(); - fs::file dump_file(elf_path, fs::create + fs::excl + fs::write); - if (!dump_file) + if (fs::exists(elf_path)) { // Wait 1 second so current_time_narrow() will return a different string std::this_thread::sleep_for(1s); - if (elf_path = get_filename(); !dump_file.open(elf_path, fs::create + fs::excl + fs::write)) + if (elf_path = get_filename(); fs::exists(elf_path)) { spu_log.error("Failed to create '%s' (error=%s)", elf_path, fs::g_tls_error); return false; } } - spu_exec.save(dump_file); + fs::pending_file temp(elf_path); + + if (!temp.file) + { + spu_log.error("Failed to create temporary file for '%s' (error=%s)", elf_path, fs::g_tls_error); + return false; + } + + temp.file.write(spu_exec.save()); + + if (!temp.commit(false)) + { + spu_log.error("Failed to create rename temporary file to '%s' (error=%s)", elf_path, fs::g_tls_error); + return false; + } spu_log.success("SPU Local Storage image saved to '%s'", elf_path); return true; diff --git a/rpcs3/Loader/ELF.h b/rpcs3/Loader/ELF.h index 76f86f714e..8757ce1b75 100644 --- a/rpcs3/Loader/ELF.h +++ b/rpcs3/Loader/ELF.h @@ -278,8 +278,10 @@ public: return m_error = elf_error::ok; } - void save(const fs::file& stream) const + std::vector save(std::vector&& init = std::vector{}) const { + fs::file stream = fs::make_stream>(std::move(init)); + // Write header ehdr_t header{}; header.e_magic = "\177ELF"_u32; @@ -322,6 +324,8 @@ public: { stream.write(prog.bin); } + + return std::move(static_cast>*>(stream.release().get())->obj); } elf_object& clear()