Keep the dynamic linker's soinfo pools mostly read-only.
We'll need a lot more refactoring of this code before we can reduce
the granularity, but this is a step forward.
Change-Id: I07061720e734b571a8399c1d5b4f2f35cd681307
diff --git a/linker/linker.h b/linker/linker.h
index 2a6c1cd..51869e7 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -46,33 +46,29 @@
// itself at the start of a page.
#define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1))
-void debugger_init();
+// Magic shared structures that GDB knows about.
-/* magic shared structures that GDB knows about */
-
-struct link_map
-{
- uintptr_t l_addr;
- char * l_name;
- uintptr_t l_ld;
- struct link_map * l_next;
- struct link_map * l_prev;
+struct link_map {
+ uintptr_t l_addr;
+ char * l_name;
+ uintptr_t l_ld;
+ struct link_map * l_next;
+ struct link_map * l_prev;
};
// Values for r_debug->state
enum {
- RT_CONSISTENT,
- RT_ADD,
- RT_DELETE
+ RT_CONSISTENT,
+ RT_ADD,
+ RT_DELETE
};
-struct r_debug
-{
- int32_t r_version;
- struct link_map * r_map;
- void (*r_brk)(void);
- int32_t r_state;
- uintptr_t r_ldbase;
+struct r_debug {
+ int32_t r_version;
+ struct link_map* r_map;
+ void (*r_brk)(void);
+ int32_t r_state;
+ uintptr_t r_ldbase;
};
#define FLAG_LINKED 0x00000001
@@ -83,75 +79,83 @@
#define SOINFO_NAME_LEN 128
struct soinfo {
- char name[SOINFO_NAME_LEN];
- const Elf32_Phdr *phdr;
- int phnum;
- unsigned entry;
- unsigned base;
- unsigned size;
+ char name[SOINFO_NAME_LEN];
+ const Elf32_Phdr* phdr;
+ int phnum;
+ unsigned entry;
+ unsigned base;
+ unsigned size;
- int unused; // DO NOT USE, maintained for compatibility.
+ int unused; // DO NOT USE, maintained for compatibility.
- unsigned *dynamic;
+ unsigned* dynamic;
- unsigned unused2; // DO NOT USE, maintained for compatibility
- unsigned unused3; // DO NOT USE, maintained for compatibility
+ unsigned unused2; // DO NOT USE, maintained for compatibility
+ unsigned unused3; // DO NOT USE, maintained for compatibility
- soinfo *next;
- unsigned flags;
+ soinfo* next;
+ unsigned flags;
- const char *strtab;
- Elf32_Sym *symtab;
+ const char* strtab;
+ Elf32_Sym* symtab;
- unsigned nbucket;
- unsigned nchain;
- unsigned *bucket;
- unsigned *chain;
+ unsigned nbucket;
+ unsigned nchain;
+ unsigned* bucket;
+ unsigned* chain;
- unsigned *plt_got;
+ unsigned* plt_got;
- Elf32_Rel *plt_rel;
- unsigned plt_rel_count;
+ Elf32_Rel* plt_rel;
+ unsigned plt_rel_count;
- Elf32_Rel *rel;
- unsigned rel_count;
+ Elf32_Rel* rel;
+ unsigned rel_count;
- unsigned *preinit_array;
- unsigned preinit_array_count;
+ unsigned* preinit_array;
+ unsigned preinit_array_count;
- unsigned *init_array;
- unsigned init_array_count;
- unsigned *fini_array;
- unsigned fini_array_count;
+ unsigned* init_array;
+ unsigned init_array_count;
+ unsigned* fini_array;
+ unsigned fini_array_count;
- void (*init_func)(void);
- void (*fini_func)(void);
+ void (*init_func)();
+ void (*fini_func)();
#if defined(ANDROID_ARM_LINKER)
- /* ARM EABI section used for stack unwinding. */
- unsigned *ARM_exidx;
- unsigned ARM_exidx_count;
+ // ARM EABI section used for stack unwinding.
+ unsigned* ARM_exidx;
+ unsigned ARM_exidx_count;
#elif defined(ANDROID_MIPS_LINKER)
#if 0
- /* not yet */
- unsigned *mips_pltgot
+ // Not yet.
+ unsigned* mips_pltgot
#endif
- unsigned mips_symtabno;
- unsigned mips_local_gotno;
- unsigned mips_gotsym;
-#endif /* ANDROID_*_LINKER */
+ unsigned mips_symtabno;
+ unsigned mips_local_gotno;
+ unsigned mips_gotsym;
+#endif
- unsigned refcount;
- struct link_map linkmap;
+ unsigned refcount;
+ struct link_map linkmap;
- int constructors_called;
+ bool constructors_called;
- /* When you read a virtual address from the ELF file, add this
- * value to get the corresponding address in the process' address space */
- Elf32_Addr load_bias;
+ // When you read a virtual address from the ELF file, add this
+ // value to get the corresponding address in the process' address space.
+ Elf32_Addr load_bias;
- bool has_text_relocations;
- bool has_DT_SYMBOLIC;
+ bool has_text_relocations;
+ bool has_DT_SYMBOLIC;
+
+ void CallConstructors();
+ void CallDestructors();
+ void CallPreInitConstructors();
+
+ private:
+ void CallArray(const char* array_name, unsigned* array, int count, bool reverse);
+ void CallFunction(const char* function_name, void (*function)());
};
extern soinfo libdl_info;
@@ -203,16 +207,17 @@
#define DT_PREINIT_ARRAYSZ 33
#endif
-soinfo *find_library(const char *name);
-Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start);
-soinfo *find_containing_library(const void *addr);
-const char *linker_get_error(void);
+soinfo* do_dlopen(const char* name);
+int do_dlclose(soinfo* si);
-int soinfo_unload(soinfo* si);
-Elf32_Sym *soinfo_find_symbol(soinfo* si, const void *addr);
-Elf32_Sym *soinfo_lookup(soinfo *si, const char *name);
-void soinfo_call_constructors(soinfo *si);
+Elf32_Sym* lookup(const char* name, soinfo** found, soinfo* start);
+soinfo* find_containing_library(const void* addr);
+const char* linker_get_error();
+Elf32_Sym* soinfo_find_symbol(soinfo* si, const void* addr);
+Elf32_Sym* soinfo_lookup(soinfo* si, const char* name);
+
+void debugger_init();
extern "C" void notify_gdb_of_libraries();
#endif