我需要将源代码移植到运行Linux的ARM平台上。不幸的是,我遇到了未对齐内存访问的问题。源代码使用指针转换和访问非常频繁。
像下面这样的代码在整个代码库中广泛传播,就像一种病毒。我可以通过gcc命令行选项-Wcast-align
找到问题出现的位置,但是有超过一千个实例需要处理。
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);
使用 echo 2 > /proc/cpu/alignment
命令可以让Linux内核解决问题,但应用程序的性能会降低到无法接受的程度。
我在网上搜索了像GCC(v4.4.1)编译器中的__unaligned
或__packed
关键字之类的东西,但目前还没有找到。
我认为一些有问题的代码行可以通过更多或更少复杂的正则表达式/替换来修复,但是现在,经过一段时间的努力后,我发现这种方法也需要大量枯燥无味的工作量。
你们有任何建议如何完成这项工作吗?我觉得gcc 4.5编译器插件可能有点过头了,但除了正则表达式还有更好的建议吗?并不是所有的问题实例都必须被修复,因为我仍然可以依靠内核处理一些更罕见的情况。