[Olsr-dev] alignment problems on FreeBSD-arm with inbuf and msg_buffer

John Hay (spam-protected)
Mon Mar 23 13:24:18 CET 2009


Hi,

Trying to get the latest 0.5.6 tip working on FreeBSD-current on an ARM
processor, I encountered bus errors which I traced back to the inbuf
and msg_buffer arrays that are non-aligned and cause the bus error as
soon as a 16 bit or 32 bit variable is read or written to it.

I do not understand why I have not encountered it before because it
looks like inbuf and msg_buffer has been like that for some time.
Maybe the compiler changed or the functions used to access those
variables.

My fix was to put the arrays in an union with an int. Is there a
better way?

John
-- 
John Hay -- (spam-protected) / (spam-protected)


--- work/olsrd-0-5-6-ecb9cb41f488/src/parser.c.orig	2009-03-17 23:52:47.000000000 +0200
+++ work/olsrd-0-5-6-ecb9cb41f488/src/parser.c	2009-03-23 14:07:45.000000000 +0200
@@ -75,7 +75,10 @@
 struct preprocessor_function_entry *preprocessor_functions;
 struct packetparser_function_entry *packetparser_functions;
 
-static char inbuf[MAXMESSAGESIZE + 1];
+static union {
+  int alingner;
+  char buf[MAXMESSAGESIZE + 1];
+} inbuf;
 
 static bool disp_pack_in = false;
 
@@ -395,7 +398,7 @@
     }
 
     fromlen = sizeof(struct sockaddr_storage);
-    cc = olsr_recvfrom(fd, inbuf, sizeof(inbuf), 0, (struct sockaddr *)&from, &fromlen);
+    cc = olsr_recvfrom(fd, inbuf.buf, sizeof(inbuf), 0, (struct sockaddr *)&from, &fromlen);
 
     if (cc <= 0) {
       if (cc < 0 && errno != EWOULDBLOCK) {
@@ -414,7 +417,7 @@
 
 #ifdef DEBUG
     OLSR_PRINTF(5, "Recieved a packet from %s\n",
-                olsr_ip_to_string(&buf, (union olsr_ip_addr *)&((struct sockaddr_in *)&from)->sin_addr.s_addr));
+                olsr_ip_to_string(&buf, (union olsr_ip_addr *)&from_addr));
 #endif
 
     if ((olsr_cnf->ip_version == AF_INET) && (fromlen != sizeof(struct sockaddr_in)))
@@ -435,7 +438,7 @@
     }
     // call preprocessors
     entry = preprocessor_functions;
