public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Ulrich Drepper <drepper@redhat.com>, Roland McGrath <roland@redhat.com>
Cc: Glibc hackers <libc-hacker@sources.redhat.com>
Subject: [PATCH] Allow __libc_dlopen from libraries __libc_dlopen'ed by statically linked executables
Date: Wed, 11 Jun 2003 20:32:00 -0000	[thread overview]
Message-ID: <20030611203206.GX24872@sunsite.ms.mff.cuni.cz> (raw)

Hi!

This patch should make Thorsten's new nss_compat module working even from
statically linked binaries.
It will work only if the binaries are relinked, but I think we should be
clear that there is no guarantee that statically linked binaries using
NSS or iconv will work after glibc upgrade unless they have been
recompiled/relinked with the new glibc.
Tested with a statically linked binary __libc_dlopen'ing shared library
doing getpwnam.
The impact on libc.so.6 shouldn't be big, basically one more exported
symbol, __WORDSIZE bytes in .bss section and in 3 different functions
memory load + compare + jump to short unlikely code.

2003-06-11  Jakub Jelinek  <jakub@redhat.com>

	* elf/Versions (libc): Add _dl_open_hook@GLIBC_PRIVATE.
	* elf/dl-libc.c (struct dl_open_hook): New.
	(_dl_open_hook): New variable.
	(do_dlsym_private): New function.
	(__libc_dlopen_mode) [!SHARED]: Lookup _dl_open_hook@GLIBC_PRIVATE
	and initialize it if found.
	(__libc_dlopen_mode) [SHARED]: If _dl_open_hook is non-NULL,
	call dlopen_mode hook.
	(__libc_dlsym) [SHARED]: If _dl_open_hook is non-NULL,
	call dlsym hook.
	(__libc_dlclose) [SHARED]: If _dl_open_hook is non-NULL,
	call dlclose hook.

--- libc/elf/Versions.jj	2003-03-20 05:58:48.000000000 -0500
+++ libc/elf/Versions	2003-06-11 10:57:15.000000000 -0400
@@ -21,6 +21,7 @@ libc {
     # functions used in other libraries
     _dl_open; _dl_close; _dl_addr;
     _dl_sym; _dl_vsym;
+    _dl_open_hook;
   }
 }
 
--- libc/elf/dl-libc.c.jj	2002-11-24 19:57:43.000000000 -0500
+++ libc/elf/dl-libc.c	2003-06-11 11:53:10.000000000 -0400
@@ -96,6 +96,50 @@ do_dlclose (void *ptr)
   _dl_close ((struct link_map *) ptr);
 }
 
+/* This code is to support __libc_dlopen from __libc_dlopen'ed shared
+   libraries.  We need to ensure the statically linked __libc_dlopen
+   etc. functions are used instead of the dynamically loaded.  */
+struct dl_open_hook
+{
+  void *(*dlopen_mode) (const char *name, int mode);
+  void *(*dlsym) (void *map, const char *name);
+  int (*dlclose) (void *map);
+};
+
+#ifdef SHARED
+extern struct dl_open_hook *_dl_open_hook;
+libc_hidden_proto (_dl_open_hook);
+struct dl_open_hook *_dl_open_hook __attribute__((nocommon));
+libc_hidden_data_def (_dl_open_hook);
+#else
+static void
+do_dlsym_private (void *ptr)
+{
+  lookup_t l;
+  struct r_found_version vers;
+  vers.name = "GLIBC_PRIVATE";
+  vers.hidden = 1;
+  /* vers.hash = _dl_elf_hash (version);  */
+  vers.hash = 0x0963cf85;
+  /* FIXME: Shouldn't we use libc.so.6* here?  */
+  vers.filename = NULL;
+
+  struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
+  args->ref = NULL;
+  l = _dl_lookup_versioned_symbol (args->name, args->map,
+				   &args->ref, args->map->l_scope,
+				   &vers, 0, 0);
+  args->loadbase = l;
+}
+
+static struct dl_open_hook _dl_open_hook =
+  {
+    .dlopen_mode = __libc_dlopen_mode,
+    .dlsym = __libc_dlsym,
+    .dlclose = __libc_dlclose
+  };
+#endif
+
 /* ... and these functions call dlerror_run. */
 
 void *
@@ -105,7 +149,29 @@ __libc_dlopen_mode (const char *name, in
   args.name = name;
   args.mode = mode;
 
+#ifdef SHARED
+  if (__builtin_expect (_dl_open_hook != NULL, 0))
+    return _dl_open_hook->dlopen_mode (name, mode);
   return (dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map);
+#else
+  if (dlerror_run (do_dlopen, &args))
+    return NULL;
+
+  struct do_dlsym_args sargs;
+  sargs.map = args.map;
+  sargs.name = "_dl_open_hook";
+
+  if (! dlerror_run (do_dlsym_private, &sargs))
+    {
+      struct dl_open_hook **hook
+	= (struct dl_open_hook **)
+	  (DL_SYMBOL_ADDRESS (sargs.loadbase, sargs.ref));
+      if (hook != NULL)
+	*hook = &_dl_open_hook;
+    }
+
+  return (void *) args.map;
+#endif
 }
 
 void *
@@ -115,6 +181,10 @@ __libc_dlsym (void *map, const char *nam
   args.map = map;
   args.name = name;
 
+#ifdef SHARED
+  if (__builtin_expect (_dl_open_hook != NULL, 0))
+    return _dl_open_hook->dlsym (map, name);
+#endif
   return (dlerror_run (do_dlsym, &args) ? NULL
 	  : (void *) (DL_SYMBOL_ADDRESS (args.loadbase, args.ref)));
 }
@@ -122,6 +192,10 @@ __libc_dlsym (void *map, const char *nam
 int
 __libc_dlclose (void *map)
 {
+#ifdef SHARED
+  if (__builtin_expect (_dl_open_hook != NULL, 0))
+    return _dl_open_hook->dlclose (map);
+#endif
   return dlerror_run (do_dlclose, map);
 }
 

	Jakub

             reply	other threads:[~2003-06-11 20:32 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-11 20:32 Jakub Jelinek [this message]
2003-06-25  8:44 ` Ulrich Drepper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030611203206.GX24872@sunsite.ms.mff.cuni.cz \
    --to=jakub@redhat.com \
    --cc=drepper@redhat.com \
    --cc=libc-hacker@sources.redhat.com \
    --cc=roland@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).