Is it possible to force a range of virtual addresses?

自古美人都是妖i 提交于 2021-02-07 09:22:04

问题


I have an Ada program that was written for a specific (embedded, multi-processor, 32-bit) architecture. I'm attempting to use this same code in a simulation on 64-bit RHEL as a shared object (since there are multiple versions and I have a requirement to choose a version at runtime).

The problem I'm having is that there are several places in the code where the people who wrote it (not me...) have used Unchecked_Conversions to convert System.Addresses to 32-bit integers. Not only that, but there are multiple routines with hard-coded memory addresses. I can make minor changes to this code, but completely porting it to x86_64 isn't really an option. There are routines that handle interrupts, CPU task scheduling, etc.

This code has run fine in the past when it was statically-linked into a previous version of the simulation (consisting of Fortran/C/C++). Now, however, the main executable starts, then loads a shared object based on some inputs. This shared object then checks some other inputs and loads the appropriate Ada shared object.

Looking through the code, it's apparent that it should work fine if I can keep the logical memory addresses between 0 and 2,147,483,647 (32-bit signed int). Is there a way to either force the shared object loader to leave space in the lower ranges for the Ada code or perhaps make the Ada code "think" that it's addresses are between 0 and 2,147,483,647?


回答1:


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

The good news is that the loader will leave the lower ranges untouched.

The bad news is that it will not load any shared object there. There is no interface you could use to influence placement of shared objects.

That said, dlopen from memory (which we implemented in our private fork of glibc) would allow you to do that. But that's not available publicly.

Your other possible options are:

  • if you can fit the entire process into 32-bit address space, then your solution is trivial: just build everything with -m32.

  • use prelink to relocate the library to desired address. Since that address should almost always be available, the loader is very likely to load the library exactly there.

  • link the loader with a custom mmap implementation, which detects the library of interest through some kind of side channel, and does mmap syscall with MAP_32BIT set, or

  • run the program in a ptrace sandbox. Such sandbox can again intercept mmap syscall, and or-in MAP_32BIT when desirable.

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

I don't see how that's possible. If the library stores an address of a function or a global in a 32-bit memory location, then loads that address and dereferences it ... it's going to get a 32-bit truncated address and a SIGSEGV on dereference.



来源:https://stackoverflow.com/questions/29948648/is-it-possible-to-force-a-range-of-virtual-addresses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!