comparison libfdproto/messages.c @ 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 edbdb35a603f
children 0f566e550813
comparison
equal deleted inserted replaced
790:b38384733ad2 791:42fa209a8cc4
1320 1320
1321 /* Following macros are used to store 32 and 64 bit fields into a buffer in network byte order */ 1321 /* Following macros are used to store 32 and 64 bit fields into a buffer in network byte order */
1322 #define PUT_in_buf_32( _u32data, _bufptr ) { \ 1322 #define PUT_in_buf_32( _u32data, _bufptr ) { \
1323 *(uint32_t *)(_bufptr) = htonl((uint32_t)(_u32data)); \ 1323 *(uint32_t *)(_bufptr) = htonl((uint32_t)(_u32data)); \
1324 } 1324 }
1325
1326 /* The location is not on 64b boundary, so we split the writing in two operations to avoid sigbus */
1325 #define PUT_in_buf_64( _u64data, _bufptr ) { \ 1327 #define PUT_in_buf_64( _u64data, _bufptr ) { \
1326 *(uint64_t *)(_bufptr) = htonll((uint64_t)(_u64data)); \ 1328 uint64_t __v = htonll((uint64_t)(_u64data)); \
1329 *(uint32_t *)(_bufptr) = (uint32_t)(__v); \
1330 *(((uint32_t *)(_bufptr))+1) = (uint32_t)(__v >> 32); \
1327 } 1331 }
1328 1332
1329 /* Write a message header in the buffer */ 1333 /* Write a message header in the buffer */
1330 static int bufferize_msg(unsigned char * buffer, size_t buflen, size_t * offset, struct msg * msg) 1334 static int bufferize_msg(unsigned char * buffer, size_t buflen, size_t * offset, struct msg * msg)
1331 { 1335 {
1771 case AVP_TYPE_INTEGER32: 1775 case AVP_TYPE_INTEGER32:
1772 avp->avp_storage.i32 = (int32_t)ntohl(*(uint32_t *)avp->avp_source); 1776 avp->avp_storage.i32 = (int32_t)ntohl(*(uint32_t *)avp->avp_source);
1773 break; 1777 break;
1774 1778
1775 case AVP_TYPE_INTEGER64: 1779 case AVP_TYPE_INTEGER64:
1776 avp->avp_storage.i64 = (int64_t)ntohll(*(uint64_t *)avp->avp_source); 1780 /* the storage might not be aligned on 64b boundary, so no direct indirection here is possible */
1781 {
1782 uint64_t __stor;
1783 memcpy(&__stor, avp->avp_source, sizeof(__stor));
1784 avp->avp_storage.i64 = (int64_t)ntohll(__stor);
1785 }
1777 break; 1786 break;
1778 1787
1779 case AVP_TYPE_UNSIGNED32: 1788 case AVP_TYPE_UNSIGNED32:
1780 case AVP_TYPE_FLOAT32: /* For float, we must not cast, or the value is changed. Instead we use implicit cast by changing the member of the union */ 1789 case AVP_TYPE_FLOAT32: /* For float, we must not cast, or the value is changed. Instead we use implicit cast by changing the member of the union */
1781 avp->avp_storage.u32 = (uint32_t)ntohl(*(uint32_t *)avp->avp_source); 1790 avp->avp_storage.u32 = (uint32_t)ntohl(*(uint32_t *)avp->avp_source);
1782 break; 1791 break;
1783 1792
1784 case AVP_TYPE_UNSIGNED64: 1793 case AVP_TYPE_UNSIGNED64:
1785 case AVP_TYPE_FLOAT64: /* same as 32 bits */ 1794 case AVP_TYPE_FLOAT64: /* same as 32 bits */
1786 avp->avp_storage.u64 = (uint64_t)ntohll(*(uint64_t *)avp->avp_source); 1795 {
1796 uint64_t __stor;
1797 memcpy(&__stor, avp->avp_source, sizeof(__stor));
1798 avp->avp_storage.u64 = (uint64_t)ntohll(__stor);
1799 }
1787 break; 1800 break;
1788 1801
1789 } 1802 }
1790 1803
1791 /* The value is now set, so set the data pointer and return 0 */ 1804 /* The value is now set, so set the data pointer and return 0 */
"Welcome to our mercurial repository"