Call _dlfcn_hook from libdl.so if not NULL.
authordrepper <drepper>
Mon, 18 Oct 2004 23:11:49 +0000 (23:11 +0000)
committerdrepper <drepper>
Mon, 18 Oct 2004 23:11:49 +0000 (23:11 +0000)
Define __ prefixed routine in libc.a and in libdl.a just call it.

dlfcn/dladdr.c
dlfcn/dladdr1.c
dlfcn/dlclose.c
dlfcn/dlerror.c
dlfcn/dlinfo.c
dlfcn/dlmopen.c
dlfcn/dlopen.c
dlfcn/dlopenold.c
dlfcn/dlsym.c
dlfcn/dlvsym.c

index b5490e5..d0462b9 100644 (file)
@@ -1,5 +1,6 @@
 /* Locate the shared object symbol nearest a given address.
-   Copyright (C) 1996, 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2003, 2004
+   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
 
 #include <dlfcn.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
 int
 dladdr (const void *address, Dl_info *info)
 {
+  return __dladdr (address, info);
+}
+
+#else
+
+int
+__dladdr (const void *address, Dl_info *info)
+{
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dladdr (address, info);
+# endif
   return _dl_addr (address, info, NULL, NULL);
 }
+# ifdef SHARED
+strong_alias (__dladdr, dladdr)
+# endif
+#endif
index 51b53b5..0f2b603 100644 (file)
@@ -1,5 +1,5 @@
 /* Locate the shared object symbol nearest a given address.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 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
 
 #include <dlfcn.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
 int
 dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
 {
+  return __dladdr1 (address, info, extra, flags);
+}
+
+#else
+
+int
+__dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
+{
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dladdr1 (address, info, extra, flags);
+# endif
+
   switch (flags)
     {
     default:                   /* Make this an error?  */
@@ -33,3 +48,7 @@ dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
       return _dl_addr (address, info, (struct link_map **) extra, NULL);
     }
 }
+# ifdef SHARED
+strong_alias (__dladdr1, dladdr1)
+# endif
+#endif
index 046e6d4..3ddedcf 100644 (file)
@@ -1,5 +1,6 @@
 /* Close a handle opened by `dlopen'.
-   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2004
+   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
 
 #include <dlfcn.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
+int
+dlclose (void *handle)
+{
+  return __dlclose (handle);
+}
+
+#else
+
 static void
 dlclose_doit (void *handle)
 {
@@ -26,7 +37,16 @@ dlclose_doit (void *handle)
 }
 
 int
-dlclose (void *handle)
+__dlclose (void *handle)
 {
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dlclose (handle);
+# endif
+
   return _dlerror_run (dlclose_doit, handle) ? -1 : 0;
 }
+# ifdef SHARED
+strong_alias (__dlclose, dlclose)
+# endif
+#endif
index 1cde04b..8789f4f 100644 (file)
 #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
   {
@@ -46,11 +56,16 @@ static void free_key_mem (void *mem);
 
 
 char *
-dlerror (void)
+__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);
 
@@ -99,6 +114,9 @@ dlerror (void)
 
   return buf;
 }
+# ifdef SHARED
+strong_alias (__dlerror, dlerror)
+# endif
 
 int
 internal_function
@@ -185,3 +203,35 @@ free_key_mem (void *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
index d54a132..44af55a 100644 (file)
 #include <ldsodefs.h>
 #include <libintl.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
+int
+dlinfo (void *handle, int request, void *arg)
+{
+  return __dlinfo (handle, request, arg, RETURN_ADDRESS (0));
+}
+
+#else
+
 struct dlinfo_args
 {
   ElfW(Addr) caller;
@@ -36,7 +46,7 @@ dlinfo_doit (void *argsblock)
   struct dlinfo_args *const args = argsblock;
   struct link_map *l = args->handle;
 
-#if 0
+# if 0
   if (args->handle == RTLD_SELF)
     {
       Lmid_t nsid;
@@ -53,7 +63,7 @@ dlinfo_doit (void *argsblock)
        GLRO(dl_signal_error) (0, NULL, NULL, N_("\
 RTLD_SELF used in code not dynamically loaded"));
     }
-#endif
+# endif
 
   switch (args->request)
     {
@@ -84,9 +94,19 @@ RTLD_SELF used in code not dynamically loaded"));
 }
 
 int
-dlinfo (void *handle, int request, void *arg)
+__dlinfo (void *handle, int request, void *arg DL_CALLER_DECL)
 {
-  struct dlinfo_args args = { (ElfW(Addr)) RETURN_ADDRESS (0),
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dlinfo (handle, request, arg,
+                               DL_CALLER);
+# endif
+
+  struct dlinfo_args args = { (ElfW(Addr)) DL_CALLER,
                              handle, request, arg };
   return _dlerror_run (&dlinfo_doit, &args) ? -1 : 0;
 }
+# ifdef SHARED
+strong_alias (__dlinfo, dlinfo)
+# endif
+#endif
index fb2a50b..5fd6543 100644 (file)
 #include <stddef.h>
 #include <ldsodefs.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
+void *
+dlmopen (Lmid_t nsid, const char *file, int mode)
+{
+  return __dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
+}
+static_link_warning (dlmopen)
+
+#else
+
 struct dlmopen_args
 {
   /* Namespace ID.  */
@@ -43,11 +54,11 @@ dlmopen_doit (void *a)
 
   /* Non-shared code has no support for multiple namespaces.  */
   if (args->nsid != LM_ID_BASE)
-#ifdef SHARED
+# ifdef SHARED
     /* If trying to open the link map for the main executable the namespace
        must be the main one.  */
     if (args->file == NULL)
-#endif
+# endif
       GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
 
   args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
@@ -56,14 +67,32 @@ dlmopen_doit (void *a)
 
 
 void *
