From d12d7952f1fa4e511275b6b70c0d25fa0efd50ff Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 10 May 2014 21:48:46 -0300 Subject: [PATCH] Align pointer in SDL_memset before doing Uint32 loop Some more recent compilers emit SSE aligned store instructions for the loop, causing crashes if the destination buffer isn't aligned on a 32-bit boundary. This would also crash on platforms like ARM that require aligned stores. This fixes a crash inside SDL_FillRect that happens with the official x64 mingw build. --- src/stdlib/SDL_string.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index fb50687cc..a9ca2674f 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -263,13 +263,25 @@ SDL_memset(void *dst, int c, size_t len) #if defined(HAVE_MEMSET) return memset(dst, c, len); #else - size_t left = (len % 4); + size_t left; Uint32 *dstp4; - Uint8 *dstp1; + Uint8 *dstp1 = (Uint8 *) dst; Uint32 value4 = (c | (c << 8) | (c << 16) | (c << 24)); Uint8 value1 = (Uint8) c; - dstp4 = (Uint32 *) dst; + /* The destination pointer needs to be aligned on a 4-byte boundary to + * execute a 32-bit set. Set first bytes manually if needed until it is + * aligned. */ + while ((intptr_t)dstp1 & 0x3) { + if (len--) { + *dstp1++ = value1; + } else { + return dst; + } + } + + dstp4 = (Uint32 *) dstp1; + left = (len % 4); len /= 4; while (len--) { *dstp4++ = value4;