diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 46fd63bba6..abf1be2e64 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -63,9 +63,9 @@ struct vdec_frame struct vdec_context final { - static constexpr u32 id_base = 0xf0000000; - static constexpr u32 id_step = 0x00000100; - static constexpr u32 id_count = 1024; + static const u32 id_base = 0xf0000000; + static const u32 id_step = 0x00000100; + static const u32 id_count = 1024; AVCodec* codec{}; AVCodecContext* ctx{}; diff --git a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp index f97d324d62..66db129ff5 100644 --- a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Utilities/StrUtil.h" diff --git a/rpcs3/Emu/Cell/lv2/sys_vm.cpp b/rpcs3/Emu/Cell/lv2/sys_vm.cpp index 00b86b691c..53d7efd939 100644 --- a/rpcs3/Emu/Cell/lv2/sys_vm.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_vm.cpp @@ -16,7 +16,7 @@ sys_vm_t::sys_vm_t(const std::shared_ptr& area, const std::shared_p sys_vm_t::~sys_vm_t() { // Free ID - g_ids[addr >> 28].release(0); + g_ids[addr >> 28].release(id_manager::id_traits::invalid); // Free block verify(HERE), vm::unmap(addr); diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 94d2d3ffd5..d771ab4e51 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -32,7 +32,8 @@ namespace id_manager static const u32 count = T::id_count; static const u32 invalid = base > 0 ? 0 : -1; - static_assert(u64{step} * count + base < UINT32_MAX, "ID traits: invalid object range"); + // Note: full 32 bits range cannot be used at current implementation + static_assert(count > 0 && step > 0 && u64{step} * count + base < u64{UINT32_MAX} + (base != 0 ? 1 : 0), "ID traits: invalid object range"); }; // Correct usage testing @@ -135,7 +136,19 @@ class idm template static constexpr u32 get_index(u32 id) { - return (id - id_manager::id_traits::base) / id_manager::id_traits::step; + using traits = id_manager::id_traits; + + // Note: if id is lower than base, diff / step will be higher than count + u32 diff = id - traits::base; + + if (diff % traits::step) + { + // id is invalid, return invalid index + return traits::count; + } + + // Get actual index + return diff / traits::step; } // Helper @@ -217,9 +230,14 @@ class idm const u32 index = get_index(id); + if (index >= id_manager::id_traits::count) + { + return nullptr; + } + auto& vec = g_map[get_type()]; - if (index >= vec.size() || index >= id_manager::id_traits::count) + if (index >= vec.size()) { return nullptr; }