x64Emitter: Fix unaligned store UBSAN errors

This compiles to the same assembly as before even without optimizations and avoids UB.

https://godbolt.org/z/4G5edM

While the UB here is benign, this improves signal-to-noise ratio of UBSAN errors.

Fixes #14005
This commit is contained in:
Gleb Mazovetskiy 2021-01-30 12:26:01 +00:00
parent c251d69eab
commit 7305ba9d9b
2 changed files with 6 additions and 4 deletions

View File

@ -501,7 +501,8 @@ void XEmitter::SetJumpTarget(const FixupBranch &branch)
{
s64 distance = (s64)(code - branch.ptr);
_assert_msg_(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register");
((s32*)branch.ptr)[-1] = (s32)distance;
const s32 distance32 = static_cast<s32>(distance);
std::memcpy(branch.ptr - sizeof(s32), &distance32, sizeof(s32));
}
}

View File

@ -20,6 +20,7 @@
#include "ppsspp_config.h"
#include <cstddef>
#include <cstring>
#include "Common/Common.h"
#include "Common/Log.h"
@ -361,9 +362,9 @@ private:
protected:
inline void Write8(u8 value) {*code++ = value;}
inline void Write16(u16 value) {*(u16*)code = (value); code += 2;}
inline void Write32(u32 value) {*(u32*)code = (value); code += 4;}
inline void Write64(u64 value) {*(u64*)code = (value); code += 8;}
inline void Write16(u16 value) {std::memcpy(code, &value, sizeof(u16)); code += 2;}
inline void Write32(u32 value) {std::memcpy(code, &value, sizeof(u32)); code += 4;}
inline void Write64(u64 value) {std::memcpy(code, &value, sizeof(u64)); code += 8;}
public:
XEmitter() { code = nullptr; flags_locked = false; }