14

Would you mind to leave your comment on this if you have really experienced which relates to the title above? I have tried to make a shared object to be delay loaded with both Clang and GCC on Ubuntu (I actually don't mind which compiler is used), but they do not look really support any delay loading feature (I expected the delay loading feature put a stub in a parent object, which was trying to load another object on demand, at a moment when the functionality is required, but it actually did not). The following commands show that I tried to make libbar.so to be delay loaded against to libfoo.so:

clang bar.c -fPIC -shared -o libbar.so clang foo.c -Wl,-zlazy,lL'/path/to/where/lib/is',-lbar -o foo 

You'll see the libfoo.so raise an exception before entering to the entry if libbar.so does not exist. Anyway, I don't mind if there were any typo in the commands above, but want to know Clang/GCC really supports a delay loading feature or not.

Personally, however, I can't believe if Linux program developers have been required to invoke dlopen() or dlsym() to make a shared object to be delay loaded if Clang/GCC did not support any delay loading feature. It could be okay if the object was written in C, but if it were written in C++, the situation must be completely complicated :(

I believe a solution which is realized with a help from compiler or linker is the best because I have successfully done it with Windows and Mac OS. So I feel it would be a natural reaction where citizen wants to dream to have a delay loading feature even on Clang/GCC. I'd also be appreciate if you have any comment on my feeling.

PS. I know Solaris supports a delay loading feature but that's not a way to go for me because I will don't develop anything on it.

Anyway, thank you very much in advance.

17
  • Yes, this can be done on Linux. Commented May 6, 2014 at 3:37
  • @ kec, thanks. Do you mean GCC/Clang can make a shared object delay loaded by passing some options to them? Does any official document describe how to use it? It'd be nice to know if you could explain why I got the result above. Commented May 6, 2014 at 3:42
  • Actually, after re-reading, I'm not sure I know what you are talking about. Are you talking about dlopen()? What do you want to happen? Commented May 6, 2014 at 3:46
  • @ kec, sorry for making you confused. I know a delay loading feature can be realized with dlopen() and dlsum() but don't want to invoke them in the source code. Instead, I want to realize by just passing some option flags to a linker or compiler and keep the source code as is. Commented May 6, 2014 at 3:52
  • Hm...lazy binding is the default. Whether or not the loading is actually lazy, I'm not sure, but is there really a practical difference? If you really want to know, you could use strace to find out when the library is mmap'ped in. What are you trying to achieve? Commented May 6, 2014 at 3:57

2 Answers 2

20

This is more a question of functionality provided by the run time linker, ld-linux.so.

This linker does support lazy binding of symbols, but not lazy loading of libraries. What this means is that each of the shared objects which an executable requires are loaded when the program starts, but the symbols within the program are not resolved to the loaded libraries until they are first referenced.

The reason for this is performance. A library may contain many thousands of symbols for functions that never get called in a single execution of a program. Resolving them all would be a waste of time.

For this reason, if a library does not contain the expected symbols, you can get 'undefined symbol' errors well after the program has started running, but if a library is missing altogether, you will get an error before the program starts.

The -zlazy option which you are quoting controls lazy symbol binding only. In fact it is enabled by default (at least for GCC, I did not check for clang).

The only way to have a library loaded after program startup, for example in response to some command line option, configuration or other dynamic condition, is to call dlopen.

You might want to look around for a good plugin framework - for references see:

Sign up to request clarification or add additional context in comments.

7 Comments

@ harmic, thank you for leaving your comment. It answered all things what I had incorrectly done. I'll read the references you posted above. Thank you again! :)
@ harmic, the reason I hesitated to use the dlopen way was it looked very complicated to implement. I have actually confirmed it works with a very simple C++ program (it calls a member function of a class which was obtained by a class pointer returned from dlsym()). But if I tried to apply the technique to a third party library (it's more and more complicated compared to the tutorial program I tested), everything goes crazy...
@user3591878 hard to know what the problem is from that description! I suggest you post that as a separate question. Include the smallest sample program you can that causes the 'crazy' behavior.
@ harmic, please never mind my comment above and thank you for your suggestion. I'll try to separate comments per question unit and put a sample code if it helps the readers to understand the issue :)
One can build delay loading on top of existing linker functionality by generating stub library which will call dlopen on first call (see another answer).
|
5

Linux does not support delay loading of libraries out of the box but it can easily be implemented using the same mechanism that is used on Windows i.e. by linking against small stub static library which dlopens main shared library on first call to any of it's functions.

You can implement such stub library by hand, via custom script tailored for your project or use Implib.so to generate it automatically:

$ clang bar.c -fPIC -shared -o libbar.so $ implib-gen.py libbar.so $ clang foo.c libbar.tramp.S libbar.init.c -o foo 

8 Comments

I love your efforts but we should have something similar directly in the linker. I think LLVM LLD guys could be more open minded than GNU ld ones. Did you try to contact them?
@ceztko You are right and actually in Sun's shlibs (after which GNU shlibs are implemented) delayed loading did work. So it's unclear why it wasn't implemented in GNU libc. There have been discussions in mailing list which didn't get any response. I just took the path of least resistance with my tool.
I just read the message you linked and in both replies people basically didn't understand the feature :)
@ceztko LLD might indeed work out, I'll try to talk to them.
I got subscribed to llvm-dev mailing list, which is currently moderated but they still manually accept all subscriptions. It's the right place where to ask for LLD. I can send an introductory post, also citing your project, asking for a /DELAYLOAD equivalent in LLD and showing some interest. After you can intervene from a technical point of view, since of your expertise. Tell me if it's ok for you
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.