繁体   English   中英

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

[英]ARM unaligned memory access workaround

我必须将源代码移植到运行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内核修复问题,但应用程序的性能会降低到不再可接受的程度。

我在网上搜索了类似于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的类型以使代码表现得更好。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM