mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	TLS setup is required. * elf/tst-tls5.c: Likewise. * elf/tst-tls6.c: Likewise. * elf/tst-tls7.c: Likewise. * elf/tst-tls8.c: Likewise. * elf/tst-tls9.c: Likewise. * elf/rtld.c (dl_main): Remove [! SHARED] conditional from `if (GL(dl_tls_max_dtv_idx) > 0)' tests for doing TLS setup. * elf/dl-close.c (libc_freeres_fn): Check GL(dl_tls_dtv_slotinfo_list) for being null before calling free_slotinfo. * elf/dl-load.c (_dl_map_object_from_fd) [SHARED]: For PT_TLS in dynamic loading, bail with error if GL(dl_tls_max_dtv_idx) is zero.
		
			
				
	
	
		
			117 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Ack, a hack!  We need to get the proper definition, or lack thereof,
 | 
						|
   for FLOATING_STACKS.  But when !IS_IN_libpthread, this can get defined
 | 
						|
   incidentally by <tls.h>.  So kludge around it.  */
 | 
						|
 | 
						|
#define IS_IN_libpthread
 | 
						|
#include <tls.h>
 | 
						|
#undef IS_IN_libpthread
 | 
						|
#undef USE___THREAD
 | 
						|
 | 
						|
#include <errno.h>
 | 
						|
#include <error.h>
 | 
						|
#include <pthread.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <ucontext.h>
 | 
						|
 | 
						|
 | 
						|
#define N	4
 | 
						|
 | 
						|
#ifdef FLOATING_STACKS
 | 
						|
static char stacks[N][8192];
 | 
						|
static ucontext_t ctx[N][2];
 | 
						|
static volatile int failures;
 | 
						|
 | 
						|
static void
 | 
						|
fct (long int n)
 | 
						|
{
 | 
						|
  /* Just to use the thread local descriptor.  */
 | 
						|
  printf ("%ld: in %s now\n", n, __FUNCTION__);
 | 
						|
  errno = 0;
 | 
						|
}
 | 
						|
 | 
						|
static void *
 | 
						|
threadfct (void *arg)
 | 
						|
{
 | 
						|
  int n = (int) (long int) arg;
 | 
						|
 | 
						|
  if (getcontext (&ctx[n][1]) != 0)
 | 
						|
    {
 | 
						|
      printf ("%d: cannot get context: %m\n", n);
 | 
						|
      exit (1);
 | 
						|
    }
 | 
						|
 | 
						|
  printf ("%d: %s: before makecontext\n", n, __FUNCTION__);
 | 
						|
 | 
						|
  ctx[n][1].uc_stack.ss_sp = stacks[n];
 | 
						|
  ctx[n][1].uc_stack.ss_size = 8192;
 | 
						|
  ctx[n][1].uc_link = &ctx[n][0];
 | 
						|
  makecontext (&ctx[n][1], (void (*) (void)) fct, 1, (long int) n);
 | 
						|
 | 
						|
  printf ("%d: %s: before swapcontext\n", n, __FUNCTION__);
 | 
						|
 | 
						|
  if (swapcontext (&ctx[n][0], &ctx[n][1]) != 0)
 | 
						|
    {
 | 
						|
      ++failures;
 | 
						|
      printf ("%d: %s: swapcontext failed\n", n, __FUNCTION__);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    printf ("%d: back in %s\n", n, __FUNCTION__);
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
#ifdef FLOATING_STACKS
 | 
						|
static volatile int global;
 | 
						|
#endif
 | 
						|
 | 
						|
int
 | 
						|
main (void)
 | 
						|
{
 | 
						|
#ifndef FLOATING_STACKS
 | 
						|
  puts ("not supported");
 | 
						|
  return 0;
 | 
						|
#else
 | 
						|
  int n;
 | 
						|
  pthread_t th[N];
 | 
						|
  ucontext_t mctx;
 | 
						|
 | 
						|
  puts ("making contexts");
 | 
						|
  if (getcontext (&mctx) != 0)
 | 
						|
    {
 | 
						|
      if (errno == ENOSYS)
 | 
						|
	{
 | 
						|
	  puts ("context handling not supported");
 | 
						|
	  exit (0);
 | 
						|
	}
 | 
						|
 | 
						|
      printf ("%s: getcontext: %m\n", __FUNCTION__);
 | 
						|
      exit (1);
 | 
						|
    }
 | 
						|
 | 
						|
  /* Play some tricks with this context.  */
 | 
						|
  if (++global == 1)
 | 
						|
    if (setcontext (&mctx) != 0)
 | 
						|
      {
 | 
						|
	printf ("%s: setcontext: %m\n", __FUNCTION__);
 | 
						|
	exit (1);
 | 
						|
      }
 | 
						|
  if (global != 2)
 | 
						|
    {
 | 
						|
      printf ("%s: 'global' not incremented twice\n", __FUNCTION__);
 | 
						|
      exit (1);
 | 
						|
    }
 | 
						|
 | 
						|
  for (n = 0; n < N; ++n)
 | 
						|
    if (pthread_create (&th[n], NULL, threadfct, (void *) (long int) n) != 0)
 | 
						|
      error (EXIT_FAILURE, errno, "cannot create all threads");
 | 
						|
 | 
						|
  for (n = 0; n < N; ++n)
 | 
						|
    pthread_join (th[n], NULL);
 | 
						|
 | 
						|
  return failures;
 | 
						|
#endif
 | 
						|
}
 |