Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Oct 2013 05:49:21 +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-9@freebsd.org
Subject:   svn commit: r256436 - stable/9/libexec/rtld-elf
Message-ID:  <201310140549.r9E5nLgO076967@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Oct 14 05:49:20 2013
New Revision: 256436
URL: http://svnweb.freebsd.org/changeset/base/256436

Log:
  MFC r256101:
  Implement support for the interpose dso flag.

Modified:
  stable/9/libexec/rtld-elf/rtld.c
  stable/9/libexec/rtld-elf/rtld.h
Directory Properties:
  stable/9/libexec/rtld-elf/   (props changed)

Modified: stable/9/libexec/rtld-elf/rtld.c
==============================================================================
--- stable/9/libexec/rtld-elf/rtld.c	Mon Oct 14 05:44:16 2013	(r256435)
+++ stable/9/libexec/rtld-elf/rtld.c	Mon Oct 14 05:49:20 2013	(r256436)
@@ -116,6 +116,7 @@ static Objlist_Entry *objlist_find(Objli
 static void objlist_init(Objlist *);
 static void objlist_push_head(Objlist *, Obj_Entry *);
 static void objlist_push_tail(Objlist *, Obj_Entry *);
+static void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *);
 static void objlist_remove(Objlist *, Obj_Entry *);
 static void *path_enumerate(const char *, path_enum_proc, void *);
 static int relocate_object_dag(Obj_Entry *root, bool bind_now,
@@ -323,6 +324,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
     Objlist_Entry *entry;
     Obj_Entry *obj;
     Obj_Entry **preload_tail;
+    Obj_Entry *last_interposer;
     Objlist initlist;
     RtldLockState lockstate;
     char *library_path_rpath;
@@ -537,8 +539,14 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
 	die();
 
     /* Make a list of all objects loaded at startup. */
+    last_interposer = obj_main;
     for (obj = obj_list;  obj != NULL;  obj = obj->next) {
-	objlist_push_tail(&list_main, obj);
+	if (obj->z_interpose && obj != obj_main) {
+	    objlist_put_after(&list_main, last_interposer, obj);
+	    last_interposer = obj;
+	} else {
+	    objlist_push_tail(&list_main, obj);
+	}
     	obj->refcount++;
     }
 
@@ -1132,6 +1140,8 @@ digest_dynamic1(Obj_Entry *obj, int earl
 		    obj->z_nodelete = true;
 		if (dynp->d_un.d_val & DF_1_LOADFLTR)
 		    obj->z_loadfltr = true;
+		if (dynp->d_un.d_val & DF_1_INTERPOSE)
+		    obj->z_interpose = true;
 		if (dynp->d_un.d_val & DF_1_NODEFLIB)
 		    obj->z_nodeflib = true;
 	    break;
@@ -1980,6 +1990,7 @@ static int
 load_preload_objects(void)
 {
     char *p = ld_preload;
+    Obj_Entry *obj;
     static const char delim[] = " \t:;";
 
     if (p == NULL)
@@ -1992,8 +2003,10 @@ load_preload_objects(void)
 
 	savech = p[len];
 	p[len] = '\0';
-	if (load_object(p, -1, NULL, 0) == NULL)
+	obj = load_object(p, -1, NULL, 0);
+	if (obj == NULL)
 	    return -1;	/* XXX - cleanup */
+	obj->z_interpose = true;
 	p[len] = savech;
 	p += len;
 	p += strspn(p, delim);
@@ -2382,6 +2395,23 @@ objlist_push_tail(Objlist *list, Obj_Ent
 }
 
 static void
+objlist_put_after(Objlist *list, Obj_Entry *listobj, Obj_Entry *obj)
+{
+	Objlist_Entry *elm, *listelm;
+
+	STAILQ_FOREACH(listelm, list, link) {
+		if (listelm->obj == listobj)
+			break;
+	}
+	elm = NEW(Objlist_Entry);
+	elm->obj = obj;
+	if (listelm != NULL)
+		STAILQ_INSERT_AFTER(list, listelm, elm, link);
+	else
+		STAILQ_INSERT_TAIL(list, elm, link);
+}
+
+static void
 objlist_remove(Objlist *list, Obj_Entry *obj)
 {
     Objlist_Entry *elm;

Modified: stable/9/libexec/rtld-elf/rtld.h
==============================================================================
--- stable/9/libexec/rtld-elf/rtld.h	Mon Oct 14 05:44:16 2013	(r256435)
+++ stable/9/libexec/rtld-elf/rtld.h	Mon Oct 14 05:49:20 2013	(r256436)
@@ -259,6 +259,7 @@ typedef struct Struct_Obj_Entry {
     bool z_nodelete : 1;	/* Do not unload the object and dependencies */
     bool z_noopen : 1;		/* Do not load on dlopen */
     bool z_loadfltr : 1;	/* Immediately load filtees */
+    bool z_interpose : 1;	/* Interpose all objects but main */
     bool z_nodeflib : 1;	/* Don't search default library path */
     bool ref_nodel : 1;		/* Refcount increased to prevent dlclose */
     bool init_scanned: 1;	/* Object is already on init list. */



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