Beispiel #1
0
static void
init (void)
{
  void *resume, *personality;
  void *handle;

  handle = __libc_dlopen (LIBGCC_S_SO);

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
    __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");

  libgcc_s_resume = resume;
  libgcc_s_personality = personality;
  atomic_write_barrier ();
  /* At the point at which any thread writes the handle
     to libgcc_s_handle, the initialization is complete.
     The writing of libgcc_s_handle is atomic. All other
     threads reading libgcc_s_handle do so atomically. Any
     thread that does not execute this function must issue
     a read barrier to ensure that all of the above has
     actually completed and that the values of the
     function pointers are correct.   */
  libgcc_s_handle = handle;
}
void
pthread_cancel_init (void)
{
  void *resume, *personality, *forcedunwind, *getcfa;
  void *handle;

  if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
    return;

  handle = __libc_dlopen ("libgcc_s.so.1");

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
      || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
	 == NULL
      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
#ifdef ARCH_CANCEL_INIT
      || ARCH_CANCEL_INIT (handle)
#endif
      )
    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");

  libgcc_s_resume = resume;
  libgcc_s_personality = personality;
  libgcc_s_forcedunwind = forcedunwind;
  libgcc_s_getcfa = getcfa;
}
Beispiel #3
0
static void
init (void)
{
  libgcc_handle = __libc_dlopen ("libgcc_s.so.1");

  if (libgcc_handle == NULL)
    return;

  unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace");
  unwind_vrs_get = __libc_dlsym (libgcc_handle, "_Unwind_VRS_Get");
  if (unwind_vrs_get == NULL)
    unwind_backtrace = NULL;
}
Beispiel #4
0
static void
init (void)
{
  void *resume, *personality;
  void *handle;

  handle = __libc_dlopen ("libgcc_s.so.1");

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");

  libgcc_s_resume = resume;
  libgcc_s_personality = personality;
}
Beispiel #5
0
void
__attribute_noinline__
pthread_cancel_init (void)
{
  void *resume;
  void *personality;
  void *forcedunwind;
  void *getcfa;
  void *handle;

  if (__builtin_expect (libgcc_s_handle != NULL, 1))
    {
      /* Force gcc to reload all values.  */
      asm volatile ("" ::: "memory");
      return;
    }

  handle = __libc_dlopen (LIBGCC_S_SO);

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
      || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
	 == NULL
      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
#ifdef ARCH_CANCEL_INIT
      || ARCH_CANCEL_INIT (handle)
#endif
      )
    __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");

  PTR_MANGLE (resume);
  libgcc_s_resume = resume;
  PTR_MANGLE (personality);
  libgcc_s_personality = personality;
  PTR_MANGLE (forcedunwind);
  libgcc_s_forcedunwind = forcedunwind;
  PTR_MANGLE (getcfa);
  libgcc_s_getcfa = getcfa;
  /* Make sure libgcc_s_handle is written last.  Otherwise,
     pthread_cancel_init might return early even when the pointer the
     caller is interested in is not initialized yet.  */
  atomic_write_barrier ();
  libgcc_s_handle = handle;
}
Beispiel #6
0
static void
init (void)
{
  libgcc_handle = __libc_dlopen ("libgcc_s.so.2");

  if (libgcc_handle == NULL)
    return;

  unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace");
  unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP");
  unwind_getcfa = __libc_dlsym (libgcc_handle, "_Unwind_GetCFA");
  unwind_getgr = __libc_dlsym (libgcc_handle, "_Unwind_GetGR");
  if (unwind_getip == NULL || unwind_getgr == NULL || unwind_getcfa == NULL)
    {
      unwind_backtrace = NULL;
      __libc_dlclose (libgcc_handle);
      libgcc_handle = NULL;
    }
}
Beispiel #7
0
__libgcc_s_init(void)
{
  void *resume, *personality;
  void *handle;

  handle = __libc_dlopen (LIBGCC_S_SO);

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
  {
    fprintf (stderr,
	     LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
    abort();
  }

  __libgcc_s_resume = resume;
  libgcc_s_personality = personality;
}
Beispiel #8
0
struct frame_state *
__frame_state_for (void *pc, struct frame_state *frame_state)
{
  static framesf frame_state_for;

  if (frame_state_for == NULL)
    {
      void *handle = __libc_dlopen (LIBGCC_S_SO);

      if (handle == NULL
	  || (frame_state_for
	      = (framesf) __libc_dlsym (handle, "__frame_state_for")) == NULL)
#ifndef __USING_SJLJ_EXCEPTIONS__
	frame_state_for = fallback_frame_state_for;
#else
      	frame_state_for = abort;
#endif
    }

  return frame_state_for (pc, frame_state);
}
pthread_cancel_init (void)
{
  void *resume;
  void *personality;
  void *forcedunwind;
  void *getcfa;
  void *handle;

  if (__builtin_expect (libgcc_s_handle != NULL, 1))
    {
      /* Force gcc to reload all values.  */
      __asm__ __volatile__ ("" ::: "memory");
      return;
    }

  handle = __libc_dlopen (LIBGCC_S_SO);

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
      || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
	 == NULL
      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
#ifdef ARCH_CANCEL_INIT
      || ARCH_CANCEL_INIT (handle)
#endif
      )
  {
    fprintf (stderr,
	     LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
    abort();
Beispiel #10
0
void *
__nss_lookup_function (service_user *ni, const char *fct_name)
{
  void **found, *result;

  /* We now modify global data.  Protect it.  */
  __libc_lock_lock (lock);

  /* Search the tree of functions previously requested.  Data in the
     tree are `known_function' structures, whose first member is a
     `const char *', the lookup key.  The search returns a pointer to
     the tree node structure; the first member of the is a pointer to
     our structure (i.e. what will be a `known_function'); since the
     first member of that is the lookup key string, &FCT_NAME is close
     enough to a pointer to our structure to use as a lookup key that
     will be passed to `known_compare' (above).  */

  found = __tsearch (&fct_name, (void **) &ni->known, &known_compare);
  if (*found != &fct_name)
    /* The search found an existing structure in the tree.  */
    result = ((known_function *) *found)->fct_ptr;
  else
    {
      /* This name was not known before.  Now we have a node in the tree
	 (in the proper sorted position for FCT_NAME) that points to
	 &FCT_NAME instead of any real `known_function' structure.
	 Allocate a new structure and fill it in.  */

      known_function *known = malloc (sizeof *known);
      if (! known)
	{
	remove_from_tree:
	  /* Oops.  We can't instantiate this node properly.
	     Remove it from the tree.  */
	  __tdelete (&fct_name, (void **) &ni->known, &known_compare);
	  result = NULL;
	}
      else
	{
	  /* Point the tree node at this new structure.  */
	  *found = known;
	  known->fct_name = fct_name;

	  if (ni->library == NULL)
	    {
	      /* This service has not yet been used.  Fetch the service
		 library for it, creating a new one if need be.  If there
		 is no service table from the file, this static variable
		 holds the head of the service_library list made from the
		 default configuration.  */
	      static name_database default_table;
	      ni->library = nss_new_service (service_table ?: &default_table,
					     ni->name);
	      if (ni->library == NULL)
		{
		  /* This only happens when out of memory.  */
		  free (known);
		  goto remove_from_tree;
		}
	    }

#if !defined DO_STATIC_NSS || defined SHARED
	  if (ni->library->lib_handle == NULL)
	    {
	      /* Load the shared library.  */
	      size_t shlen = (7 + strlen (ni->library->name) + 3
			      + strlen (__nss_shlib_revision) + 1);
	      int saved_errno = errno;
	      char shlib_name[shlen];

	      /* Construct shared object name.  */
	      __stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,
						      "libnss_"),
					    ni->library->name),
				  ".so"),
			__nss_shlib_revision);

	      ni->library->lib_handle = __libc_dlopen (shlib_name);
	      if (ni->library->lib_handle == NULL)
		{
		  /* Failed to load the library.  */
		  ni->library->lib_handle = (void *) -1l;
		  __set_errno (saved_errno);
		}
	    }

	  if (ni->library->lib_handle == (void *) -1l)
	    /* Library not found => function not found.  */
	    result = NULL;
	  else
	    {
	      /* Get the desired function.  */
	      size_t namlen = (5 + strlen (ni->library->name) + 1
			       + strlen (fct_name) + 1);
	      char name[namlen];

	      /* Construct the function name.  */
	      __stpcpy (__stpcpy (__stpcpy (__stpcpy (name, "_nss_"),
					    ni->library->name),
				  "_"),
			fct_name);

	      /* Look up the symbol.  */
	      result = __libc_dlsym (ni->library->lib_handle, name);
	    }
#else
	  /* We can't get function address dynamically in static linking. */
	  {
# define DEFINE_ENT(h,nm)						      \
	    { #h"_get"#nm"ent_r", _nss_##h##_get##nm##ent_r },		      \
	    { #h"_end"#nm"ent", _nss_##h##_end##nm##ent },		      \
	    { #h"_set"#nm"ent", _nss_##h##_set##nm##ent },
# define DEFINE_GET(h,nm)						      \
	    { #h"_get"#nm"_r", _nss_##h##_get##nm##_r },
# define DEFINE_GETBY(h,nm,ky)						      \
	    { #h"_get"#nm"by"#ky"_r", _nss_##h##_get##nm##by##ky##_r },
	    static struct fct_tbl { const char *fname; void *fp; } *tp, tbl[] =
	      {
# include "function.def"
		{ NULL, NULL }
	      };
	    size_t namlen = (5 + strlen (ni->library->name) + 1
			     + strlen (fct_name) + 1);
	    char name[namlen];

	    /* Construct the function name.  */
	    __stpcpy (__stpcpy (__stpcpy (name, ni->library->name),
				"_"),
		      fct_name);

	    result = NULL;
	    for (tp = &tbl[0]; tp->fname; tp++)
	      if (strcmp (tp->fname, name) == 0)
		{
		  result = tp->fp;
		  break;
		}
	  }
#endif

	  /* Remember function pointer for later calls.  Even if null, we
	     record it so a second try needn't search the library again.  */
	  known->fct_ptr = result;
	}
    }

  /* Remove the lock.  */
  __libc_lock_unlock (lock);

  return result;
}
Beispiel #11
0
/* Open the gconv database if necessary.  A non-negative return value
   means success.  */
struct __gconv_loaded_object *
__gconv_find_shlib (const char *name)
{
  struct __gconv_loaded_object *found;
  void *keyp;

  /* Search the tree of shared objects previously requested.  Data in
     the tree are `loaded_object' structures, whose first member is a
     `const char *', the lookup key.  The search returns a pointer to
     the tree node structure; the first member of the is a pointer to
     our structure (i.e. what will be a `loaded_object'); since the
     first member of that is the lookup key string, &FCT_NAME is close
     enough to a pointer to our structure to use as a lookup key that
     will be passed to `known_compare' (above).  */

  keyp = __tfind (&name, &loaded, known_compare);
  if (keyp == NULL)
    {
      /* This name was not known before.  */
      size_t namelen = strlen (name) + 1;

      found = malloc (sizeof (struct __gconv_loaded_object) + namelen);
      if (found != NULL)
	{
	  /* Point the tree node at this new structure.  */
	  found->name = (char *) memcpy (found + 1, name, namelen);
	  found->counter = -TRIES_BEFORE_UNLOAD - 1;
	  found->handle = NULL;

	  if (__builtin_expect (__tsearch (found, &loaded, known_compare)
				== NULL, 0))
	    {
	      /* Something went wrong while inserting the entry.  */
	      free (found);
	      found = NULL;
	    }
	}
    }
  else
    found = *(struct __gconv_loaded_object **) keyp;

  /* Try to load the shared object if the usage count is 0.  This
     implies that if the shared object is not loadable, the handle is
     NULL and the usage count > 0.  */
  if (found != NULL)
    {
      if (found->counter < -TRIES_BEFORE_UNLOAD)
	{
	  assert (found->handle == NULL);
	  found->handle = __libc_dlopen (found->name);
	  if (found->handle != NULL)
	    {
	      found->fct = __libc_dlsym (found->handle, "gconv");
	      if (found->fct == NULL)
		{
		  /* Argh, no conversion function.  There is something
                     wrong here.  */
		  __gconv_release_shlib (found);
		  found = NULL;
		}
	      else
		{
		  found->init_fct = __libc_dlsym (found->handle, "gconv_init");
		  found->end_fct = __libc_dlsym (found->handle, "gconv_end");

#ifdef PTR_MANGLE
		  PTR_MANGLE (found->fct);
		  PTR_MANGLE (found->init_fct);
		  PTR_MANGLE (found->end_fct);
#endif

		  /* We have succeeded in loading the shared object.  */
		  found->counter = 1;
		}
	    }
	  else
	    /* Error while loading the shared object.  */
	    found = NULL;
	}
      else if (found->handle != NULL)
	found->counter = MAX (found->counter + 1, 1);
    }

  return found;
}