Fix global variable initialization for linker

Linker now calls init functions for itself.

Change-Id: Ibd099812493041ac70f591e3f379ee742b4683b8
This commit is contained in:
Dmitriy Ivanov 2014-07-24 15:33:25 -07:00
parent 7d22a45196
commit 4151ea73b7
4 changed files with 7 additions and 21 deletions

View File

@ -2077,12 +2077,6 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
ldpreload_env = linker_env_get("LD_PRELOAD"); 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 ]"); INFO("[ android linker & debugger ]");
soinfo* si = soinfo_alloc(args.argv[0], NULL); soinfo* si = soinfo_alloc(args.argv[0], NULL);
@ -2271,6 +2265,9 @@ extern "C" ElfW(Addr) __linker_init(void* raw_args) {
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
// lets properly initialize global variables
linker_so.CallConstructors();
// We have successfully fixed our own relocations. It's safe to run // We have successfully fixed our own relocations. It's safe to run
// the main part of the linker now. // the main part of the linker now.
args.abort_message_ptr = &g_abort_message; args.abort_message_ptr = &g_abort_message;

View File

@ -28,17 +28,12 @@ struct FreeBlockInfo {
size_t num_free_blocks; size_t num_free_blocks;
}; };
LinkerBlockAllocator::LinkerBlockAllocator() LinkerBlockAllocator::LinkerBlockAllocator(size_t block_size)
: block_size_(0), : block_size_(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size),
page_list_(nullptr), page_list_(nullptr),
free_block_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() { void* LinkerBlockAllocator::alloc() {
if (free_block_list_ == nullptr) { if (free_block_list_ == nullptr) {
create_new_page(); create_new_page();

View File

@ -32,9 +32,8 @@ struct LinkerAllocatorPage;
*/ */
class LinkerBlockAllocator { class LinkerBlockAllocator {
public: public:
LinkerBlockAllocator(); explicit LinkerBlockAllocator(size_t block_size);
void init(size_t block_size);
void* alloc(); void* alloc();
void free(void* block); void free(void* block);
void protect_all(int prot); void protect_all(int prot);
@ -60,8 +59,7 @@ class LinkerBlockAllocator {
template<typename T> template<typename T>
class LinkerAllocator { class LinkerAllocator {
public: public:
LinkerAllocator() : block_allocator_() {} LinkerAllocator() : block_allocator_(sizeof(T)) {}
void init() { block_allocator_.init(sizeof(T)); }
T* alloc() { return reinterpret_cast<T*>(block_allocator_.alloc()); } T* alloc() { return reinterpret_cast<T*>(block_allocator_.alloc()); }
void free(T* t) { block_allocator_.free(t); } void free(T* t) { block_allocator_.free(t); }
void protect_all(int prot) { block_allocator_.protect_all(prot); } void protect_all(int prot) { block_allocator_.protect_all(prot); }

View File

@ -50,7 +50,6 @@ static size_t kPageSize = sysconf(_SC_PAGE_SIZE);
TEST(linker_allocator, test_nominal) { TEST(linker_allocator, test_nominal) {
LinkerAllocator<test_struct_nominal> allocator; LinkerAllocator<test_struct_nominal> allocator;
allocator.init();
test_struct_nominal* ptr1 = allocator.alloc(); test_struct_nominal* ptr1 = allocator.alloc();
ASSERT_TRUE(ptr1 != nullptr); ASSERT_TRUE(ptr1 != nullptr);
@ -67,7 +66,6 @@ TEST(linker_allocator, test_nominal) {
TEST(linker_allocator, test_small) { TEST(linker_allocator, test_small) {
LinkerAllocator<test_struct_small> allocator; LinkerAllocator<test_struct_small> allocator;
allocator.init();
char* ptr1 = reinterpret_cast<char*>(allocator.alloc()); char* ptr1 = reinterpret_cast<char*>(allocator.alloc());
char* ptr2 = 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) { TEST(linker_allocator, test_larger) {
LinkerAllocator<test_struct_larger> allocator; LinkerAllocator<test_struct_larger> allocator;
allocator.init();
test_struct_larger* ptr1 = allocator.alloc(); test_struct_larger* ptr1 = allocator.alloc();
test_struct_larger* ptr2 = allocator.alloc(); test_struct_larger* ptr2 = allocator.alloc();
@ -103,7 +100,6 @@ TEST(linker_allocator, test_larger) {
static void protect_all() { static void protect_all() {
LinkerAllocator<test_struct_larger> allocator; LinkerAllocator<test_struct_larger> allocator;
allocator.init();
// number of allocs to reach the end of first page // number of allocs to reach the end of first page
size_t n = kPageSize/sizeof(test_struct_larger) - 1; size_t n = kPageSize/sizeof(test_struct_larger) - 1;