示例#1
0
/*
 * This replaces __pthread_initialize_minimal() from libnacl and
 * __pthread_initialize() from libpthread.
 */
void __pthread_initialize(void) {
  struct nc_combined_tdb *tdb;

  /*
   * Allocate the area.  If malloc fails here, we'll crash before it returns.
   */
  size_t combined_size = __nacl_tls_combined_size(sizeof(*tdb));
  void *combined_area = malloc(combined_size);

  /*
   * Initialize TLS proper (i.e., __thread variable initializers).
   */
  void *tp = __nacl_tls_initialize_memory(combined_area, sizeof(*tdb));
  tdb = get_irt_tdb(tp);
  __nc_initialize_unjoinable_thread(tdb);
  tdb->tdb.irt_thread_data = combined_area;

  /*
   * Now install it for later fetching.
   * This is what our private version of __nacl_read_tp will read.
   */
  NACL_SYSCALL(second_tls_set)(tp);

  /*
   * Finally, do newlib per-thread initialization.
   */
  __newlib_thread_init();

  __nc_initialize_globals();
}
示例#2
0
static void nc_thread_starter(void) {
  nc_thread_descriptor_t *tdb = nc_get_tdb();
  __newlib_thread_init();
#if defined(NACL_IN_IRT)
  g_is_irt_internal_thread = 1;
#endif
  void *retval = tdb->start_func(tdb->state);

  /*
   * Free handler list to prevent memory leak in case function returns
   * without calling pthread_cleanup_pop(), although doing that is unspecified
   * behaviour.
   */
  while (NULL != __nc_cleanup_handlers) {
    pthread_cleanup_pop(0);
  }

  /* If the function returns, terminate the thread. */
  pthread_exit(retval);
  /* NOTREACHED */
  /* TODO(gregoryd) - add assert */
}
示例#3
0
/* See tls.h. */
int __pthread_initialize_minimal(size_t tdb_size) {
  /* Use sbrk not malloc here since the library is not initialized yet. */
  size_t combined_size = __nacl_tls_combined_size(tdb_size);
  /* Adapt size for sbrk. */
  /* TODO(robertm): this is somewhat arbitrary - re-examine). */
  combined_size = (combined_size + 15) & ~15;
  void *combined_area = sbrk(combined_size);  /* (uses nacl_sysbrk) */

  __nacl_tls_data_bss_initialize_from_template(combined_area);

  /* Patch the first word of the TDB to contain the "base" of the TLS area. */
  void *tdb = __nacl_tls_tdb_start(combined_area);
  *(void**) tdb = tdb;

  /* Set %gs, r9, or equivalent platform-specific mechanism.  Requires
   * a syscall since certain bitfields of these registers are trusted. */
  NACL_SYSCALL(tls_init)(tdb, tdb_size);

  /* initialize newlib's thread-specific pointer. */
  __newlib_thread_init();
  return 0;
}
示例#4
0
/*
 * This is the real first entry point for new threads.
 */
static void irt_start_thread(void) {
  struct nc_combined_tdb *tdb = get_irt_tdb(__nacl_read_tp());

  /*
   * Fetch the user's start routine.
   */
  void (*user_start)(void) = (void (*)(void)) tdb->tdb.start_func;

  /*
   * Now do per-thread initialization for the IRT-private C library state.
   */
  __newlib_thread_init();

  /*
   * Finally, run the user code.
   */
  (*user_start)();

  /*
   * That should never return.  Crash hard if it does.
   */
  while (1) *(volatile int *) 0 = 0;  /* Crash.  */
}