我有一个为特定(embedded式,多处理器,32位)体系结构编写的Ada程序。 我试图在64位RHEL上使用相同的代码作为共享对象(因为有多个版本,而且我有要求在运行时select一个版本)。
我遇到的问题是,代码中有几个地方写的人(不是我…)使用Unchecked_Conversions将System.Addresses转换为32位整数。 不仅如此,还有多个具有硬编码内存地址的例程。 我可以对这段代码做一些小的修改,但完全移植到x86_64并不是一个真正的select。 有例程处理中断,CPU任务调度等。
这个代码在静态链接到以前版本的模拟(由Fortran / C / C ++组成)中时运行良好。 但是,现在,主可执行文件启动,然后根据一些input加载共享对象。 这个共享对象然后检查一些其他input并加载适当的Ada共享对象。
仔细查看代码,很明显,如果我可以将逻辑内存地址保持在0到2,147,483,647(32位有符号整数)之间,它应该工作的很好。 有没有办法强制共享对象加载程序在较低的范围内为Ada代码留下空间,或者可能使Ada代码“认为”它的地址介于0和2,147,483,647之间?
有没有办法强制共享对象加载器在Ada代码的较低范围内留出空间
好消息是,装载机将保持不变。
坏消息是它不会加载任何共享对象。 没有可用于影响共享对象放置的界面。
也就是说, 记忆中的dlopen (我们在glibc的私人分支中实现)可以让你做到这一点。 但是这不是公开的。
您的其他可能选项是:
如果你可以把整个过程整合到32位地址空间中,那么你的解决方案是微不足道的:只需用-m32
构建所有的东西。
使用prelink
将库重定位到所需的地址。 由于该地址几乎总是可用的,加载器很可能正好在那里加载库。
使用自定义mmap
实现链接加载程序,该实现通过某种辅助通道检测感兴趣的库,并使用MAP_32BIT
集进行mmap
系统调用,或
ptrace
沙箱中运行程序。 这样的沙箱可以在MAP_32BIT
时候再次截取mmap
系统调用和/或MAP_32BIT
。 或者使Ada代码“认为”它的地址在0到2,147,483,647之间?
我不明白这是可能的。 如果库存储了一个32位内存位置的函数或全局地址,然后加载该地址并将其解引用…它将得到一个32位截断地址和一个SIGSEGV
取消引用。