我有一个为特定(嵌入式、多处理器、32 位)架构编写的 Ada 程序。我尝试在 64 位 RHEL 上的模拟中使用相同的代码作为共享对象(因为有多个版本,并且我需要在运行时选择一个版本)。
我遇到的问题是代码中的几个地方编写代码的人(不是我...)使用 Unchecked_Conversions 将 System.Addresses 转换为 32 位整数。不仅如此,还有多个带有硬编码内存地址的例程。我可以对此代码进行微小的更改,但将其完全移植到 x86_64 并不是一个真正的选择。有处理中断、CPU 任务调度等的例程。
该代码过去在静态链接到以前版本的模拟(由 Fortran/C/C++ 组成)时运行良好。然而现在,主可执行文件启动,然后根据一些输入加载共享对象。然后,该共享对象检查其他一些输入并加载适当的 Ada 共享对象。
查看代码,很明显,如果我可以将逻辑内存地址保持在 0 到 2,147,483,647(32 位有符号整数)之间,它应该可以正常工作。有没有办法强制共享对象加载器在较低范围内为 Ada 代码留出空间,或者让 Ada 代码“认为”它的地址在 0 到 2,147,483,647 之间?
有没有办法强制共享对象加载器在较低范围内为 Ada 代码留出空间
好消息是装载机将保持较低的范围不变。
坏消息是它不会在那里加载任何共享对象。没有可用于影响共享对象放置的界面。
也就是说,从内存中 dlopen https://sourceware.org/bugzilla/show_bug.cgi?id=11767(我们在 glibc 的私有分支中实现)将允许您做到这一点。但这是不公开的。
您的其他可能的选择是:
如果您可以将整个过程放入 32 位地址空间,那么您的解决方案就很简单:只需使用-m32
.
use prelink
将图书馆重新定位到所需的地址。由于该地址几乎总是可用的,因此加载器很可能将库准确地加载到那里。
将加载程序与自定义链接mmap
实现,它通过某种侧通道检测感兴趣的库,并执行mmap
系统调用与MAP_32BIT
set, or
- 在 a 中运行该程序
ptrace
沙箱。这样的沙箱可以再次拦截mmap
系统调用和 or-inMAP_32BIT
当需要时。
或者也许让 Ada 代码“认为”它的地址在 0 到 2,147,483,647 之间?
我不明白这怎么可能。如果库将函数或全局的地址存储在 32 位内存位置,然后加载该地址并取消引用它......它将获得一个 32 位截断地址和一个SIGSEGV
关于取消引用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)