【发布时间】:2011-07-04 10:03:57
【问题描述】:
我必须将源代码移植到运行 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 on 可使 Linux 内核修复问题,但应用程序的性能下降到无法再接受的程度。
我在网上搜索了类似 __unaligned 或 __packed 关键字的 GCC (v4.4.1) 编译器,但到目前为止还没有找到。
我认为可以通过或多或少复杂的正则表达式/替换来修复许多有问题的代码行,但现在,在这样做了一段时间后,我发现这种方法也需要大量繁琐的工作。
你们对如何完成这项工作有什么建议吗?我认为 gcc 4.5 编译器插件会有点矫枉过正,但有什么比正则表达式更好的吗?你还能提出什么其他建议?不一定要修复所有问题实例,因为在少数情况下我仍然可以依赖内核。
【问题讨论】:
-
我很想开玩笑说这应该转移到 TheDailyWTF.com。
-
继续我们对现代语言学的研究,这里我们有一个嵌入式程序员常用的 C 方言样本。大致翻译成英文,上面的文字意思是“F *** YOU!”,尽管没有任何自然语言能真正表达出这里所传达的怨恨、对所有神圣事物的蔑视以及对读者人性的普遍漠视。