ARM未对齐的内存访问解决方法

我必须将源代码移植到运行Linux的ARM平台。 不幸的是,我遇到了未对齐的内存访问问题。 源使用指针强制转换和访问。

像下面这样的代码像病毒一样遍布代码库。 由于gcc -Wcast-align命令行选项,我可以查明有问题的位置,但是有超过一千个实例要经历。

 u = (IEC_BOOL); (((*(IEC_LINT*)pSP).H < bH) || (((*(IEC_LINT*)pSP).H == bH) && ((*(IEC_LINT*)pSP).L > u); *(IEC_DWORD OS_SPTR *)pSP = (IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP < bL))) ? 1 : 0); u = (IEC_BYTE)((*(IEC_REAL*)pSP >= b) ? 1 : 0); 

使用echo 2 > /proc/cpu/alignment on会使Linux内核修复问题,但应用程序的性能会降低到不再可接受的程度。

我在网上搜索了类似于GCC(v4.4.1)编译器的__unaligned__packed关键字,但截至目前为止还是空的。

我认为很多问题的代码行可以通过一个或多或少复杂的正则表达式/替换来修复,但现在,在我做了一段时间之后,我发现,这种方法也需要大量繁琐的工作。

你们有什么建议如何完成这项工作? 我认为一个gcc 4.5编译器插件会有点矫枉过正但是有没有比正则表达式好的东西? 您还能提出哪些其他建议? 不一定所有问题实例都必须修复,因为我仍然可以依赖内核来处理一些罕见的情况。

__attribute__((__packed__))在某些情况下可能会有所帮助,但我认为这段代码应该比以后更早清理,因为你可能会花更多的时间解决问题,而不是修复它。一劳永逸。

哇,这是一个不圣洁的混乱。 摆弄编译器不会让你到处都是。 代码在所有体系结构上都是非法的,但恰好在某些体系结构上工作(例如x86)。 我会修复代码本身。

可悲的是,没有办法做到这一点。 但是,您可以通过一长串搜索和替换获得很长的路要走,然后手动修复其余部分。 我首先删除这些数据类型的声明,所以如果你编译错过了任何代码,那就错了。 然后,搜索和替换“*(IEC_DWORD OS_SPTR *)pSP =”“set_dword(pSP,” 。)使用内联函数“set_dword”来做正确的事情。继续执行尽可能多的易于更换的代码段。你可以想象。仍然有大量的手工修理。

我能想到的唯一另一种方法就是编译器插件,正如你的建议,并使整个编译单元中的每个指针都具有对齐1.然后编译器将字节加载/存储所有内容。 它可能最终会做的不仅仅是你想要的代码。 这可能并不像听起来那么容易实现。

我们可以假设问题源于ARM是32位机器并且Linux盒子以64位模式运行的事实,或者代码可以假设它是在16位机器上运行。

一种方法是查看访问的底层结构。 成员“H”和“L”可能是32位类型,可以像64位一样进行访问。

尝试修改L和H的类型以使代码表现得更好。

(不可否认,这是一个空洞,因为代码片段没有透露应用程序的细节,也没有透露底层结构。)