From 876f07cbeea5b583ca75685cefa0fd4be1e904a4 Mon Sep 17 00:00:00 2001 From: Joost VandeVondele Date: Sat, 5 Nov 2016 09:04:51 +0100 Subject: [PATCH] Fix undefined behaviour with unaligned loads in syzygy code Casting a pointer to a different type with stricter alignment requirements yields to implementation dependent behaviour. Practicaly everything is fine for common platforms because the CPU/OS/compiler will generate correct code, but anyhow it is better to be safe than sorry. Testing with dbg_hit_on() shows that the unalignment accesses are very rare (below 0.1%) so it makes sense to split the code in a fast path for the common case and a slower path as a fallback. No functional change (verified with TB enabled). --- src/syzygy/tbprobe.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/syzygy/tbprobe.cpp b/src/syzygy/tbprobe.cpp index a1e73c81..9debcc6f 100644 --- a/src/syzygy/tbprobe.cpp +++ b/src/syzygy/tbprobe.cpp @@ -239,7 +239,13 @@ template T number(void* addr) const union { uint32_t i; char c[4]; } Le = { 0x01020304 }; const bool IsLittleEndian = (Le.c[0] == 4); - T v = *((T*)addr); + T v; + + if ((uintptr_t)addr & (alignof(T) - 1)) // Unaligned pointer (very rare) + std::memcpy(&v, addr, sizeof(T)); + else + v = *((T*)addr); + if (LE != IsLittleEndian) swap_byte(v); return v; -- 2.39.2