alignment issues in wrc on solaris

Warren_Baird at cimmetry.com Warren_Baird at cimmetry.com
Fri May 3 11:15:37 CDT 2002



ChangeLog:

  - solve alignment problems by converting bitmap headers *after*
    they have been copied into an aligned location, and then copying
    the converted header back over the original header

Wordier Description:


This patch solves some alignment issuse in the wrc convert_bitmap
code.  In several places the bitmap information headers were being
modified in place, and then copied to their final resting place.
Unfortunately this causes bus errors on solaris, since the original
location of the bitmap headers isn't 4-byte aligned.

The patch memcopies the headers into their new location, performs the
conversion there, and then memcopies the converted headers back over
the original location.

This could have been ifdef'd to only happen on platforms that need
alignment, but it seems to me that the performance impact of this
should be very minor, and the readability impact of having yet more
ifdef's floating around seems worse and I verified that it does work on
x86 linux.

Warren Baird : Warren_Baird at cimmetry.com


--- wine-clean/tools/wrc/newstruc.c      Sat Mar  9 19:24:24 2002
+++ wine-current/tools/wrc/newstruc.c    Fri May  3 11:16:24 2002
@@ -228,6 +228,7 @@
     BITMAPINFOHEADER *bih = (BITMAPINFOHEADER *)data;
     BITMAPV4HEADER *b4h = (BITMAPV4HEADER *)data;
     int type = 0;
+    int returnSize = 0;           /* size to be returned */
 #ifdef WORDS_BIGENDIAN
     DWORD bisizel = BYTESWAP_DWORD(sizeof(BITMAPINFOHEADER));
     DWORD b4sizel = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
@@ -240,17 +241,24 @@
     DWORD b4sizeb = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
 #endif

+
+    /*
+     * Originally the bih and b4h pointers were simply incremented here,
+     * and memmoved at the end of the function.  This causes alignment
+     * issues on solaris, so we do the memmove here rather than at the end.
+     */
     if(data[0] == 'B' && data[1] == 'M')
     {
          /* Little endian signature */
-         bih = (BITMAPINFOHEADER *)(data + sizeof(BITMAPFILEHEADER));
-         b4h = (BITMAPV4HEADER *)(data + sizeof(BITMAPFILEHEADER));
+         memmove(data, data+sizeof(BITMAPFILEHEADER), size -
sizeof(BITMAPFILEHEADER));
+         returnSize = sizeof(BITMAPFILEHEADER);
     }
     else if(data[0] == 'M' && data[1] == 'B')
     {
          type |= FL_SIGBE;   /* Big endian signature */
-         bih = (BITMAPINFOHEADER *)(data + sizeof(BITMAPFILEHEADER));
-         b4h = (BITMAPV4HEADER *)(data + sizeof(BITMAPFILEHEADER));
+         memmove(data, data+sizeof(BITMAPFILEHEADER), size -
sizeof(BITMAPFILEHEADER));
+         returnSize = sizeof(BITMAPFILEHEADER);
+
     }

     if(bih->biSize == bisizel)
@@ -323,7 +331,7 @@
          memmove(data, data+sizeof(BITMAPFILEHEADER), size -
sizeof(BITMAPFILEHEADER));
          return sizeof(BITMAPFILEHEADER);
     }
-    return 0;
+    return returnSize;
 }
 #undef FL_SIGBE
 #undef FL_SIZEBE
@@ -423,8 +431,10 @@
          ico->nclr = ide.nclr;
          ico->planes = swap ? BYTESWAP_WORD(ide.planes) : ide.planes;
          ico->bits = swap ? BYTESWAP_WORD(ide.bits) : ide.bits;
-         convert_bitmap((char *)rd->data + ide.offset, 0);
          memcpy(&info, rd->data + ide.offset, sizeof(info));
+         convert_bitmap((char *) &info, 0);
+         memcpy(rd->data + ide.offset, &info, sizeof(info));
+
          if(!ico->planes)
          {
               /* Argh! They did not fill out the resdir structure */
@@ -513,8 +523,9 @@
          cur->width = cde.width;
          cur->height = cde.height;
          cur->nclr = cde.nclr;
-         convert_bitmap((char *)rd->data + cde.offset, 0);
          memcpy(&info, rd->data + cde.offset, sizeof(info));
+         convert_bitmap((char *)&info, 0);
+         memcpy(rd->data + cde.offset, &info, sizeof(info));
          /* The bitmap is in destination byteorder. We want native for our
structures */
          switch(byteorder)
          {





More information about the wine-patches mailing list