I have to port source code from to an ARM platform that runs Linux. Unfortunately I have run into unaligned memory access problems. The source uses pointer casts and access heavily.
Code like the one below has spread over the codebase like a virus. I can pinpoint the problematic locations thanks to the gcc -Wcast-align
command line option but there are over a thousand instances to go through.
u = (IEC_BOOL);
(((*(IEC_LINT*)pSP).H < b.H)
|| (((*(IEC_LINT*)pSP).H == b.H) && ((*(IEC_LINT*)pSP).L < b.L) )) ? 1 : 0);
*(IEC_DWORD OS_SPTR *)pSP =
(IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP >> u);
*(IEC_DWORD OS_SPTR *)pSP =
(IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP << -u);
u = (IEC_BYTE)((*(IEC_DINT*)pSP != b) ? 1 : 0);
*(IEC_DWORD*)pSP = (IEC_DWORD)(*(IEC_DWORD*)pSP & w);
(*(IEC_ULINT*)pSP).H += u.H;
(((*(IEC_ULINT OS_SPTR *)pSP).H == b.H)
&& ((*(IEC_ULINT OS_SPTR *)pSP).L > b.L))) ? 1 : 0);
u = (IEC_BYTE)((*(IEC_REAL*)pSP >= b) ? 1 : 0);
Using echo 2 > /proc/cpu/alignment
on makes the Linux Kernel fix the problems but the performance of the application is degraded to a point that is not acceptable any more.
I searched the net for something like a __unaligned
or __packed
keyword for the GCC (v4.4.1) compiler but as of yet came up empty.
I thought a lot of the poblematic code lines could be fixed with a more or less complex regexp/replace but now, after doing that for a while I see, that also this approach will take enourmous amounts of tedious work.
Do you guys have any suggestion how to get this job done? I think a gcc 4.5 compiler plugin would be overkill but is there something better than regular expressions? what other suggestions can you come up with? Not necessarily all problem instances have to be fixed since I can still rely on the Kernel for a few rarer cases.