From patchwork Sat Jul 25 10:52:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoming Ni X-Patchwork-Id: 1336229 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=huawei.com Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BDNF61F7xz9sPf for ; Sat, 25 Jul 2020 20:52:26 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 160553857C49; Sat, 25 Jul 2020 10:52:22 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from huawei.com (szxga04-in.huawei.com [45.249.212.190]) by sourceware.org (Postfix) with ESMTPS id 832403858D37 for ; Sat, 25 Jul 2020 10:52:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 832403858D37 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nixiaoming@huawei.com Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 82360B52A883E8CA369E; Sat, 25 Jul 2020 18:52:16 +0800 (CST) Received: from use12-sp2.huawei.com (10.67.189.174) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.487.0; Sat, 25 Jul 2020 18:52:08 +0800 From: Xiaoming Ni To: , , , , , Subject: [PATCH] elf: Sort only uninitialized objects in _dl_map_object_deps() Date: Sat, 25 Jul 2020 18:52:05 +0800 Message-ID: <20200725105205.103328-1-nixiaoming@huawei.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Originating-IP: [10.67.189.174] X-CFilter-Loop: Reflected X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_MANYTO, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: wangle6@huawei.com, nixiaoming@huawei.com Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" TIS ELF Version 1.2 Initialization and Termination Functions: 1. Before the initialization code for any object A is called, the initialization code for any other objects that object A depends on are called. 2. The order in which the dynamic linker calls termination functions is the exact reverse order of their corresponding initialization functions. 3. The dynamic linker ensures that it will not execute any initialization or termination functions more than once. According to 1 and 2: _dl_sort_maps() is used for sorting when dlopen/dlclose. According to 3: At dlopen, only the uninitialized objects need to be sorted. Construct 200 dynamic libraries that depend on each other cyclically. Run the dlopen() for each dynamic library. Before the patch is installed, it takes 214 seconds. After patching, it takes 37 seconds. Signed-off-by: Xiaoming Ni --- elf/dl-deps.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/elf/dl-deps.c b/elf/dl-deps.c index b5a43232a7..5df1e32156 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -152,6 +152,43 @@ preload (struct list *known, unsigned int *nlist, struct link_map *map) map->l_reserved = 1; } +/* TIS ELF Version 1.2 + * Initialization and Termination Functions: + * 1. Before the initialization code for any object A is called, the + * initialization code for any other objects that object A depends on are called. + * 2. The order in which the dynamic linker calls termination functions is the + * exact reverse order of their corresponding initialization functions. + * 3. The dynamic linker ensures that it will not execute any initialization + * or termination functions more than once. + * + * According to 1 and 2, _dl_sort_maps() is used for sorting when dlopen/dlclose. + * According to 3, we only need to sort the uninitialized objects. + */ +static void +_dl_sort_uninit_maps (struct link_map **maps, unsigned int nmaps) +{ + unsigned int s = 0; + unsigned int e = nmaps - 1; + struct link_map *tmp; + + while (s < e) + { + while ((e > 0) && maps[e]->l_init_called) + e--; + while ((s < nmaps) && maps[s]->l_init_called == 0) + s++; + if (s >= e) + break; + tmp = maps[e]; + maps[e] = maps[s]; + maps[s] = tmp; + s++; + e--; + } + + _dl_sort_maps (maps, s, NULL, false); +} + void _dl_map_object_deps (struct link_map *map, struct link_map **preloads, unsigned int npreloads, @@ -611,7 +648,8 @@ Filters not supported with LD_TRACE_PRELINKING")); memcpy (l_initfini, map->l_searchlist.r_list, nlist * sizeof (struct link_map *)); - _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false); + if (map->l_init_called == 0) + _dl_sort_uninit_maps (&l_initfini[1], nlist - 1); /* Terminate the list of dependencies. */ l_initfini[nlist] = NULL;