This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Restore dlsym(RTLD_NEXT, ...) behaviour


Hi!

Informix uses dlsym(RTLD_NEXT, "foo") in the main program, which used to
work but does not work any longer.
IMHO dlsym(RTLD_NEXT, "foo") in the main program makes sense, consider
something like:
#define _GNU_SOURCE
#include <dlfcn.h>
int getpid()
{
  return 32;
}
int main(void)
{
  void *p = (void *)getpid;
  void *q = dlsym (RTLD_DEFAULT, "getpid");
  void *r = dlsym (RTLD_NEXT, "getpid");
  printf ("%p %p %p\n", p, q, r);
}
It looks like this was changed when strict map range checking was added to
dl-sym.c. The patch below does not catch all cases where the error could be
signalled, but I think it is better if it works in the main program than to
catch them all (alternatively, the code could e.g. find at least smallest
l_map_start above _dl_loaded->l_map_start and check if caller is less than
that; BTW: why isn't l_map_end for the main program deducted from
Elf_Phdr?).
What is also needed is some variant of either H.J.'s _dl_signal_error or
e.g. the attached one (so that signalling error in real statically linked
application works).

	Jakub
2001-05-10  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-sym.c (_dl_sym, _dl_vsym): Only signal error if not called
	from the main program.

--- libc/elf/dl-sym.c.jj	Thu Nov  2 08:50:59 2000
+++ libc/elf/dl-sym.c	Thu May 10 15:20:32 2001
@@ -65,8 +65,13 @@ _dl_sym (void *handle, const char *name,
       else
 	{
 	  if (__builtin_expect (match == _dl_loaded, 0))
-	    _dl_signal_error (0, NULL, N_("\
+	    {
+	      if (! _dl_loaded
+		  || _dl_loaded->l_addr != 0
+		  || caller < _dl_loaded->l_map_start)
+	        _dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
+	    }
 
 	  l = match;
 	  while (l->l_loader != NULL)
@@ -121,9 +126,14 @@ _dl_vsym (void *handle, const char *name
 					  &vers, 0, 0);
   else if (handle == RTLD_NEXT)
     {
-      if (match == _dl_loaded)
-	_dl_signal_error (0, NULL, N_("\
+      if (__builtin_expect (match == _dl_loaded, 0))
+	{
+	  if (! _dl_loaded
+	      || _dl_loaded->l_addr != 0
+	      || caller < _dl_loaded->l_map_start)
+	    _dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
+	}
 
       l = match;
       while (l->l_loader != NULL)
2001-05-10  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-error.c (_dl_signal_error): Change NULL objname into "".

--- libc/elf/dl-error.c.jj	Fri Mar  2 13:44:29 2001
+++ libc/elf/dl-error.c	Thu May 10 15:58:08 2001
@@ -71,6 +71,8 @@ _dl_signal_error (int errcode, const cha
     errstring = N_("DYNAMIC LINKER BUG!!!");
 
   lcatch = tsd_getspecific ();
+  if (objname == NULL)
+    objname = "";
   if (lcatch != NULL)
     {
       /* We are inside _dl_catch_error.  Return to it.  We have to
@@ -100,7 +102,7 @@ _dl_signal_error (int errcode, const cha
       _dl_fatal_printf ("\
 %s: error while loading shared libraries: %s%s%s%s%s\n",
 			_dl_argv[0] ?: "<program name unknown>",
-			objname ?: "", objname && *objname ? ": " : "",
+			objname, *objname ? ": " : "",
 			errstring, errcode ? ": " : "",
 			(errcode
 			 ? __strerror_r (errcode, buffer, sizeof buffer)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]