Weak symbol linking when loading dynamic libraries

946 views
Skip to first unread message

kamil.r...@gmail.com

unread,
Sep 21, 2018, 3:17:35 AM9/21/18
to android-ndk
Hi,
I have a problem when dynamically loading two libraries on Android, which seems to be able to work on Linux. I have a situation where I have two shared libraries, let's call them libA.so and libB.so. libA.so gets loaded via dlopen() and uses a singleton. libA.so at some point loads libB.so via dlopen(), which also uses the same singleton. Unfortunately, the dynamic linker cannot merge those tho singleton symbols into one, and the result is two singleton instances. nm -C -D shows the instance to be a weak symbol "V" in both libraries. Is there any way to make the dynamic linker merge those symbols?

Ryan Prichard

unread,
Sep 24, 2018, 7:37:56 PM9/24/18
to andro...@googlegroups.com
While the build-time linker prefers a strong symbol definition to a weak definition, I don't think the runtime loader has that preference. It always uses the first symbol it finds (with a binding of either STB_GLOBAL or STB_WEAK). I think this is common behavior for ELF linkers.

Maybe it works on (glibc) Linux because libA.so is loaded with RTLD_GLOBAL, which would make its symbols available when loading any other library. The linker could then use libA.so's copy for both libA.so and libB.so. Android's dlopen recognizes the RTLD_GLOBAL flag, and it affects dlsym, but it doesn't make a shared object's symbols available during later dlopen calls:


We might want to change this behavior eventually, but that wouldn't be useful for a while. We have a bug filed internally for that -- http://b/110188176.

As the comment in that code indicates, you could mark the libraries with DF_1_GLOBAL, but unfortunately, that only works with P and up. (Technically M and up, but there's a bug with O MR1.)

For M and up, if you could load all of your shared objects with a single dlopen call, that would avoid the problem, but I'm not sure if that's practical. (e.g. Maybe use System.loadLibrary on one shared object that links against every other shared object in your app?)

I suspect placing each singleton instance in only one shared object is the best fix. If the variable instances are generated using templates, then I think you can use "extern template" declarations to control where specific instantiations are emitted.

-Ryan


On Fri, Sep 21, 2018 at 12:17 AM <kamil.r...@gmail.com> wrote:
Hi,
I have a problem when dynamically loading two libraries on Android, which seems to be able to work on Linux. I have a situation where I have two shared libraries, let's call them libA.so and libB.so. libA.so gets loaded via dlopen() and uses a singleton. libA.so at some point loads libB.so via dlopen(), which also uses the same singleton. Unfortunately, the dynamic linker cannot merge those tho singleton symbols into one, and the result is two singleton instances. nm -C -D shows the instance to be a weak symbol "V" in both libraries. Is there any way to make the dynamic linker merge those symbols?

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To post to this group, send email to andro...@googlegroups.com.
Visit this group at https://groups.google.com/group/android-ndk.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/a2a39aea-97d7-4c26-bf6b-abd7813f19ad%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages