__noreturn void __libc_init(void* raw_args,
                            void (*onexit)(void),
                            int (*slingshot)(int, char**, char**),
                            structors_array_t const * const structors) {
  KernelArgumentBlock args(raw_args);
  __libc_init_tls(args);
  __libc_init_common(args);

  apply_gnu_relro();

  // Several Linux ABIs don't pass the onexit pointer, and the ones that
  // do never use it.  Therefore, we ignore it.

  call_array(structors->preinit_array);
  call_array(structors->init_array);

  // The executable may have its own destructors listed in its .fini_array
  // so we need to ensure that these are called when the program exits
  // normally.
  if (structors->fini_array != NULL) {
    __cxa_atexit(__libc_fini,structors->fini_array,NULL);
  }

  exit(slingshot(args.argc, args.argv, args.envp));
}
예제 #2
0
// We flag the __libc_preinit function as a constructor to ensure
// that its address is listed in libc.so's .init_array section.
// This ensures that the function is called by the dynamic linker
// as soon as the shared library is loaded.
__attribute__((constructor)) static void __libc_preinit() {
  /* ARC MOD BEGIN */
#endif
  /* Initialize IRT table using __nacl_irt_query. */
#if defined(__native_client__) || defined(BARE_METAL_BIONIC)
  __nacl_irt_query = irt_query;
  __init_irt_table();
#endif
  /* ARC MOD END */
  // Read the kernel argument block pointer from TLS.
  void* tls = const_cast<void*>(__get_tls());
  KernelArgumentBlock** args_slot = &reinterpret_cast<KernelArgumentBlock**>(tls)[TLS_SLOT_BIONIC_PREINIT];
  KernelArgumentBlock* args = *args_slot;

  // Clear the slot so no other initializer sees its value.
  // __libc_init_common() will change the TLS area so the old one won't be accessible anyway.
  *args_slot = NULL;

  __libc_init_common(*args);

  // Hooks for the debug malloc and pthread libraries to let them know that we're starting up.
  /* ARC MOD BEGIN */
  // We do not use the pthread debug feature.
  // pthread_debug_init();
  /* ARC MOD END */
  malloc_debug_init();
}
예제 #3
0
__noreturn void __libc_init(uintptr_t *elfdata,
                            void (*onexit)(void),
                            int (*slingshot)(int, char**, char**),
                            structors_array_t const * const structors)
{
    int  argc;
    char **argv, **envp;

    /* Initialize the C runtime environment */
    __libc_init_common(elfdata);

    /* Several Linux ABIs don't pass the onexit pointer, and the ones that
     * do never use it.  Therefore, we ignore it.
     */

    /* pre-init array. */
    call_array(structors->preinit_array);

    /* .ctors section initializers, for non-arm-eabi ABIs */
    call_array(structors->ctors_array);

    // call static constructors
    call_array(structors->init_array);

    argc = (int) *elfdata;
    argv = (char**)(elfdata + 1);
    envp = argv + argc + 1;

    exit(slingshot(argc, argv, envp));
}
void __libc_preinit(void)
{
    /* Read the ELF data pointer from a special slot of the
     * TLS area, then call __libc_init_common with it.
     *
     * Note that:
     * - we clear the slot so no other initializer sees its value.
     * - __libc_init_common() will change the TLS area so the old one
     *   won't be accessible anyway.
     */
    void**      tls_area = (void**)__get_tls();
    unsigned*   elfdata   = tls_area[TLS_SLOT_BIONIC_PREINIT];

    tls_area[TLS_SLOT_BIONIC_PREINIT] = NULL;

    __libc_init_common(elfdata);

    /* Setup pthread routines accordingly to the environment.
     * Requires system properties
     */
#ifdef PTHREAD_DEBUG
    extern void pthread_debug_init(void);
    pthread_debug_init();
#endif
    /* Setup malloc routines accordingly to the environment.
     * Requires system properties
     */
    extern void malloc_debug_init(void);
    malloc_debug_init();
}
예제 #5
0
// We flag the __libc_preinit function as a constructor to ensure
// that its address is listed in libc.so's .init_array section.
// This ensures that the function is called by the dynamic linker
// as soon as the shared library is loaded.
__attribute__((constructor)) static void __libc_preinit() {
  // Read the kernel argument block pointer from TLS.
  void** tls = __get_tls();
  KernelArgumentBlock** args_slot = &reinterpret_cast<KernelArgumentBlock**>(tls)[TLS_SLOT_BIONIC_PREINIT];
  KernelArgumentBlock* args = *args_slot;

  // Clear the slot so no other initializer sees its value.
  // __libc_init_common() will change the TLS area so the old one won't be accessible anyway.
  *args_slot = NULL;

  __libc_init_common(*args);

  // Hooks for various libraries to let them know that we're starting up.
  malloc_debug_init();
  netdClientInit();
}
__noreturn void __libc_init(uintptr_t *elfdata,
                       void (*onexit)(void),
                       int (*slingshot)(int, char**, char**),
                       structors_array_t const * const structors)
{
    int  argc;
    char **argv, **envp;

    __libc_init_tls(NULL);

    /* Initialize the C runtime environment */
    __libc_init_common(elfdata);

    /* Several Linux ABIs don't pass the onexit pointer, and the ones that
     * do never use it.  Therefore, we ignore it.
     */

    /* pre-init array. */
    call_array(structors->preinit_array);

    // call static constructors
    call_array(structors->init_array);

    argc = (int) *elfdata;
    argv = (char**)(elfdata + 1);
    envp = argv + argc + 1;

    /* The executable may have its own destructors listed in its .fini_array
     * so we need to ensure that these are called when the program exits
     * normally.
     */
    if (structors->fini_array)
        __cxa_atexit(__libc_fini,structors->fini_array,NULL);

    apply_gnu_relro();
    exit(slingshot(argc, argv, envp));
}