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

标签 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 位有符号整数)之间,它应该可以正常工作。有没有办法强制共享对象加载器在较低范围内为 Ada 代码留出空间,或者让 Ada 代码“认为”它的地址在 0 到 2,147,483,647 之间?

最佳答案

Is there a way to either force the shared object loader to leave space in the lower ranges for the Ada code

好消息是加载程序将保持较低的范围不变。

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

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

您的其他可能的选择是:

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

  • 使用prelink 将库重新定位到所需地址。由于该地址应该几乎始终可用,因此加载程序很可能会恰好在那里加载库。

  • 将加载程序与自定义 mmap 实现链接,它通过某种侧 channel 检测感兴趣的库,并使用 执行 mmap 系统调用MAP_32BIT 设置,或

  • ptrace 沙盒中运行程序。这样的沙箱可以再次拦截 mmap 系统调用,并在需要时或在 MAP_32BIT 中。

or perhaps make the Ada code "think" that it's addresses are between 0 and 2,147,483,647?

我不明白这怎么可能。如果库在 32 位内存位置存储函数地址或全局地址,然后加载该地址并取消引用它……它将获得一个 32 位截断地址和一个 SIGSEGV关于取消引用。

关于linux - 是否可以强制使用一系列虚拟地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29948648/

相关文章:

linux - socket - 事件套接字的最大限制

c - 使用自定义堆的类似 malloc 的函数

android - 桌面文件到安卓手机的自定义通知

c - 请解释这个对齐错误

c - 从映射文件中获取第 N 个字节

linux - 通过操作 ext4 创建目录循环

c - 如何在 linux 中获取 C 中可用内存的总大小?

c++ - 与库的 c 绑定(bind)链接

c++ - ld 链接器错误 "cpu model hidden symbol"

linux - 外来库链接