Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Apr 95 01:00:14 +0100
From:      jmz@cabri.obs-besancon.fr (Jean-Marc Zucconi)
To:        hackers@FreeBSD.org
Subject:   proposed change to ld.so
Message-ID:  <9504190000.AA15602@cabri.obs-besancon.fr>

next in thread | raw e-mail | index | archive | help
Current ld.so can't load a shared library that depends on other shared
libraries (cascades). The patch below, which is taken from
NetBSD-current (and due to matthew green <mrg@fulcrum.com.au>) solve
this problem. I tested it and it seems to work correctly.
What about adopting this change?

Jean-Marc.

Index: rtld.c
===================================================================
RCS file: /home/ncvs/src/gnu/usr.bin/ld/rtld/rtld.c,v
retrieving revision 1.22
diff -c -r1.22 rtld.c
*** 1.22	1995/03/04 17:46:24
--- rtld.c	1995/04/18 22:35:20
***************
*** 186,191 ****
--- 186,193 ----
  static void		maphints __P((void));
  static void		unmaphints __P((void));
  
+ static int		dl_cascade __P((struct so_map *));
+ 
  static inline int
  strcmp (register const char *s1, register const char *s2)
  {
***************
*** 1291,1296 ****
--- 1293,1302 ----
  #endif
  		return NULL;
  	}
+ 
+ 	if (dl_cascade(smp) == 0)
+ 		return NULL;
+ 
  	if (LM_PRIVATE(smp)->spd_refcount++ == 0) {
  		LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
  		if (reloc_map(smp) < 0)
***************
*** 1406,1409 ****
--- 1412,1458 ----
  	vsprintf(buf, fmt, ap);
  	(void)write(1, buf, strlen(buf));
  	va_end(ap);
+ }
+ 
+ static int
+ dl_cascade(smp)
+ 	struct so_map	*smp;
+ {
+ 	struct sod	*sodp;
+ 	struct so_map	*smp2;
+ 	long		next;
+ 
+ 	next = LD_NEED(smp->som_dynamic);
+ 
+ 	while (next) {
+ 		sodp = (struct sod *)(LM_LDBASE(smp) + next);
+ 		if ((smp2 = map_object(sodp, smp)) == NULL) {
+ #ifdef DEBUG
+ xprintf("ld.so: map_object failed on cascaded %s %s (%d.%d): %s\n",
+ 	smp->sod_library ? "library" : "file", smp->sod_name,
+ 	smp->sod_major, smp->sod_minor, strerror(errno));
+ #endif
+                         /* XXX call generror here? */
+ 			return 0;
+ 		}
+ #if 0
+ 		/*
+ 		 * XXX - this doesn't work for some reason.  not
+ 		 * at all sure why.  -mrg
+ 		 */
+ 		if (dl_cascade(smp2) == 0)
+ 			return 0;
+ #endif
+ 
+ 		if (LM_PRIVATE(smp2)->spd_refcount++ == 0) {
+ 			LM_PRIVATE(smp2)->spd_flags |= RTLD_DL;
+ 			reloc_map(smp2);
+ 			reloc_copy(smp2);
+ 			init_map(smp2, ".init");
+ 			init_map(smp2, "_init");
+ 		}
+ 
+ 		next = sodp->sod_next;
+ 	}
+ 	return 1;
  }

    ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
    Jean-Marc Zucconi             |         jmz@cabri.obs-besancon.fr
    Observatoire de Besancon      |    
    F 25010 Besancon cedex        | PGP Key: finger jmz@cabri.obs-besancon.fr
    =========================================================================



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9504190000.AA15602>