avr-gcc-list
[Top][All Lists]
Advanced

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

Re: [avr-gcc-list] Re: C aliasing rules


From: Bernard Fouché
Subject: Re: [avr-gcc-list] Re: C aliasing rules
Date: Wed, 19 May 2010 17:06:25 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.1.9) Gecko/20100317 Lightning/1.0b1 Thunderbird/3.0.4

Hi Lars.

I don't understand what 'tmpbuf' is declared 'static'. And what do you mean by 'broken'? In your example, main() calls functions by providing pointers to uninitialized data located in the stack. Having functions being inlined completely changes the stack usage. Maybe your program should be 'broken' from the beginning :-)

    Bernard

Le 19/05/2010 14:10, Lars Noschinski a écrit :
Hello!

* David Brown<address@hidden>  [10-05-18 21:01]:

Thanks for your answer, David.

Lars Noschinski wrote:
I'm trying to debug a strange problem, which depends on whether a
function is inlined (then it's broken) or not (then it's ok). Can
someone tell me if the following code snippet violates the C aliasing
rules for b1 (declared as uint8_t*, written as uint32_t* by
xteaDecrypt)?
[...]
It's not impossible that this is a bug when inlining such complex
code (and 32-bit code like this is complex on an 8-bit micro).  It's
difficult to tell without a compilable code snippet, and some
indication of the expected results.  If you can, you should look at
the generated assembly to see if you can figure out what is going
wrong.  Also try to simplify or remove parts of the code until you
have a minimal example of the problem.

While it would be useful to find out about the problem (especially
if it is a bug that is not already known), code like this does not
benefit much from being inlined.  It's too complex, and requires too
many registers - the function call overhead is therefore minimal.
You could improve the results somewhat by manual restructuring
(perhaps eliminating the memcpy calls), but unless XTEA_ROUNDS is
very small, the loop there will dominate everything.
XTEA_ROUNDS is 32 and this code is far from being performance critical,
but code breaking with optimization always makes me nervous ;)

Reading more about strict aliasing issues, especially

     
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
     http://davmac.wordpress.com/2010/02/26/c99-revisited/

I'm fairly sure, that accessing a uint8_t[] via a uint32_t* constitutes
undefined behaviour; the same holds for converting the pointer by use of an
union { uint32_t[2]; uint8_t[8] }; by the gcc (4.3.4) documentation for
-fstrict-aliasing:

|     Similarly, access by taking the address, casting the resulting
|     pointer and dereferencing the result has undefined behavior, even
|     if the cast uses a union type, e.g.:
|          int f() {
|            double d = 3.0;
|            return ((union a_union *)&d)->i;
|          }

So it seems the only correct way is either changing the declaration of
xteaDecryptCbc (i.e. use uint32_t from the beginning) or using memcpy.
Or maybe some playing around with __attribute__((may_alias)).

OTOH, this problem also occurs with -fno-strict-aliasing, so maybe there
is some real bug down there in the compiler. I'll try analyising it
later.

If I read http://mail-index.netbsd.org/tech-kern/2003/08/11/0001.html
correctly, it should violate the rules?

// ---------------------------------------------------------------------------
void xteaDecrypt(uint32_t v[2], uint32_t const k[4]) {
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*XTEA_ROUNDS;
    for (uint8_t i=0; i<  XTEA_ROUNDS; i++) {
        v1 -= (((v0<<  4) ^ (v0>>  5)) + v0) ^ (sum + k[(sum>>11)&  3]);
        sum -= delta;
        v0 -= (((v1<<  4) ^ (v1>>  5)) + v1) ^ (sum + k[sum&  3]);
    }
    v[0]=v0; v[1]=v1;
}

void xteaDecryptCbc(uint8_t v[8], uint8_t cb[8], uint8_t const k[16]) {
    static uint8_t tmpbuf[8];
    memcpy(tmpbuf, v, 8);
    xteaDecrypt((uint32_t*)v, (uint32_t*)k);
    for (uint8_t i=0; i<  8; i++)
        v[i] ^= cb[i];
    memcpy(cb, tmpbuf, 8);
}

int main(void) {
    uint8_t b1[8], b2[8], b3[16];
    xteaDecryptCbc(b1, b2 b3);
}
// ---------------------------------------------------------------------------
   -- Lars

_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list




reply via email to

[Prev in Thread] Current Thread [Next in Thread]