-dlmopen (Lmid_t nsid, const char *file, int mode)
+__dlmopen (Lmid_t nsid, const char *file, int mode DL_CALLER_DECL)
 {
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
+# endif
+
   struct dlmopen_args args;
   args.nsid = nsid;
   args.file = file;
   args.mode = mode;
-  args.caller = RETURN_ADDRESS (0);
+  args.caller = DL_CALLER;
 
+# ifdef SHARED
   return _dlerror_run (dlmopen_doit, &args) ? NULL : args.new;
+# else
+  if (_dlerror_run (dlmopen_doit, &args))
+    return NULL;
+
+  __libc_register_dl_open_hook ((struct link_map *) args.new);
+  __libc_register_dlfcn_hook ((struct link_map *) args.new);
+
+  return args.new;
+# endif
 }
-static_link_warning (dlmopen)
+# ifdef SHARED
+strong_alias (__dlmopen, dlmopen)
+# endif
+#endif
index cfd7963..6381ffc 100644 (file)
 #include <dlfcn.h>
 #include <stddef.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
+void *
+dlopen (const char *file, int mode)
+{
+  return __dlopen (file, mode, RETURN_ADDRESS (0));
+}
+static_link_warning (dlopen)
+
+#else
+
 struct dlopen_args
 {
   /* The arguments for dlopen_doit.  */
@@ -33,11 +44,11 @@ struct dlopen_args
 
 
 /* Non-shared code has no support for multiple namespaces.  */
-#ifdef SHARED
-# define NS __LM_ID_CALLER
-#else
-# define NS LM_ID_BASE
-#endif
+# ifdef SHARED
+#  define NS __LM_ID_CALLER
+# else
+#  define NS LM_ID_BASE
+# endif
 
 
 static void
@@ -50,17 +61,34 @@ dlopen_doit (void *a)
 }
 
 
-extern void *__dlopen_check (const char *file, int mode);
 void *
-__dlopen_check (const char *file, int mode)
+__dlopen (const char *file, int mode DL_CALLER_DECL)
 {
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dlopen (file, mode, DL_CALLER);
+# endif
+
   struct dlopen_args args;
   args.file = file;
   args.mode = mode;
-  args.caller = RETURN_ADDRESS (0);
+  args.caller = DL_CALLER;
 
+# ifdef SHARED
   return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
+# else
+  if (_dlerror_run (dlopen_doit, &args))
+    return NULL;
+
+  __libc_register_dl_open_hook ((struct link_map *) args.new);
+  __libc_register_dlfcn_hook ((struct link_map *) args.new);
+
+  return args.new;
+# endif
 }
-#include <shlib-compat.h>
+# ifdef SHARED
+#  include <shlib-compat.h>
+strong_alias (__dlopen, __dlopen_check)
 versioned_symbol (libdl, __dlopen_check, dlopen, GLIBC_2_1);
-static_link_warning (dlopen)
+# endif
+#endif
index f10674a..148716c 100644 (file)
@@ -67,6 +67,9 @@ __dlopen_nocheck (const char *file, int mode)
     mode |= RTLD_LAZY;
   args.mode = mode;
 
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dlopen (file, mode, RETURN_ADDRESS (0));
+
   return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
 }
 compat_symbol (libdl, __dlopen_nocheck, dlopen, GLIBC_2_0);
index 76dda59..a656ca6 100644 (file)
 
 #include <ldsodefs.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
+void *
+dlsym (void *handle, const char *name)
+{
+  return __dlsym (handle, name, RETURN_ADDRESS (0));
+}
+
+#else
+
 struct dlsym_args
 {
   /* The arguments to dlsym_doit.  */
@@ -43,10 +53,15 @@ dlsym_doit (void *a)
 
 
 void *
-dlsym (void *handle, const char *name)
+__dlsym (void *handle, const char *name DL_CALLER_DECL)
 {
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dlsym (handle, name, DL_CALLER);
+# endif
+
   struct dlsym_args args;
-  args.who = RETURN_ADDRESS (0);
+  args.who = DL_CALLER;
   args.handle = handle;
   args.name = name;
 
@@ -59,3 +74,7 @@ dlsym (void *handle, const char *name)
 
   return result;
 }
+# ifdef SHARED
+strong_alias (__dlsym, dlsym)
+# endif
+#endif
index 2486845..9f12764 100644 (file)
 
 #include <ldsodefs.h>
 
+#if !defined SHARED && defined IS_IN_libdl
+
+void *
+weak_function
+dlvsym (void *handle, const char *name, const char *version_str)
+{
+  return __dlvsym (handle, name, version_str, RETURN_ADDRESS (0));
+}
+
+#else
+
 struct dlvsym_args
 {
   /* The arguments to dlvsym_doit.  */
@@ -44,13 +55,18 @@ dlvsym_doit (void *a)
 }
 
 void *
-__dlvsym (void *handle, const char *name, const char *version_str)
+__dlvsym (void *handle, const char *name, const char *version_str
+         DL_CALLER_DECL)
 {
-  struct dlvsym_args args;
+# ifdef SHARED
+  if (__builtin_expect (_dlfcn_hook != NULL, 0))
+    return _dlfcn_hook->dlvsym (handle, name, version_str, DL_CALLER);
+# endif
 
+  struct dlvsym_args args;
   args.handle = handle;
   args.name = name;
-  args.who = RETURN_ADDRESS (0);
+  args.who = DL_CALLER;
   args.version = version_str;
 
   /* Protect against concurrent loads and unloads.  */
@@ -62,4 +78,7 @@ __dlvsym (void *handle, const char *name, const char *version_str)
 
   return result;
 }
+# ifdef SHARED
 weak_alias (__dlvsym, dlvsym)
+# endif
+#endif