From owner-svn-src-head@FreeBSD.ORG Wed Apr 15 08:16:36 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2C277A0A; Wed, 15 Apr 2015 08:16:36 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 16E92268; Wed, 15 Apr 2015 08:16:36 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t3F8GZHg022055; Wed, 15 Apr 2015 08:16:35 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t3F8GZo6022053; Wed, 15 Apr 2015 08:16:35 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201504150816.t3F8GZo6022053@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 15 Apr 2015 08:16:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r281549 - head/libexec/rtld-elf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Apr 2015 08:16:36 -0000 Author: kib Date: Wed Apr 15 08:16:34 2015 New Revision: 281549 URL: https://svnweb.freebsd.org/changeset/base/281549 Log: Implement support -z global linker option. It marks the shared object as always participating in the global symbols namespace, regardless of the way the object was brought into the process address space. Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/libexec/rtld-elf/rtld.c head/libexec/rtld-elf/rtld.h Modified: head/libexec/rtld-elf/rtld.c ============================================================================== --- head/libexec/rtld-elf/rtld.c Wed Apr 15 08:13:53 2015 (r281548) +++ head/libexec/rtld-elf/rtld.c Wed Apr 15 08:16:34 2015 (r281549) @@ -1158,8 +1158,8 @@ digest_dynamic1(Obj_Entry *obj, int earl obj->z_noopen = true; if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust) obj->z_origin = true; - /*if (dynp->d_un.d_val & DF_1_GLOBAL) - XXX ;*/ + if (dynp->d_un.d_val & DF_1_GLOBAL) + obj->z_global = true; if (dynp->d_un.d_val & DF_1_BIND_NOW) obj->bind_now = true; if (dynp->d_un.d_val & DF_1_NODELETE) @@ -1790,22 +1790,35 @@ init_dag(Obj_Entry *root) } static void -process_nodelete(Obj_Entry *root) +process_z(Obj_Entry *root) { const Objlist_Entry *elm; + Obj_Entry *obj; /* - * Walk over object DAG and process every dependent object that - * is marked as DF_1_NODELETE. They need to grow their own DAG, - * which then should have its reference upped separately. + * Walk over object DAG and process every dependent object + * that is marked as DF_1_NODELETE or DF_1_GLOBAL. They need + * to grow their own DAG. + * + * For DF_1_GLOBAL, DAG is required for symbol lookups in + * symlook_global() to work. + * + * For DF_1_NODELETE, the DAG should have its reference upped. */ STAILQ_FOREACH(elm, &root->dagmembers, link) { - if (elm->obj != NULL && elm->obj->z_nodelete && - !elm->obj->ref_nodel) { - dbg("obj %s nodelete", elm->obj->path); - init_dag(elm->obj); - ref_dag(elm->obj); - elm->obj->ref_nodel = true; + obj = elm->obj; + if (obj == NULL) + continue; + if (obj->z_nodelete && !obj->ref_nodel) { + dbg("obj %s -z nodelete", obj->path); + init_dag(obj); + ref_dag(obj); + obj->ref_nodel = true; + } + if (obj->z_global && objlist_find(&list_global, obj) == NULL) { + dbg("obj %s -z global", obj->path); + objlist_push_tail(&list_global, obj); + init_dag(obj); } } } @@ -3044,13 +3057,13 @@ dlopen_object(const char *name, int fd, initlist_add_objects(obj, &obj->next, &initlist); } /* - * Process all no_delete objects here, given them own - * DAGs to prevent their dependencies from being unloaded. - * This has to be done after we have loaded all of the - * dependencies, so that we do not miss any. + * Process all no_delete or global objects here, given + * them own DAGs to prevent their dependencies from being + * unloaded. This has to be done after we have loaded all + * of the dependencies, so that we do not miss any. */ if (obj != NULL) - process_nodelete(obj); + process_z(obj); } else { /* * Bump the reference counts for objects on this DAG. If Modified: head/libexec/rtld-elf/rtld.h ============================================================================== --- head/libexec/rtld-elf/rtld.h Wed Apr 15 08:13:53 2015 (r281548) +++ head/libexec/rtld-elf/rtld.h Wed Apr 15 08:16:34 2015 (r281549) @@ -264,6 +264,7 @@ typedef struct Struct_Obj_Entry { 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 z_global : 1; /* Make the object global */ bool ref_nodel : 1; /* Refcount increased to prevent dlclose */ bool init_scanned: 1; /* Object is already on init list. */ bool on_fini_list: 1; /* Object is already on fini list. */