]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - iconv/gconv_dl.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / iconv / gconv_dl.c
index 990338f0707e3dd1c31d95b34ef2ff59ae4f39f8..3bb732e76679def512b5323ce298c035ec0b90cc 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle loading/unloading of shared object for transformation.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -14,9 +14,8 @@
    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, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
 
 #include <assert.h>
 #include <dlfcn.h>
 #include <search.h>
 #include <stdlib.h>
 #include <string.h>
-#include <bits/libc-lock.h>
+#include <libc-lock.h>
 #include <sys/param.h>
 
 #include <gconv_int.h>
+#include <sysdep.h>
 
 
 #ifdef DEBUG
@@ -64,7 +64,6 @@ known_compare (const void *p1, const void *p2)
 /* 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;
@@ -129,6 +128,12 @@ __gconv_find_shlib (const char *name)
                  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;
                }
@@ -144,15 +149,10 @@ __gconv_find_shlib (const char *name)
   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)
+do_release_shlib (const void *nodep, VISIT value, void *closure)
 {
+  struct __gconv_loaded_object *release_handle = closure;
   struct __gconv_loaded_object *obj = *(struct __gconv_loaded_object **) nodep;
 
   if (value != preorder && value != leaf)
@@ -177,21 +177,17 @@ do_release_shlib (void *nodep, VISIT value, int level)
 
 /* 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);
+  __twalk_r (loaded, do_release_shlib, handle);
 }
 
 
 /* We run this if we debug the memory allocation.  */
-static void
+static void __libc_freeres_fn_section
 do_release_all (void *nodep)
 {
   struct __gconv_loaded_object *obj = (struct __gconv_loaded_object *) nodep;
@@ -203,28 +199,30 @@ do_release_all (void *nodep)
   free (obj);
 }
 
-static void __attribute__ ((unused))
-free_mem (void)
+libc_freeres_fn (free_mem)
 {
   __tdestroy (loaded, do_release_all);
+  loaded = NULL;
 }
-text_set_element (__libc_subfreeres, free_mem);
 
 
 #ifdef DEBUG
+
+#include <stdio.h>
+
 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",
+         value == leaf ? "leaf"
+         : value == preorder ? "preorder"
+         value == postorder ? "postorder" : "endorder",
          obj->name, obj->counter);
 }
 
-static void
+static void __attribute__ ((used))
 print_all (void)
 {
   __twalk (loaded, do_print);