From nobody Sat May 10 19:33:12 2025 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4ZvwyJ4wnGz5vkf7; Sat, 10 May 2025 19:33:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ZvwyJ49Zsz3TFs; Sat, 10 May 2025 19:33:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1746905592; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=SYEN39I+BrJj+6w7UQMm+Le97JmAItPUO2iY9eQ2Gg0=; b=uLGnXiafMqMaUJN/dz0I5wXtWbcCPM+l9IwGeoZDLMc2wnt+vWtNW5iiptS3iima8htsaw Q7EkRRAtuGPWdFoeOM4Nuh7fDB2X8EV/ZtwDwl5lctxrb9f47BNzGX86ioM5/oiFGA8MHt JdkEkPQPhoXEX7mNssN95C4fFP/8b+PAeKYRZSqeh7I1YpSL2r30Cd9/EiaLIpTB4Lh5iB l2HSwobxSJPeZZO6Kvk2MkWCdWvu5pLq2ycWXD6m9FLfrjH+c5aeXuqJitSIQ45HLC8NqV xGkrJu62ZB1Kog8rpYl/oMluiUh2tLTEVjLr0iG1aebnpMWuBETgPl8DJmV0Pw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1746905592; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=SYEN39I+BrJj+6w7UQMm+Le97JmAItPUO2iY9eQ2Gg0=; b=seaNOv8trISNpD/vUcazi/FMY+cgjL/+ANKD82LvgQ5yzOdgpGuvzuSpeXCNKiYuiZ8u2f 9i6oKMY7/poVoNL1xQeBd+4rjQTv5iE/ga6iwgPuYtYpGJKD1qm7MIgsRJYEVTfQp4T84N Q7jizWYj4eIWKMimeRRKPlshxZa92L2XVNeV9SZ78RO8u+LrOknRB/CG2z+cbEioD0qqGV xfJF5Jsr2XwyT0HAB1poUUJxbbRNl7VPnGS1qCs0rqxOadjW92kJGR9wh0O12h83CZKk73 U8E0h0OeWGGHYt3DI2A8OJzAMb/CrbRDGWU5xfcdiYQ8pvgk7MekxTeC9LtXDg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1746905592; a=rsa-sha256; cv=none; b=aEuURR6c6snFYETIfzybcj8hKwYjrzuB2A4vdXqaztG8rRRvMP+THvOzpg/nwK2e1EK5zj Eb0p1J7mE90mcFmWCtolITbxDn+mPBJx+6ATsxjZiz4TqAzl6d8rw2k839faFlCNUKAW3p MPY5Em5ws4y6zL0rPSx5olHmAa1BsTpSNDdiKy6lWjCT3yecy3hQeqfwa4pw4lqnKIRu9H jwgq0+a+vGtD7dkwJ7batunmDBsXSoSkdYGBFYAFmk/2n6eAz7mixbB3TEl69Z1Gx5wHgq F8TTBhmwmruQe21k1bYCQESqc9GfMW2a5m2kXbYZHjTetVl86HsmjwIJobyQaQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4ZvwyJ3cLdzytq; Sat, 10 May 2025 19:33:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 54AJXCfo055065; Sat, 10 May 2025 19:33:12 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 54AJXCmQ055062; Sat, 10 May 2025 19:33:12 GMT (envelope-from git) Date: Sat, 10 May 2025 19:33:12 GMT Message-Id: <202505101933.54AJXCmQ055062@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: f31acb9d5cb2 - stable/14 - rtld: add support for -z initfirst List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: f31acb9d5cb25678cb497cb28bc466442b99239f Auto-Submitted: auto-generated The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=f31acb9d5cb25678cb497cb28bc466442b99239f commit f31acb9d5cb25678cb497cb28bc466442b99239f Author: Konstantin Belousov AuthorDate: 2025-05-03 08:14:25 +0000 Commit: Konstantin Belousov CommitDate: 2025-05-10 18:57:46 +0000 rtld: add support for -z initfirst (cherry picked from commit 78aaab9f1cf359f3b7325e4369653f6b50593393) --- libexec/rtld-elf/rtld.c | 138 +++++++++++++++++++++++++++++++++++------------- libexec/rtld-elf/rtld.h | 1 + 2 files changed, 103 insertions(+), 36 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index ba8e2aea6e7c..8a3129093e8c 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -114,8 +114,11 @@ static void init_dag(Obj_Entry *); static void init_marker(Obj_Entry *); static void init_pagesizes(Elf_Auxinfo **aux_info); static void init_rtld(caddr_t, Elf_Auxinfo **); -static void initlist_add_neededs(Needed_Entry *, Objlist *); -static void initlist_add_objects(Obj_Entry *, Obj_Entry *, Objlist *); +static void initlist_add_neededs(Needed_Entry *, Objlist *, Objlist *); +static void initlist_add_objects(Obj_Entry *, Obj_Entry *, Objlist *, + Objlist *); +static void initlist_for_loaded_obj(Obj_Entry *obj, Obj_Entry *tail, + Objlist *list); static int initlist_objects_ifunc(Objlist *, bool, int, RtldLockState *); static void linkmap_add(Obj_Entry *); static void linkmap_delete(Obj_Entry *); @@ -932,8 +935,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) /* Make a list of init functions to call. */ objlist_init(&initlist); - initlist_add_objects(globallist_curr(TAILQ_FIRST(&obj_list)), - preload_tail, &initlist); + initlist_for_loaded_obj(globallist_curr(TAILQ_FIRST(&obj_list)), + preload_tail, &initlist); r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */ @@ -1510,6 +1513,8 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath, obj->bind_now = true; if (dynp->d_un.d_val & DF_STATIC_TLS) obj->static_tls = true; + if (dynp->d_un.d_val & DF_1_INITFIRST) + obj->z_initfirst = true; break; #ifdef __powerpc__ @@ -2518,15 +2523,15 @@ psa_filled: * when this function is called. */ static void -initlist_add_neededs(Needed_Entry *needed, Objlist *list) +initlist_add_neededs(Needed_Entry *needed, Objlist *list, Objlist *iflist) { /* Recursively process the successor needed objects. */ if (needed->next != NULL) - initlist_add_neededs(needed->next, list); + initlist_add_neededs(needed->next, list, iflist); /* Process the current needed object. */ if (needed->obj != NULL) - initlist_add_objects(needed->obj, needed->obj, list); + initlist_add_objects(needed->obj, needed->obj, list, iflist); } /* @@ -2539,36 +2544,97 @@ initlist_add_neededs(Needed_Entry *needed, Objlist *list) * held when this function is called. */ static void -initlist_add_objects(Obj_Entry *obj, Obj_Entry *tail, Objlist *list) +initlist_for_loaded_obj(Obj_Entry *obj, Obj_Entry *tail, Objlist *list) { - Obj_Entry *nobj; + Objlist iflist; /* initfirst objs and their needed */ + Objlist_Entry *tmp; - if (obj->init_scanned || obj->init_done) - return; - obj->init_scanned = true; - - /* Recursively process the successor objects. */ - nobj = globallist_next(obj); - if (nobj != NULL && obj != tail) - initlist_add_objects(nobj, tail, list); - - /* Recursively process the needed objects. */ - if (obj->needed != NULL) - initlist_add_neededs(obj->needed, list); - if (obj->needed_filtees != NULL) - initlist_add_neededs(obj->needed_filtees, list); - if (obj->needed_aux_filtees != NULL) - initlist_add_neededs(obj->needed_aux_filtees, list); - - /* Add the object to the init list. */ - objlist_push_tail(list, obj); - - /* Add the object to the global fini list in the reverse order. */ - if ((obj->fini != (Elf_Addr)NULL || obj->fini_array != (Elf_Addr)NULL) - && !obj->on_fini_list) { - objlist_push_head(&list_fini, obj); - obj->on_fini_list = true; - } + objlist_init(&iflist); + initlist_add_objects(obj, tail, list, &iflist); + + STAILQ_FOREACH(tmp, &iflist, link) { + Obj_Entry *tobj = tmp->obj; + + if ((tobj->fini != (Elf_Addr)NULL || + tobj->fini_array != (Elf_Addr)NULL) && + !tobj->on_fini_list) { + objlist_push_tail(&list_fini, tobj); + tobj->on_fini_list = true; + } + } + + /* + * This might result in the same object appearing more + * than once on the init list. objlist_call_init() + * uses obj->init_scanned to avoid dup calls. + */ + STAILQ_REVERSE(&iflist, Struct_Objlist_Entry, link); + STAILQ_FOREACH(tmp, &iflist, link) + objlist_push_head(list, tmp->obj); + + objlist_clear(&iflist); +} + +static void +initlist_add_objects(Obj_Entry *obj, Obj_Entry *tail, Objlist *list, + Objlist *iflist) +{ + Obj_Entry *nobj; + + if (obj->init_done) + return; + + if (obj->z_initfirst || list == NULL) { + /* + * Ignore obj->init_scanned. The object might indeed + * already be on the init list, but due to being + * needed by an initfirst object, we must put it at + * the head of the init list. obj->init_done protects + * against double-initialization. + */ + if (obj->needed != NULL) + initlist_add_neededs(obj->needed, NULL, iflist); + if (obj->needed_filtees != NULL) + initlist_add_neededs(obj->needed_filtees, NULL, + iflist); + if (obj->needed_aux_filtees != NULL) + initlist_add_neededs(obj->needed_aux_filtees, + NULL, iflist); + objlist_push_tail(iflist, obj); + } else { + if (obj->init_scanned) + return; + obj->init_scanned = true; + + /* Recursively process the successor objects. */ + nobj = globallist_next(obj); + if (nobj != NULL && obj != tail) + initlist_add_objects(nobj, tail, list, iflist); + + /* Recursively process the needed objects. */ + if (obj->needed != NULL) + initlist_add_neededs(obj->needed, list, iflist); + if (obj->needed_filtees != NULL) + initlist_add_neededs(obj->needed_filtees, list, + iflist); + if (obj->needed_aux_filtees != NULL) + initlist_add_neededs(obj->needed_aux_filtees, list, + iflist); + + /* Add the object to the init list. */ + objlist_push_tail(list, obj); + + /* + * Add the object to the global fini list in the + * reverse order. + */ + if ((obj->fini != (Elf_Addr)NULL || + obj->fini_array != (Elf_Addr)NULL) && + !obj->on_fini_list) { + objlist_push_head(&list_fini, obj); + obj->on_fini_list = true; + } + } } static void @@ -3824,7 +3890,7 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags, */ } else { /* Make list of init functions to call. */ - initlist_add_objects(obj, obj, &initlist); + initlist_for_loaded_obj(obj, obj, &initlist); } /* * Process all no_delete or global objects here, given diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index 97187b24ce84..8d0b8bfed2ab 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -256,6 +256,7 @@ typedef struct Struct_Obj_Entry { bool z_nodeflib : 1; /* Don't search default library path */ bool z_global : 1; /* Make the object global */ bool z_pie : 1; /* Object proclaimed itself PIE executable */ + bool z_initfirst : 1; /* Proceed initializers before other objects */ bool static_tls : 1; /* Needs static TLS allocation */ bool static_tls_copied : 1; /* Needs static TLS copying */ bool ref_nodel : 1; /* Refcount increased to prevent dlclose */