Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2013 06:51:19 -0600
From:      Ian Lepore <ian@FreeBSD.org>
To:        Michael Tuexen <tuexen@FreeBSD.org>
Cc:        freebsd-arm@FreeBSD.org
Subject:   Re: A simple question about C...
Message-ID:  <1378212679.1111.366.camel@revolution.hippie.lan>
In-Reply-To: <DA4B80F8-E42F-4230-BD45-929CE92F1098@freebsd.org>
References:  <DA4B80F8-E42F-4230-BD45-929CE92F1098@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 2013-09-03 at 14:31 +0200, Michael Tuexen wrote:
> Dear all,
> 
> I'm trying to get a C program (packetdrill) running FreeBSD r254973
> on a Raspberry Pi.
> Since tests are failing, I wrote the little C program:
> 
> #include <stdint.h>
> #include <stdio.h>
> #include <string.h>
> 
> int
> main(void)
> {
>         uint8_t byte[] = {0x00, 0x01, 0x02, 0x03,
>                           0x04, 0x05, 0x06, 0x07,
>                           0x08, 0x09, 0x0a, 0x0b};
>         uint32_t i, n, *p;
> 
>         for (i = 0; i <= 8; i++) {
>                 p = (uint32_t *)(byte + i);
>                 memcpy(&n, byte + i, sizeof(uint32_t));
>                 printf("p = %p, *p = %08x, n = %08x.\n", (void *)p, *p, n);
>         }
>         return (0);
> }
> 
> It produces the following output:
> 
> p = 0xbfffec48, *p = 03020100, n = 03020100.
> p = 0xbfffec49, *p = 00030201, n = 04030201.
> p = 0xbfffec4a, *p = 01000302, n = 05040302.
> p = 0xbfffec4b, *p = 02010003, n = 06050403.
> p = 0xbfffec4c, *p = 07060504, n = 07060504.
> p = 0xbfffec4d, *p = 04070605, n = 08070605.
> p = 0xbfffec4e, *p = 05040706, n = 09080706.
> p = 0xbfffec4f, *p = 06050407, n = 0a090807.
> p = 0xbfffec50, *p = 0b0a0908, n = 0b0a0908.
> 
> So everything is fine when reading the 4 byte long uint32_t on a 4-byte aligned
> address. Results are strange (at least for me), when the address is not 4-byte
> aligned. There is no difference between clang and gcc. Can I only dereference
> properly aligned pointers? Is the above expected or is it a bug in the compiler?
> 
> Best regards
> Michael

Yes, you can only safely dereference pointers aligned to the size of the
dereference (2, 4, 8 bytes).  On some ARM platforms a misaligned
reference leads to alignment fault, on others the data is rotated in
some predefined way, and on some it's just "undefined behavior."

There are functions in endian.h to help with the alignment, in
particular the leNNdec() and leNNenc() functions are designed to be
alignment-agnostic.

-- Ian





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1378212679.1111.366.camel>