From owner-svn-src-all@FreeBSD.ORG Wed Apr 22 10:59:06 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id B7DDECC9; Wed, 22 Apr 2015 10:59:06 +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 A4CF81067; Wed, 22 Apr 2015 10:59:06 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t3MAx6LA061798; Wed, 22 Apr 2015 10:59:06 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t3MAx6f0061792; Wed, 22 Apr 2015 10:59:06 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201504221059.t3MAx6f0061792@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 22 Apr 2015 10:59:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r281849 - stable/10/libexec/rtld-elf X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Apr 2015 10:59:06 -0000 Author: kib Date: Wed Apr 22 10:59:05 2015 New Revision: 281849 URL: https://svnweb.freebsd.org/changeset/base/281849 Log: MFC r281549: Implement support for -z global linker option. Modified: stable/10/libexec/rtld-elf/rtld.c stable/10/libexec/rtld-elf/rtld.h Directory Properties: stable/10/ (props changed) Modified: stable/10/libexec/rtld-elf/rtld.c ============================================================================== --- stable/10/libexec/rtld-elf/rtld.c Wed Apr 22 10:57:00 2015 (r281848) +++ stable/10/libexec/rtld-elf/rtld.c Wed Apr 22 10:59:05 2015 (r281849) @@ -1150,8 +1150,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) @@ -1775,22 +1775,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); } } } @@ -2961,13 +2974,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: stable/10/libexec/rtld-elf/rtld.h ============================================================================== --- stable/10/libexec/rtld-elf/rtld.h Wed Apr 22 10:57:00 2015 (r281848) +++ stable/10/libexec/rtld-elf/rtld.h Wed Apr 22 10:59:05 2015 (r281849) @@ -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. */