diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 487c0df441..43eba93eaa 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -4,6 +4,7 @@ #include "StrUtil.h" #include "Crypto/sha1.h" +#include #include #include #include @@ -293,7 +294,7 @@ namespace fs struct id_view { std::string_view type_view; - std::basic_string_view data_view; + std::span data_view; }; id_view _rhs{rhs.type, {rhs.data.data(), rhs.data.size()}}; @@ -311,7 +312,7 @@ namespace fs } // Remove offsets data - id.data_view.remove_suffix(sizeof(u64) * offset_count); + id.data_view = id.data_view.subspan(sizeof(u64) * offset_count); // Get last category identifier if (usz sep = id.type_view.rfind(": "); sep != umax) @@ -329,7 +330,7 @@ namespace fs return false; } - return _rhs.type_view == _lhs.type_view && _rhs.data_view == _lhs.data_view; + return _rhs.type_view == _lhs.type_view && std::equal(_rhs.data_view.begin(), _rhs.data_view.end(), _lhs.data_view.begin(), _lhs.data_view.end()); } dir_base::~dir_base() diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index a52eff0db7..49b19f5bda 100644 --- a/Utilities/bin_patch.cpp +++ b/Utilities/bin_patch.cpp @@ -9,11 +9,11 @@ #include "Emu/VFS.h" #include "util/types.hpp" -#include "util/endian.hpp" #include "util/asm.hpp" #include #include +#include LOG_CHANNEL(patch_log, "PAT"); @@ -907,7 +907,7 @@ void unmap_vm_area(std::shared_ptr& ptr) } // Returns old 'applied' size -static usz apply_modification(std::basic_string& applied, patch_engine::patch_info& patch, std::function mem_translate, u32 filesz, u32 min_addr) +static usz apply_modification(std::vector& applied, patch_engine::patch_info& patch, std::function mem_translate, u32 filesz, u32 min_addr) { const usz old_applied_size = applied.size(); @@ -1447,14 +1447,13 @@ static usz apply_modification(std::basic_string& applied, patch_engine::pat return old_applied_size; } -std::basic_string patch_engine::apply(const std::string& name, std::function mem_translate, u32 filesz, u32 min_addr) +void patch_engine::apply(std::vector& applied_total, const std::string& name, std::function mem_translate, u32 filesz, u32 min_addr) { if (!m_map.contains(name)) { - return {}; + return; } - std::basic_string applied_total; const patch_container& container = ::at32(m_map, name); const std::string& serial = Emu.GetTitleID(); const std::string& app_version = Emu.GetAppVersion(); @@ -1598,8 +1597,6 @@ std::basic_string patch_engine::apply(const std::string& name, std::functio } } } - - return applied_total; } void patch_engine::unload(const std::string& name) diff --git a/Utilities/bin_patch.h b/Utilities/bin_patch.h index d857ab1a0b..1e06c54570 100644 --- a/Utilities/bin_patch.h +++ b/Utilities/bin_patch.h @@ -215,7 +215,7 @@ public: void append_title_patches(std::string_view title_id); // Apply patch (returns the number of entries applied) - std::basic_string apply(const std::string& name, std::function mem_translate, u32 filesz = -1, u32 min_addr = 0); + void apply(std::vector& applied_total, const std::string& name, std::function mem_translate, u32 filesz = -1, u32 min_addr = 0); // Deallocate memory used by patches void unload(const std::string& name); diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index 845ce21cfb..0192265298 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -5,11 +5,11 @@ #include "lz.h" #include "ec.h" -#include "Utilities/mutex.h" #include "Emu/system_utils.hpp" -#include #include "util/asm.hpp" +#include +#include LOG_CHANNEL(edat_log, "EDAT"); @@ -614,9 +614,11 @@ bool validate_npd_hashes(std::string_view file_name, const u8* klicensee, NPD_HE std::memcpy(buf_lower.get(), buf.get(), buf_len); std::memcpy(buf_upper.get(), buf.get(), buf_len); - for (usz i = std::basic_string_view(buf.get() + 0x30, file_name.size()).find_last_of('.'); i < buf_len; i++) + const auto buf_span = std::span(buf.get(), buf.get() + buf_len); + const auto it = std::find(buf_span.rbegin(), buf_span.rend() - 0x30, '.'); + for (usz i = std::distance(it, buf_span.rend()) - 1; i < buf_len; ++i) { - const u8 c = static_cast(buf[i]); + const u8 c = buf[i]; buf_upper[i] = std::toupper(c); buf_lower[i] = std::tolower(c); } diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index b3c38bb383..15a0cc6679 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -17,9 +17,10 @@ #include "Utilities/StrUtil.h" #include "Emu/Cell/lv2/sys_event.h" -#include "Emu/Cell/lv2/sys_process.h" #include "Emu/Cell/lv2/sys_fs.h" +#include +#include #include #include "util/asm.hpp" @@ -479,7 +480,7 @@ error_code sceNpTrophyCreateContext(vm::ptr context, vm::cptr(&commSign_data.data[6], 6).find_first_not_of('\0') != umax) + if (std::any_of(&commSign_data.data[6], &commSign_data.data[6] + 6, FN(x != '\0'))) { // 6 padding bytes - must be 0 return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID; diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index 63e2c2d462..8d948cc972 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -2,8 +2,7 @@ #include "PPUAnalyser.h" #include "PPUOpcodes.h" -#include "PPUModule.h" -#include "Emu/system_config.h" +#include "PPUThread.h" #include #include "util/yaml.hpp" @@ -530,7 +529,7 @@ namespace ppu_patterns }; } -bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::basic_string& applied, const std::vector& exported_funcs, std::function check_aborted) +bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::vector& applied, const std::vector& exported_funcs, std::function check_aborted) { if (segs.empty()) { diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index c7e690cd1f..287418e802 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -109,7 +109,7 @@ struct ppu_module addr_to_seg_index = info.addr_to_seg_index; } - bool analyse(u32 lib_toc, u32 entry, u32 end, const std::basic_string& applied, const std::vector& exported_funcs = std::vector{}, std::function check_aborted = {}); + bool analyse(u32 lib_toc, u32 entry, u32 end, const std::vector& applied, const std::vector& exported_funcs = std::vector{}, std::function check_aborted = {}); void validate(u32 reloc); template @@ -181,7 +181,7 @@ struct main_ppu_module : public ppu_module { u32 elf_entry{}; u32 seg0_code_end{}; - std::basic_string applied_patches; + std::vector applied_patches; }; // Aux diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index ea78939456..627bb256ae 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include "util/asm.hpp" LOG_CHANNEL(ppu_loader); @@ -683,7 +682,7 @@ extern bool ppu_register_library_lock(std::string_view libname, bool lock_lib) } // Load and register exports; return special exports found (nameless module) -static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false, std::vector* funcs = nullptr, std::basic_string* loaded_flags = nullptr) +static auto ppu_load_exports(const ppu_module& _module, ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false, std::vector* funcs = nullptr, std::basic_string* loaded_flags = nullptr) { std::unordered_map result; @@ -984,7 +983,7 @@ static auto ppu_load_imports(const ppu_module& _module, std::vector& } // For _sys_prx_register_module -void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string& loaded_flags) +void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string& loaded_flags) { auto& _main = g_fxo->get(); auto& link = g_fxo->get(); @@ -1289,7 +1288,7 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment& std::string name; std::string dump; - std::basic_string applied; + std::vector applied; // Executable hash sha1_context sha2; @@ -1363,12 +1362,12 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment& } // Apply the patch - applied += g_fxo->get().apply(hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr); + g_fxo->get().apply(applied, hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr); if (!Emu.GetTitleID().empty()) { // Alternative patch - applied += g_fxo->get().apply(Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr); + g_fxo->get().apply(applied, Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr); } } @@ -1830,7 +1829,7 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo liblv2_end = prx->segs[0].addr + prx->segs[0].size; } - std::basic_string applied; + std::vector applied; for (usz i = Emu.DeserialManager() ? prx->segs.size() : 0; i < prx->segs.size(); i++) { @@ -1841,18 +1840,19 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo const std::string hash_seg = fmt::format("%s-%u", hash, i); // Apply the patch - auto _applied = g_fxo->get().apply(hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr(addr + seg.addr, size); }, seg.size); + std::vector _applied; + g_fxo->get().apply(_applied, hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr(addr + seg.addr, size); }, seg.size); if (!Emu.GetTitleID().empty()) { // Alternative patch - _applied += g_fxo->get().apply(Emu.GetTitleID() + '-' + hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr(addr + seg.addr, size); }, seg.size); + g_fxo->get().apply(_applied, Emu.GetTitleID() + '-' + hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr(addr + seg.addr, size); }, seg.size); } // Rebase patch offsets std::for_each(_applied.begin(), _applied.end(), [&](u32& res) { if (res != umax) res += seg.addr; }); - applied += _applied; + applied.insert(applied.end(), _applied.begin(), _applied.end()); if (_applied.empty()) { @@ -1877,10 +1877,11 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo // Find the first segment if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz) { - std::basic_string_view elf_memory{prog.bin.data(), prog.bin.size()}; - elf_memory.remove_prefix(end - prx->segs[0].addr); + std::span elf_memory{prog.bin.begin(), prog.bin.size()}; + elf_memory = elf_memory.subspan(end - prx->segs[0].addr); - if (elf_memory != std::basic_string_view{&prx->get_ref(end), elf_memory.size()}) + const auto tmp = std::span{&prx->get_ref(end), elf_memory.size()}; + if (!std::equal(elf_memory.begin(), elf_memory.end(), tmp.begin(), tmp.end())) { // There are changes, disable analysis optimization ppu_loader.notice("Disabling analysis optimization due to memory changes from original file"); @@ -2198,12 +2199,13 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str Emu.SetExecutableHash(hash); // Apply the patch - auto applied = g_fxo->get().apply(!ar ? hash : std::string{}, [&](u32 addr, u32 size) { return _main.get_ptr(addr, size); }); + std::vector applied; + g_fxo->get().apply(applied, !ar ? hash : std::string{}, [&](u32 addr, u32 size) { return _main.get_ptr(addr, size); }); if (!ar && !Emu.GetTitleID().empty()) { // Alternative patch - applied += g_fxo->get().apply(Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 size) { return _main.get_ptr(addr, size); }); + g_fxo->get().apply(applied, Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 size) { return _main.get_ptr(addr, size); }); } if (!applied.empty() || ar) @@ -2216,10 +2218,11 @@ bool ppu_load_exec(const ppu_exec_object& elf, bool virtual_load, const std::str // Find the first segment if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz) { - std::basic_string_view elf_memory{prog.bin.data(), prog.bin.size()}; - elf_memory.remove_prefix(end - _main.segs[0].addr); + std::span elf_memory{prog.bin.begin(), prog.bin.size()}; + elf_memory = elf_memory.subspan(end - _main.segs[0].addr); - if (elf_memory != std::basic_string_view{&_main.get_ref(end), elf_memory.size()}) + const auto tmp = std::span{&_main.get_ref(end), elf_memory.size()}; + if (!std::equal(elf_memory.begin(), elf_memory.end(), tmp.begin(), tmp.end())) { // There are changes, disable analysis optimization ppu_loader.notice("Disabling analysis optimization due to memory changes from original file"); @@ -2881,12 +2884,13 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex } // Apply the patch - auto applied = g_fxo->get().apply(!Emu.DeserialManager() ? hash : std::string{}, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr(addr, size); }); + std::vector applied; + g_fxo->get().apply(applied, !Emu.DeserialManager() ? hash : std::string{}, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr(addr, size); }); if (!Emu.DeserialManager() && !Emu.GetTitleID().empty()) { // Alternative patch - applied += g_fxo->get().apply(Emu.GetTitleID() + '-' + hash, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr(addr, size); }); + g_fxo->get().apply(applied, Emu.GetTitleID() + '-' + hash, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr(addr, size); }); } if (!applied.empty() || ar) @@ -2899,10 +2903,10 @@ std::pair, CellError> ppu_load_overlay(const ppu_ex // Find the first segment if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz) { - std::basic_string_view elf_memory{prog.bin.data(), prog.bin.size()}; - elf_memory.remove_prefix(end - ovlm->segs[0].addr); + std::span elf_memory{prog.bin.begin(), prog.bin.size()}; + elf_memory = elf_memory.subspan(end - ovlm->segs[0].addr); - if (elf_memory != std::basic_string_view{&ovlm->get_ref(end), elf_memory.size()}) + if (!std::equal(elf_memory.begin(), elf_memory.end(), &ovlm->get_ref(end))) { // There are changes, disable analysis optimization ppu_loader.notice("Disabling analysis optimization due to memory changes from original file"); diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index 01176889c2..c60e76ecd6 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -20,6 +20,7 @@ #include "SPUInterpreter.h" #include "SPUDisAsm.h" #include +#include #include #include @@ -33,6 +34,15 @@ const extern spu_decoder g_spu_iflag; constexpr u32 s_reg_max = spu_recompiler_base::s_reg_max; +template +struct span_less +{ + bool operator()(const std::span& this_, const std::span& that) const + { + return std::memcmp(this_.data(), that.data(), std::min(this_.size_bytes(), that.size_bytes())) < 0; + } +}; + // Move 4 args for calling native function from a GHC calling convention function #if defined(ARCH_X64) static u8* move_args_ghc_to_native(u8* raw) @@ -533,7 +543,7 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s return; } - std::basic_string data(size / 4, 0); + std::vector data(size / 4, 0); std::memcpy(data.data(), ls_data_vaddr, size); spu_cache::precompile_data_t obj{vaddr, std::move(data)}; @@ -926,7 +936,7 @@ void spu_cache::initialize(bool build_existing_cache) u32 next_func = 0; u32 sec_addr = umax; u32 sec_idx = 0; - std::basic_string_view inst_data; + std::vector inst_data; // Try to get the data this index points to for (auto& sec : data_list) @@ -976,7 +986,7 @@ void spu_cache::initialize(bool build_existing_cache) u32 block_addr = func_addr; - std::map> targets; + std::map> targets; // Call analyser spu_program func2 = compiler->analyse(ls.data(), block_addr, &targets); @@ -1135,12 +1145,12 @@ void spu_cache::initialize(bool build_existing_cache) std::string dump; dump.reserve(10'000'000); - std::map, spu_program*> sorted; + std::map, spu_program*, span_less> sorted; for (auto&& f : func_list) { // Interpret as a byte string - std::basic_string_view data = {reinterpret_cast(f.data.data()), f.data.size() * sizeof(u32)}; + std::span data = {reinterpret_cast(f.data.data()), f.data.size() * sizeof(u32)}; sorted[data] = &f; } @@ -1252,9 +1262,9 @@ bool spu_program::operator<(const spu_program& rhs) const noexcept const u32 rhs_offs = (rhs.entry_point - rhs.lower_bound) / 4; // Select range for comparison - std::basic_string_view lhs_data(data.data() + lhs_offs, data.size() - lhs_offs); - std::basic_string_view rhs_data(rhs.data.data() + rhs_offs, rhs.data.size() - rhs_offs); - const auto cmp0 = lhs_data.compare(rhs_data); + std::span lhs_data(data.data() + lhs_offs, data.size() - lhs_offs); + std::span rhs_data(rhs.data.data() + rhs_offs, rhs.data.size() - rhs_offs); + const auto cmp0 = std::memcmp(lhs_data.data(), rhs_data.data(), std::min(lhs_data.size_bytes(), rhs_data.size_bytes())); if (cmp0 < 0) return true; @@ -1264,7 +1274,7 @@ bool spu_program::operator<(const spu_program& rhs) const noexcept // Compare from address 0 to the point before the entry point (TODO: undesirable) lhs_data = {data.data(), lhs_offs}; rhs_data = {rhs.data.data(), rhs_offs}; - const auto cmp1 = lhs_data.compare(rhs_data); + const auto cmp1 = std::memcmp(lhs_data.data(), rhs_data.data(), std::min(lhs_data.size_bytes(), rhs_data.size_bytes())); if (cmp1 < 0) return true; @@ -1330,7 +1340,7 @@ spu_item* spu_runtime::add_empty(spu_program&& data) spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst) { // Prepare sorted list - static thread_local std::vector, spu_function_t>> m_flat_list; + static thread_local std::vector, spu_function_t>> m_flat_list; // Remember top position auto stuff_it = ::at32(m_stuff, id_inst >> 12).begin(); @@ -1347,8 +1357,8 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst) { if (const auto ptr = it->compiled.load()) { - std::basic_string_view range{it->data.data.data(), it->data.data.size()}; - range.remove_prefix((it->data.entry_point - it->data.lower_bound) / 4); + std::span range{it->data.data.data(), it->data.data.size()}; + range = range.subspan((it->data.entry_point - it->data.lower_bound) / 4); m_flat_list.emplace_back(range, ptr); } else @@ -1359,7 +1369,7 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst) } } - std::sort(m_flat_list.begin(), m_flat_list.end(), FN(x.first < y.first)); + std::sort(m_flat_list.begin(), m_flat_list.end(), FN(std::memcmp(x.first.data(), y.first.data(), std::min(x.first.size_bytes(), y.first.size_bytes())) < 0)); struct work { @@ -1551,13 +1561,13 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst) // Resort subrange starting from the new level std::stable_sort(w.beg, w.end, [&](const auto& a, const auto& b) { - std::basic_string_view lhs = a.first; - std::basic_string_view rhs = b.first; + std::span lhs = a.first; + std::span rhs = b.first; - lhs.remove_prefix(w.level); - rhs.remove_prefix(w.level); + lhs = lhs.subspan(w.level); + rhs = rhs.subspan(w.level); - return lhs < rhs; + return std::memcmp(lhs.data(), rhs.data(), std::min(lhs.size_bytes(), rhs.size_bytes())) < 0; }); continue; @@ -1919,15 +1929,15 @@ spu_function_t spu_runtime::find(const u32* ls, u32 addr) const { if (const auto ptr = item.compiled.load()) { - std::basic_string_view range{item.data.data.data(), item.data.data.size()}; - range.remove_prefix((item.data.entry_point - item.data.lower_bound) / 4); + std::span range{item.data.data.data(), item.data.data.size()}; + range = range.subspan((item.data.entry_point - item.data.lower_bound) / 4); if (addr / 4 + range.size() > 0x10000) { continue; } - if (range.compare(0, range.size(), ls + addr / 4, range.size()) == 0) + if (std::equal(range.begin(), range.end(), ls + addr / 4)) { return ptr; } @@ -2836,7 +2846,7 @@ struct block_reg_info } }; -spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, std::map>* out_target_list) +spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, std::map>* out_target_list) { // Result: addr + raw instruction data spu_program result; @@ -2920,7 +2930,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } // Add predecessor - if (m_preds[target].find_first_of(pos) + 1 == 0) + if (std::find(m_preds[target].begin(), m_preds[target].end(), pos) == m_preds[target].end()) { m_preds[target].push_back(pos); } @@ -3077,8 +3087,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s else if (type == spu_itype::BI && g_cfg.core.spu_block_size != spu_block_size_type::safe && !op.d && !op.e && !sync) { // Analyse jump table (TODO) - std::basic_string jt_abs; - std::basic_string jt_rel; + std::vector jt_abs; + std::vector jt_rel; const u32 start = pos + 4; u64 dabs = 0; u64 drel = 0; @@ -3585,7 +3595,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } // All (direct and indirect) predecessors to check - std::basic_string workload; + std::vector workload; // Bit array used to deduplicate workload list workload.push_back(pair.first); @@ -4028,7 +4038,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s workload.push_back(entry_point); ensure(m_bbs.count(entry_point)); - std::basic_string new_entries; + std::vector new_entries; for (u32 wi = 0; wi < workload.size(); wi++) { @@ -4707,7 +4717,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s { if (target < bb.func || target >= flim || (bb.terminator == term_type::call && target == bb.func)) { - if (func.calls.find_first_of(target) + 1 == 0) + if (std::find(func.calls.begin(), func.calls.end(), target) == func.calls.end()) { func.calls.push_back(target); } @@ -4861,7 +4871,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s reg_state_t ch_state{+vf::is_null}; // Channel stat, example: RCNCNT ch_state, MFC_Cmd reg_state_t ch_product{+vf::is_null}; // Optional comparison state for channl state, example: CEQI ch_product, ch_state, 1 bool product_test_negate = false; // Compare the opposite way, such as: CEQI ch_product, ch_state, 0 which turns 0 t -1 and 1 to 0 - std::basic_string origins; + std::vector origins; u32 branch_pc = SPU_LS_SIZE; // Where the loop branch is located u32 branch_target = SPU_LS_SIZE; // The target of the loop branch @@ -5216,7 +5226,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s u32 stackframe_pc = SPU_LS_SIZE; usz entry_index = umax; - auto get_block_targets = [&](u32 pc) -> std::basic_string_view + auto get_block_targets = [&](u32 pc) -> std::span { if (m_block_info[pc / 4] && m_bbs.count(pc)) { @@ -5658,7 +5668,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s if (rchcnt_loop->active) { - if (rchcnt_loop->origins.find_first_of(pos) != umax) + if (std::find(rchcnt_loop->origins.begin(), rchcnt_loop->origins.end(), pos) != rchcnt_loop->origins.end()) { rchcnt_loop->failed = true; rchcnt_loop->active = false; @@ -7032,7 +7042,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s if (rchcnt_loop->active) { - if (rchcnt_loop->origins.find_first_of(vregs[op_rt].origin) == umax) + if (std::find(rchcnt_loop->origins.begin(), rchcnt_loop->origins.end(), vregs[op_rt].origin) == rchcnt_loop->origins.end()) { rchcnt_loop->origins.push_back(vregs[op_rt].origin); } @@ -8002,7 +8012,7 @@ std::array& block_reg_info::evaluate_start_state(const s if (!has_true_state) { std::array temp; - std::basic_string been_there; + std::vector been_there; struct iterator_info { diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 0472acdf44..18f9fa27b3 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -13,10 +13,8 @@ #include "SPUThread.h" #include "SPUAnalyser.h" #include "SPUInterpreter.h" -#include "SPUDisAsm.h" #include #include -#include #include "util/v128.hpp" #include "util/simd.hpp" @@ -406,7 +404,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator llvm::BasicBlock* add_block(u32 target, bool absolute = false) { // Check the predecessor - const bool pred_found = m_block_info[target / 4] && m_preds[target].find_first_of(m_pos) + 1; + const bool pred_found = m_block_info[target / 4] && std::find(m_preds[target].begin(), m_preds[target].end(), m_pos) != m_preds[target].end(); if (m_blocks.empty()) { @@ -2053,7 +2051,7 @@ public: { const auto tfound = m_targets.find(m_pos); - if (tfound == m_targets.end() || tfound->second.find_first_of(target) + 1 == 0) + if (tfound == m_targets.end() || std::find(tfound->second.begin(), tfound->second.end(), target) == tfound->second.end()) { spu_log.error("[%s] Unregistered fallthrough to 0x%x (chunk=0x%x, entry=0x%x)", m_hash, target, m_entry, m_function_queue[0]); } diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index 968fab287c..03b69583d8 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -40,7 +40,7 @@ public: struct precompile_data_t { u32 vaddr; - std::basic_string inst_data; + std::vector inst_data; std::vector funcs; }; @@ -291,10 +291,10 @@ protected: std::bitset<0x10000> m_use_rc; // List of possible targets for the instruction (entry shouldn't exist for simple instructions) - std::unordered_map, value_hash> m_targets; + std::unordered_map, value_hash> m_targets; // List of block predecessors - std::unordered_map, value_hash> m_preds; + std::unordered_map, value_hash> m_preds; // List of function entry points and return points (set after BRSL, BRASL, BISL, BISLED) std::bitset<0x10000> m_entry_info; @@ -351,17 +351,17 @@ protected: std::array reg_origin, reg_origin_abs; // All possible successor blocks - std::basic_string targets; + std::vector targets; // All predeccessor blocks - std::basic_string preds; + std::vector preds; }; // Sorted basic block info std::map m_bbs; // Sorted advanced block (chunk) list - std::basic_string m_chunks; + std::vector m_chunks; // Function information struct func_info @@ -373,7 +373,7 @@ protected: bool good = false; // Call targets - std::basic_string calls; + std::vector calls; // Register save info (stack offset) std::array reg_save_off{}; @@ -432,7 +432,7 @@ public: static void old_interpreter(spu_thread&, void* ls, u8*); // Get the function data at specified address - spu_program analyse(const be_t* ls, u32 entry_point, std::map>* out_target_list = nullptr); + spu_program analyse(const be_t* ls, u32 entry_point, std::map>* out_target_list = nullptr); // Print analyser internal state void dump(const spu_program& result, std::string& out); diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index af7b4644bc..6d21098b0e 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1412,7 +1412,7 @@ std::vector> spu_thread::dump_callstack_list() const std::vector passed(_pc / 4); // Start with PC - std::basic_string start_points{_pc}; + std::vector start_points{_pc}; bool is_ok = false; bool all_failed = false; diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index d30a516607..247c32ef12 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -51,6 +51,7 @@ #include "sys_uart.h" #include "sys_crypto_engine.h" +#include #include #include #include "util/tsc.hpp" @@ -1338,15 +1339,14 @@ bool lv2_obj::sleep(cpu_thread& cpu, const u64 timeout) { // Ignore outdated notification request } - else if (usz notify_later_idx = std::basic_string_view{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t{}); - notify_later_idx != umax) + else if (auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t{}); it != std::end(g_to_notify)) { - g_to_notify[notify_later_idx] = vm::reservation_notifier_notify(addr, true); + *it = vm::reservation_notifier_notify(addr, true); - if (notify_later_idx < std::size(g_to_notify) - 1) + if (it < std::end(g_to_notify) - 1) { // Null-terminate the list if it ends before last slot - g_to_notify[notify_later_idx + 1] = nullptr; + *(it + 1) = nullptr; } } else @@ -1392,15 +1392,14 @@ bool lv2_obj::awake(cpu_thread* thread, s32 prio) { // Ignore outdated notification request } - else if (usz notify_later_idx = std::basic_string_view{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t{}); - notify_later_idx != umax) + else if (auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t{}); it != std::end(g_to_notify)) { - g_to_notify[notify_later_idx] = vm::reservation_notifier_notify(addr, true); + *it = vm::reservation_notifier_notify(addr, true); - if (notify_later_idx < std::size(g_to_notify) - 1) + if (it < std::end(g_to_notify) - 1) { // Null-terminate the list if it ends before last slot - g_to_notify[notify_later_idx + 1] = nullptr; + *(it + 1) = nullptr; } } else @@ -1834,7 +1833,7 @@ void lv2_obj::cleanup() void lv2_obj::schedule_all(u64 current_time) { - usz notify_later_idx = std::basic_string_view{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t{}); + auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t{}); if (!g_pending && g_scheduler_ready) { @@ -1857,14 +1856,14 @@ void lv2_obj::schedule_all(u64 current_time) continue; } - if (notify_later_idx >= std::size(g_to_notify)) + if (it == std::end(g_to_notify)) { // Out of notification slots, notify locally (resizable container is not worth it) target->state.notify_one(); } else { - g_to_notify[notify_later_idx++] = &target->state; + *it++ = &target->state; } } } @@ -1891,14 +1890,14 @@ void lv2_obj::schedule_all(u64 current_time) ensure(!target->state.test_and_set(cpu_flag::notify)); // Otherwise notify it to wake itself - if (notify_later_idx >= std::size(g_to_notify)) + if (it == std::end(g_to_notify)) { // Out of notification slots, notify locally (resizable container is not worth it) target->state.notify_one(); } else { - g_to_notify[notify_later_idx++] = &target->state; + *it++ = &target->state; } } } @@ -1909,10 +1908,10 @@ void lv2_obj::schedule_all(u64 current_time) } } - if (notify_later_idx - 1 < std::size(g_to_notify) - 1) + if (it < std::end(g_to_notify) - 1) { // Null-terminate the list if it ends before last slot - g_to_notify[notify_later_idx] = nullptr; + *(it + 1) = nullptr; } if (const u64 freq = s_yield_frequency) diff --git a/rpcs3/Emu/Cell/lv2/sys_overlay.h b/rpcs3/Emu/Cell/lv2/sys_overlay.h index 9b3278a848..1636ac38e0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_overlay.h +++ b/rpcs3/Emu/Cell/lv2/sys_overlay.h @@ -1,7 +1,9 @@ #pragma once #include "Emu/Cell/PPUAnalyser.h" +#include "Emu/Memory/vm_ptr.h" #include "sys_sync.h" +#include struct lv2_overlay final : lv2_obj, ppu_module { @@ -9,7 +11,7 @@ struct lv2_overlay final : lv2_obj, ppu_module u32 entry{}; u32 seg0_code_end{}; - std::basic_string applied_patches; + std::vector applied_patches; lv2_overlay() = default; lv2_overlay(utils::serial&){} diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index 2c7b79df9e..49b5839cfa 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -8,7 +8,7 @@ #include "Crypto/unself.h" #include "Loader/ELF.h" -#include "Emu/Cell/PPUModule.h" +#include "Emu/Cell/PPUThread.h" #include "Emu/Cell/ErrorCodes.h" #include "Crypto/unedat.h" #include "Utilities/StrUtil.h" @@ -23,7 +23,7 @@ extern std::shared_ptr ppu_load_prx(const ppu_prx_object&, bool virtual extern void ppu_unload_prx(const lv2_prx& prx); extern bool ppu_initialize(const ppu_module&, bool check_only = false, u64 file_size = 0); extern void ppu_finalize(const ppu_module& info, bool force_mem_release = false); -extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string& loaded_flags); +extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string& loaded_flags); LOG_CHANNEL(sys_prx); @@ -327,7 +327,7 @@ std::shared_ptr lv2_prx::load(utils::serial& ar) if (seg_count) { - std::basic_string loaded_flags, external_flags; + std::basic_string loaded_flags, external_flags; ar(loaded_flags, external_flags); @@ -771,7 +771,7 @@ void lv2_prx::restore_exports() { constexpr usz sizeof_export_data = 0x1C; - std::basic_string loaded_flags_empty; + std::basic_string loaded_flags_empty; for (u32 start = exports_start, i = 0; start < exports_end; i++, start += vm::read8(start) ? vm::read8(start) : sizeof_export_data) { @@ -791,7 +791,7 @@ void lv2_prx::unload_exports() return; } - std::basic_string merged = m_loaded_flags; + std::basic_string merged = m_loaded_flags; for (usz i = 0; i < merged.size(); i++) { @@ -848,7 +848,7 @@ error_code _sys_prx_register_module(ppu_thread& ppu, vm::cptr name, vm::pt { if (Emu.IsVsh()) { - ppu_manual_load_imports_exports(info.lib_stub_ea.addr(), info.lib_stub_size, info.lib_entries_ea.addr(), info.lib_entries_size, *std::make_unique>()); + ppu_manual_load_imports_exports(info.lib_stub_ea.addr(), info.lib_stub_size, info.lib_entries_ea.addr(), info.lib_entries_size, *std::make_unique>()); } else { @@ -884,7 +884,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr library) std::array mem_copy{}; std::memcpy(mem_copy.data(), library.get_ptr(), sizeof_lib); - std::basic_string flags; + std::basic_string flags; ppu_manual_load_imports_exports(0, 0, library.addr(), sizeof_lib, flags); if (flags.front()) @@ -897,7 +897,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr library) { if (std::memcpy(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0) { - atomic_storage::release(prx.m_external_loaded_flags[index], true); + atomic_storage::release(prx.m_external_loaded_flags[index], true); return true; } } diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.h b/rpcs3/Emu/Cell/lv2/sys_prx.h index e700a3c99e..328d67cc6e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.h +++ b/rpcs3/Emu/Cell/lv2/sys_prx.h @@ -195,8 +195,8 @@ struct lv2_prx final : lv2_obj, ppu_module u32 exports_start = umax; u32 exports_end = 0; - std::basic_string m_loaded_flags; - std::basic_string m_external_loaded_flags; + std::basic_string m_loaded_flags; + std::basic_string m_external_loaded_flags; void load_exports(); // (Re)load exports void restore_exports(); // For savestates diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index 51b6721048..0de03fcbaa 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -190,12 +190,13 @@ void sys_spu_image::deploy(u8* loc, std::span segs, bool }; // Apply the patch - auto applied = g_fxo->get().apply(hash, mem_translate); + std::vector applied; + g_fxo->get().apply(applied, hash, mem_translate); if (!Emu.GetTitleID().empty()) { // Alternative patch - applied += g_fxo->get().apply(Emu.GetTitleID() + '-' + hash, mem_translate); + g_fxo->get().apply(applied, Emu.GetTitleID() + '-' + hash, mem_translate); } (is_verbose ? spu_log.notice : sys_spu.trace)("Loaded SPU image: %s (<- %u)%s", hash, applied.size(), dump); diff --git a/rpcs3/Emu/NP/np_structs_extra.cpp b/rpcs3/Emu/NP/np_structs_extra.cpp index d64b76be0a..66e7a342f7 100644 --- a/rpcs3/Emu/NP/np_structs_extra.cpp +++ b/rpcs3/Emu/NP/np_structs_extra.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Emu/System.h" +#include #include "np_structs_extra.h" LOG_CHANNEL(sceNp); @@ -39,7 +40,7 @@ namespace extra_nps if (ptr && size) { - sceNp2.warning("Data: %s", std::basic_string_view{ptr.get_ptr(), size}); + sceNp2.warning("Data: %s", std::span{ptr.get_ptr(), size}); } } @@ -57,7 +58,7 @@ namespace extra_nps void print_SceNpMatching2PresenceOptionData(const SceNpMatching2PresenceOptionData* opt) { - sceNp2.warning("Data: %s", std::basic_string_view{std::data(opt->data), std::size(opt->data)}); + sceNp2.warning("Data: %s", std::span{std::data(opt->data), std::size(opt->data)}); } void print_range(const SceNpMatching2Range* range) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 167e1d5e20..685897960f 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -1260,8 +1260,8 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, if (game_data.find_first_of('\0') != umax || !sysutil_check_name_string(game_data.c_str(), 1, CELL_GAME_DIRNAME_SIZE)) { - const std::basic_string_view dirname{reinterpret_cast(game_data.data()), game_data.size()}; - fmt::throw_exception("HDD0 deserialization failed: Invalid directory name: %s, ar=%s", dirname.substr(0, CELL_GAME_DIRNAME_SIZE + 1), *m_ar); + const std::span dirname{reinterpret_cast(game_data.data()), game_data.size()}; + fmt::throw_exception("HDD0 deserialization failed: Invalid directory name: %s, ar=%s", dirname.subspan(0, CELL_GAME_DIRNAME_SIZE + 1), *m_ar); } load_tar(hdd0_game + game_data, ""); diff --git a/rpcs3/Loader/PSF.cpp b/rpcs3/Loader/PSF.cpp index 6bb7f4bb0e..ee88424608 100644 --- a/rpcs3/Loader/PSF.cpp +++ b/rpcs3/Loader/PSF.cpp @@ -2,6 +2,7 @@ #include "PSF.h" #include "util/asm.hpp" +#include LOG_CHANNEL(psf_log, "PSF"); @@ -75,7 +76,7 @@ void fmt_class_string::format(std::string& out, u64 arg) continue; } - fmt::append(out, "%s: %s\n", entry.first, std::basic_string_view(reinterpret_cast(entry.second.as_string().data()), entry.second.size())); + fmt::append(out, "%s: %s\n", entry.first, std::span(reinterpret_cast(entry.second.as_string().data()), entry.second.size())); } } diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index e64de72a45..d515751523 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -31,7 +31,8 @@ #include #include #include -#include +#include +#include #include "util/asm.hpp" @@ -753,8 +754,8 @@ void debugger_frame::keyPressEvent(QKeyEvent* event) default: break; } - if (const usz pos = std::basic_string_view(res.data(), 2).find_last_not_of(umax); pos != umax) - m_debugger_list->ShowAddress(res[pos] - std::max(row, 0) * 4, true); + if (auto it = std::find_if(res.rbegin(), res.rend(), FN(x != umax)); it != res.rend()) + m_debugger_list->ShowAddress(*it - std::max(row, 0) * 4, true); return; } diff --git a/rpcs3/util/logs.cpp b/rpcs3/util/logs.cpp index 8ef9404e20..764dbc7efc 100644 --- a/rpcs3/util/logs.cpp +++ b/rpcs3/util/logs.cpp @@ -398,7 +398,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) co // Get text, extract va_args /*constinit thread_local*/ std::string text; - /*constinit thread_local*/ std::basic_string args; + /*constinit thread_local*/ std::vector args; static constexpr fmt_type_info empty_sup{};