From 03332c340d9e5487bf7f3727abef553235e47f1a Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 10 Mar 2021 15:54:32 +0300 Subject: [PATCH] Implement utils::bless (pointer cast) Tries to workaround strict aliasing troubles. Don't confuse with std::bless which works differently. --- rpcs3/Emu/Cell/SPUThread.cpp | 2 +- rpcs3/Emu/RSX/GL/GLDraw.cpp | 4 ++-- rpcs3/util/asm.hpp | 13 +++++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index c46c5ce7a8..f929d75e68 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -2161,7 +2161,7 @@ void spu_thread::do_dma_transfer(spu_thread* _this, const spu_mfc_cmd& args, u8* auto& res = vm::reservation_acquire(eal); // Lock each bit corresponding to a byte being written, using some free space in reservation memory - auto* bits = reinterpret_cast*>(vm::g_reservations + ((eal & 0xff80) / 2 + 16)); + auto* bits = utils::bless>(vm::g_reservations + ((eal & 0xff80) / 2 + 16)); // Get writing mask const u128 wmask = (~u128{} << (eal & 127)) & (~u128{} >> (127 - ((eal + size0 - 1) & 127))); diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index 75b9c5553b..527e389b70 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -493,7 +493,7 @@ void GLGSRender::emit_geometry(u32 sub_index) m_scratch_buffer.resize(draw_count * 24); GLint* firsts = reinterpret_cast(m_scratch_buffer.data()); GLsizei* counts = (firsts + draw_count); - const GLvoid** offsets = reinterpret_cast(counts + draw_count); + const GLvoid** offsets = utils::bless(counts + draw_count); u32 first = 0; u32 dst_index = 0; @@ -560,7 +560,7 @@ void GLGSRender::emit_geometry(u32 sub_index) m_scratch_buffer.resize(draw_count * 16); GLsizei *counts = reinterpret_cast(m_scratch_buffer.data()); - const GLvoid** offsets = reinterpret_cast(counts + draw_count); + const GLvoid** offsets = utils::bless(counts + draw_count); int dst_index = 0; for (const auto &range : subranges) diff --git a/rpcs3/util/asm.hpp b/rpcs3/util/asm.hpp index a31b5c6102..ab4170061e 100644 --- a/rpcs3/util/asm.hpp +++ b/rpcs3/util/asm.hpp @@ -390,6 +390,19 @@ namespace utils return static_cast(value / align + (value > 0 ? T{(value % align) > (align / 2)} : 0 - T{(value % align) < (align / 2)})); } + + // Hack. Pointer cast util to workaround UB. Use with extreme care. + template + [[nodiscard]] T* bless(U* ptr) + { +#ifdef _MSC_VER + return (T*)ptr; +#else + T* result; + __asm__("movq %1, %0;" : "=r" (result) : "r" (ptr) : "memory"); + return result; +#endif + } } // namespace utils using utils::busy_wait;