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


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

A patch for dl bug in glibc 2.0.7


> 
> What about PR 612/620 (_fini calls in dlclose() give SIGSEGV)?  I have
> verified that the patch works, and IMHO it should be installed.  I think
> it will also fix H.J.'s problem, but in a more general way.
> 
> Andreas.
> 

I don't think so. The bug is in _dl_open and other places. I cannot
reproduce the bug because my glibc 2.0.7 contains the following patch.

Philippe, can you verify if it fixes your bug?

Thanks.


-- 
H.J. Lu (hjl@gnu.org)
----
Sat May  2 16:21:03 1998  H.J. Lu  <hjl@gnu.org>

	* elf/dl-open.c (_dl_open): Increment the open count if the
	shared object is put at the first place on the global scope
	list.
	Don't put the shared object on the global scope list twice.

Wed Apr 15 17:39:13 1998  H.J. Lu  <hjl@gnu.org>

	* set-hooks.h (RUN_HOOK): Support multiple calls.
	* posix/getopt_init.c (__getopt_clean_environment): Likewise.

	* sysdeps/unix/sysv/linux/init-first.h (SYSDEP_CALL_INIT): Don't
	check if PIC is not defined.

Index: elf/dl-open.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc-2.0/elf/dl-open.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 dl-open.c
--- elf/dl-open.c	1998/03/31 16:18:44	1.1.1.5
+++ elf/dl-open.c	1998/05/02 23:20:53
@@ -91,7 +91,14 @@
     }
 
   new->l_global = (mode & RTLD_GLOBAL) ? 1 : 0;
-  if (new->l_global)
+
+  if (_dl_loaded == new)
+    /* We are put at the first place on the global scope list, one way
+       or the other. We may be used by other shared objects. We have to
+       make sure that it stays in memory for them. Increment the open
+       count. */
+    new->l_opencount++;
+  else if (new->l_global)
     {
       /* The symbols of the new object and its dependencies are to be
 	 introduced into the global scope that will be used to resolve
Index: set-hooks.h
===================================================================
RCS file: /home/work/cvs/gnu/glibc-2.0/set-hooks.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 set-hooks.h
--- set-hooks.h	1997/09/19 18:10:01	1.1.1.1
+++ set-hooks.h	1998/04/16 00:37:22
@@ -40,9 +40,8 @@
 
 #define RUN_HOOK(NAME, ARGS) \
 do {									      \
-  void *const *ptr;							      \
-  for (ptr = symbol_set_first_element (NAME);				      \
-       ! symbol_set_end_p (NAME, ptr); ++ptr)				      \
+  static void *const *ptr = symbol_set_first_element (NAME);		      \
+  for (; ! symbol_set_end_p (NAME, ptr); ++ptr)				      \
     (*(__##NAME##_hook_function_t *) *ptr) ARGS;			      \
 } while (0)
 
Index: posix/getopt_init.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc-2.0/posix/getopt_init.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 getopt_init.c
--- posix/getopt_init.c	1997/09/19 18:10:41	1.1.1.1
+++ posix/getopt_init.c	1998/04/16 00:42:36
@@ -50,6 +50,11 @@
   char var[100];
   char *cp, **ep;
   size_t len;
+  static int done = 0;
+
+  if (done)
+    return;
+  done = 1;
 
   /* Generate name of the environment variable.  We must know the PID
      and we must not use `sprintf'.  */
Index: sysdeps/unix/sysv/linux/init-first.h
===================================================================
RCS file: /home/work/cvs/gnu/glibc-2.0/sysdeps/unix/sysv/linux/init-first.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 init-first.h
--- sysdeps/unix/sysv/linux/init-first.h	1997/09/19 18:10:10	1.1.1.1
+++ sysdeps/unix/sysv/linux/init-first.h	1998/04/16 05:40:54
@@ -21,6 +21,7 @@
    This is done in one of two ways: either in the stack context
    of program start, or having dlopen pass them in.  */
 
+#ifdef PIC
 #define SYSDEP_CALL_INIT(NAME, INIT)					      \
 void NAME (void *arg)							      \
 {									      \
@@ -48,3 +49,16 @@
 									      \
   INIT (argc, argv, envp);						      \
 }
+#else
+#define SYSDEP_CALL_INIT(NAME, INIT)					      \
+void NAME (void *arg)							      \
+{									      \
+  int argc;								      \
+  char **argv, **envp;							      \
+  argc = (int) arg;							      \
+  argv = (char **) &arg + 1;						      \
+  envp = &argv[argc+1];							      \
+									      \
+  INIT (argc, argv, envp);						      \
+}
+#endif


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