Re: 64-bit alignment problems.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Andy Fiddaman wrote:
On Mon, 17 Sep 2007, Ken Murchison wrote:
; Good point.  I'm wondering if we need the struct at all, and can just use a
; union.

You're right, I've just tested the following and it works fine:

#define ALIGNBUF(buf, size) \
        union { \
            bit64 align8; \
            char buf[(size)]; \
        } align8buf; \
        char *buf = align8buf.buf


I didn't like the way that the macro looked in the code, so I just typedef'd it instead. Here is my current patch. If it works, I'll commit it.


--
Kenneth Murchison
Systems Programmer
Project Cyrus Developer/Maintainer
Carnegie Mellon University
Index: annotate.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/annotate.c,v
retrieving revision 1.37
diff -u -r1.37 annotate.c
--- annotate.c	5 Sep 2007 17:26:26 -0000	1.37
+++ annotate.c	17 Sep 2007 17:44:56 -0000
@@ -306,11 +306,12 @@
 static int split_attribs(const char *data, int datalen __attribute__((unused)),
 			 struct annotation_data *attrib)
 {
-    unsigned long tmp;
+    unsigned long tmp; /* for alignment */
 
     /* xxx use datalen? */
     /* xxx sanity check the data? */
-    attrib->size = (size_t) ntohl(*(unsigned long *) data);
+    memcpy(&tmp, data, sizeof(unsigned long));
+    attrib->size = (size_t) ntohl(tmp);
     data += sizeof(unsigned long); /* skip to value */
 
     attrib->value = data;
Index: mailbox.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/mailbox.c,v
retrieving revision 1.170
diff -u -r1.170 mailbox.c
--- mailbox.c	13 Sep 2007 20:49:53 -0000	1.170
+++ mailbox.c	17 Sep 2007 17:44:57 -0000
@@ -1291,8 +1291,9 @@
  */
 int mailbox_write_index_header(struct mailbox *mailbox)
 {
-    char buf[INDEX_HEADER_SIZE];
-    unsigned long header_size = sizeof(buf);
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf;
+    unsigned long header_size = INDEX_HEADER_SIZE;
     int n;
     
     assert(mailbox->index_lock_count != 0);
@@ -1396,7 +1397,8 @@
 			   int sync)
 {
     int n;
-    char buf[INDEX_RECORD_SIZE];
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf;
 
     mailbox_index_record_to_buf(record, buf);
 
@@ -1530,9 +1532,8 @@
     unsigned long exists;
     unsigned msgno;
     bit32 oldstart_offset, oldrecord_size, recsize_diff;
-    char buf[INDEX_HEADER_SIZE > INDEX_RECORD_SIZE ?
-	     INDEX_HEADER_SIZE : INDEX_RECORD_SIZE];
-    char *bufp;
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf, *bufp;
     int quota_offset = 0;
     int calculate_flagcounts = 0;
     bit32 numansweredflag = 0;
@@ -1859,8 +1860,8 @@
 			   mailbox_decideproc_t *decideproc, void *deciderock,
 			   int expunge_flags)
 {
-    char buf[INDEX_HEADER_SIZE > INDEX_RECORD_SIZE ?
-	     INDEX_HEADER_SIZE : INDEX_RECORD_SIZE];
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf;
     unsigned msgno;
     unsigned newexpunged;
     unsigned newexists;
@@ -2052,8 +2053,8 @@
     unsigned newanswered;
     unsigned newflagged; 
     
-    char buf[INDEX_HEADER_SIZE > INDEX_RECORD_SIZE ?
-	     INDEX_HEADER_SIZE : INDEX_RECORD_SIZE];
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf;
     unsigned msgno;
     struct stat sbuf;
     struct txn *tid = NULL;
Index: mailbox.h
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/mailbox.h,v
retrieving revision 1.84
diff -u -r1.84 mailbox.h
--- mailbox.h	5 Sep 2007 17:26:27 -0000	1.84
+++ mailbox.h	17 Sep 2007 17:44:57 -0000
@@ -267,6 +267,17 @@
 extern const struct mailbox_header_cache mailbox_cache_headers[];
 extern const int MAILBOX_NUM_CACHE_HEADERS;
 
+/* Aligned buffer for manipulating index header/record fields */
+typedef union {
+    char buf[INDEX_HEADER_SIZE > INDEX_RECORD_SIZE ?
+	     INDEX_HEADER_SIZE : INDEX_RECORD_SIZE];
+#ifdef HAVE_LONG_LONG_INT
+    bit64 align8; /* align on 8-byte boundary */
+#else
+    bit32 align4; /* align on 4-byte boundary */
+#endif
+} indexbuffer_t;
+
 /* Bitmasks for expunging */
 enum {
     EXPUNGE_FORCE =		(1<<0),
Index: reconstruct.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/reconstruct.c,v
retrieving revision 1.96
diff -u -r1.96 reconstruct.c
--- reconstruct.c	13 Sep 2007 20:21:38 -0000	1.96
+++ reconstruct.c	17 Sep 2007 17:44:57 -0000
@@ -450,8 +450,8 @@
     char newfnamebuf[MAX_MAILBOX_PATH+1];
     struct stat sbuf;
 
-    char buf[((INDEX_HEADER_SIZE > INDEX_RECORD_SIZE) ?
-             INDEX_HEADER_SIZE : INDEX_RECORD_SIZE)];
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf;
 
     int expunge_fd;
     FILE *fexpunge;
@@ -704,8 +704,8 @@
  */
 int reconstruct(char *name, struct discovered *found)
 {
-    char buf[((INDEX_HEADER_SIZE > INDEX_RECORD_SIZE) ?
-	     INDEX_HEADER_SIZE : INDEX_RECORD_SIZE)];
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf;
     char quota_root[MAX_MAILBOX_PATH+1];
     bit32 valid_user_flags[MAX_USER_FLAGS/32];
 
Index: unexpunge.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/unexpunge.c,v
retrieving revision 1.5
diff -u -r1.5 unexpunge.c
--- unexpunge.c	30 Mar 2007 18:40:21 -0000	1.5
+++ unexpunge.c	17 Sep 2007 17:44:57 -0000
@@ -168,8 +168,8 @@
 {
     int r = 0;
     const char *irec;
-    char buf[INDEX_HEADER_SIZE > INDEX_RECORD_SIZE ?
-	     INDEX_HEADER_SIZE : INDEX_RECORD_SIZE];
+    indexbuffer_t ibuf;
+    char *buf = ibuf.buf;
     char *path, fnamebuf[MAX_MAILBOX_PATH+1], fnamebufnew[MAX_MAILBOX_PATH+1];
     FILE *newindex = NULL, *newexpungeindex = NULL;
     unsigned emsgno, imsgno;
----
Cyrus Home Page: http://cyrusimap.web.cmu.edu/
Cyrus Wiki/FAQ: http://cyrusimap.web.cmu.edu/twiki
List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html

[Index of Archives]     [Cyrus SASL]     [Squirrel Mail]     [Asterisk PBX]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [KDE]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux