是否可以强制使用一系列虚拟地址?

时间:2015-04-29 15:48:06

标签: linux memory linker shared-libraries ada

我有一个为特定(嵌入式,多处理器,32位)架构编写的Ada程序。我试图在64位RHEL的模拟中使用相同的代码作为共享对象(因为有多个版本,我需要在运行时选择一个版本)。

我遇到的问题是代码中有几个地方,编写它的人(不是我......)使用Unchecked_Conversions将System.Addresses转换为32位整数。不仅如此,还有多个具有硬编码内存地址的例程。我可以对此代码进行微小的更改,但完全将其移植到x86_64并不是一个真正的选择。有一些例程可以处理中断,CPU任务调度等。

此代码在过去运行良好时,它静态链接到先前版本的模拟(由Fortran / C / C ++组成)。但是,现在,主可执行文件启动,然后根据某些输入加载共享对象。然后,此共享对象检查其他一些输入并加载相应的Ada共享对象。

仔细查看代码,如果我能将逻辑内存地址保持在0和2,147,483,647(32位signed int)之间,那么它应该可以正常工作。有没有办法强制共享对象加载器在Ada代码的较低范围内留出空间,或者可能使Ada代码"思考"它的地址介于0和2,147,483,647之间?

1 个答案:

答案 0 :(得分:2)

  

有没有办法强制共享对象加载器在Ada代码的较低范围内留出空间

好消息是装载机将保持较低的范围不受影响。

坏消息是它不会在那里加载任何共享对象。没有可用于影响共享对象放置的界面。

那就是说,dlopen from memory(我们在glibc的私有分支中实现)将允许你这样做。但这不是公开的。

您可能的其他选择是:

  • 如果您可以将整个过程放入32位地址空间,那么您的解决方案是微不足道的:只需使用-m32构建所有内容。

  • 使用prelink将库重定位到所需的地址。由于该地址几乎总是可用,因此加载器很可能正好在那里加载库。

  • 将加载程序与自定义mmap实现相关联,该实现通过某种侧通道检测感兴趣的库,并mmap系统调用MAP_32BIT设置,或< / p>

  • ptrace沙箱中运行该程序。在需要时,此类沙箱可以再次拦截mmap系统调用和/或MAP_32BIT
  

或者让Ada代码“认为”它的地址介于0和2,147,483,647之间?

我不明白这是怎么回事。如果库在32位内存位置存储函数或全局的地址,则加载该地址并取消引用它...它将获得32位截断地址和取消引用SIGSEGV