From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS31976 209.132.180.0/23 X-Spam-Status: No, score=-4.0 required=3.0 tests=AWL,BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 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 dcvr.yhbt.net (Postfix) with ESMTPS id 48EAE1F45E for ; Fri, 14 Feb 2020 22:36:59 +0000 (UTC) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:to:references:from:message-id:date :mime-version:in-reply-to:content-type :content-transfer-encoding; q=dns; s=default; b=fV0Kulxv93ngaGtR 9EKuwyvO87hyw0FA00y055/thuwKPkqLDA2p84jJ5hJaf0zOz2RDgdAGBSH8ewaa dSPX57Fof/jm7um/VOtHAg2Q8fUhksYihsPGXZu7wPs+GaWq8Gl04Dk08IYtkBYY qjQ/NZKfJicBIwOahEXdbUg9TIk= 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:subject:to:references:from:message-id:date :mime-version:in-reply-to:content-type :content-transfer-encoding; s=default; bh=1u0LOzZFC/HEdeR560xdk9 cdBpI=; b=NlXOc1HgUO61kIzL/Rmx9DUrNWt38dN+CUy8pgo6bfDQAQCt9d9Baa wL3+t8z5I1x4RCLw/4tXDUPvHmVNaeW3pFdW+rCQUM43gzTUx+e+Dw6tERiA6j9A N8JlkAsllgbZ1JtRltIQCjc3VaceIk7iP1xcB1HTjaZXodIPa4/HE= Received: (qmail 62920 invoked by alias); 14 Feb 2020 22:36:42 -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 Received: (qmail 62832 invoked by uid 89); 14 Feb 2020 22:36:41 -0000 Authentication-Results: sourceware.org; auth=none X-HELO: us-smtp-1.mimecast.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1581719797; 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: in-reply-to:in-reply-to:references:references; bh=OXepALCGStg+s6X1rECaI6pLK1vjPO1hhuuWRJyxj/0=; b=Rdp/D+mm28RP5FnFemg0Y2FugBb2MYKN+Kk9zGFHOIUvIxE+TPb5RSkqtTGTvsyuf3pI00 LqfZdEC5/u66D3IVmUJ5rUXiepmZ55X1LefILwb/Kw1eZbC4mLxScutGOaQHw5UtDs4nGx Vup4rY5XlQsb/rCy16RajODZocD/XMY= Subject: Re: [PATCH 2/4] elf: Extract _dl_sym_post, _dl_sym_find_caller_map from elf/dl-sym.c To: Florian Weimer , libc-alpha@sourceware.org References: <68608ef426b88e73e0e3178497bcfe34dd8a66ef.1581182210.git.fweimer@redhat.com> From: Carlos O'Donell Message-ID: <7dcb0e98-bf5b-4a9c-242a-a0340d038f59@redhat.com> Date: Fri, 14 Feb 2020 17:36:32 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1 MIME-Version: 1.0 In-Reply-To: <68608ef426b88e73e0e3178497bcfe34dd8a66ef.1581182210.git.fweimer@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit On 2/8/20 2:01 PM, Florian Weimer wrote: > The definitions are moved into a new file, elf/dl-sym-post.h, so that > this code can be used by the dynamic loader as well. OK for master. I like the cleanup. Reviewed-by: Carlos O'Donell > --- > elf/dl-sym-post.h | 106 ++++++++++++++++++++++++++++++++++++++++++++++ > elf/dl-sym.c | 86 ++----------------------------------- > 2 files changed, 110 insertions(+), 82 deletions(-) > create mode 100644 elf/dl-sym-post.h > > diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h > new file mode 100644 > index 0000000000..4c4f574633 > --- /dev/null > +++ b/elf/dl-sym-post.h > @@ -0,0 +1,106 @@ > +/* Post-processing of a symbol produced by dlsym, dlvsym. > + Copyright (C) 1999-2020 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + . */ > + > + > +/* Return the link map containing the caller address. */ > +static struct link_map * > +_dl_sym_find_caller_link_map (ElfW(Addr) caller) > +{ > + struct link_map *l = _dl_find_dso_for_object (caller); > + if (l != NULL) > + return l; > + else > + /* If the address is not recognized the call comes from the main > + program (we hope). */ > + return GL(dl_ns)[LM_ID_BASE]._ns_loaded; > +} OK. > + > +/* Translates RESULT, *REF, VALUE into a symbol address from the point > + of view of MATCH. Performs IFUNC resolution and auditing if > + necessary. If MATCH is NULL, CALLER is used to determine it. */ > +static void * > +_dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value, > + ElfW(Addr) caller, struct link_map *match) > +{ > + /* Resolve indirect function address. */ > + if (__glibc_unlikely (ELFW(ST_TYPE) (ref->st_info) == STT_GNU_IFUNC)) > + { > + DL_FIXUP_VALUE_TYPE fixup > + = DL_FIXUP_MAKE_VALUE (result, (ElfW(Addr)) value); > + fixup = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (fixup)); > + value = (void *) DL_FIXUP_VALUE_CODE_ADDR (fixup); > + } > + > +#ifdef SHARED > + /* Auditing checkpoint: we have a new binding. Provide the > + auditing libraries the possibility to change the value and > + tell us whether further auditing is wanted. */ > + if (__glibc_unlikely (GLRO(dl_naudit) > 0)) > + { > + const char *strtab = (const char *) D_PTR (result, > + l_info[DT_STRTAB]); > + /* Compute index of the symbol entry in the symbol table of > + the DSO with the definition. */ > + unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, > + l_info[DT_SYMTAB])); > + > + if (match == NULL) > + match = _dl_sym_find_caller_link_map (caller); > + > + if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0) > + { > + unsigned int altvalue = 0; > + struct audit_ifaces *afct = GLRO(dl_audit); > + /* Synthesize a symbol record where the st_value field is > + the result. */ > + ElfW(Sym) sym = *ref; > + sym.st_value = (ElfW(Addr)) value; > + > + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) > + { > + struct auditstate *match_audit > + = link_map_audit_state (match, cnt); > + struct auditstate *result_audit > + = link_map_audit_state (result, cnt); > + if (afct->symbind != NULL > + && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0 > + || ((result_audit->bindflags & LA_FLG_BINDTO) > + != 0))) > + { > + unsigned int flags = altvalue | LA_SYMB_DLSYM; > + uintptr_t new_value > + = afct->symbind (&sym, ndx, > + &match_audit->cookie, > + &result_audit->cookie, > + &flags, strtab + ref->st_name); > + if (new_value != (uintptr_t) sym.st_value) > + { > + altvalue = LA_SYMB_ALTVALUE; > + sym.st_value = new_value; > + } > + } > + > + afct = afct->next; > + } > + > + value = (void *) sym.st_value; > + } > + } > +#endif > + return value; > +} OK. > diff --git a/elf/dl-sym.c b/elf/dl-sym.c > index b43a50e544..361b926ea9 100644 > --- a/elf/dl-sym.c > +++ b/elf/dl-sym.c > @@ -28,6 +28,7 @@ > #include > #include > #include > +#include > > > #ifdef SHARED > @@ -80,19 +81,6 @@ call_dl_lookup (void *ptr) > args->flags, NULL); > } > > -/* Return the link map containing the caller address. */ > -static inline struct link_map * > -find_caller_link_map (ElfW(Addr) caller) > -{ > - struct link_map *l = _dl_find_dso_for_object (caller); > - if (l != NULL) > - return l; > - else > - /* If the address is not recognized the call comes from the main > - program (we hope). */ > - return GL(dl_ns)[LM_ID_BASE]._ns_loaded; > -} > - > static void * > do_sym (void *handle, const char *name, void *who, > struct r_found_version *vers, int flags) > @@ -106,7 +94,7 @@ do_sym (void *handle, const char *name, void *who, > > if (handle == RTLD_DEFAULT) > { > - match = find_caller_link_map (caller); > + match = _dl_sym_find_caller_link_map (caller); > > /* Search the global scope. We have the simple case where > we look up in the scope of an object which was part of > @@ -140,7 +128,7 @@ do_sym (void *handle, const char *name, void *who, > } > else if (handle == RTLD_NEXT) > { > - match = find_caller_link_map (caller); > + match = _dl_sym_find_caller_link_map (caller); > > if (__glibc_unlikely (match == GL(dl_ns)[LM_ID_BASE]._ns_loaded)) > { > @@ -179,73 +167,7 @@ RTLD_NEXT used in code not dynamically loaded")); > #endif > value = DL_SYMBOL_ADDRESS (result, ref); > > - /* Resolve indirect function address. */ > - if (__glibc_unlikely (ELFW(ST_TYPE) (ref->st_info) == STT_GNU_IFUNC)) > - { > - DL_FIXUP_VALUE_TYPE fixup > - = DL_FIXUP_MAKE_VALUE (result, (ElfW(Addr)) value); > - fixup = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (fixup)); > - value = (void *) DL_FIXUP_VALUE_CODE_ADDR (fixup); > - } > - > -#ifdef SHARED > - /* Auditing checkpoint: we have a new binding. Provide the > - auditing libraries the possibility to change the value and > - tell us whether further auditing is wanted. */ > - if (__glibc_unlikely (GLRO(dl_naudit) > 0)) > - { > - const char *strtab = (const char *) D_PTR (result, > - l_info[DT_STRTAB]); > - /* Compute index of the symbol entry in the symbol table of > - the DSO with the definition. */ > - unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, > - l_info[DT_SYMTAB])); > - > - if (match == NULL) > - match = find_caller_link_map (caller); > - > - if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0) > - { > - unsigned int altvalue = 0; > - struct audit_ifaces *afct = GLRO(dl_audit); > - /* Synthesize a symbol record where the st_value field is > - the result. */ > - ElfW(Sym) sym = *ref; > - sym.st_value = (ElfW(Addr)) value; > - > - for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) > - { > - struct auditstate *match_audit > - = link_map_audit_state (match, cnt); > - struct auditstate *result_audit > - = link_map_audit_state (result, cnt); > - if (afct->symbind != NULL > - && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0 > - || ((result_audit->bindflags & LA_FLG_BINDTO) > - != 0))) > - { > - unsigned int flags = altvalue | LA_SYMB_DLSYM; > - uintptr_t new_value > - = afct->symbind (&sym, ndx, > - &match_audit->cookie, > - &result_audit->cookie, > - &flags, strtab + ref->st_name); > - if (new_value != (uintptr_t) sym.st_value) > - { > - altvalue = LA_SYMB_ALTVALUE; > - sym.st_value = new_value; > - } > - } > - > - afct = afct->next; > - } > - > - value = (void *) sym.st_value; > - } > - } > -#endif > - > - return value; > + return _dl_sym_post (result, ref, value, caller, match); > } > > return NULL; > -- Cheers, Carlos.