Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Nov 2008 12:28:45 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r184684 - stable/7/libexec/rtld-elf
Message-ID:  <200811051228.mA5CSjSf026889@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Nov  5 12:28:44 2008
New Revision: 184684
URL: http://svn.freebsd.org/changeset/base/184684

Log:
  MFC r183737 (by kan):
  Allow strong symbols to override weak ones for lookups done through
  dlsym with RTLD_NEXT/RTLD_SELF handles.
  Allow symbols from ld-elf.so to be located this way too.
  
  Approved by:	re (kensmith), kan

Modified:
  stable/7/libexec/rtld-elf/   (props changed)
  stable/7/libexec/rtld-elf/rtld.c

Modified: stable/7/libexec/rtld-elf/rtld.c
==============================================================================
--- stable/7/libexec/rtld-elf/rtld.c	Wed Nov  5 12:13:10 2008	(r184683)
+++ stable/7/libexec/rtld-elf/rtld.c	Wed Nov  5 12:28:44 2008	(r184684)
@@ -1891,7 +1891,7 @@ do_dlsym(void *handle, const char *name,
 {
     DoneList donelist;
     const Obj_Entry *obj, *defobj;
-    const Elf_Sym *def;
+    const Elf_Sym *def, *symp;
     unsigned long hash;
     int lockstate;
 
@@ -1917,9 +1917,26 @@ do_dlsym(void *handle, const char *name,
 	    if (handle == RTLD_NEXT)
 		obj = obj->next;
 	    for (; obj != NULL; obj = obj->next) {
-		if ((def = symlook_obj(name, hash, obj, ve, flags)) != NULL) {
-		    defobj = obj;
-		    break;
+	    	if ((symp = symlook_obj(name, hash, obj, ve, flags)) != NULL) {
+		    if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) {
+			def = symp;
+			defobj = obj;
+			if (ELF_ST_BIND(def->st_info) != STB_WEAK)
+			    break;
+		    }
+		}
+	    }
+	    /*
+	     * Search the dynamic linker itself, and possibly resolve the
+	     * symbol from there.  This is how the application links to
+	     * dynamic linker services such as dlopen.  Only the values listed
+	     * in the "exports" array can be resolved from the dynamic linker.
+	     */
+	    if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
+		symp = symlook_obj(name, hash, &obj_rtld, ve, flags);
+		if (symp != NULL && is_exported(symp)) {
+		    def = symp;
+		    defobj = &obj_rtld;
 		}
 	    }
 	} else {



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