libc_init_common.c revision 3a654b1e04d4275ae315cfe1b196998acf10052c
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <stddef.h> 30#include <stdio.h> 31#include <stdlib.h> 32#include <stdint.h> 33#include <elf.h> 34#include <asm/page.h> 35#include "pthread_internal.h" 36#include "atexit.h" 37#include "libc_init_common.h" 38 39#include <bionic_tls.h> 40#include <errno.h> 41 42extern void _init(void); 43extern void _fini(void); 44 45static void call_array(void(**list)()) 46{ 47 // First element is -1, list is null-terminated 48 while (*++list) { 49 (*list)(); 50 } 51} 52 53static void __bionic_do_global_dtors(structors_array_t const * const p) 54{ 55 call_array(p->fini_array); 56 //_fini(); 57} 58 59extern unsigned __get_sp(void); 60extern pid_t gettid(void); 61 62char* __progname; 63char **environ; 64 65/* from asm/page.h */ 66unsigned int __page_size = PAGE_SIZE; 67unsigned int __page_shift = PAGE_SHIFT; 68 69 70int __system_properties_init(void); 71 72void __libc_init_common(uintptr_t *elfdata, 73 void (*onexit)(void), 74 int (*slingshot)(int, char**, char**), 75 structors_array_t const * const structors, 76 void (*pre_ctor_hook)()) 77{ 78 pthread_internal_t thread; 79 pthread_attr_t thread_attr; 80 void *tls_area[BIONIC_TLS_SLOTS]; 81 int argc; 82 char **argv, **envp, **envend; 83 struct auxentry *auxentry; 84 unsigned int page_size = 0, page_shift = 0; 85 86 /* The main thread's stack has empirically shown to be 84k */ 87 unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; 88 unsigned stacksize = 128 * 1024; //84 * 1024; 89 unsigned stackbottom = stacktop - stacksize; 90 91 pthread_attr_init(&thread_attr); 92 pthread_attr_setstack(&thread_attr, (void*)stackbottom, stacksize); 93 _init_thread(&thread, gettid(), &thread_attr, (void*)stackbottom); 94 __init_tls(tls_area, &thread); 95 96 argc = (int) *elfdata++; 97 argv = (char**) elfdata; 98 envp = argv+(argc+1); 99 environ = envp; 100 101 __progname = argv[0] ? argv[0] : "<unknown>"; 102 103 errno = 0; 104 105 __system_properties_init(); 106 107 if (pre_ctor_hook) pre_ctor_hook(); 108 109 // XXX: we should execute the .fini_array upon exit 110 111 // pre-init array. 112 // XXX: I'm not sure what's the different with the init array. 113 call_array(structors->preinit_array); 114 115 // for compatibility with non-eabi binary, call the .ctors section 116 call_array(structors->ctors_array); 117 118 // call static constructors 119 call_array(structors->init_array); 120 121 exit(slingshot(argc, argv, envp)); 122} 123