changeset 791:42fa209a8cc4

Attempt at fixing unaligned 64b direct memory access (sigbus on sparc)
author Sebastien Decugis <sdecugis@nict.go.jp>
date Thu, 12 Jul 2012 22:31:20 +0200
parents b38384733ad2
children 0f566e550813
files libfdproto/messages.c
diffstat 1 files changed, 16 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/libfdproto/messages.c	Tue Jul 03 08:17:27 2012 +0200
+++ b/libfdproto/messages.c	Thu Jul 12 22:31:20 2012 +0200
@@ -1322,8 +1322,12 @@
 #define PUT_in_buf_32( _u32data, _bufptr ) {							\
 	*(uint32_t *)(_bufptr) = htonl((uint32_t)(_u32data));					\
 }
+
+/* The location is not on 64b boundary, so we split the writing in two operations to avoid sigbus */
 #define PUT_in_buf_64( _u64data, _bufptr ) {							\
-	*(uint64_t *)(_bufptr) = htonll((uint64_t)(_u64data));					\
+	uint64_t __v = htonll((uint64_t)(_u64data));						\
+	*(uint32_t *)(_bufptr) = (uint32_t)(__v);						\
+	*(((uint32_t *)(_bufptr))+1) = (uint32_t)(__v >> 32);					\
 }
 
 /* Write a message header in the buffer */
@@ -1773,7 +1777,12 @@
 			break;
 	
 		case AVP_TYPE_INTEGER64:
-			avp->avp_storage.i64 = (int64_t)ntohll(*(uint64_t *)avp->avp_source);
+			/* the storage might not be aligned on 64b boundary, so no direct indirection here is possible */
+			{
+				uint64_t __stor;
+				memcpy(&__stor, avp->avp_source, sizeof(__stor));
+				avp->avp_storage.i64 = (int64_t)ntohll(__stor);
+			}
 			break;
 	
 		case AVP_TYPE_UNSIGNED32:
@@ -1783,7 +1792,11 @@
 	
 		case AVP_TYPE_UNSIGNED64:
 		case AVP_TYPE_FLOAT64: /* same as 32 bits */
-			avp->avp_storage.u64 = (uint64_t)ntohll(*(uint64_t *)avp->avp_source);
+			{
+				uint64_t __stor;
+				memcpy(&__stor, avp->avp_source, sizeof(__stor));
+				avp->avp_storage.u64 = (uint64_t)ntohll(__stor);
+			}
 			break;
 	
 	}
"Welcome to our mercurial repository"