Statically linked executable with dynamic loading

121 Views Asked by At

I'm not sure if it makes sense or not, but is it possible to have a statically linked executable + dynamic loading ?

In other words: at compile/linking time an object code is statically linked against libraries, however at runtime the loading in memory of the relevant code from libraries is postponed until the relevant library's functions are actually called/invoked from the executable.

Does it makes sense ? Thank you.

Edit: to me it seems Dynamic Linking actually requires Dynamic Loading.

1

There are 1 best solutions below

7
On BEST ANSWER

In other words: at compile/linking time an object code is statically linked against libraries, however at runtime the loading in memory of the relevant code from libraries is postponed until the relevant library's functions are actually called/invoked from the executable.

This question is somewhat ambiguous and depends on what exactly you mean by "loading in memory".

Let's consider execution of a fully-statically linked ./a.out ELF binary on Linux.

Such a binary has one or more PT_LOAD segments, which tell the kernel how to mmap that binary into memory.

In one sense, the entire code of the binary (including all library code) is loaded into memory (e.g., that code appears in /proc/self/maps) before the first instruction from ./a.out even runs.

However, with demand paging, none of that code is actually occupying any physical RAM. When you access the first instruction (at the _start symbol) of ./a.out, there is a page fault, and the OS loads the page containing that instruction is actually loaded into physical memory and restarts the instruction, which causes it to finally be executed.

Likewise, when you call some library function, there is (possibly) another page fault, and the OS loads the code for the called library function.

(Aside: above behavior could be modified by a call to mlock or mlockall).


Another possible interpretation of your question is "is it possible to mmap the library code only when the library function is called?".

In this interpretation, the library code does not appear in the process's address space until called.

This is quite possible to do: you just need to replace the actual code for the library_function with a "stub". When that stub is called, it would perform the necessary mmap to "actually load" the library code into memory (if that hasn't been done already) and then jump to the "actual" library_function.


The only reason to perform the second (more complicated) dance (that I can think of) is if your OS lacks demand paging (which probably means that it doesn't support paging at all).

There is probably some embedded OS out there which does do that.