From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id kY3gMKfF/V9JRwAAWB0awg (envelope-from ) for ; Tue, 12 Jan 2021 10:52:07 -0500 Received: by simark.ca (Postfix, from userid 112) id BC0591EF7E; Tue, 12 Jan 2021 10:52:07 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,NORMAL_HTTP_TO_IP,RDNS_NONE, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 0F2531E940 for ; Tue, 12 Jan 2021 10:52:07 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6BED138930CD; Tue, 12 Jan 2021 15:52:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6BED138930CD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1610466726; bh=OwZo4IIVpZTwAB/cg2qafFCYnKXTUss78IeVLMYrxts=; h=To:Subject:References:Date:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=i1ZnYu+R0EahTBpdKB936t/I8BHatkxCcagdcwwYwIcU0LqFpocYDPl9bWHD/Qf6w mi4ACyW5fWJ9shqaYow1rG/5sGHbSaUHbWlfXDk/ZxtjHPl1ELS0XydshB1pYDWeJZ H9gwY4YIQ/TawGF0qTVgKauxJfjKd/ZPOZmx28cU= Received: from mail.sergiodj.net (mail.sergiodj.net [IPv6:2607:5300:60:3666::3]) by sourceware.org (Postfix) with ESMTPS id 9473D3858031 for ; Tue, 12 Jan 2021 15:52:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9473D3858031 Received: from localhost (bras-base-toroon1016w-grc-31-76-64-52-221.dsl.bell.ca [76.64.52.221]) by mail.sergiodj.net (Postfix) with ESMTPSA id 0E43AA0073; Tue, 12 Jan 2021 10:52:03 -0500 (EST) To: Sergio Durigan Junior via Gdb-patches Subject: Re: [PATCH] Change handling of '!' operator in stap probes References: <20201231230205.264712-1-tom@tromey.com> <87h7ny30xu.fsf@paluero> X-URL: http://blog.sergiodj.net Date: Tue, 12 Jan 2021 10:52:02 -0500 In-Reply-To: <87h7ny30xu.fsf@paluero> (Sergio Durigan Junior via Gdb-patches's message of "Sun, 03 Jan 2021 02:59:57 -0500") Message-ID: <87lfcy5f19.fsf@paluero> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergio Durigan Junior via Gdb-patches Reply-To: Sergio Durigan Junior Cc: Tom Tromey Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" On Sunday, January 03 2020, Sergio Durigan Junior via Gdb-patches wrote: > On Thursday, December 31 2020, Tom Tromey wrote: > >> While working on the expression rewrite, I noticed that the '!' >> operator is handled as if it were a binary operator. However, this >> seems incorrect. Instead, I think it should be handled alongside the >> other unary operators in stap_parse_single_operand. >> >> This patch makes this change. Ping. > > Thanks for the patch, Tom. > > This code was written based on the information contained here: > > https://sourceware.org/binutils/docs/as/Infix-Ops.html > > You can see that it says: > > ! > Bitwise Or Not > > The problem is that, when we examine gas' source code, we see that it > doesn't treat '!' as "bitwise or not" (fortunately!), but as the > "logical not": > > https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gas/symbols.c;h=f6e4b718ef719eef8a7e6e29dbadf3605058403d;hb=HEAD#l1128 > > OK, this means that our stap-probe.c is not completely wrong: the enum > should indeed be named UNOP_LOGICAL_NOT. > > Now, when we check to see if the precedence assigned to UNOP_LOGICAL_NOT > is the right one, we see that it is: > > https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gas/expr.c;h=1b420d928cde50456af0137529b8215294ba521d;hb=HEAD#l1481 > > > /* Rank Examples > 0 operand, (expression) > 1 || > 2 && > 3 == <> < <= >= > > 4 + - > 5 used for * / % in MRI mode > 6 & ^ ! | > ... > > Huh, interesting. Anyway, this whole investigation (plus the fact that, > as you mentioned, we don't have tests to exercise this part of the code) > made me uncover a few latent bugs on the stap parser code, so I'm > sending a patch that incorporates part of your changes and also fixes > the issues I found. As a bonus, I'm proposing a new testcase > (amd64-only) to make sure that we expand the coverage of this code. > > WDYT? > > -- > Sergio > GPG key ID: 237A 54B1 0287 28BF 00EF 31F4 D0EB 7628 65FC 5E36 > Please send encrypted e-mail if possible > https://sergiodj.net/ > > From da02db7cacef62ce085d5715b1339b24d8f2260c Mon Sep 17 00:00:00 2001 > From: Sergio Durigan Junior > Date: Sun, 3 Jan 2021 02:42:52 -0500 > Subject: [PATCH] Fix a few stap parser issues and add a new test for probe > expressions > > The creation of this patch was motivated by Tom's "Change handling of > '!' operator in stap probes" patch. > > While reviewing his patch, I stumbled upon a few issues with the stap > expression parser. They are: > > - As it turns out, even with Tom's patch applied the parser doesn't > properly handle the '!' operator. The underlying issue was the fact > that stap_parse_argument_conditionally also needed to be patched in > order to recognize '!' as an operator that is part of a single > operand, and parse it accordingly. > > - While writing the testcase I'm proposing on this patch, I found that > parenthesized sub-expressions were not being parsed correctly when > there was another term after them. For example: > > 1 - (2 + 3) + 4 > > In this case, the parser was considering "1" to be the left-side of > the expression, and "(2 + 3) + 4" to be the right-side. The patch > fixes the parser by making it identify whether a parenthesized > sub-expression has just been parsed, and act accordingly. > > I've tested this on my Debian testing amd64, and everything seems OK. > > gdb/ChangeLog: > 2021-01-03 Sergio Durigan Junior > Tom Tromey > > * stap-probe.c (stap_parse_single_operand): Handle '!' > operator. > (stap_parse_argument_conditionally): Likewise. > Skip spaces after processing open-parenthesis sub-expression. > (stap_parse_argument_1): Skip spaces after call to > stap_parse_argument_conditionally. > Handle case when right-side expression is a parenthesized > sub-expression. > Skip spaces after call to stap_parse_argument_1. > > gdb/testsuite/ChangeLog: > 2021-01-03 Sergio Durigan Junior > > * gdb.arch/amd64-stap-expressions.S: New file. > * gdb.arch/amd64-stap-expressions.exp: New file. > --- > gdb/stap-probe.c | 31 +++++++-- > .../gdb.arch/amd64-stap-expressions.S | 43 ++++++++++++ > .../gdb.arch/amd64-stap-expressions.exp | 68 +++++++++++++++++++ > 3 files changed, 137 insertions(+), 5 deletions(-) > create mode 100644 gdb/testsuite/gdb.arch/amd64-stap-expressions.S > create mode 100644 gdb/testsuite/gdb.arch/amd64-stap-expressions.exp > > diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c > index c2ddd047f6..224dd5714f 100644 > --- a/gdb/stap-probe.c > +++ b/gdb/stap-probe.c > @@ -870,7 +870,7 @@ stap_parse_single_operand (struct stap_parse_info *p) > return; > } > > - if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+') > + if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' || *p->arg == '!') > { > char c = *p->arg; > /* We use this variable to do a lookahead. */ > @@ -924,6 +924,8 @@ stap_parse_single_operand (struct stap_parse_info *p) > write_exp_elt_opcode (&p->pstate, UNOP_NEG); > else if (c == '~') > write_exp_elt_opcode (&p->pstate, UNOP_COMPLEMENT); > + else if (c == '!') > + write_exp_elt_opcode (&p->pstate, UNOP_LOGICAL_NOT); > } > } > else if (isdigit (*p->arg)) > @@ -1012,7 +1014,7 @@ stap_parse_argument_conditionally (struct stap_parse_info *p) > { > gdb_assert (gdbarch_stap_is_single_operand_p (p->gdbarch)); > > - if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' /* Unary. */ > + if (*p->arg == '-' || *p->arg == '~' || *p->arg == '+' || *p->arg == '!' > || isdigit (*p->arg) > || gdbarch_stap_is_single_operand (p->gdbarch, p->arg)) > stap_parse_single_operand (p); > @@ -1027,11 +1029,12 @@ stap_parse_argument_conditionally (struct stap_parse_info *p) > > stap_parse_argument_1 (p, 0, STAP_OPERAND_PREC_NONE); > > - --p->inside_paren_p; > + p->arg = skip_spaces (p->arg); > if (*p->arg != ')') > - error (_("Missign close-paren on expression `%s'."), > + error (_("Missign close-parenthesis on expression `%s'."), > p->saved_arg); > > + --p->inside_paren_p; > ++p->arg; > if (p->inside_paren_p) > p->arg = skip_spaces (p->arg); > @@ -1067,6 +1070,9 @@ stap_parse_argument_1 (struct stap_parse_info *p, bool has_lhs, > stap_parse_argument_conditionally (p); > } > > + if (p->inside_paren_p) > + p->arg = skip_spaces (p->arg); > + > /* Start to parse the right-side, and to "join" left and right sides > depending on the operation specified. > > @@ -1104,8 +1110,21 @@ stap_parse_argument_1 (struct stap_parse_info *p, bool has_lhs, > if (p->inside_paren_p) > p->arg = skip_spaces (p->arg); > > - /* Parse the right-side of the expression. */ > + /* Parse the right-side of the expression. > + > + We save whether the right-side is a parenthesized > + subexpression because, if it is, we will have to finish > + processing this part of the expression before continuing. */ > + bool paren_subexp = *p->arg == '('; > + > stap_parse_argument_conditionally (p); > + if (p->inside_paren_p) > + p->arg = skip_spaces (p->arg); > + if (paren_subexp) > + { > + write_exp_elt_opcode (&p->pstate, opcode); > + continue; > + } > > /* While we still have operators, try to parse another > right-side, but using the current right-side as a left-side. */ > @@ -1130,6 +1149,8 @@ stap_parse_argument_1 (struct stap_parse_info *p, bool has_lhs, > /* Parse the right-side of the expression, but since we already > have a left-side at this point, set `has_lhs' to 1. */ > stap_parse_argument_1 (p, 1, lookahead_prec); > + if (p->inside_paren_p) > + p->arg = skip_spaces (p->arg); > } > > write_exp_elt_opcode (&p->pstate, opcode); > diff --git a/gdb/testsuite/gdb.arch/amd64-stap-expressions.S b/gdb/testsuite/gdb.arch/amd64-stap-expressions.S > new file mode 100644 > index 0000000000..76a47aa9b5 > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/amd64-stap-expressions.S > @@ -0,0 +1,43 @@ > +/* Copyright (C) 2021 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + This program 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 General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program. If not, see . */ > + > +#include > + > + .file "amd64-stap-expressions.S" > + .text > + .globl main > +main: > + /* We use a nop here because we don't want the first probe to > + be placed at the same location as the main label. */ > + nop > + > + /* Single operands. */ > + STAP_PROBE1(probe, log_neg, 8@!($0+$1)) > + STAP_PROBE1(probe, minus, -8@-($3+$4)) > + STAP_PROBE1(probe, bit_neg, -8@~$22) > + > + /* Arithmetic expressions. */ > + STAP_PROBE1(probe, plus1, 8@$3+($10-$8)-$1) > + STAP_PROBE1(probe, plus2, 8@$100-( ($8+$10) -$50)+$3) > + STAP_PROBE1(probe, plus3, 8@$100-(($8+$10)-$50)+((($8 - $9) + $40) - $4)+$4) > + > + /* Bitwise expressions. */ > + STAP_PROBE1(probe, and, 8@$128&$128) > + STAP_PROBE1(probe, or, 8@$8|$4) > + > + xor %rax,%rax > + ret > diff --git a/gdb/testsuite/gdb.arch/amd64-stap-expressions.exp b/gdb/testsuite/gdb.arch/amd64-stap-expressions.exp > new file mode 100644 > index 0000000000..5e3cb60a9e > --- /dev/null > +++ b/gdb/testsuite/gdb.arch/amd64-stap-expressions.exp > @@ -0,0 +1,68 @@ > +# Copyright 2021 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program 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 General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program. If not, see . > + > +standard_testfile ".S" > + > +if { ![istarget "x86_64-*-*"] || ![is_lp64_target] } { > + verbose "Skipping $testfile.exp" > + return > +} > + > +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { > + return -1 > +} > + > +# Helper procedure to go to probe NAME > + > +proc goto_probe { name } { > + global decimal hex > + > + gdb_test "break -pstap $name" "Breakpoint $decimal at $hex" > + gdb_test "continue" "Breakpoint $decimal, main \\(\\) at .*\r\n.*STAP_PROBE1.*${name},.*\\)" > +} > + > +# Helper procedure to test the probe's argument > + > +proc test_probe_value { value } { > + gdb_test "print \$_probe_argc" "= 1" > + gdb_test "print \$_probe_arg0" "= $value" > +} > + > +if { ![runto_main] } { > + return -1 > +} > + > +# Name and expected value for each probe. > +set probe_names_and_values { > + { "log_neg" "0" } > + { "minus" "-7" } > + { "bit_neg" "-23" } > + > + { "plus1" "4" } > + { "plus2" "135" } > + { "plus3" "171" } > + > + { "and" "128" } > + { "or" "12" } > +} > + > +foreach probe_info $probe_names_and_values { > + set name [lindex $probe_info 0] > + set value [lindex $probe_info 1] > + with_test_prefix $name { > + goto_probe $name > + test_probe_value $value > + } > +} > -- > > 2.29.2 > > -- Sergio GPG key ID: 237A 54B1 0287 28BF 00EF 31F4 D0EB 7628 65FC 5E36 Please send encrypted e-mail if possible https://sergiodj.net/