From patchwork Wed Oct 1 23:08:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantin Serebryany X-Patchwork-Id: 395709 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E5B92140078 for ; Thu, 2 Oct 2014 09:08:47 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :content-type; q=dns; s=default; b=klL6fxOsi1njXUsIKF1q/lWXtuJbT BVKTPXgOPm+LlwonL6strzvx0YUkorE10K4lpOtYIDT2DtzaX70T7BR9hDHqu0MA hZEiHxaAniQD2TmBMk5Pi2bIux/IBup0MkVwJgIqqsiNqWVj6lkBYVTgYPUejhN5 pIAhQjqwPQrEjg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :content-type; s=default; bh=IXko6AsA1WkLr9qSPq4hA4IeHKM=; b=Ggt NBm2yaP54aLAg8cPoKPzTyUAPWaONC+NNdwn9J5sEnktPLgx7pe1s5Fv9G+dQe0a qjT8OvPj34YJPhBESOGstIUkf51Bg3wqoL4GH5n/7PeAJd7TWW73nWDHpAwOU764 IX7g9f6MBSHwJ3OvAS5AzhUageqlP6HEzJv2eWTU= Received: (qmail 5756 invoked by alias); 1 Oct 2014 23:08:40 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 5746 invoked by uid 89); 1 Oct 2014 23:08:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-vc0-f173.google.com X-Received: by 10.220.91.136 with SMTP id n8mr4768274vcm.57.1412204915730; Wed, 01 Oct 2014 16:08:35 -0700 (PDT) MIME-Version: 1.0 From: Konstantin Serebryany Date: Wed, 1 Oct 2014 16:08:15 -0700 Message-ID: Subject: [PATCH] remove nested functions from elf/dl-load.c To: Roland McGrath , GNU C Library Hi, Please review the patch that removes nested functions from elf/dl-load.c I had to pack 4 parameters into a struct, just like with hack_digit in stdio-common/printf_fp.c recently. With this patch the generated code for _dl_rtld_di_serinfo is ~8 instructions longer than in trunk (larger function prologue/epilogue) and add_path is 2 instructions longer. No regressions in 'make check' on x86_64-linux-gnu (Ubuntu 14.04) 2014-10-01 Kostya Serebryany * elf/dl-load.c (add_path): New function broken out of _dl_rtld_di_serinfo. (_dl_rtld_di_serinfo): Remove a nested function. Update call sites. diff --git a/elf/dl-load.c b/elf/dl-load.c index 016a99c..4e51567 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -2201,49 +2201,62 @@ _dl_map_object (struct link_map *loader, const char *name, &stack_end, nsid); } +struct add_path_args +{ + bool counting; + unsigned int idx; + Dl_serinfo *si; + char *allocptr; +}; + +static void +add_path (struct add_path_args *p, const struct r_search_path_struct *sps, + unsigned int flags) +{ + if (sps->dirs != (void *) -1) + { + struct r_search_path_elem **dirs = sps->dirs; + do + { + const struct r_search_path_elem *const r = *dirs++; + if (p->counting) + { + p->si->dls_cnt++; + p->si->dls_size += MAX (2, r->dirnamelen); + } + else + { + Dl_serpath *const sp = &p->si->dls_serpath[p->idx++]; + sp->dls_name = p->allocptr; + if (r->dirnamelen < 2) + *p->allocptr++ = r->dirnamelen ? '/' : '.'; + else + p->allocptr = __mempcpy (p->allocptr, + r->dirname, r->dirnamelen - 1); + *p->allocptr++ = '\0'; + sp->dls_flags = flags; + } + } + while (*dirs != NULL); + } +} void internal_function _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting) { + struct add_path_args p; if (counting) { si->dls_cnt = 0; si->dls_size = 0; } + p.counting = counting; + p.idx = 0; + p.allocptr = (char *) &si->dls_serpath[si->dls_cnt]; + p.si = si; - unsigned int idx = 0; - char *allocptr = (char *) &si->dls_serpath[si->dls_cnt]; - void add_path (const struct r_search_path_struct *sps, unsigned int flags) -# define add_path(sps, flags) add_path(sps, 0) /* XXX */ - { - if (sps->dirs != (void *) -1) - { - struct r_search_path_elem **dirs = sps->dirs; - do - { - const struct r_search_path_elem *const r = *dirs++; - if (counting) - { - si->dls_cnt++; - si->dls_size += MAX (2, r->dirnamelen); - } - else - { - Dl_serpath *const sp = &si->dls_serpath[idx++]; - sp->dls_name = allocptr; - if (r->dirnamelen < 2) - *allocptr++ = r->dirnamelen ? '/' : '.'; - else - allocptr = __mempcpy (allocptr, - r->dirname, r->dirnamelen - 1); - *allocptr++ = '\0'; - sp->dls_flags = flags; - } - } - while (*dirs != NULL); - } - } +# define add_path(p, sps, flags) add_path(p, sps, 0) /* XXX */ /* When the object has the RUNPATH information we don't use any RPATHs. */ if (loader->l_info[DT_RUNPATH] == NULL) @@ -2255,7 +2268,7 @@ _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting) do { if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH")) - add_path (&l->l_rpath_dirs, XXX_RPATH); + add_path (&p, &l->l_rpath_dirs, XXX_RPATH); l = l->l_loader; } while (l != NULL); @@ -2266,16 +2279,16 @@ _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting) l = GL(dl_ns)[LM_ID_BASE]._ns_loaded; if (l != NULL && l->l_type != lt_loaded && l != loader) if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH")) - add_path (&l->l_rpath_dirs, XXX_RPATH); + add_path (&p, &l->l_rpath_dirs, XXX_RPATH); } } /* Try the LD_LIBRARY_PATH environment variable. */ - add_path (&env_path_list, XXX_ENV); + add_path (&p, &env_path_list, XXX_ENV); /* Look at the RUNPATH information for this binary. */ if (cache_rpath (loader, &loader->l_runpath_dirs, DT_RUNPATH, "RUNPATH")) - add_path (&loader->l_runpath_dirs, XXX_RUNPATH); + add_path (&p, &loader->l_runpath_dirs, XXX_RUNPATH); /* XXX Here is where ld.so.cache gets checked, but we don't have @@ -2283,7 +2296,7 @@ _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting) /* Finally, try the default path. */ if (!(loader->l_flags_1 & DF_1_NODEFLIB)) - add_path (&rtld_search_dirs, XXX_default); + add_path (&p, &rtld_search_dirs, XXX_default); if (counting) /* Count the struct size before the string area, which we didn't