问题
I have a Linux application which loads in very small (a few small functions) shared libraries at run-time. For various Important Reasons™ I need the shared libraries to be loaded into a certain virtual memory range. However, dlopen()
doesn't provide any means (that I can see) to tell it, or hint to it, where to put what it loads.
Is there a way to tell dlopen()
where it should put the library it loads?
Is there some alternative to dlopen()
which would provide that functionality?
回答1:
I think that the prelink program may actually demonstrate a way to do this if you are willing to modify the library. The goal is to modify the library so that it will have a preferred address. The intent of prelink is to do this for performance, but my suspicion is that it can be modified to work for your use case. Note that you will never be guaranteed that this will happen in the general case, but in controlled cases you may be able to guarantee that it will happen. Certainly examining prelink will allow you to understand the parts of elf involved and make a more informed determination about whether it is possible. http://en.wikipedia.org/wiki/Prelink# Or see http://packages.qa.debian.org/prelink for the sources in Debian.
回答2:
You need to specify the actual problem you are trying to solve.
For various Important Reasons™
I can only interpret this statement as this is requested to you and you can not do anything about that (i.e. dispute).
So regarding your question:
The loading address has already been specified so you can not change it via this libraries. Actually you need to read about PIC
I think the only way to do what you want is to "hack" the libraries and modify the text segment.
Check this out specify-preferred-load-address.
To be honest you should explain here what is the problem you are trying to solve so you can get answers to help you out in all ways. I.e. so that you can have another option as a solution
回答3:
You cannot do that, and dlopen
(and even any mmap
without MAP_FIXED
) on recent Linux systems is subject to ASLR.
Consequently, your approach will fail, even if you succeed in doing the equivalent of dlopen
at some fixed address, unless you disable ASLR system-wide
In particular two "identical" runs of the same program doing the same dlopen
-s will go (i.e. have the dlopen
-ed shared libraries go) into probably different addresses.
Also, on Linux, you can dlopen
a big lot (at least several hundred thousands) of shared objects. See my manydl.c as an example
As I commented, your question looks like an XY problem. You should explain the reasons you want this. What is the real motivation and overall goals?
You could reimplement your modified dlopen
yourself by processing the ELF shared object files and do yourself the relocations. You'll also need to compile and link specially your shared object.
If the functions are simple and small (and if you accept a slight decrease in performance relative to dlopen
-ing small shared libraries compiled with gcc -fPIC -O2 -shared -Wall
), you could consider using some JIT compilation libraries like libjit, GNU lighting, asmjit, LLVM, ... to generate the machine code at some fixed address (or simply to generate a call or a jump to the real shared library function)
BTW, you might use and adapt to your weird needs the musl-libc (it includes a dlopen
function which you could port to your needs)
来源:https://stackoverflow.com/questions/25919859/is-there-a-way-to-load-a-linux-shared-library-into-a-specific-memory-location