-    packet = &inbuf[0];
+    packet = inbuf.buf;
 
     while (entry) {
       packet = entry->function(packet, olsr_in_if, &from_addr, &cc);
@@ -482,7 +485,7 @@
   int cc = recv(fd, from_addr.v6.s6_addr, olsr_cnf->ipsize, 0);
   if (cc != (int)olsr_cnf->ipsize) {
     fprintf(stderr, "Error receiving host-client IP hook(%d) %s!\n", cc, strerror(errno));
-    memcpy(&from_addr, &((struct olsr *)inbuf)->olsr_msg->originator, olsr_cnf->ipsize);
+    memcpy(&from_addr, &((struct olsr *)inbuf.buf)->olsr_msg->originator, olsr_cnf->ipsize);
   }
 
   /* are we talking to ourselves? */
@@ -503,7 +506,7 @@
 
   fromlen = sizeof(struct sockaddr_storage);
 
-  cc = olsr_recvfrom(fd, inbuf, pcklen, 0, (struct sockaddr *)&from, &fromlen);
+  cc = olsr_recvfrom(fd, inbuf.buf, pcklen, 0, (struct sockaddr *)&from, &fromlen);
 
   if (cc <= 0) {
     if (cc < 0 && errno != EWOULDBLOCK) {
@@ -528,7 +531,7 @@
   }
   // call preprocessors
   entry = preprocessor_functions;
-  packet = &inbuf[0];
+  packet = inbuf.buf;
 
   while (entry) {
     packet = entry->function(packet, olsr_in_if, &from_addr, &cc);
@@ -544,7 +547,7 @@
    * &inbuf.olsr
    * cc - bytes read
    */
-  parse_packet((struct olsr *)inbuf, cc, olsr_in_if, &from_addr);
+  parse_packet((struct olsr *)inbuf.buf, cc, olsr_in_if, &from_addr);
 
 }
 
--- work/olsrd-0-5-6-ecb9cb41f488/src/lq_packet.c.orig	2009-03-17 23:52:47.000000000 +0200
+++ work/olsrd-0-5-6-ecb9cb41f488/src/lq_packet.c	2009-03-23 12:54:18.000000000 +0200
@@ -61,7 +61,10 @@
 
 bool lq_tc_pending = false;
 
-static unsigned char msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
+static union {
+  int aligner;
+  unsigned char buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
+} msgb;
 
 static void
 create_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
@@ -291,7 +294,7 @@
 {
   if (olsr_cnf->ip_version == AF_INET) {
     // serialize an IPv4 OLSR message header
-    struct olsr_header_v4 *olsr_head_v4 = (struct olsr_header_v4 *)msg_buffer;
+    struct olsr_header_v4 *olsr_head_v4 = (struct olsr_header_v4 *)msgb.buffer;
 
     olsr_head_v4->type = comm->type;
     olsr_head_v4->vtime = reltime_to_me(comm->vtime);
@@ -304,7 +307,7 @@
     olsr_head_v4->seqno = htons(get_msg_seqno());
   } else {
     // serialize an IPv6 OLSR message header
-    struct olsr_header_v6 *olsr_head_v6 = (struct olsr_header_v6 *)msg_buffer;
+    struct olsr_header_v6 *olsr_head_v6 = (struct olsr_header_v6 *)msgb.buffer;
 
     olsr_head_v6->type = comm->type;
     olsr_head_v6->vtime = reltime_to_me(comm->vtime);
@@ -334,7 +337,7 @@
 
   // initialize the LQ_HELLO header
 
-  struct lq_hello_header *head = (struct lq_hello_header *)(msg_buffer + off);
+  struct lq_hello_header *head = (struct lq_hello_header *)(msgb.buffer + off);
 
   head->reserved = 0;
   head->htime = reltime_to_me(lq_hello->htime);
@@ -346,7 +349,7 @@
 
   // our work buffer starts at 'off'...
 
-  buff = msg_buffer + off;
+  buff = msgb.buffer + off;
 
   // ... that's why we start with a 'size' of 0 and subtract 'off' from
   // the remaining bytes in the output buffer
@@ -427,7 +430,7 @@
 
           // output packet
 
-          net_outbuffer_push(outif, msg_buffer, size + off);
+          net_outbuffer_push(outif, msgb.buffer, size + off);
 
           net_output(outif);
 
@@ -476,7 +479,7 @@
 
   // move the message to the output buffer
 
-  net_outbuffer_push(outif, msg_buffer, size + off);
+  net_outbuffer_push(outif, msgb.buffer, size + off);
 }
 
 static uint8_t
@@ -525,7 +528,7 @@
 
   // initialize the LQ_TC header
 
-  head = (struct lq_tc_header *)(msg_buffer + off);
+  head = (struct lq_tc_header *)(msgb.buffer + off);
 
   head->ansn = htons(lq_tc->ansn);
   head->lower_border = 0;
@@ -537,7 +540,7 @@
 
   // our work buffer starts at 'off'...
 
-  buff = msg_buffer + off;
+  buff = msgb.buffer + off;
 
   // ... that's why we start with a 'size' of 0 and subtract 'off' from
   // the remaining bytes in the output buffer
@@ -584,7 +587,7 @@
 
       // output packet
 
-      net_outbuffer_push(outif, msg_buffer, size + off);
+      net_outbuffer_push(outif, msgb.buffer, size + off);
 
       net_output(outif);
 
@@ -613,7 +616,7 @@
 
   serialize_common((struct olsr_common *)lq_tc);
 
-  net_outbuffer_push(outif, msg_buffer, size + off);
+  net_outbuffer_push(outif, msgb.buffer, size + off);
 }
 
 void




More information about the Olsr-dev mailing list