<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 17 May 2017, at 12:08, Frediano Ziglio <<a href="mailto:fziglio@redhat.com" class="">fziglio@redhat.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class=""><br class=""><blockquote type="cite" class="">On 17 May 2017, at 09:44, Frediano Ziglio <<a href="mailto:fziglio@redhat.com" class="">fziglio@redhat.com</a>> wrote:<br class=""><br class=""><blockquote type="cite" class=""><br class="">From: Christophe de Dinechin <<a href="mailto:dinechin@redhat.com" class="">dinechin@redhat.com</a>><br class=""><br class="">For example, something like this:<br class="">  uint8_t  *p8;<br class="">  uint32_t *p32 = (uint32_t *) p8;<br class=""><br class="">generates a warning like this:<br class="">spice-channel.c:1350:10: error: cast from 'uint8_t *' (aka 'unsigned char<br class="">*') to<br class="">    'uint32_t *' (aka 'unsigned int *') increases required alignment from<br class="">    1<br class="">    to<br class="">    4 [-Werror,-Wcast-align]<br class=""><br class="">The warning indicates that we end up with a pointer to data that<br class="">should be 4-byte aligned, but its value may be misaligned. On x86,<br class="">this does not make much of a difference, except a relatively minor<br class="">performance penalty. However, on platforms such as ARM, misaligned<br class="">accesses are emulated by the kernel, and support for them is optional.<br class="">So we may end up with a fault.<br class=""><br class="">The intent of the fix here is to make it easy to identify and rework<br class="">places where actual mis-alignment occurs. Wherever casts raise the<br class="">warning,<br class="">they are replaced with a macro:<br class=""><br class="">- SPICE_ALIGNED_CAST(type, value) casts value to type, and indicates that<br class="">we believe the resulting pointer is aligned. If it is not, a warning will<br class="">be issued.<br class=""><br class="">- SPICE_UNALIGNED_CAST(type, value) casts value to type, and indicates<br class="">that<br class="">we believe the resulting pointer is not always aligned<br class=""><br class="">Any code using SPICE_UNALIGNED_CAST may need to be revisited in order<br class="">to improve performance, e.g. by using memcpy.<br class=""><br class="">There are normally no warnings for SPICE_UNALIGNED_CAST, but it is<br class="">possible<br class="">to emit debug messages for mis-alignment in SPICE_UNALIGNED_CAST.<br class="">Set environment variable SPICE_DEBUG_ALIGNMENT to activate this check.<br class=""><br class="">Signed-off-by: Christophe de Dinechin <<a href="mailto:dinechin@redhat.com" class="">dinechin@redhat.com</a>><br class="">---<br class="">spice-common                |  2 +-<br class="">src/channel-cursor.c        |  6 +++---<br class="">src/channel-display-mjpeg.c |  2 +-<br class="">src/decode-glz-tmpl.c       |  2 +-<br class="">src/spice-channel.c         | 14 +++++++++-----<br class="">5 files changed, 15 insertions(+), 11 deletions(-)<br class=""><br class="">diff --git a/spice-common b/spice-common<br class="">index af682b1..1239c82 160000<br class="">--- a/spice-common<br class="">+++ b/spice-common<br class="">@@ -1 +1 @@<br class="">-Subproject commit af682b1b06dea55007d9aa7c37cd443e4349e43f<br class="">+Subproject commit 1239c82c54dee0244cca262cca0aa21071b23e24<br class="">diff --git a/src/channel-cursor.c b/src/channel-cursor.c<br class="">index 609243b..50de5ce 100644<br class="">--- a/src/channel-cursor.c<br class="">+++ b/src/channel-cursor.c<br class="">@@ -340,7 +340,7 @@ static display_cursor *set_cursor(SpiceChannel<br class="">*channel,<br class="">SpiceCursor *scursor)<br class="">       memcpy(cursor->data, data, size);<br class="">       for (i = 0; i < hdr->width * hdr->height; i++) {<br class="">           pix_mask = get_pix_mask(data, size, i);<br class="">-            if (pix_mask && *((guint32*)data + i) == 0xffffff) {<br class="">+            if (pix_mask && *(SPICE_ALIGNED_CAST(guint32*, data) + i) ==<br class="">0xffffff) {<br class="">               cursor->data[i] = get_pix_hack(i, hdr->width);<br class="">           } else {<br class="">               cursor->data[i] |= (pix_mask ? 0 : 0xff000000);<br class="">@@ -350,7 +350,7 @@ static display_cursor *set_cursor(SpiceChannel<br class="">*channel,<br class="">SpiceCursor *scursor)<br class="">   case SPICE_CURSOR_TYPE_COLOR16:<br class="">       for (i = 0; i < hdr->width * hdr->height; i++) {<br class="">           pix_mask = get_pix_mask(data, size, i);<br class="">-            pix = *((guint16*)data + i);<br class="">+            pix = *(SPICE_ALIGNED_CAST(guint16*,data) + i);<br class="">           if (pix_mask && pix == 0x7fff) {<br class="">               cursor->data[i] = get_pix_hack(i, hdr->width);<br class="">           } else {<br class=""></blockquote><br class="">If these 2 hits you are going to have a message for every single pixel<br class="">in the image, potentially millions.<br class=""></blockquote><br class="">No, you will get one message only when you enter the image.<br class=""><br class="">   static const char *last_loc = NULL;<br class="">   if (loc != last_loc) {<br class="">       last_loc = loc;<br class="">       spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_WARNING, loc,<br class="">       __FUNCTION__,<br class="">                 "Misaligned access at %p, alignment %u", p, sz);<br class="">   }<br class=""><br class="">If it’s the same source code location, you get it once. But if you have two<br class="">such warnings, then yes, it may become verbose.<br class=""><br class="">But if you get millions of calls in case of mis-alignment, it means that on<br class="">ARM, you get millions of faults into the kernel to correct the alignment,<br class="">which is surely a lot worse performance-wise than a call.<br class=""><br class="">I remember someone (Pavel?) recently saying that Spice performance on ARM was<br class="">terrible. Something like this could easily explain it.<br class=""><br class=""><br class=""><blockquote type="cite" class="">I'm still convinced, like in this case, that if we are sure that data<br class="">should be aligned no check and warning should be done.<br class=""></blockquote><br class="">Would you be OK with a check and warning under #ifndef NDEBUG (like an<br class="">assert).<br class=""><br class=""><blockquote type="cite" class="">I'm really sure no architecture on hearth can do check and print in<br class="">a single machine instruction.<br class=""></blockquote><br class="">This is not what I said. I said that the cost in the likely case was one<br class="">extra instruction.<br class=""><br class=""><blockquote type="cite" class="">Actually I don't know any architecture<br class="">where a single check like this can be done in a single instruction.<br class=""></blockquote><br class="">Reduced source code: <a href="https://pastebin.com/ibZEVThA" class="">https://pastebin.com/ibZEVThA</a>.<br class=""><br class="">Machine code for x86 with clang: <a href="https://pastebin.com/Vmtwpkhf" class="">https://pastebin.com/Vmtwpkhf</a><br class=""><br class="">The test follows the call to malloc. It’s a single “testb” instruction<br class="">followed by a never-taken conditional jump to cold-code. I am not positive,<br class="">but I’m pretty sure all recent x86 architectures execute this combination in<br class="">a single cycle under nominal conditions. So two additional instructions in<br class="">the hot code path, one of them (the jump) normally never executed.<br class=""><br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Yes, 1+1 == 2 so that's 2 instructions not counting the print.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">The jump is always executed, just not taken.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Not many processors implements speculative execution so there's</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">a penalty on the jump preventing following instructions to be</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">executed.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div><div>There, I disagree. All recent CPUs have branch prediction, and in that case, we have a “statically not taken” branch if there is no history, and a strongly not taken if there is history.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Beside these quite paranoid consideration my point is simple</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">that in different cases we know this is SURELY to never happen</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">and I don't see the point of doing the check at all.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Our current platforms don't have much issues with unaligned</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">memory </span></div></div></blockquote><div><br class=""></div><div>I actually checked that. It’s true. x86 seems to have zero penalty. It looks like recent ARM chips also support misaligned. I have old chips at home ;-)</div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">but the compiler is currently helping porting spice-gtk</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">to platforms with more strongly alignment issues so I don't</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">think is wasted time to fix properly these problems to avoid</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">alignment issues in the possible future.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-converted-space"> </span>    movl    $27, %edi<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-converted-space"> </span>    callq   _malloc<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-converted-space"> </span> <br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-converted-space"> </span>## A single instruction to test<br class=""><span class="Apple-tab-span" style="white-space: pre;">       </span><span class="Apple-converted-space"> </span>    testb   $7, %al<br class=""><span class="Apple-tab-span" style="white-space: pre;">     </span><span class="Apple-converted-space"> </span> <br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">did you notice the bug in the macro?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">You are aligning on the pointer, not to the int type.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div><br class=""></div><div>No, I had not noticed. Very good catch. So no-ack ;-)</div><div><br class=""></div><div>Christophe</div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-converted-space"> </span>## Fall through jump not taken, cost presumably 0 cycles<br class=""><span class="Apple-tab-span" style="white-space: pre;">      </span><span class="Apple-converted-space"> </span>    jne LBB2_1<br class=""><span class="Apple-tab-span" style="white-space: pre;">    </span><span class="Apple-converted-space"> </span>LBB2_2:<br class=""><br class=""><br class="">Christophe<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">@@ -364,7 +364,7 @@ static display_cursor *set_cursor(SpiceChannel<br class="">*channel,<br class="">SpiceCursor *scursor)<br class="">       for (i = 0; i < hdr->width * hdr->height; i++) {<br class="">           pix_mask = get_pix_mask(data, size + (sizeof(uint32_t) << 4),<br class="">           i);<br class="">           int idx = (i & 1) ? (data[i >> 1] & 0x0f) : ((data[i >> 1] &<br class="">           0xf0) >> 4);<br class="">-            pix = *((uint32_t*)(data + size) + idx);<br class="">+            pix = *(SPICE_UNALIGNED_CAST(uint32_t*,(data + size)) + idx);<br class="">           if (pix_mask && pix == 0xffffff) {<br class="">               cursor->data[i] = get_pix_hack(i, hdr->width);<br class="">           } else {<br class="">diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c<br class="">index 3ae9d21..17c0f4f 100644<br class="">--- a/src/channel-display-mjpeg.c<br class="">+++ b/src/channel-display-mjpeg.c<br class="">@@ -151,7 +151,7 @@ static gboolean mjpeg_decoder_decode_frame(gpointer<br class="">video_decoder)<br class="">#ifndef JCS_EXTENSIONS<br class="">       {<br class="">           uint8_t *s = lines[0];<br class="">-            uint32_t *d = (uint32_t *)s;<br class="">+            uint32_t *d = SPICE_ALIGNED_CAST(uint32_t *,s);<br class=""><br class="">           if (back_compat) {<br class="">               for (unsigned int j = lines_read * width; j > 0; ) {<br class="">diff --git a/src/decode-glz-tmpl.c b/src/decode-glz-tmpl.c<br class="">index b337a8b..7695a28 100644<br class="">--- a/src/decode-glz-tmpl.c<br class="">+++ b/src/decode-glz-tmpl.c<br class="">@@ -178,7 +178,7 @@ static size_t FNAME(decode)(SpiceGlzDecoderWindow<br class="">*window,<br class="">                           uint64_t image_id, SpicePalette *plt)<br class="">{<br class="">   uint8_t      *ip = in_buf;<br class="">-    OUT_PIXEL    *out_pix_buf = (OUT_PIXEL *)out_buf;<br class="">+    OUT_PIXEL    *out_pix_buf = SPICE_ALIGNED_CAST(OUT_PIXEL *,out_buf);<br class="">   OUT_PIXEL    *op = out_pix_buf;<br class="">   OUT_PIXEL    *op_limit = out_pix_buf + size;<br class=""><br class=""></blockquote><br class="">This is safe too. 16 byte and 32 byte images must be aligned and 24 and 8<br class="">bit<br class="">are surely aligned (to byte).<br class=""><br class=""><blockquote type="cite" class="">diff --git a/src/spice-channel.c b/src/spice-channel.c<br class="">index 3b6231e..88d0567 100644<br class="">--- a/src/spice-channel.c<br class="">+++ b/src/spice-channel.c<br class="">@@ -1312,6 +1312,7 @@ static void spice_channel_send_link(SpiceChannel<br class="">*channel)<br class="">{<br class="">   SpiceChannelPrivate *c = channel->priv;<br class="">   uint8_t *buffer, *p;<br class="">+    uint32_t *p32;<br class="">   int protocol, i;<br class=""><br class="">   c->link_hdr.magic = SPICE_MAGIC;<br class="">@@ -1356,14 +1357,15 @@ static void spice_channel_send_link(SpiceChannel<br class="">*channel)<br class="">   memcpy(p, &c->link_hdr, sizeof(c->link_hdr)); p +=<br class="">   sizeof(c->link_hdr);<br class="">   memcpy(p, &c->link_msg, sizeof(c->link_msg)); p +=<br class="">   sizeof(c->link_msg);<br class=""><br class="">+    // Need this to avoid error with -Wcast-align<br class="">+    p32 = SPICE_UNALIGNED_CAST(uint32_t *,p);<br class="">   for (i = 0; i < c->common_caps->len; i++) {<br class="">-        *(uint32_t *)p = GUINT32_TO_LE(g_array_index(c->common_caps,<br class="">uint32_t, i));<br class="">-        p += sizeof(uint32_t);<br class="">+        *p32++ = GUINT32_TO_LE(g_array_index(c->common_caps, uint32_t,<br class="">i));<br class="">   }<br class="">   for (i = 0; i < c->caps->len; i++) {<br class="">-        *(uint32_t *)p = GUINT32_TO_LE(g_array_index(c->caps, uint32_t,<br class="">i));<br class="">-        p += sizeof(uint32_t);<br class="">+        *p32++ = GUINT32_TO_LE(g_array_index(c->caps, uint32_t, i));<br class="">   }<br class="">+    p = (uint8_t *) p32;<br class="">   CHANNEL_DEBUG(channel, "channel type %d id %d num common caps %u num<br class="">   caps %u",<br class="">                 c->channel_type,<br class="">                 c->channel_id,<br class="">@@ -1887,6 +1889,7 @@ static gboolean<br class="">spice_channel_recv_link_msg(SpiceChannel *channel)<br class="">   SpiceChannelPrivate *c;<br class="">   int rc, num_caps, i;<br class="">   uint32_t *caps, num_channel_caps, num_common_caps;<br class="">+    uint8_t *caps_src;<br class="">   SpiceChannelEvent event = SPICE_CHANNEL_ERROR_LINK;<br class=""><br class="">   g_return_val_if_fail(channel != NULL, FALSE);<br class="">@@ -1926,7 +1929,8 @@ static gboolean<br class="">spice_channel_recv_link_msg(SpiceChannel *channel)<br class="">   /* see original spice/client code: */<br class="">   /* g_return_if_fail(c->peer_msg + c->peer_msg->caps_offset *<br class="">   sizeof(uint32_t) > c->peer_msg + c->peer_hdr.size); */<br class=""><br class="">-    caps = (uint32_t *)((uint8_t *)c->peer_msg +<br class="">GUINT32_FROM_LE(c->peer_msg->caps_offset));<br class="">+    caps_src = (uint8_t *)c->peer_msg +<br class="">GUINT32_FROM_LE(c->peer_msg->caps_offset);<br class="">+    caps = SPICE_UNALIGNED_CAST(uint32_t *, caps_src);<br class=""><br class="">   g_array_set_size(c->remote_common_caps, num_common_caps);<br class="">   for (i = 0; i < num_common_caps; i++, caps++) {<br class=""></blockquote><br class="">Also you should merge style changes from 5/5.</blockquote></blockquote></div></div></blockquote></div><br class=""></body></html>