mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-02 15:02:11 +00:00
Savestates: Add TAR and VM assert
This commit is contained in:
parent
5dbeb68ed2
commit
a0b521ba8e
@ -2256,7 +2256,15 @@ namespace vm
|
||||
void load(utils::serial& ar)
|
||||
{
|
||||
std::vector<std::shared_ptr<utils::shm>> shared;
|
||||
shared.resize(ar.pop<usz>());
|
||||
|
||||
const usz shared_size = ar.pop<usz>();
|
||||
|
||||
if (!shared_size || ar.get_size(umax) / 4096 < shared_size)
|
||||
{
|
||||
fmt::throw_exception("Invalid VM serialization state: shared_size=0x%x, ar=%s", shared_size, ar);
|
||||
}
|
||||
|
||||
shared.resize(shared_size);
|
||||
|
||||
for (auto& shm : shared)
|
||||
{
|
||||
|
@ -1056,7 +1056,13 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
|
||||
auto load_tar = [&](const std::string& path)
|
||||
{
|
||||
const usz size = *m_ar;
|
||||
const usz size = m_ar->pop<usz>();
|
||||
const usz max_data_size = m_ar->get_size(utils::add_saturate<usz>(size, m_ar->pos));
|
||||
|
||||
if (size % 512 || max_data_size < size || max_data_size - size < m_ar->pos)
|
||||
{
|
||||
fmt::throw_exception("TAR desrialization failed: Invalid size. TAR size: 0x%x, path='%s', ar: %s", size, path, *m_ar);
|
||||
}
|
||||
|
||||
fs::remove_all(path, size == 0);
|
||||
|
||||
@ -1065,7 +1071,12 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
m_ar->breathe(true);
|
||||
m_ar->m_max_data = m_ar->pos + size;
|
||||
ensure(tar_object(*m_ar).extract(path));
|
||||
m_ar->seek_pos(m_ar->m_max_data, size >= 4096);
|
||||
|
||||
if (m_ar->m_max_data != m_ar->pos)
|
||||
{
|
||||
fmt::throw_exception("TAR desrialization failed: read bytes: 0x%x, expected: 0x%x, path='%s', ar: %s", m_ar->pos - (m_ar->m_max_data - size), size, path, *m_ar);
|
||||
}
|
||||
|
||||
m_ar->m_max_data = umax;
|
||||
m_ar->breathe();
|
||||
}
|
||||
@ -1079,13 +1090,19 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
|
||||
for (const std::string hdd0_game = rpcs3::utils::get_hdd0_dir() + "game/";;)
|
||||
{
|
||||
const std::string game_data = *m_ar;
|
||||
const std::string game_data = m_ar->pop<std::string>();
|
||||
|
||||
if (game_data.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
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()};
|
||||
fmt::throw_exception("HDD0 deserialization failed: Invalid directory name: %s, ar=%s", dirname.substr(0, CELL_GAME_DIRNAME_SIZE + 1), *m_ar);
|
||||
}
|
||||
|
||||
load_tar(hdd0_game + game_data);
|
||||
}
|
||||
|
||||
@ -2993,7 +3010,7 @@ void Emulator::Kill(bool allow_autoexit, bool savestate, savestate_stage* save_s
|
||||
|
||||
const usz tar_size = new_pos - old_pos;
|
||||
|
||||
if (tar_size != ar_null.pos)
|
||||
if (tar_size % 512 || tar_size != ar_null.pos)
|
||||
{
|
||||
fmt::throw_exception("Unexpected TAR entry size (size=0x%x, expected=0x%x, entries=0x%x)", tar_size, ar_null.pos, dir_entries.size());
|
||||
}
|
||||
|
@ -23,7 +23,12 @@ void fmt_class_string<utils::serial>::format(std::string& out, u64 arg)
|
||||
{
|
||||
const utils::serial& ar = get_object(arg);
|
||||
|
||||
fmt::append(out, "{ %s, 0x%x/0x%x, memory=0x%x }", ar.is_writing() ? "writing" : "reading", ar.pos, ar.data_offset + ar.data.size(), ar.data.size());
|
||||
|
||||
be_t<u64> sample64 = 0;
|
||||
const usz read_size = std::min<usz>(ar.data.size(), sizeof(sample64));
|
||||
std::memcpy(&sample64, ar.data.data() + ar.data.size() - read_size, read_size);
|
||||
|
||||
fmt::append(out, "{ %s, 0x%x/0x%x, memory=0x%x, sample64=0x%016x }", ar.is_writing() ? "writing" : "reading", ar.pos, ar.data_offset + ar.data.size(), ar.data.size(), sample64);
|
||||
}
|
||||
|
||||
struct serial_ver_t
|
||||
|
@ -139,7 +139,7 @@ std::unique_ptr<utils::serial> tar_object::get_file(const std::string& path, std
|
||||
}
|
||||
else
|
||||
{
|
||||
tar_log.trace("tar_object::get_file() failed to parse header: offset=0x%x, filesize=0x%x", largest_offset, max_size);
|
||||
tar_log.error("tar_object::get_file() failed to parse header: offset=0x%x, filesize=0x%x", largest_offset, max_size);
|
||||
}
|
||||
|
||||
return { size, {} };
|
||||
|
Loading…
Reference in New Issue
Block a user