From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/10877 Path: news.gmane.org!.POSTED!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: Reviving planned ldso changes Date: Wed, 4 Jan 2017 01:06:40 -0500 Message-ID: <20170104060640.GM1555@brightrain.aerifal.cx> References: <20170103054351.GA8459@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="N1GIdlSm9i+YlY4t" X-Trace: blaine.gmane.org 1483510020 26032 195.159.176.226 (4 Jan 2017 06:07:00 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 4 Jan 2017 06:07:00 +0000 (UTC) User-Agent: Mutt/1.5.21 (2010-09-15) To: musl@lists.openwall.com Original-X-From: musl-return-10890-gllmg-musl=m.gmane.org@lists.openwall.com Wed Jan 04 07:06:56 2017 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1cOeip-0005kJ-Tx for gllmg-musl@m.gmane.org; Wed, 04 Jan 2017 07:06:51 +0100 Original-Received: (qmail 5737 invoked by uid 550); 4 Jan 2017 06:06:54 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 5719 invoked from network); 4 Jan 2017 06:06:53 -0000 Content-Disposition: inline In-Reply-To: <20170103054351.GA8459@brightrain.aerifal.cx> Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:10877 Archived-At: --N1GIdlSm9i+YlY4t Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Jan 03, 2017 at 12:43:51AM -0500, Rich Felker wrote: > - Dependency-order ctor execution. I think the walk order looks > something like, starting at a given node (initially the main app or > new library being loaded dynamically), traversing to its first > deps[] entry that hasn't been constructed, or, if none remain, > executing its ctors then traversing back to its needed_by. This > process avoids the need for any call recursion and should be > near-optimal (if not optimal) provided the position in a dso's > deps[] list is saved in the dso struct. Attached is a proposed, completely untested patch to implement dependency order loading, posted for review/comments. In order to work, I think it also needs p->deps to be setup unconditionally (right now it's only setup for dynamically loaded libs). Rich --N1GIdlSm9i+YlY4t Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ctor_dep_order.diff" diff --git a/ldso/dynlink.c b/ldso/dynlink.c index c689084..cb82b2c 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -67,6 +67,7 @@ struct dso { char constructed; char kernel_mapped; struct dso **deps, *needed_by; + size_t next_dep; char *rpath_orig, *rpath; struct tls_module tls; size_t tls_id; @@ -1211,13 +1212,14 @@ void __libc_exit_fini() static void do_init_fini(struct dso *p) { size_t dyn[DYN_CNT]; - int need_locking = libc.threads_minus_1; - /* Allow recursive calls that arise when a library calls - * dlopen from one of its constructors, but block any - * other threads until all ctors have finished. */ - if (need_locking) pthread_mutex_lock(&init_fini_lock); - for (; p; p=p->prev) { - if (p->constructed) continue; + pthread_mutex_lock(&init_fini_lock); + while (!p->constructed) { + while (p->deps[p->next_dep] && p->deps[p->next_dep]->constructed) + p->next_dep++; + if (p->deps[p->next_dep]) { + p = p->deps[p->next_dep++]; + continue; + } p->constructed = 1; decode_vec(p->dynv, dyn, DYN_CNT); if (dyn[0] & ((1<needed_by; } - if (need_locking) pthread_mutex_unlock(&init_fini_lock); + pthread_mutex_unlock(&init_fini_lock); } void __libc_start_init(void) --N1GIdlSm9i+YlY4t--