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