mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Fix std::basic_string warnings (#16261)
This commit is contained in:
parent
2262ac1684
commit
2b0f786b2d
@ -4,6 +4,7 @@
|
|||||||
#include "StrUtil.h"
|
#include "StrUtil.h"
|
||||||
#include "Crypto/sha1.h"
|
#include "Crypto/sha1.h"
|
||||||
|
|
||||||
|
#include <span>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -293,7 +294,7 @@ namespace fs
|
|||||||
struct id_view
|
struct id_view
|
||||||
{
|
{
|
||||||
std::string_view type_view;
|
std::string_view type_view;
|
||||||
std::basic_string_view<u8> data_view;
|
std::span<const u8> data_view;
|
||||||
};
|
};
|
||||||
|
|
||||||
id_view _rhs{rhs.type, {rhs.data.data(), rhs.data.size()}};
|
id_view _rhs{rhs.type, {rhs.data.data(), rhs.data.size()}};
|
||||||
@ -311,7 +312,7 @@ namespace fs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove offsets data
|
// 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
|
// Get last category identifier
|
||||||
if (usz sep = id.type_view.rfind(": "); sep != umax)
|
if (usz sep = id.type_view.rfind(": "); sep != umax)
|
||||||
@ -329,7 +330,7 @@ namespace fs
|
|||||||
return false;
|
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()
|
dir_base::~dir_base()
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
#include "Emu/VFS.h"
|
#include "Emu/VFS.h"
|
||||||
|
|
||||||
#include "util/types.hpp"
|
#include "util/types.hpp"
|
||||||
#include "util/endian.hpp"
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
LOG_CHANNEL(patch_log, "PAT");
|
LOG_CHANNEL(patch_log, "PAT");
|
||||||
|
|
||||||
@ -907,7 +907,7 @@ void unmap_vm_area(std::shared_ptr<vm::block_t>& ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns old 'applied' size
|
// Returns old 'applied' size
|
||||||
static usz apply_modification(std::basic_string<u32>& applied, patch_engine::patch_info& patch, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr)
|
static usz apply_modification(std::vector<u32>& applied, patch_engine::patch_info& patch, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr)
|
||||||
{
|
{
|
||||||
const usz old_applied_size = applied.size();
|
const usz old_applied_size = applied.size();
|
||||||
|
|
||||||
@ -1447,14 +1447,13 @@ static usz apply_modification(std::basic_string<u32>& applied, patch_engine::pat
|
|||||||
return old_applied_size;
|
return old_applied_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::basic_string<u32> patch_engine::apply(const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr)
|
void patch_engine::apply(std::vector<u32>& applied_total, const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz, u32 min_addr)
|
||||||
{
|
{
|
||||||
if (!m_map.contains(name))
|
if (!m_map.contains(name))
|
||||||
{
|
{
|
||||||
return {};
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::basic_string<u32> applied_total;
|
|
||||||
const patch_container& container = ::at32(m_map, name);
|
const patch_container& container = ::at32(m_map, name);
|
||||||
const std::string& serial = Emu.GetTitleID();
|
const std::string& serial = Emu.GetTitleID();
|
||||||
const std::string& app_version = Emu.GetAppVersion();
|
const std::string& app_version = Emu.GetAppVersion();
|
||||||
@ -1598,8 +1597,6 @@ std::basic_string<u32> patch_engine::apply(const std::string& name, std::functio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return applied_total;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_engine::unload(const std::string& name)
|
void patch_engine::unload(const std::string& name)
|
||||||
|
@ -215,7 +215,7 @@ public:
|
|||||||
void append_title_patches(std::string_view title_id);
|
void append_title_patches(std::string_view title_id);
|
||||||
|
|
||||||
// Apply patch (returns the number of entries applied)
|
// Apply patch (returns the number of entries applied)
|
||||||
std::basic_string<u32> apply(const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz = -1, u32 min_addr = 0);
|
void apply(std::vector<u32>& applied_total, const std::string& name, std::function<u8*(u32, u32)> mem_translate, u32 filesz = -1, u32 min_addr = 0);
|
||||||
|
|
||||||
// Deallocate memory used by patches
|
// Deallocate memory used by patches
|
||||||
void unload(const std::string& name);
|
void unload(const std::string& name);
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
#include "lz.h"
|
#include "lz.h"
|
||||||
#include "ec.h"
|
#include "ec.h"
|
||||||
|
|
||||||
#include "Utilities/mutex.h"
|
|
||||||
#include "Emu/system_utils.hpp"
|
#include "Emu/system_utils.hpp"
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
LOG_CHANNEL(edat_log, "EDAT");
|
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_lower.get(), buf.get(), buf_len);
|
||||||
std::memcpy(buf_upper.get(), buf.get(), buf_len);
|
std::memcpy(buf_upper.get(), buf.get(), buf_len);
|
||||||
|
|
||||||
for (usz i = std::basic_string_view<u8>(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<u8>(buf[i]);
|
const u8 c = buf[i];
|
||||||
buf_upper[i] = std::toupper(c);
|
buf_upper[i] = std::toupper(c);
|
||||||
buf_lower[i] = std::tolower(c);
|
buf_lower[i] = std::tolower(c);
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,10 @@
|
|||||||
#include "Utilities/StrUtil.h"
|
#include "Utilities/StrUtil.h"
|
||||||
|
|
||||||
#include "Emu/Cell/lv2/sys_event.h"
|
#include "Emu/Cell/lv2/sys_event.h"
|
||||||
#include "Emu/Cell/lv2/sys_process.h"
|
|
||||||
#include "Emu/Cell/lv2/sys_fs.h"
|
#include "Emu/Cell/lv2/sys_fs.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
|
||||||
@ -479,7 +480,7 @@ error_code sceNpTrophyCreateContext(vm::ptr<u32> context, vm::cptr<SceNpCommunic
|
|||||||
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;
|
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::basic_string_view<u8>(&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
|
// 6 padding bytes - must be 0
|
||||||
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;
|
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
#include "PPUAnalyser.h"
|
#include "PPUAnalyser.h"
|
||||||
|
|
||||||
#include "PPUOpcodes.h"
|
#include "PPUOpcodes.h"
|
||||||
#include "PPUModule.h"
|
#include "PPUThread.h"
|
||||||
#include "Emu/system_config.h"
|
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include "util/yaml.hpp"
|
#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<u32>& applied, const std::vector<u32>& exported_funcs, std::function<bool()> check_aborted)
|
bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::vector<u32>& applied, const std::vector<u32>& exported_funcs, std::function<bool()> check_aborted)
|
||||||
{
|
{
|
||||||
if (segs.empty())
|
if (segs.empty())
|
||||||
{
|
{
|
||||||
|
@ -109,7 +109,7 @@ struct ppu_module
|
|||||||
addr_to_seg_index = info.addr_to_seg_index;
|
addr_to_seg_index = info.addr_to_seg_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool analyse(u32 lib_toc, u32 entry, u32 end, const std::basic_string<u32>& applied, const std::vector<u32>& exported_funcs = std::vector<u32>{}, std::function<bool()> check_aborted = {});
|
bool analyse(u32 lib_toc, u32 entry, u32 end, const std::vector<u32>& applied, const std::vector<u32>& exported_funcs = std::vector<u32>{}, std::function<bool()> check_aborted = {});
|
||||||
void validate(u32 reloc);
|
void validate(u32 reloc);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -181,7 +181,7 @@ struct main_ppu_module : public ppu_module
|
|||||||
{
|
{
|
||||||
u32 elf_entry{};
|
u32 elf_entry{};
|
||||||
u32 seg0_code_end{};
|
u32 seg0_code_end{};
|
||||||
std::basic_string<u32> applied_patches;
|
std::vector<u32> applied_patches;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Aux
|
// Aux
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include <span>
|
#include <span>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <shared_mutex>
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
|
||||||
LOG_CHANNEL(ppu_loader);
|
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)
|
// 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<u32>* funcs = nullptr, std::basic_string<bool>* 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<u32>* funcs = nullptr, std::basic_string<char>* loaded_flags = nullptr)
|
||||||
{
|
{
|
||||||
std::unordered_map<u32, u32> result;
|
std::unordered_map<u32, u32> result;
|
||||||
|
|
||||||
@ -984,7 +983,7 @@ static auto ppu_load_imports(const ppu_module& _module, std::vector<ppu_reloc>&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For _sys_prx_register_module
|
// 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<bool>& loaded_flags)
|
void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<char>& loaded_flags)
|
||||||
{
|
{
|
||||||
auto& _main = g_fxo->get<main_ppu_module>();
|
auto& _main = g_fxo->get<main_ppu_module>();
|
||||||
auto& link = g_fxo->get<ppu_linkage_info>();
|
auto& link = g_fxo->get<ppu_linkage_info>();
|
||||||
@ -1289,7 +1288,7 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment&
|
|||||||
std::string name;
|
std::string name;
|
||||||
std::string dump;
|
std::string dump;
|
||||||
|
|
||||||
std::basic_string<u32> applied;
|
std::vector<u32> applied;
|
||||||
|
|
||||||
// Executable hash
|
// Executable hash
|
||||||
sha1_context sha2;
|
sha1_context sha2;
|
||||||
@ -1363,12 +1362,12 @@ static void ppu_check_patch_spu_images(const ppu_module& mod, const ppu_segment&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply the patch
|
// Apply the patch
|
||||||
applied += g_fxo->get<patch_engine>().apply(hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr);
|
g_fxo->get<patch_engine>().apply(applied, hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr);
|
||||||
|
|
||||||
if (!Emu.GetTitleID().empty())
|
if (!Emu.GetTitleID().empty())
|
||||||
{
|
{
|
||||||
// Alternative patch
|
// Alternative patch
|
||||||
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 /*size*/) { return addr + elf_header + prog.p_offset; }, prog.p_filesz, prog.p_vaddr);
|
g_fxo->get<patch_engine>().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<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo
|
|||||||
liblv2_end = prx->segs[0].addr + prx->segs[0].size;
|
liblv2_end = prx->segs[0].addr + prx->segs[0].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::basic_string<u32> applied;
|
std::vector<u32> applied;
|
||||||
|
|
||||||
for (usz i = Emu.DeserialManager() ? prx->segs.size() : 0; i < prx->segs.size(); i++)
|
for (usz i = Emu.DeserialManager() ? prx->segs.size() : 0; i < prx->segs.size(); i++)
|
||||||
{
|
{
|
||||||
@ -1841,18 +1840,19 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo
|
|||||||
const std::string hash_seg = fmt::format("%s-%u", hash, i);
|
const std::string hash_seg = fmt::format("%s-%u", hash, i);
|
||||||
|
|
||||||
// Apply the patch
|
// Apply the patch
|
||||||
auto _applied = g_fxo->get<patch_engine>().apply(hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size);
|
std::vector<u32> _applied;
|
||||||
|
g_fxo->get<patch_engine>().apply(_applied, hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size);
|
||||||
|
|
||||||
if (!Emu.GetTitleID().empty())
|
if (!Emu.GetTitleID().empty())
|
||||||
{
|
{
|
||||||
// Alternative patch
|
// Alternative patch
|
||||||
_applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size);
|
g_fxo->get<patch_engine>().apply(_applied, Emu.GetTitleID() + '-' + hash_seg, [&](u32 addr, u32 size) { return prx->get_ptr<u8>(addr + seg.addr, size); }, seg.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rebase patch offsets
|
// Rebase patch offsets
|
||||||
std::for_each(_applied.begin(), _applied.end(), [&](u32& res) { if (res != umax) res += seg.addr; });
|
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())
|
if (_applied.empty())
|
||||||
{
|
{
|
||||||
@ -1877,10 +1877,11 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, bool virtual_lo
|
|||||||
// Find the first segment
|
// Find the first segment
|
||||||
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
|
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
|
||||||
{
|
{
|
||||||
std::basic_string_view<uchar> elf_memory{prog.bin.data(), prog.bin.size()};
|
std::span<const uchar> elf_memory{prog.bin.begin(), prog.bin.size()};
|
||||||
elf_memory.remove_prefix(end - prx->segs[0].addr);
|
elf_memory = elf_memory.subspan(end - prx->segs[0].addr);
|
||||||
|
|
||||||
if (elf_memory != std::basic_string_view<uchar>{&prx->get_ref<uchar>(end), elf_memory.size()})
|
const auto tmp = std::span<uchar>{&prx->get_ref<uchar>(end), elf_memory.size()};
|
||||||
|
if (!std::equal(elf_memory.begin(), elf_memory.end(), tmp.begin(), tmp.end()))
|
||||||
{
|
{
|
||||||
// There are changes, disable analysis optimization
|
// There are changes, disable analysis optimization
|
||||||
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");
|
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);
|
Emu.SetExecutableHash(hash);
|
||||||
|
|
||||||
// Apply the patch
|
// Apply the patch
|
||||||
auto applied = g_fxo->get<patch_engine>().apply(!ar ? hash : std::string{}, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); });
|
std::vector<u32> applied;
|
||||||
|
g_fxo->get<patch_engine>().apply(applied, !ar ? hash : std::string{}, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); });
|
||||||
|
|
||||||
if (!ar && !Emu.GetTitleID().empty())
|
if (!ar && !Emu.GetTitleID().empty())
|
||||||
{
|
{
|
||||||
// Alternative patch
|
// Alternative patch
|
||||||
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); });
|
g_fxo->get<patch_engine>().apply(applied, Emu.GetTitleID() + '-' + hash, [&](u32 addr, u32 size) { return _main.get_ptr<u8>(addr, size); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!applied.empty() || ar)
|
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
|
// Find the first segment
|
||||||
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
|
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
|
||||||
{
|
{
|
||||||
std::basic_string_view<uchar> elf_memory{prog.bin.data(), prog.bin.size()};
|
std::span<const uchar> elf_memory{prog.bin.begin(), prog.bin.size()};
|
||||||
elf_memory.remove_prefix(end - _main.segs[0].addr);
|
elf_memory = elf_memory.subspan(end - _main.segs[0].addr);
|
||||||
|
|
||||||
if (elf_memory != std::basic_string_view<uchar>{&_main.get_ref<u8>(end), elf_memory.size()})
|
const auto tmp = std::span<uchar>{&_main.get_ref<u8>(end), elf_memory.size()};
|
||||||
|
if (!std::equal(elf_memory.begin(), elf_memory.end(), tmp.begin(), tmp.end()))
|
||||||
{
|
{
|
||||||
// There are changes, disable analysis optimization
|
// There are changes, disable analysis optimization
|
||||||
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");
|
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");
|
||||||
@ -2881,12 +2884,13 @@ std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply the patch
|
// Apply the patch
|
||||||
auto applied = g_fxo->get<patch_engine>().apply(!Emu.DeserialManager() ? hash : std::string{}, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); });
|
std::vector<u32> applied;
|
||||||
|
g_fxo->get<patch_engine>().apply(applied, !Emu.DeserialManager() ? hash : std::string{}, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); });
|
||||||
|
|
||||||
if (!Emu.DeserialManager() && !Emu.GetTitleID().empty())
|
if (!Emu.DeserialManager() && !Emu.GetTitleID().empty())
|
||||||
{
|
{
|
||||||
// Alternative patch
|
// Alternative patch
|
||||||
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); });
|
g_fxo->get<patch_engine>().apply(applied, Emu.GetTitleID() + '-' + hash, [ovlm](u32 addr, u32 size) { return ovlm->get_ptr<u8>(addr, size); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!applied.empty() || ar)
|
if (!applied.empty() || ar)
|
||||||
@ -2899,10 +2903,10 @@ std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_ex
|
|||||||
// Find the first segment
|
// Find the first segment
|
||||||
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
|
if (prog.p_type == 0x1u /* LOAD */ && prog.p_memsz)
|
||||||
{
|
{
|
||||||
std::basic_string_view<uchar> elf_memory{prog.bin.data(), prog.bin.size()};
|
std::span<const uchar> elf_memory{prog.bin.begin(), prog.bin.size()};
|
||||||
elf_memory.remove_prefix(end - ovlm->segs[0].addr);
|
elf_memory = elf_memory.subspan(end - ovlm->segs[0].addr);
|
||||||
|
|
||||||
if (elf_memory != std::basic_string_view<uchar>{&ovlm->get_ref<u8>(end), elf_memory.size()})
|
if (!std::equal(elf_memory.begin(), elf_memory.end(), &ovlm->get_ref<u8>(end)))
|
||||||
{
|
{
|
||||||
// There are changes, disable analysis optimization
|
// There are changes, disable analysis optimization
|
||||||
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");
|
ppu_loader.notice("Disabling analysis optimization due to memory changes from original file");
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "SPUInterpreter.h"
|
#include "SPUInterpreter.h"
|
||||||
#include "SPUDisAsm.h"
|
#include "SPUDisAsm.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
@ -33,6 +34,15 @@ const extern spu_decoder<spu_iflag> g_spu_iflag;
|
|||||||
|
|
||||||
constexpr u32 s_reg_max = spu_recompiler_base::s_reg_max;
|
constexpr u32 s_reg_max = spu_recompiler_base::s_reg_max;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct span_less
|
||||||
|
{
|
||||||
|
bool operator()(const std::span<T>& this_, const std::span<T>& 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
|
// Move 4 args for calling native function from a GHC calling convention function
|
||||||
#if defined(ARCH_X64)
|
#if defined(ARCH_X64)
|
||||||
static u8* move_args_ghc_to_native(u8* raw)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::basic_string<u32> data(size / 4, 0);
|
std::vector<u32> data(size / 4, 0);
|
||||||
std::memcpy(data.data(), ls_data_vaddr, size);
|
std::memcpy(data.data(), ls_data_vaddr, size);
|
||||||
|
|
||||||
spu_cache::precompile_data_t obj{vaddr, std::move(data)};
|
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 next_func = 0;
|
||||||
u32 sec_addr = umax;
|
u32 sec_addr = umax;
|
||||||
u32 sec_idx = 0;
|
u32 sec_idx = 0;
|
||||||
std::basic_string_view<u32> inst_data;
|
std::vector<u32> inst_data;
|
||||||
|
|
||||||
// Try to get the data this index points to
|
// Try to get the data this index points to
|
||||||
for (auto& sec : data_list)
|
for (auto& sec : data_list)
|
||||||
@ -976,7 +986,7 @@ void spu_cache::initialize(bool build_existing_cache)
|
|||||||
|
|
||||||
u32 block_addr = func_addr;
|
u32 block_addr = func_addr;
|
||||||
|
|
||||||
std::map<u32, std::basic_string<u32>> targets;
|
std::map<u32, std::vector<u32>> targets;
|
||||||
|
|
||||||
// Call analyser
|
// Call analyser
|
||||||
spu_program func2 = compiler->analyse(ls.data(), block_addr, &targets);
|
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;
|
std::string dump;
|
||||||
dump.reserve(10'000'000);
|
dump.reserve(10'000'000);
|
||||||
|
|
||||||
std::map<std::basic_string_view<u8>, spu_program*> sorted;
|
std::map<std::span<u8>, spu_program*, span_less<u8>> sorted;
|
||||||
|
|
||||||
for (auto&& f : func_list)
|
for (auto&& f : func_list)
|
||||||
{
|
{
|
||||||
// Interpret as a byte string
|
// Interpret as a byte string
|
||||||
std::basic_string_view<u8> data = {reinterpret_cast<u8*>(f.data.data()), f.data.size() * sizeof(u32)};
|
std::span<u8> data = {reinterpret_cast<u8*>(f.data.data()), f.data.size() * sizeof(u32)};
|
||||||
|
|
||||||
sorted[data] = &f;
|
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;
|
const u32 rhs_offs = (rhs.entry_point - rhs.lower_bound) / 4;
|
||||||
|
|
||||||
// Select range for comparison
|
// Select range for comparison
|
||||||
std::basic_string_view<u32> lhs_data(data.data() + lhs_offs, data.size() - lhs_offs);
|
std::span<const u32> lhs_data(data.data() + lhs_offs, data.size() - lhs_offs);
|
||||||
std::basic_string_view<u32> rhs_data(rhs.data.data() + rhs_offs, rhs.data.size() - rhs_offs);
|
std::span<const u32> rhs_data(rhs.data.data() + rhs_offs, rhs.data.size() - rhs_offs);
|
||||||
const auto cmp0 = lhs_data.compare(rhs_data);
|
const auto cmp0 = std::memcmp(lhs_data.data(), rhs_data.data(), std::min(lhs_data.size_bytes(), rhs_data.size_bytes()));
|
||||||
|
|
||||||
if (cmp0 < 0)
|
if (cmp0 < 0)
|
||||||
return true;
|
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)
|
// Compare from address 0 to the point before the entry point (TODO: undesirable)
|
||||||
lhs_data = {data.data(), lhs_offs};
|
lhs_data = {data.data(), lhs_offs};
|
||||||
rhs_data = {rhs.data.data(), rhs_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)
|
if (cmp1 < 0)
|
||||||
return true;
|
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)
|
spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
|
||||||
{
|
{
|
||||||
// Prepare sorted list
|
// Prepare sorted list
|
||||||
static thread_local std::vector<std::pair<std::basic_string_view<u32>, spu_function_t>> m_flat_list;
|
static thread_local std::vector<std::pair<std::span<const u32>, spu_function_t>> m_flat_list;
|
||||||
|
|
||||||
// Remember top position
|
// Remember top position
|
||||||
auto stuff_it = ::at32(m_stuff, id_inst >> 12).begin();
|
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())
|
if (const auto ptr = it->compiled.load())
|
||||||
{
|
{
|
||||||
std::basic_string_view<u32> range{it->data.data.data(), it->data.data.size()};
|
std::span<const u32> range{it->data.data.data(), it->data.data.size()};
|
||||||
range.remove_prefix((it->data.entry_point - it->data.lower_bound) / 4);
|
range = range.subspan((it->data.entry_point - it->data.lower_bound) / 4);
|
||||||
m_flat_list.emplace_back(range, ptr);
|
m_flat_list.emplace_back(range, ptr);
|
||||||
}
|
}
|
||||||
else
|
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
|
struct work
|
||||||
{
|
{
|
||||||
@ -1551,13 +1561,13 @@ spu_function_t spu_runtime::rebuild_ubertrampoline(u32 id_inst)
|
|||||||
// Resort subrange starting from the new level
|
// Resort subrange starting from the new level
|
||||||
std::stable_sort(w.beg, w.end, [&](const auto& a, const auto& b)
|
std::stable_sort(w.beg, w.end, [&](const auto& a, const auto& b)
|
||||||
{
|
{
|
||||||
std::basic_string_view<u32> lhs = a.first;
|
std::span<const u32> lhs = a.first;
|
||||||
std::basic_string_view<u32> rhs = b.first;
|
std::span<const u32> rhs = b.first;
|
||||||
|
|
||||||
lhs.remove_prefix(w.level);
|
lhs = lhs.subspan(w.level);
|
||||||
rhs.remove_prefix(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;
|
continue;
|
||||||
@ -1919,15 +1929,15 @@ spu_function_t spu_runtime::find(const u32* ls, u32 addr) const
|
|||||||
{
|
{
|
||||||
if (const auto ptr = item.compiled.load())
|
if (const auto ptr = item.compiled.load())
|
||||||
{
|
{
|
||||||
std::basic_string_view<u32> range{item.data.data.data(), item.data.data.size()};
|
std::span<const u32> range{item.data.data.data(), item.data.data.size()};
|
||||||
range.remove_prefix((item.data.entry_point - item.data.lower_bound) / 4);
|
range = range.subspan((item.data.entry_point - item.data.lower_bound) / 4);
|
||||||
|
|
||||||
if (addr / 4 + range.size() > 0x10000)
|
if (addr / 4 + range.size() > 0x10000)
|
||||||
{
|
{
|
||||||
continue;
|
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;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -2836,7 +2846,7 @@ struct block_reg_info
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::basic_string<u32>>* out_target_list)
|
spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::vector<u32>>* out_target_list)
|
||||||
{
|
{
|
||||||
// Result: addr + raw instruction data
|
// Result: addr + raw instruction data
|
||||||
spu_program result;
|
spu_program result;
|
||||||
@ -2920,7 +2930,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add predecessor
|
// 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);
|
m_preds[target].push_back(pos);
|
||||||
}
|
}
|
||||||
@ -3077,8 +3087,8 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* 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)
|
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)
|
// Analyse jump table (TODO)
|
||||||
std::basic_string<u32> jt_abs;
|
std::vector<u32> jt_abs;
|
||||||
std::basic_string<u32> jt_rel;
|
std::vector<u32> jt_rel;
|
||||||
const u32 start = pos + 4;
|
const u32 start = pos + 4;
|
||||||
u64 dabs = 0;
|
u64 dabs = 0;
|
||||||
u64 drel = 0;
|
u64 drel = 0;
|
||||||
@ -3585,7 +3595,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All (direct and indirect) predecessors to check
|
// All (direct and indirect) predecessors to check
|
||||||
std::basic_string<u32> workload;
|
std::vector<u32> workload;
|
||||||
|
|
||||||
// Bit array used to deduplicate workload list
|
// Bit array used to deduplicate workload list
|
||||||
workload.push_back(pair.first);
|
workload.push_back(pair.first);
|
||||||
@ -4028,7 +4038,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
|||||||
workload.push_back(entry_point);
|
workload.push_back(entry_point);
|
||||||
ensure(m_bbs.count(entry_point));
|
ensure(m_bbs.count(entry_point));
|
||||||
|
|
||||||
std::basic_string<u32> new_entries;
|
std::vector<u32> new_entries;
|
||||||
|
|
||||||
for (u32 wi = 0; wi < workload.size(); wi++)
|
for (u32 wi = 0; wi < workload.size(); wi++)
|
||||||
{
|
{
|
||||||
@ -4707,7 +4717,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
|||||||
{
|
{
|
||||||
if (target < bb.func || target >= flim || (bb.terminator == term_type::call && target == bb.func))
|
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);
|
func.calls.push_back(target);
|
||||||
}
|
}
|
||||||
@ -4861,7 +4871,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* 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_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
|
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
|
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<u32> origins;
|
std::vector<u32> origins;
|
||||||
u32 branch_pc = SPU_LS_SIZE; // Where the loop branch is located
|
u32 branch_pc = SPU_LS_SIZE; // Where the loop branch is located
|
||||||
u32 branch_target = SPU_LS_SIZE; // The target of the loop branch
|
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<u32>* ls, u32 entry_point, s
|
|||||||
u32 stackframe_pc = SPU_LS_SIZE;
|
u32 stackframe_pc = SPU_LS_SIZE;
|
||||||
usz entry_index = umax;
|
usz entry_index = umax;
|
||||||
|
|
||||||
auto get_block_targets = [&](u32 pc) -> std::basic_string_view<u32>
|
auto get_block_targets = [&](u32 pc) -> std::span<u32>
|
||||||
{
|
{
|
||||||
if (m_block_info[pc / 4] && m_bbs.count(pc))
|
if (m_block_info[pc / 4] && m_bbs.count(pc))
|
||||||
{
|
{
|
||||||
@ -5658,7 +5668,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
|||||||
|
|
||||||
if (rchcnt_loop->active)
|
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->failed = true;
|
||||||
rchcnt_loop->active = false;
|
rchcnt_loop->active = false;
|
||||||
@ -7032,7 +7042,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
|||||||
|
|
||||||
if (rchcnt_loop->active)
|
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);
|
rchcnt_loop->origins.push_back(vregs[op_rt].origin);
|
||||||
}
|
}
|
||||||
@ -8002,7 +8012,7 @@ std::array<reg_state_t, s_reg_max>& block_reg_info::evaluate_start_state(const s
|
|||||||
if (!has_true_state)
|
if (!has_true_state)
|
||||||
{
|
{
|
||||||
std::array<reg_state_t, s_reg_max> temp;
|
std::array<reg_state_t, s_reg_max> temp;
|
||||||
std::basic_string<u32> been_there;
|
std::vector<u32> been_there;
|
||||||
|
|
||||||
struct iterator_info
|
struct iterator_info
|
||||||
{
|
{
|
||||||
|
@ -13,10 +13,8 @@
|
|||||||
#include "SPUThread.h"
|
#include "SPUThread.h"
|
||||||
#include "SPUAnalyser.h"
|
#include "SPUAnalyser.h"
|
||||||
#include "SPUInterpreter.h"
|
#include "SPUInterpreter.h"
|
||||||
#include "SPUDisAsm.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
#include "util/v128.hpp"
|
#include "util/v128.hpp"
|
||||||
#include "util/simd.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)
|
llvm::BasicBlock* add_block(u32 target, bool absolute = false)
|
||||||
{
|
{
|
||||||
// Check the predecessor
|
// 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())
|
if (m_blocks.empty())
|
||||||
{
|
{
|
||||||
@ -2053,7 +2051,7 @@ public:
|
|||||||
{
|
{
|
||||||
const auto tfound = m_targets.find(m_pos);
|
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]);
|
spu_log.error("[%s] Unregistered fallthrough to 0x%x (chunk=0x%x, entry=0x%x)", m_hash, target, m_entry, m_function_queue[0]);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
struct precompile_data_t
|
struct precompile_data_t
|
||||||
{
|
{
|
||||||
u32 vaddr;
|
u32 vaddr;
|
||||||
std::basic_string<u32> inst_data;
|
std::vector<u32> inst_data;
|
||||||
std::vector<u32> funcs;
|
std::vector<u32> funcs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,10 +291,10 @@ protected:
|
|||||||
std::bitset<0x10000> m_use_rc;
|
std::bitset<0x10000> m_use_rc;
|
||||||
|
|
||||||
// List of possible targets for the instruction (entry shouldn't exist for simple instructions)
|
// List of possible targets for the instruction (entry shouldn't exist for simple instructions)
|
||||||
std::unordered_map<u32, std::basic_string<u32>, value_hash<u32, 2>> m_targets;
|
std::unordered_map<u32, std::vector<u32>, value_hash<u32, 2>> m_targets;
|
||||||
|
|
||||||
// List of block predecessors
|
// List of block predecessors
|
||||||
std::unordered_map<u32, std::basic_string<u32>, value_hash<u32, 2>> m_preds;
|
std::unordered_map<u32, std::vector<u32>, value_hash<u32, 2>> m_preds;
|
||||||
|
|
||||||
// List of function entry points and return points (set after BRSL, BRASL, BISL, BISLED)
|
// List of function entry points and return points (set after BRSL, BRASL, BISL, BISLED)
|
||||||
std::bitset<0x10000> m_entry_info;
|
std::bitset<0x10000> m_entry_info;
|
||||||
@ -351,17 +351,17 @@ protected:
|
|||||||
std::array<u32, s_reg_max> reg_origin, reg_origin_abs;
|
std::array<u32, s_reg_max> reg_origin, reg_origin_abs;
|
||||||
|
|
||||||
// All possible successor blocks
|
// All possible successor blocks
|
||||||
std::basic_string<u32> targets;
|
std::vector<u32> targets;
|
||||||
|
|
||||||
// All predeccessor blocks
|
// All predeccessor blocks
|
||||||
std::basic_string<u32> preds;
|
std::vector<u32> preds;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sorted basic block info
|
// Sorted basic block info
|
||||||
std::map<u32, block_info> m_bbs;
|
std::map<u32, block_info> m_bbs;
|
||||||
|
|
||||||
// Sorted advanced block (chunk) list
|
// Sorted advanced block (chunk) list
|
||||||
std::basic_string<u32> m_chunks;
|
std::vector<u32> m_chunks;
|
||||||
|
|
||||||
// Function information
|
// Function information
|
||||||
struct func_info
|
struct func_info
|
||||||
@ -373,7 +373,7 @@ protected:
|
|||||||
bool good = false;
|
bool good = false;
|
||||||
|
|
||||||
// Call targets
|
// Call targets
|
||||||
std::basic_string<u32> calls;
|
std::vector<u32> calls;
|
||||||
|
|
||||||
// Register save info (stack offset)
|
// Register save info (stack offset)
|
||||||
std::array<u32, s_reg_max> reg_save_off{};
|
std::array<u32, s_reg_max> reg_save_off{};
|
||||||
@ -432,7 +432,7 @@ public:
|
|||||||
static void old_interpreter(spu_thread&, void* ls, u8*);
|
static void old_interpreter(spu_thread&, void* ls, u8*);
|
||||||
|
|
||||||
// Get the function data at specified address
|
// Get the function data at specified address
|
||||||
spu_program analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::basic_string<u32>>* out_target_list = nullptr);
|
spu_program analyse(const be_t<u32>* ls, u32 entry_point, std::map<u32, std::vector<u32>>* out_target_list = nullptr);
|
||||||
|
|
||||||
// Print analyser internal state
|
// Print analyser internal state
|
||||||
void dump(const spu_program& result, std::string& out);
|
void dump(const spu_program& result, std::string& out);
|
||||||
|
@ -1412,7 +1412,7 @@ std::vector<std::pair<u32, u32>> spu_thread::dump_callstack_list() const
|
|||||||
std::vector<bool> passed(_pc / 4);
|
std::vector<bool> passed(_pc / 4);
|
||||||
|
|
||||||
// Start with PC
|
// Start with PC
|
||||||
std::basic_string<u32> start_points{_pc};
|
std::vector<u32> start_points{_pc};
|
||||||
|
|
||||||
bool is_ok = false;
|
bool is_ok = false;
|
||||||
bool all_failed = false;
|
bool all_failed = false;
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "sys_uart.h"
|
#include "sys_uart.h"
|
||||||
#include "sys_crypto_engine.h"
|
#include "sys_crypto_engine.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include "util/tsc.hpp"
|
#include "util/tsc.hpp"
|
||||||
@ -1338,15 +1339,14 @@ bool lv2_obj::sleep(cpu_thread& cpu, const u64 timeout)
|
|||||||
{
|
{
|
||||||
// Ignore outdated notification request
|
// Ignore outdated notification request
|
||||||
}
|
}
|
||||||
else if (usz notify_later_idx = std::basic_string_view<const void*>{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t<const void>{});
|
else if (auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t<const void>{}); it != std::end(g_to_notify))
|
||||||
notify_later_idx != umax)
|
|
||||||
{
|
{
|
||||||
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
|
// Null-terminate the list if it ends before last slot
|
||||||
g_to_notify[notify_later_idx + 1] = nullptr;
|
*(it + 1) = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1392,15 +1392,14 @@ bool lv2_obj::awake(cpu_thread* thread, s32 prio)
|
|||||||
{
|
{
|
||||||
// Ignore outdated notification request
|
// Ignore outdated notification request
|
||||||
}
|
}
|
||||||
else if (usz notify_later_idx = std::basic_string_view<const void*>{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t<const void>{});
|
else if (auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t<const void>{}); it != std::end(g_to_notify))
|
||||||
notify_later_idx != umax)
|
|
||||||
{
|
{
|
||||||
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
|
// Null-terminate the list if it ends before last slot
|
||||||
g_to_notify[notify_later_idx + 1] = nullptr;
|
*(it + 1) = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1834,7 +1833,7 @@ void lv2_obj::cleanup()
|
|||||||
|
|
||||||
void lv2_obj::schedule_all(u64 current_time)
|
void lv2_obj::schedule_all(u64 current_time)
|
||||||
{
|
{
|
||||||
usz notify_later_idx = std::basic_string_view<const void*>{g_to_notify, std::size(g_to_notify)}.find_first_of(std::add_pointer_t<const void>{});
|
auto it = std::find(g_to_notify, std::end(g_to_notify), std::add_pointer_t<const void>{});
|
||||||
|
|
||||||
if (!g_pending && g_scheduler_ready)
|
if (!g_pending && g_scheduler_ready)
|
||||||
{
|
{
|
||||||
@ -1857,14 +1856,14 @@ void lv2_obj::schedule_all(u64 current_time)
|
|||||||
continue;
|
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)
|
// Out of notification slots, notify locally (resizable container is not worth it)
|
||||||
target->state.notify_one();
|
target->state.notify_one();
|
||||||
}
|
}
|
||||||
else
|
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));
|
ensure(!target->state.test_and_set(cpu_flag::notify));
|
||||||
|
|
||||||
// Otherwise notify it to wake itself
|
// 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)
|
// Out of notification slots, notify locally (resizable container is not worth it)
|
||||||
target->state.notify_one();
|
target->state.notify_one();
|
||||||
}
|
}
|
||||||
else
|
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
|
// 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)
|
if (const u64 freq = s_yield_frequency)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Emu/Cell/PPUAnalyser.h"
|
#include "Emu/Cell/PPUAnalyser.h"
|
||||||
|
#include "Emu/Memory/vm_ptr.h"
|
||||||
#include "sys_sync.h"
|
#include "sys_sync.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct lv2_overlay final : lv2_obj, ppu_module
|
struct lv2_overlay final : lv2_obj, ppu_module
|
||||||
{
|
{
|
||||||
@ -9,7 +11,7 @@ struct lv2_overlay final : lv2_obj, ppu_module
|
|||||||
|
|
||||||
u32 entry{};
|
u32 entry{};
|
||||||
u32 seg0_code_end{};
|
u32 seg0_code_end{};
|
||||||
std::basic_string<u32> applied_patches;
|
std::vector<u32> applied_patches;
|
||||||
|
|
||||||
lv2_overlay() = default;
|
lv2_overlay() = default;
|
||||||
lv2_overlay(utils::serial&){}
|
lv2_overlay(utils::serial&){}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "Crypto/unself.h"
|
#include "Crypto/unself.h"
|
||||||
#include "Loader/ELF.h"
|
#include "Loader/ELF.h"
|
||||||
|
|
||||||
#include "Emu/Cell/PPUModule.h"
|
#include "Emu/Cell/PPUThread.h"
|
||||||
#include "Emu/Cell/ErrorCodes.h"
|
#include "Emu/Cell/ErrorCodes.h"
|
||||||
#include "Crypto/unedat.h"
|
#include "Crypto/unedat.h"
|
||||||
#include "Utilities/StrUtil.h"
|
#include "Utilities/StrUtil.h"
|
||||||
@ -23,7 +23,7 @@ extern std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object&, bool virtual
|
|||||||
extern void ppu_unload_prx(const lv2_prx& prx);
|
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 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_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<bool>& loaded_flags);
|
extern void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<char>& loaded_flags);
|
||||||
|
|
||||||
LOG_CHANNEL(sys_prx);
|
LOG_CHANNEL(sys_prx);
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ std::shared_ptr<void> lv2_prx::load(utils::serial& ar)
|
|||||||
|
|
||||||
if (seg_count)
|
if (seg_count)
|
||||||
{
|
{
|
||||||
std::basic_string<bool> loaded_flags, external_flags;
|
std::basic_string<char> loaded_flags, external_flags;
|
||||||
|
|
||||||
ar(loaded_flags, external_flags);
|
ar(loaded_flags, external_flags);
|
||||||
|
|
||||||
@ -771,7 +771,7 @@ void lv2_prx::restore_exports()
|
|||||||
{
|
{
|
||||||
constexpr usz sizeof_export_data = 0x1C;
|
constexpr usz sizeof_export_data = 0x1C;
|
||||||
|
|
||||||
std::basic_string<bool> loaded_flags_empty;
|
std::basic_string<char> loaded_flags_empty;
|
||||||
|
|
||||||
for (u32 start = exports_start, i = 0; start < exports_end; i++, start += vm::read8(start) ? vm::read8(start) : sizeof_export_data)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::basic_string<bool> merged = m_loaded_flags;
|
std::basic_string<char> merged = m_loaded_flags;
|
||||||
|
|
||||||
for (usz i = 0; i < merged.size(); i++)
|
for (usz i = 0; i < merged.size(); i++)
|
||||||
{
|
{
|
||||||
@ -848,7 +848,7 @@ error_code _sys_prx_register_module(ppu_thread& ppu, vm::cptr<char> name, vm::pt
|
|||||||
{
|
{
|
||||||
if (Emu.IsVsh())
|
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<std::basic_string<bool>>());
|
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<std::basic_string<char>>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -884,7 +884,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr<void> library)
|
|||||||
std::array<char, sizeof_lib> mem_copy{};
|
std::array<char, sizeof_lib> mem_copy{};
|
||||||
std::memcpy(mem_copy.data(), library.get_ptr(), sizeof_lib);
|
std::memcpy(mem_copy.data(), library.get_ptr(), sizeof_lib);
|
||||||
|
|
||||||
std::basic_string<bool> flags;
|
std::basic_string<char> flags;
|
||||||
ppu_manual_load_imports_exports(0, 0, library.addr(), sizeof_lib, flags);
|
ppu_manual_load_imports_exports(0, 0, library.addr(), sizeof_lib, flags);
|
||||||
|
|
||||||
if (flags.front())
|
if (flags.front())
|
||||||
@ -897,7 +897,7 @@ error_code _sys_prx_register_library(ppu_thread& ppu, vm::ptr<void> library)
|
|||||||
{
|
{
|
||||||
if (std::memcpy(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0)
|
if (std::memcpy(vm::base(lib_addr), mem_copy.data(), sizeof_lib) == 0)
|
||||||
{
|
{
|
||||||
atomic_storage<bool>::release(prx.m_external_loaded_flags[index], true);
|
atomic_storage<char>::release(prx.m_external_loaded_flags[index], true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,8 +195,8 @@ struct lv2_prx final : lv2_obj, ppu_module
|
|||||||
u32 exports_start = umax;
|
u32 exports_start = umax;
|
||||||
u32 exports_end = 0;
|
u32 exports_end = 0;
|
||||||
|
|
||||||
std::basic_string<bool> m_loaded_flags;
|
std::basic_string<char> m_loaded_flags;
|
||||||
std::basic_string<bool> m_external_loaded_flags;
|
std::basic_string<char> m_external_loaded_flags;
|
||||||
|
|
||||||
void load_exports(); // (Re)load exports
|
void load_exports(); // (Re)load exports
|
||||||
void restore_exports(); // For savestates
|
void restore_exports(); // For savestates
|
||||||
|
@ -190,12 +190,13 @@ void sys_spu_image::deploy(u8* loc, std::span<const sys_spu_segment> segs, bool
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Apply the patch
|
// Apply the patch
|
||||||
auto applied = g_fxo->get<patch_engine>().apply(hash, mem_translate);
|
std::vector<u32> applied;
|
||||||
|
g_fxo->get<patch_engine>().apply(applied, hash, mem_translate);
|
||||||
|
|
||||||
if (!Emu.GetTitleID().empty())
|
if (!Emu.GetTitleID().empty())
|
||||||
{
|
{
|
||||||
// Alternative patch
|
// Alternative patch
|
||||||
applied += g_fxo->get<patch_engine>().apply(Emu.GetTitleID() + '-' + hash, mem_translate);
|
g_fxo->get<patch_engine>().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);
|
(is_verbose ? spu_log.notice : sys_spu.trace)("Loaded SPU image: %s (<- %u)%s", hash, applied.size(), dump);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
#include <span>
|
||||||
#include "np_structs_extra.h"
|
#include "np_structs_extra.h"
|
||||||
|
|
||||||
LOG_CHANNEL(sceNp);
|
LOG_CHANNEL(sceNp);
|
||||||
@ -39,7 +40,7 @@ namespace extra_nps
|
|||||||
|
|
||||||
if (ptr && size)
|
if (ptr && size)
|
||||||
{
|
{
|
||||||
sceNp2.warning("Data: %s", std::basic_string_view<u8>{ptr.get_ptr(), size});
|
sceNp2.warning("Data: %s", std::span<u8>{ptr.get_ptr(), size});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ namespace extra_nps
|
|||||||
|
|
||||||
void print_SceNpMatching2PresenceOptionData(const SceNpMatching2PresenceOptionData* opt)
|
void print_SceNpMatching2PresenceOptionData(const SceNpMatching2PresenceOptionData* opt)
|
||||||
{
|
{
|
||||||
sceNp2.warning("Data: %s", std::basic_string_view<u8>{std::data(opt->data), std::size(opt->data)});
|
sceNp2.warning("Data: %s", std::span<const u8>{std::data(opt->data), std::size(opt->data)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_range(const SceNpMatching2Range* range)
|
void print_range(const SceNpMatching2Range* range)
|
||||||
|
@ -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))
|
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<u8> dirname{reinterpret_cast<const u8*>(game_data.data()), game_data.size()};
|
const std::span<const u8> dirname{reinterpret_cast<const u8*>(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);
|
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, "");
|
load_tar(hdd0_game + game_data, "");
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "PSF.h"
|
#include "PSF.h"
|
||||||
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
#include <span>
|
||||||
|
|
||||||
LOG_CHANNEL(psf_log, "PSF");
|
LOG_CHANNEL(psf_log, "PSF");
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ void fmt_class_string<psf::registry>::format(std::string& out, u64 arg)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::append(out, "%s: %s\n", entry.first, std::basic_string_view<u8>(reinterpret_cast<const u8*>(entry.second.as_string().data()), entry.second.size()));
|
fmt::append(out, "%s: %s\n", entry.first, std::span<const u8>(reinterpret_cast<const u8*>(entry.second.as_string().data()), entry.second.size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <charconv>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
|
||||||
@ -753,8 +754,8 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const usz pos = std::basic_string_view<u32>(res.data(), 2).find_last_not_of(umax); pos != umax)
|
if (auto it = std::find_if(res.rbegin(), res.rend(), FN(x != umax)); it != res.rend())
|
||||||
m_debugger_list->ShowAddress(res[pos] - std::max(row, 0) * 4, true);
|
m_debugger_list->ShowAddress(*it - std::max(row, 0) * 4, true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -398,7 +398,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) co
|
|||||||
|
|
||||||
// Get text, extract va_args
|
// Get text, extract va_args
|
||||||
/*constinit thread_local*/ std::string text;
|
/*constinit thread_local*/ std::string text;
|
||||||
/*constinit thread_local*/ std::basic_string<u64> args;
|
/*constinit thread_local*/ std::vector<u64> args;
|
||||||
|
|
||||||
static constexpr fmt_type_info empty_sup{};
|
static constexpr fmt_type_info empty_sup{};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user