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/linker.h b/linker/linker.h
index 645498a..e5aca6e 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -33,8 +33,10 @@
#include <link.h>
#include <unistd.h>
#include <android/dlext.h>
+#include <sys/stat.h>
#include "private/libc_logging.h"
+#include "linked_list.h"
#define DL_ERR(fmt, x...) \
do { \
@@ -84,6 +86,7 @@
#define FLAG_LINKED 0x00000001
#define FLAG_EXE 0x00000004 // The main executable
#define FLAG_LINKER 0x00000010 // The linker itself
+#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
#define SOINFO_NAME_LEN 128
@@ -94,8 +97,21 @@
#define USE_RELA 1
#endif
+struct soinfo;
+
+class SoinfoListAllocator {
+public:
+ static LinkedListEntry<soinfo>* alloc();
+ static void free(LinkedListEntry<soinfo>* entry);
+private:
+ // unconstructable
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
+};
+
struct soinfo {
public:
+ typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
+ public:
char name[SOINFO_NAME_LEN];
const ElfW(Phdr)* phdr;
size_t phnum;
@@ -179,17 +195,39 @@
bool has_text_relocations;
#endif
bool has_DT_SYMBOLIC;
-
void CallConstructors();
void CallDestructors();
void CallPreInitConstructors();
+ void add_child(soinfo* child);
+ void remove_all_links();
+
+ void set_st_dev(dev_t st_dev);
+ void set_st_ino(ino_t st_ino);
+ ino_t get_st_ino();
+ dev_t get_st_dev();
+
+ soinfo_list_t& get_children();
+
private:
void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
void CallFunction(const char* function_name, linker_function_t function);
+
+ private:
+ // This part of the structure is only available
+ // when FLAG_NEW_SOINFO is set in this->flags.
+ unsigned int version;
+
+ dev_t st_dev;
+ ino_t st_ino;
+
+ // dependency graph
+ soinfo_list_t children;
+ soinfo_list_t parents;
+
};
-extern soinfo libdl_info;
+extern soinfo* get_libdl_info();
void do_android_get_LD_LIBRARY_PATH(char*, size_t);
void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);