How does dynamic linker work
A typical program could contain a large number of sections, each of which would have to be located in the program and loaded into memory separately.
By using the execution view, the task of the loader is greatly simplified: all it has to do is copy to memory the load segments usually two of the program or library. As a result, process creation and library loading operations are much faster.
The diagram below shows the memory layout of a typical process. The main stack is located just below and grows downwards. Any additional threads that are created will have their own stacks, located below the main stack.
Each of the stacks is separated by a guard page to detect stack overflows. The heap is located above the process and grows upwards. In the middle of the process's address space, a large region is reserved for shared objects. Shared libraries are located at the top of the address space and grow downwards. When a new process is created, the process manager first maps the two segments from the executable into memory.
It then decodes the program's ELF header. If the program header indicates that the executable was linked against a shared library, the process manager will extract the name of the dynamic interpreter from the program header.
The dynamic interpreter points to a shared library that contains the runtime linker code. The process manager will load this shared library in memory and will then pass control to the runtime linker code in this library. The runtime linker is invoked when a program that was linked against a shared object is started or when a program requests that a shared object be dynamically loaded. The runtime linker is contained within the C runtime library. The runtime linker performs several tasks when loading a shared library.
This dynamic section provides information to the linker about other libraries that this library was linked against. It also gives information about the relocations that need to be applied and the external symbols that need to be resolved. The runtime linker will first load any other required shared libraries which may themselves reference other shared libraries. It will then process the relocations for each library. Some of these relocations are local to the library, while others require the runtime linker to resolve a global symbol.
In the latter case, the runtime linker will search through the list of libraries for this symbol. In ELF files, hash tables are used for the symbol lookup, so they're very fast. Once all relocations have been applied, any initialization functions that have been registered in the shared library's init section are called. A process can load a shared library at runtime by using the dlopen call, which instructs the runtime linker to load this library.
Once the library is loaded, the program can call any function within that library by using the dlsym call to determine its address. The program can also determine the symbol associated with a given address by using the dladdr call.
Finally, when the process no longer needs the shared library, it can call dlclose to unload the library from memory. When the runtime linker loads a shared library, the symbols within that library have to be resolved. The order and the scope of the symbol resolution are important. If a shared library calls a function that happens to exist by the same name in several libraries that the program has loaded, the order in which these libraries are searched for this symbol is critical.
This is why the OS defines several options that can be used when loading libraries. All the objects executables and libraries that have global scope are stored on an internal list the global list. Any global-scope object, by default, makes available all of its symbols to any shared library that gets loaded. The global list initially contains the executable and any libraries that are loaded at the program's startup.
By default, when a new shared library is loaded by using the dlopen call, symbols within that library are resolved by searching in this order through:. The runtime linker's scoping behavior can be changed in two ways when dlopen 'ing a shared library:. Remember: shared libraries are available only to processes that are dynamically linked. You don't need to know. You specify what you want to link with and let the compiler and linker etc do the work. Note the -l flag names the library and the -L tells it where to look.
There's a decent write up on how the compiler finds thing here. What are the -L and -l flags for? What does it mean to specify for example a -lusb flag on the command line? Add path searchdir to the list of paths that ld will search for archive libraries and ld control scripts. You may use this option any number of times. The directories are searched in the order in which they are specified on the command line. Directories specified on the command line are searched before the default directories.
All -L options apply to all -l options, regardless of the order in which the options appear. If you managed to get here it pays dividends to learn about the linker ie ld. The main difference is that you include static linked libraries with your app. They are linked when you build your app. Dynamic libraries are linked at run time, so you do not need to include them with your app.
These days dynamic libraries are used to reduce the size of apps by having many dynamic libraries on everyone's computer. Dynamic libraries also allow users to update libraries without re-building the client apps. If a bug is found in a library that you use in your app and it is statically linked, you will have to rebuild your app and re-issue it to all your users.
If a bug is found in a dynamically linked library, all your users just need to update their libraries and your app does not need an update. Stack Overflow for Teams — Collaborate and share knowledge with a private group. Create a free Team What is Teams? Collectives on Stack Overflow.
Learn more. How dynamic linking works, its usage and how and why you would make a dylib Ask Question. Asked 5 years, 7 months ago. Active 7 months ago. Viewed 4k times. And this is what I have taken away from all those readings - Dynamic linking is an optimization technique that was employed to take full advantage of the virtual memory of the system.
How does the compiler make the executable have these references? Does this not result in a circular dependency between the compiler and the operating system? Since the compiler has to make a reference to the dynamic library in the executable. Which compiler flag would one use to link to these?
Improve this question. Francesco Boi 6, 8 8 gold badges 60 60 silver badges 94 94 bronze badges. Curious Curious You can find a good potion of what you need here Add a comment.
Active Oldest Votes. This is linux specific There's a decent write up on how the compiler finds thing here gcc Linkage option -L: Alternative ways how to specify the path to the dynamic library Or have a look at man ld. See the above link. This is from man ld.. Improve this answer. Harry Harry Thank you! That is the conceptual explanation I read online! I was looking into more details about how these shared libraries work, how the compiler generates code that makes calls to the OS on start and how to go about achieving this.
Thanks anyway though! The compiler generates object files which are used by the loader on the system and edited as required setting up the addresses. How you build them depends on your environment. In XCode, for example, when you create a project you can specify that you are building a library when you create the project.
0コメント