Question

According to this expert,

Dynamic loading refers to mapping (or less often copying) an executable or library into a process's memory after is has started. Dynamic linking refers to resolving symbols - associating their names with addresses or offsets - after compile time.

Hence, correspondingly: static loading refers to mapping an executable or libary into memory before it has started, and static linking refers to resolving symbols at compile time.

Now, when you do static loading and static linking of a library, the library's binary code is appended to your binary code, and the (function and variable) references your binary code makes to the library are patched (not sure if that's the correct term) so that they point to the correct positions.

This means that before static linking a call to a function

foo()

would give you (in x86 ASM), among others, an instruction like:

 call    0x00000000

and after static linking you have something like:

 call    0x00001043

where 0x00001043 is the entry point of the function foo in the binary code that is output by the linker.

Now, when you do dynamic loading and dynamic linking, you will call a library function by way of a function pointer: typedef int (*fun_ptr)(void);

library = dlopen("mylib.so");
fun_ptr foo = dlsym(library, "foo");
foo();

This mechanism is also how C++ virtual methods work. The address of the method to be called is resolved at runtime by making a function pointer to the method part of the instance (stored in the so-called vtable).

My question is this:

When you do static loading and dynamic linking of a shared library (for context, let's say a .so in linux), does this linking patch my binary's references like in the static loading & linking scenario, or does it work by way of function pointers like in the case of dynamic loading & linking and C++ virtual methods?

Was it helpful?

Solution

When you do static loading and dynamic linking of a shared library

You don't do 'static loading' of a shared library.

Even though it looks to you as an end-user that e.g. libc.so.6 is 'static loaded' at process startup, it is not in fact the case. Rather, the kernel 'static loads' the main binary and ld-linux.so, and then ld-linux dynamic loads all the other shared libraries.

does this linking patch my binary's references like in the static loading & linking scenario, or does it work by way of function pointers like in the case of dynamic loading

It depends.

Usually shared libraries are linked from position-independent code (PIC), and work the way of function pointers (the pointers are stored in the GOT -- global offset table).

But sometimes shared libraries are linked from non-PIC code, and require "text relocations", which work similar to "static linking".

OTHER TIPS

I have been able to produce an example of runtime static linking using libbfd (which is the library sitting beneath GNU binutils' ld linker): https://github.com/bloff/runtime-static-linking-with-libbfd

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top