/* Handle loading/unloading of shared object for transformation.
   Copyright (C) 1997-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <assert.h>
#include <dlfcn.h>
#include <inttypes.h>
#include <search.h>
#include <stdlib.h>
#include <string.h>
#include <bits/libc-lock.h>
#include <sys/param.h>

#include <gconv_int.h>
#include <sysdep.h>


#ifdef DEBUG
/* For debugging purposes.  */
static void print_all (void);
#endif


/* This is a tuning parameter.  If a transformation module is not used
   anymore it gets not immediately unloaded.  Instead we wait a certain
   number of load attempts for further modules.  If none of the
   subsequent load attempts name the same object it finally gets unloaded.
   Otherwise it is still available which hopefully is the frequent case.
   The following number is the number of unloading attempts we wait
   before unloading.  */
#define TRIES_BEFORE_UNLOAD	2

/* Array of loaded objects.  This is shared by all threads so we have
   to use semaphores to access it.  */
static void *loaded;

/* Comparison function for searching `loaded_object' tree.  */
static int
known_compare (const void *p1, const void *p2)
{
  const struct __gconv_loaded_object *s1 =
    (const struct __gconv_loaded_object *) p1;
  const struct __gconv_loaded_object *s2 =
    (const struct __gconv_loaded_object *) p2;

  return strcmp (s1->name, s2->name);
}

/* Open the gconv database if necessary.  A non-negative return value
   means success.  */
struct __gconv_loaded_object *
internal_function
__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);
		  if (found->init_fct != NULL)
		    PTR_MANGLE (found->init_fct);
		  if (found->end_fct !=  NULL)
		    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;
}


/* This is very ugly but the tsearch functions provide no way to pass
   information to the walker function.  So we use a global variable.
   It is MT safe since we use a lock.  */
static struct __gconv_loaded_object *release_handle;

static void
do_release_shlib (void *nodep, VISIT value, int level)
{
  struct __gconv_loaded_object *obj = *(struct __gconv_loaded_object **) nodep;

  if (value != preorder && value != leaf)
    return;

  if (obj == release_handle)
    {
      /* This is the object we want to unload.  Now decrement the
	 reference counter.  */
      assert (obj->counter > 0);
      --obj->counter;
    }
  else if (obj->counter <= 0 && obj->counter >= -TRIES_BEFORE_UNLOAD
	   && --obj->counter < -TRIES_BEFORE_UNLOAD && obj->handle != NULL)
    {
      /* Unload the shared object.  */
      __libc_dlclose (obj->handle);
      obj->handle = NULL;
    }
}


/* Notify system that a shared object is not longer needed.  */
void
internal_function
__gconv_release_shlib (struct __gconv_loaded_object *handle)
{
  /* Urgh, this is ugly but we have no other possibility.  */
  release_handle = handle;

  /* Process all entries.  Please note that we also visit entries
     with release counts <= 0.  This way we can finally unload them
     if necessary.  */
  __twalk (loaded, (__action_fn_t) do_release_shlib);
}


/* We run this if we debug the memory allocation.  */
static void __libc_freeres_fn_section
do_release_all (void *nodep)
{
  struct __gconv_loaded_object *obj = (struct __gconv_loaded_object *) nodep;

  /* Unload the shared object.  */
  if (obj->handle != NULL)
    __libc_dlclose (obj->handle);

  free (obj);
}

libc_freeres_fn (free_mem)
{
  __tdestroy (loaded, do_release_all);
  loaded = NULL;
}


#ifdef DEBUG
static void
do_print (const void *nodep, VISIT value, int level)
{
  struct __gconv_loaded_object *obj = *(struct __gconv_loaded_object **) nodep;

  printf ("%10s: \"%s\", %d\n",
	  value == leaf ? "leaf" :
	  value == preorder ? "preorder" :
	  value == postorder ? "postorder" : "endorder",
	  obj->name, obj->counter);
}

static void
print_all (void)
{
  __twalk (loaded, do_print);
}
#endif
