/* Return error detail for failing <dlfcn.h> functions.
   Copyright (C) 1995-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   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 <dlfcn.h>
#include <libintl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bits/libc-lock.h>
#include <ldsodefs.h>

#if !defined SHARED && defined IS_IN_libdl

char *
dlerror (void)
{
  return __dlerror ();
}

#else

/* Type for storing results of dynamic loading actions.  */
struct dl_action_result
  {
    int errcode;
    int returned;
    bool malloced;
    const char *objname;
    const char *errstring;
  };
static struct dl_action_result last_result;
static struct dl_action_result *static_buf;

/* This is the key for the thread specific memory.  */
static __libc_key_t key;
__libc_once_define (static, once);

/* Destructor for the thread-specific data.  */
static void init (void);
static void free_key_mem (void *mem);


char *
__dlerror (void)
{
  char *buf = NULL;
  struct dl_action_result *result;

# ifdef SHARED
  if (__builtin_expect (_dlfcn_hook != NULL, 0))
    return _dlfcn_hook->dlerror ();
# endif

  /* If we have not yet initialized the buffer do it now.  */
  __libc_once (once, init);

  /* Get error string.  */
  result = (struct dl_action_result *) __libc_getspecific (key);
  if (result == NULL)
    result = &last_result;

  /* Test whether we already returned the string.  */
  if (result->returned != 0)
    {
      /* We can now free the string.  */
      if (result->errstring != NULL)
	{
	  if (strcmp (result->errstring, "out of memory") != 0)
	    free ((char *) result->errstring);
	  result->errstring = NULL;
	}
    }
  else if (result->errstring != NULL)
    {
      buf = (char *) result->errstring;
      int n;
      if (result->errcode == 0)
	n = __asprintf (&buf, "%s%s%s",
			result->objname,
			result->objname[0] == '\0' ? "" : ": ",
			_(result->errstring));
      else
	n = __asprintf (&buf, "%s%s%s: %s",
			result->objname,
			result->objname[0] == '\0' ? "" : ": ",
			_(result->errstring),
			strerror (result->errcode));
      if (n != -1)
	{
	  /* We don't need the error string anymore.  */
	  if (strcmp (result->errstring, "out of memory") != 0)
	    free ((char *) result->errstring);
	  result->errstring = buf;
	}

      /* Mark the error as returned.  */
      result->returned = 1;
    }

  return buf;
}
# ifdef SHARED
strong_alias (__dlerror, dlerror)
# endif

int
internal_function
_dlerror_run (void (*operate) (void *), void *args)
{
  struct dl_action_result *result;

  /* If we have not yet initialized the buffer do it now.  */
  __libc_once (once, init);

  /* Get error string and number.  */
  if (static_buf != NULL)
    result = static_buf;
  else
    {
      /* We don't use the static buffer and so we have a key.  Use it
	 to get the thread-specific buffer.  */
      result = __libc_getspecific (key);
      if (result == NULL)
	{
	  result = (struct dl_action_result *) calloc (1, sizeof (*result));
	  if (result == NULL)
	    /* We are out of memory.  Since this is no really critical
	       situation we carry on by using the global variable.
	       This might lead to conflicts between the threads but
	       they soon all will have memory problems.  */
	    result = &last_result;
	  else
	    /* Set the tsd.  */
	    __libc_setspecific (key, result);
	}
    }

  if (result->errstring != NULL)
    {
      /* Free the error string from the last failed command.  This can
	 happen if `dlerror' was not run after an error was found.  */
      if (result->malloced)
	free ((char *) result->errstring);
      result->errstring = NULL;
    }

  result->errcode = GLRO(dl_catch_error) (&result->objname, &result->errstring,
					  &result->malloced, operate, args);

  /* If no error we mark that no error string is available.  */
  result->returned = result->errstring == NULL;

  return result->errstring != NULL;
}


/* Initialize buffers for results.  */
static void
init (void)
{
  if (__libc_key_create (&key, free_key_mem))
    /* Creating the key failed.  This means something really went
       wrong.  In any case use a static buffer which is better than
       nothing.  */
    static_buf = &last_result;
}


static void
check_free (struct dl_action_result *rec)
{
  if (rec->errstring != NULL
      && strcmp (rec->errstring, "out of memory") != 0)
    {
      /* We can free the string only if the allocation happened in the
	 C library used by the dynamic linker.  This means, it is
	 always the C library in the base namespace.  When we're statically
         linked, the dynamic linker is part of the program and so always
	 uses the same C library we use here.  */
#ifdef SHARED
      struct link_map *map = NULL;
      Dl_info info;
      if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
#endif
	free ((char *) rec->errstring);
    }
}


static void
__attribute__ ((destructor))
fini (void)
{
  check_free (&last_result);
}


/* Free the thread specific data, this is done if a thread terminates.  */
static void
free_key_mem (void *mem)
{
  check_free ((struct dl_action_result *) mem);

  free (mem);
  __libc_setspecific (key, NULL);
}

# ifdef SHARED

struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon));
libdl_hidden_data_def (_dlfcn_hook)

# else

static struct dlfcn_hook _dlfcn_hooks =
  {
    .dlopen = __dlopen,
    .dlclose = __dlclose,
    .dlsym = __dlsym,
    .dlvsym = __dlvsym,
    .dlerror = __dlerror,
    .dladdr = __dladdr,
    .dladdr1 = __dladdr1,
    .dlinfo = __dlinfo,
    .dlmopen = __dlmopen
  };

void
__libc_register_dlfcn_hook (struct link_map *map)
{
  struct dlfcn_hook **hook;

  hook = (struct dlfcn_hook **) __libc_dlsym_private (map, "_dlfcn_hook");
  if (hook != NULL)
    *hook = &_dlfcn_hooks;
}
# endif
#endif
