From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25143 invoked by alias); 1 Sep 2016 05:03:20 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 25129 invoked by uid 89); 1 Sep 2016 05:03:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=distinction, H*Ad:U*uweigand, FUNCTION, s390x X-HELO: mail-lf0-f65.google.com Received: from mail-lf0-f65.google.com (HELO mail-lf0-f65.google.com) (209.85.215.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Sep 2016 05:03:09 +0000 Received: by mail-lf0-f65.google.com with SMTP id e7so2293355lfe.2 for ; Wed, 31 Aug 2016 22:03:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=AWyDsX/bK1E3h5eEIlMD8mMT1swJtc89yCUXzGYHKO8=; b=dKxt3VagrxRNyxID72pLvimpiACRIBJtlub4M5j+S3sdc6bta6IYEPy3ymcQPsYAgt n/HyoPsXWlv9GDtDSKimAg54nfqBVYyaCB4RPeoNZl+ohBuRRFRSjyEIMItsl39aCvRH 5B5Y5gaeH+3s5hE1kDb1KKm5hQ/+VxXnn9uIilkS3GIs/WjgMXxxPzIXUykoQLqVYfaS ZoH2rkRRAifW1ilVUtZe9IEWyebJ30orP2lRlBxiqsPXd4Ahyloo07jSIsTwTlAUPp13 /281O1mQ2sHKclH3QljpIDW2iluRxj9fDn2RjsJf+TeADWD1nl+5mNHkcceju1rBh3uY Iwxg== X-Gm-Message-State: AE9vXwMiMmDKZOeYnw179bJj597+nZuL9fWeAB42oVIvypPZp3nckCfBvmkdb29aWhLaeRLmx2n7lYellVd8YQ== X-Received: by 10.25.207.10 with SMTP id f10mr3838834lfg.108.1472706186936; Wed, 31 Aug 2016 22:03:06 -0700 (PDT) MIME-Version: 1.0 Received: by 10.25.16.224 with HTTP; Wed, 31 Aug 2016 22:03:06 -0700 (PDT) In-Reply-To: References: From: Andrew Pinski Date: Thu, 01 Sep 2016 05:03:00 -0000 Message-ID: Subject: Re: [PATCH] Pass HWCAP to ifunc resolver To: Andreas Arnez Cc: "gdb-patches@sourceware.org" , Ulrich Weigand Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2016-09/txt/msg00001.txt.bz2 On Wed, Aug 31, 2016 at 4:49 AM, Andreas Arnez wrote: > On various GNU Elf architectures, including AArch64, ARM, s390/s390x, > ppc32/64, and sparc32/64, the dynamic loader passes HWCAP as a parameter > to each ifunc resolver. Currently there is an open glibc Bugzilla that > requests this to be generalized to all architectures: > > https://sourceware.org/bugzilla/show_bug.cgi?id=19766 > > And various ifunc resolvers already rely on receiving HWCAP. Currently > GDB always calls an ifunc resolver without any arguments; thus the > resolver may receive garbage, and based on that, the resolver may decide > to return a function that is not suited for the given platform. > > This patch always passes HWCAP to ifunc resolvers, even on systems where > the dynamic loader currently behaves otherwise. The rationale is > that (1) the dynamic loader may get adjusted on those systems as well in > the future; (2) passing an unused argument should not cause a problem > with existing resolvers; and (3) the logic is much simpler without such > a distinction. Doesn't some targets pass HWCAP2 too? Thanks, Andrew > > gdb/ChangeLog: > > * elfread.c (auxv.h): New include. > (elf_gnu_ifunc_resolve_addr): Pass HWCAP to ifunc resolver. > > gdb/testsuite/ChangeLog: > > * gdb.base/gnu-ifunc-lib.c (resolver_hwcap): New external > variable declaration. > (gnu_ifunc): Add parameter hwcap. Store it in resolver_hwcap. > * gdb.base/gnu-ifunc.c (resolver_hwcap): New global variable. > * gdb.base/gnu-ifunc.exp: Add test to verify that the resolver > received HWCAP as its argument. > --- > gdb/elfread.c | 13 ++++++++++--- > gdb/testsuite/gdb.base/gnu-ifunc-lib.c | 4 +++- > gdb/testsuite/gdb.base/gnu-ifunc.c | 4 ++++ > gdb/testsuite/gdb.base/gnu-ifunc.exp | 15 +++++++++++++++ > 4 files changed, 32 insertions(+), 4 deletions(-) > > diff --git a/gdb/elfread.c b/gdb/elfread.c > index e90466b..84355cf 100644 > --- a/gdb/elfread.c > +++ b/gdb/elfread.c > @@ -46,6 +46,7 @@ > #include "gdb_bfd.h" > #include "build-id.h" > #include "location.h" > +#include "auxv.h" > > extern void _initialize_elfread (void); > > @@ -860,6 +861,8 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc) > CORE_ADDR start_at_pc, address; > struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func; > struct value *function, *address_val; > + CORE_ADDR hwcap = 0; > + struct value *hwcap_val; > > /* Try first any non-intrusive methods without an inferior call. */ > > @@ -875,10 +878,14 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc) > function = allocate_value (func_func_type); > set_value_address (function, pc); > > - /* STT_GNU_IFUNC resolver functions have no parameters. FUNCTION is the > - function entry address. ADDRESS may be a function descriptor. */ > + /* STT_GNU_IFUNC resolver functions usually receive the HWCAP vector as > + parameter. FUNCTION is the function entry address. ADDRESS may be a > + function descriptor. */ > > - address_val = call_function_by_hand (function, 0, NULL); > + target_auxv_search (¤t_target, AT_HWCAP, &hwcap); > + hwcap_val = value_from_longest (builtin_type (gdbarch) > + ->builtin_unsigned_long, hwcap); > + address_val = call_function_by_hand (function, 1, &hwcap_val); > address = value_as_address (address_val); > address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, > ¤t_target); > diff --git a/gdb/testsuite/gdb.base/gnu-ifunc-lib.c b/gdb/testsuite/gdb.base/gnu-ifunc-lib.c > index 8a55f60..0c0aeef 100644 > --- a/gdb/testsuite/gdb.base/gnu-ifunc-lib.c > +++ b/gdb/testsuite/gdb.base/gnu-ifunc-lib.c > @@ -16,6 +16,7 @@ > along with this program. If not, see . */ > > extern volatile int gnu_ifunc_initialized; > +extern volatile unsigned long resolver_hwcap; > extern int init_stub (int arg); > extern int final (int arg); > > @@ -24,8 +25,9 @@ typedef int (*final_t) (int arg); > asm (".type gnu_ifunc, %gnu_indirect_function"); > > final_t > -gnu_ifunc (void) > +gnu_ifunc (unsigned long hwcap) > { > + resolver_hwcap = hwcap; > if (! gnu_ifunc_initialized) > return init_stub; > else > diff --git a/gdb/testsuite/gdb.base/gnu-ifunc.c b/gdb/testsuite/gdb.base/gnu-ifunc.c > index c68866e..77dea30 100644 > --- a/gdb/testsuite/gdb.base/gnu-ifunc.c > +++ b/gdb/testsuite/gdb.base/gnu-ifunc.c > @@ -35,6 +35,10 @@ final (int arg) > > volatile int gnu_ifunc_initialized; > > +/* This stores the argument received by the ifunc resolver. */ > + > +volatile unsigned long resolver_hwcap = -1; > + > static void > gnu_ifunc_pre (void) > { > diff --git a/gdb/testsuite/gdb.base/gnu-ifunc.exp b/gdb/testsuite/gdb.base/gnu-ifunc.exp > index 097e48a9..3b2775b 100644 > --- a/gdb/testsuite/gdb.base/gnu-ifunc.exp > +++ b/gdb/testsuite/gdb.base/gnu-ifunc.exp > @@ -76,6 +76,21 @@ gdb_continue_to_breakpoint "break-at-call" ".*break-at-call.*" > > gdb_test "p gnu_ifunc (3)" " = 4" > > +# Test that the resolver received its argument. > + > +set actual_hwcap "0x0" > +set test "info auxv" > +gdb_test_multiple $test $test { > + -re "\r\n\\d+\\s+AT_HWCAP\[^\r\n\]+($hex)\r\n.*$gdb_prompt $" { > + set actual_hwcap $expect_out(1,string) > + } > + -re ".*$gdb_prompt $" { > + pass "$test (no HWCAP)" > + } > +} > + > +gdb_test "p/x resolver_hwcap" "= $actual_hwcap" "resolver received HWCAP" > + > # Test GDB will skip the gnu_ifunc resolver on first call. > > gdb_test "step" "\r\nfinal .*" > -- > 2.3.0 >