From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id xF0INE33BGBJDwAAWB0awg (envelope-from ) for ; Sun, 17 Jan 2021 21:49:49 -0500 Received: by simark.ca (Postfix, from userid 112) id C5A7C1EF80; Sun, 17 Jan 2021 21:49:49 -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 3FE4F1E940 for ; Sun, 17 Jan 2021 21:49:46 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8CAD239960EF; Mon, 18 Jan 2021 02:49:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8CAD239960EF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1610938185; bh=Jt6QDnxpGcbFx2K4fZ0zI6vmFN6dsnlgxRsC3sHlLVw=; 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=Y6btEpiTTrubMRd4bNv5KGcO7MWKfqZmJnGzkOJqv3NrQzRXFk5NgUcgBMMBqDjt7 olQEqfWOlR+x3RWYjriUAsnNBWvEqMaTqqsDAly4N8UP880ld4UGWWfFL9r8SkWiHW irUg85WPMprg7oT+KgvmNafm/uujdnIYvbg0RFSc= Received: from mail.sergiodj.net (mail.sergiodj.net [167.114.15.217]) by sourceware.org (Postfix) with ESMTPS id 67B393857C4E for ; Mon, 18 Jan 2021 02:49:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 67B393857C4E 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 B0337A008C; Sun, 17 Jan 2021 21:49:33 -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> <87lfcy5f19.fsf@paluero> X-URL: http://blog.sergiodj.net Date: Sun, 17 Jan 2021 21:49:33 -0500 In-Reply-To: <87lfcy5f19.fsf@paluero> (Sergio Durigan Junior via Gdb-patches's message of "Tue, 12 Jan 2021 10:52:02 -0500") Message-ID: <87o8hnot6q.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 Tuesday, January 12 2021, Sergio Durigan Junior via Gdb-patches wrote: > 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. Ping^2. >> >> 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/ -- Sergio GPG key ID: 237A 54B1 0287 28BF 00EF 31F4 D0EB 7628 65FC 5E36 Please send encrypted e-mail if possible https://sergiodj.net/