OSDN Git Service

Fix global variable initialization for linker
authorDmitriy Ivanov <dimitry@google.com>
Thu, 24 Jul 2014 22:33:25 +0000 (15:33 -0700)
committerDmitriy Ivanov <dimitry@google.com>
Thu, 24 Jul 2014 22:33:25 +0000 (15:33 -0700)
 Linker now calls init functions for itself.

Change-Id: Ibd099812493041ac70f591e3f379ee742b4683b8

linker/linker.cpp
linker/linker_allocator.cpp
linker/linker_allocator.h
linker/tests/linker_allocator_test.cpp

index 04ffe59..4c76594 100644 (file)
@@ -2077,12 +2077,6 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
       ldpreload_env = linker_env_get("LD_PRELOAD");
     }
 
-    // Linker does not call constructors for its own
-    // global variables so we need to initialize
-    // the allocators explicitly.
-    g_soinfo_allocator.init();
-    g_soinfo_links_allocator.init();
-
     INFO("[ android linker & debugger ]");
 
     soinfo* si = soinfo_alloc(args.argv[0], NULL);
@@ -2271,6 +2265,9 @@ extern "C" ElfW(Addr) __linker_init(void* raw_args) {
     _exit(EXIT_FAILURE);
   }
 
+  // lets properly initialize global variables
+  linker_so.CallConstructors();
+
   // We have successfully fixed our own relocations. It's safe to run
   // the main part of the linker now.
   args.abort_message_ptr = &g_abort_message;
index c8b97b1..f5d3745 100644 (file)
@@ -28,17 +28,12 @@ struct FreeBlockInfo {
   size_t num_free_blocks;
 };
 
-LinkerBlockAllocator::LinkerBlockAllocator()
-  : block_size_(0),
+LinkerBlockAllocator::LinkerBlockAllocator(size_t block_size)
+  : block_size_(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size),
     page_list_(nullptr),
     free_block_list_(nullptr)
 {}
 
-void LinkerBlockAllocator::init(size_t block_size) {
-  block_size_ = block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size;
-}
-
-
 void* LinkerBlockAllocator::alloc() {
   if (free_block_list_ == nullptr) {
     create_new_page();
index fbf58fe..5d3563f 100644 (file)
@@ -32,9 +32,8 @@ struct LinkerAllocatorPage;
  */
 class LinkerBlockAllocator {
  public:
-  LinkerBlockAllocator();
+  explicit LinkerBlockAllocator(size_t block_size);
 
-  void init(size_t block_size);
   void* alloc();
   void free(void* block);
   void protect_all(int prot);
@@ -60,8 +59,7 @@ class LinkerBlockAllocator {
 template<typename T>
 class LinkerAllocator {
  public:
-  LinkerAllocator() : block_allocator_() {}
-  void init() { block_allocator_.init(sizeof(T)); }
+  LinkerAllocator() : block_allocator_(sizeof(T)) {}
   T* alloc() { return reinterpret_cast<T*>(block_allocator_.alloc()); }
   void free(T* t) { block_allocator_.free(t); }
   void protect_all(int prot) { block_allocator_.protect_all(prot); }
index 0ed8252..9292a05 100644 (file)
@@ -50,7 +50,6 @@ static size_t kPageSize = sysconf(_SC_PAGE_SIZE);
 
 TEST(linker_allocator, test_nominal) {
   LinkerAllocator<test_struct_nominal> allocator;
-  allocator.init();
 
   test_struct_nominal* ptr1 = allocator.alloc();
   ASSERT_TRUE(ptr1 != nullptr);
@@ -67,7 +66,6 @@ TEST(linker_allocator, test_nominal) {
 
 TEST(linker_allocator, test_small) {
   LinkerAllocator<test_struct_small> allocator;
-  allocator.init();
 
   char* ptr1 = reinterpret_cast<char*>(allocator.alloc());
   char* ptr2 = reinterpret_cast<char*>(allocator.alloc());
@@ -79,7 +77,6 @@ TEST(linker_allocator, test_small) {
 
 TEST(linker_allocator, test_larger) {
   LinkerAllocator<test_struct_larger> allocator;
-  allocator.init();
 
   test_struct_larger* ptr1 = allocator.alloc();
   test_struct_larger* ptr2 = allocator.alloc();
@@ -103,7 +100,6 @@ TEST(linker_allocator, test_larger) {
 
 static void protect_all() {
   LinkerAllocator<test_struct_larger> allocator;
-  allocator.init();
 
   // number of allocs to reach the end of first page
   size_t n = kPageSize/sizeof(test_struct_larger) - 1;