Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Feb 2002 15:30:02 -0800 (PST)
From:      Dag-Erling Smorgrav <des@ofug.org>
To:        freebsd-bugs@FreeBSD.org
Subject:   bin/25059 (rtld bug)
Message-ID:  <200202232330.g1NNU2j18622@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/25059; it has been noted by GNATS.

From: Dag-Erling Smorgrav <des@ofug.org>
To: arch@freebsd.org
Cc:  
Subject: bin/25059 (rtld bug)
Date: 24 Feb 2002 00:21:49 +0100

 --=-=-=
 
 Our dlopen(3) man page states:
 
      RTLD_GLOBAL   Symbols from this shared object and its directed acyclic
                    graph (DAG) of needed objects will be available for resolv
                    ing undefined references from all other shared objects.
 
 but this is a lie - only the object itself is searched, not its DAG.
 
 The attached patch fixes this by adding a flag to the Obj_Entry
 structure that marks an object as global, and changing symlook_list()
 to search each global object's DAG if the object itself doesn't have
 the requested symbol.  With this patch applied, the test program
 referenced in the PR works.
 
 (some might argue that symlook_obj() should be changed instead - but
 changing symlook_list() was simpler, and the only difference it makes
 is, in the worst case, a slightly longer search)
 
 DES
 -- 
 Dag-Erling Smorgrav - des@ofug.org
 
 
 --=-=-=
 Content-Type: text/x-patch
 Content-Disposition: attachment; filename=rtld.diff
 
 Index: rtld.c
 ===================================================================
 RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.c,v
 retrieving revision 1.60
 diff -u -r1.60 rtld.c
 --- rtld.c	17 Feb 2002 07:00:25 -0000	1.60
 +++ rtld.c	23 Feb 2002 23:21:28 -0000
 @@ -1329,6 +1329,7 @@
      elm = NEW(Objlist_Entry);
      elm->obj = obj;
      STAILQ_INSERT_TAIL(list, elm, link);
 +    obj->global = true;
  }
  
  static void
 @@ -1581,7 +1582,7 @@
  
      if (obj) {
  	obj->dl_refcount++;
 -	if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
 +	if (mode & RTLD_GLOBAL && !obj->global)
  	    objlist_push_tail(&list_global, obj);
  	mode &= RTLD_MODEMASK;
  	if (*old_obj_tail != NULL) {		/* We loaded something new. */
 @@ -1915,7 +1916,7 @@
  	}
      }
  
 -    /* Search all RTLD_GLOBAL objects. */
 +    /* Search all RTLD_GLOBAL objects and their DAGs. */
      if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
  	symp = symlook_list(name, hash, &list_global, &obj, in_plt, &donelist);
  	if (symp != NULL &&
 @@ -1965,6 +1966,12 @@
  		if (ELF_ST_BIND(def->st_info) != STB_WEAK)
  		    break;
  	    }
 +	} else if (elm->obj->global) {
 +	    /* search the DAGs of global objects */
 +	    symp = symlook_list(name, hash, &elm->obj->dagmembers,
 +	      defobj_out, in_plt, dlp);
 +	    if (symp != NULL)
 +		return symp;
  	}
      }
      if (def != NULL)
 Index: rtld.h
 ===================================================================
 RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.h,v
 retrieving revision 1.24
 diff -u -r1.24 rtld.h
 --- rtld.h	29 Oct 2001 10:10:02 -0000	1.24
 +++ rtld.h	23 Feb 2002 23:02:18 -0000
 @@ -155,6 +155,7 @@
      bool traced;		/* Already printed in ldd trace output */
      bool jmpslots_done;		/* Already have relocated the jump slots */
      bool init_done;		/* Already have added object to init list */
 +    bool global;		/* This object is on the global list */
  
      struct link_map linkmap;	/* for GDB */
      Objlist dldags;		/* Object belongs to these dlopened DAGs (%) */
 
 --=-=-=--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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