Improve detection of already loaded libraries
Linker is now able to resolve symlinked libraries correctly.
soinfo is extended to save the graph of dependencies during
load/unload. Dependencies are used only in CallConstructor.
Bug: 9741592
Change-Id: Id9c48a74c46aa89bcdf3d54ec2f8ba3d398130b1
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a3cad11..85e91c3 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -225,78 +225,26 @@
static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
#endif
+// Defined as global because we do not yet have access
+// to synchronization functions __cxa_guard_* needed
+// to define statics inside functions.
+static soinfo __libdl_info;
+
// This is used by the dynamic linker. Every process gets these symbols for free.
-soinfo libdl_info = {
- "libdl.so",
+soinfo* get_libdl_info() {
+ if (__libdl_info.name[0] == '\0') {
+ // initialize
+ strncpy(__libdl_info.name, "libdl.so", sizeof(__libdl_info.name));
+ __libdl_info.flags = FLAG_LINKED | FLAG_NEW_SOINFO;
+ __libdl_info.strtab = ANDROID_LIBDL_STRTAB;
+ __libdl_info.symtab = g_libdl_symtab;
+ __libdl_info.nbucket = sizeof(g_libdl_buckets)/sizeof(unsigned);
+ __libdl_info.nchain = sizeof(g_libdl_chains)/sizeof(unsigned);
+ __libdl_info.bucket = g_libdl_buckets;
+ __libdl_info.chain = g_libdl_chains;
+ __libdl_info.has_DT_SYMBOLIC = true;
+ }
- .phdr = 0,
- .phnum = 0,
- .entry = 0,
- .base = 0,
- .size = 0,
+ return &__libdl_info;
+}
-#if !defined(__LP64__)
- .unused1 = 0,
-#endif
-
- .dynamic = 0,
-
-#if !defined(__LP64__)
- .unused2 = 0, .unused3 = 0,
-#endif
-
- .next = 0,
-
- .flags = FLAG_LINKED,
-
- .strtab = ANDROID_LIBDL_STRTAB,
- .symtab = g_libdl_symtab,
-
- .nbucket = sizeof(g_libdl_buckets)/sizeof(unsigned),
- .nchain = sizeof(g_libdl_chains)/sizeof(unsigned),
- .bucket = g_libdl_buckets,
- .chain = g_libdl_chains,
-
-#if defined(USE_RELA)
- .plt_rela = 0,
- .plt_rela_count = 0,
- .rela = 0,
- .rela_count = 0,
-#else
- .plt_got = 0,
- .plt_rel = 0,
- .plt_rel_count = 0,
- .rel = 0,
- .rel_count = 0,
-#endif
-
- .preinit_array = 0,
- .preinit_array_count = 0,
-
- .init_array = 0,
- .init_array_count = 0,
-
- .fini_array = 0,
- .fini_array_count = 0,
-
- .init_func = 0,
- .fini_func = 0,
-
-#if defined(__arm__)
- .ARM_exidx = 0,
- .ARM_exidx_count = 0,
-#elif defined(__mips__)
- .mips_symtabno = 0,
- .mips_local_gotno = 0,
- .mips_gotsym = 0,
-#endif
-
- .ref_count = 0,
- { .l_addr = 0, .l_name = 0, .l_ld = 0, .l_next = 0, .l_prev = 0, },
- .constructors_called = false,
- .load_bias = 0,
-#if !defined(__LP64__)
- .has_text_relocations = false,
-#endif
- .has_DT_SYMBOLIC = true,
-};