How does linker resolves duplicate symbols in dynamically loadable libraries?
Asked Answered
E

2

6

I have two dynamically loadable libraries lib_smtp.so and and libpop.so etc. Both have a global variable named protocol which is initialized to "SMTP" and "POP" respectively. I have another static library libhttp.a where protocol is initialized to "HTTP".

Now for some reason i need to compile all dynamic linkable and loadable libraries statically and include in the executable. Doing so i am getting error "multiple definition of symbol" during linking of static libraries.

I am curious to know how linker resolves duplicate symbols during dynamic linking where all three mentioned libraries are getting linked ?

Is there some way i can do the same statically as linker is doing in dynamic linking ie without any conflict add all static libraries to executable which have same symbols? if not, why the process is different for statically linked libraries.

Emf answered 6/5, 2015 at 14:59 Comment(0)
V
7

Dynamic linking in modern Linux and several other operating systems is based on the ELF binary format. The (ELF) dynamic libraries on which an executable or other shared library relies are prioritized. To resolve a given symbol, the dynamic linker checks each library in priority order until it finds one that defines the symbol.

That can be dicey when multiple dynamic objects define the same symbol and also multiple dynamic objects use that symbol. It can then be the case that the symbol is resolved differently in different dynamic objects.

Full details are out of scope for SO, but I don't know a better technical explanation than the one in Ulrich Drepper's paper "How to Write Shared Libraries".

Vial answered 6/5, 2015 at 15:16 Comment(2)
Thanks, in my case multiple dynamic object are defining and using the same symbol 'protocol' but without any issue. so at the run time a routine process_http() will be reading the symbol value as "HTTP' and process_smtp(), which is define in libsmtp.so will be reading symbol value as "SMTP" . For this to be possible symbol must have been resolved cleanly and having separate addresses ? please correct me if i am wrongEmf
Whether different modules in the same program seeing different values for a global is well characterized as "without any issue" is debatable, but I guess it's what want. Yes, of course the symbol must be resolved to different addresses in the different modules, as all components of a program run in the same address space. The highest-priority object in which a dynamic symbol is looked up is ordinarily the object in which the reference being resolved appears; this likely explains your observed behavior.Vial
M
2

In dynamic linking some facility called "symbol visibility" kicks in. Essentially this allows to expose only certain symbols across the object's (object in the sense of shared object) boundaries. It is good style to compile and link shared objects with symbols being hidden by default and only expose those explicitly that are required by callees.

Symbol visibility is applied during linking and so far only implemented in dynamic linkers. It's certainly possible to also have it in static linkage, Apple's GCC variant implements so called Mach-O relocateable object files which can be statically linked with visibility applied. But I don't know if the vanilla GCC, binutils ld or the gold linker can do this for plain old ELF.

Meditate answered 8/5, 2015 at 8:27 Comment(1)
how do you statically link with visibility limits for a Cocoa app?Tiana

© 2022 - 2024 — McMap. All rights reserved.