|
From: | David Brown |
Subject: | [avr-gcc-list] Re: C aliasing rules |
Date: | Tue, 18 May 2010 21:01:20 +0200 |
User-agent: | Thunderbird 2.0.0.24 (Windows/20100228) |
Lars Noschinski wrote:
Hello! 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)?
On many platforms, casting a pointer to an uint8_t into a pointer to an uint32_t will give you alignment issues - you may end up with inefficient code, code that causes some sort of machine-check exception, or code that appears to work but gives incorrect results. If you have warnings enabled, the compiler will give you warnings about it. (Use __attribute__((aligned(4))) on the uint8_t arrays to fix the alignment for portable code.)
But on an 8-bit device you don't get alignment issues - 32-bit values can have any alignment. So that's not your problem.
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.
mvh., David
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
[Prev in Thread] | Current Thread | [Next in Thread] |