as: fix bpf expression parsing regression
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Testing passed
|
Commit Message
As a result of a switch instead of an if, as would issue non-specific
error messages when it encountered an operand it could not parse in bpf.
This patch fixes that regression and adds a test to prevent it from
reoccurring.
Tested for bpf-unknown-none on x86_64-redhat-linux.
gas/ChangeLog:
* config/tc-bpf.c (parse_expression): Change switch to if so that error
* condition is handled.
* testsuite/gas/bpf/bpf.exp: Invoke new test.
* testsuite/gas/bpf/indcall-badoperand.d: New test.
* testsuite/gas/bpf/indcall-badoperand.l: New test.
* testsuite/gas/bpf/indcall-badoperand.s: New test.
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
---
gas/config/tc-bpf.c | 2 +-
gas/testsuite/gas/bpf/bpf.exp | 3 +++
gas/testsuite/gas/bpf/indcall-badoperand.d | 3 +++
gas/testsuite/gas/bpf/indcall-badoperand.l | 3 +++
gas/testsuite/gas/bpf/indcall-badoperand.s | 8 ++++++++
5 files changed, 18 insertions(+), 1 deletion(-)
create mode 100644 gas/testsuite/gas/bpf/indcall-badoperand.d
create mode 100644 gas/testsuite/gas/bpf/indcall-badoperand.l
create mode 100644 gas/testsuite/gas/bpf/indcall-badoperand.s
Comments
Hi Will,
> As a result of a switch instead of an if, as would issue non-specific
> error messages when it encountered an operand it could not parse in bpf.
> This patch fixes that regression and adds a test to prevent it from
> reoccurring.
>
> Tested for bpf-unknown-none on x86_64-redhat-linux.
Approved - please apply.
> - switch (exp->X_op == O_absent || exp_parse_failed)
> + if (exp->X_op == O_absent || exp_parse_failed)
> return NULL;
I have to say that I am surprised that the original version of this
code compiled at all. Or at least compiled without generating any
kind of warning message.
Cheers
Nick
On Mon, Feb 19, 2024 at 6:16 AM Nick Clifton <nickc@redhat.com> wrote:
>
> Hi Will,
>
> > As a result of a switch instead of an if, as would issue non-specific
> > error messages when it encountered an operand it could not parse in bpf.
> > This patch fixes that regression and adds a test to prevent it from
> > reoccurring.
> >
> > Tested for bpf-unknown-none on x86_64-redhat-linux.
>
> Approved - please apply.
>
> > - switch (exp->X_op == O_absent || exp_parse_failed)
> > + if (exp->X_op == O_absent || exp_parse_failed)
> > return NULL;
>
> I have to say that I am surprised that the original version of this
> code compiled at all. Or at least compiled without generating any
> kind of warning message.
Funny you mentioned that! I only saw this problem because I compiled
with clang on macOS and it failed to compile. There are warnings for
gcc that will detect this idiom
(https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wswitch-bool)
and an unreachable body of a switch
(https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wswitch-unreachable)
but for some reason (and I tried multiple invocations) this did not
trigger it.
I hope the patch helps!
Thank you for accepting it!
Sincerely,
Will
>
> Cheers
> Nick
>
>
Hi Will.
Thanks for the patch.
> diff --git a/gas/config/tc-bpf.c b/gas/config/tc-bpf.c
> index 43e098c2a86..86489c72898 100644
> --- a/gas/config/tc-bpf.c
> +++ b/gas/config/tc-bpf.c
> @@ -1240,7 +1240,7 @@ parse_expression (char *s, expressionS *exp)
> s = input_line_pointer;
> input_line_pointer = saved_input_line_pointer;
>
> - switch (exp->X_op == O_absent || exp_parse_failed)
> + if (exp->X_op == O_absent || exp_parse_failed)
> return NULL;
Uoh! How did that end there... ^^
> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.l b/gas/testsuite/gas/bpf/indcall-badoperand.l
> new file mode 100644
> index 00000000000..d791435a2ac
> --- /dev/null
> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.l
> @@ -0,0 +1,3 @@
> +.*: Assembler messages:
> +.*:7: Error: unrecognized instruction `call %0'
> +.*:7: Error: expected register name, got '%0'
> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.s b/gas/testsuite/gas/bpf/indcall-badoperand.s
> new file mode 100644
> index 00000000000..cf19c0a56b6
> --- /dev/null
> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.s
> @@ -0,0 +1,8 @@
> +
> + .text
> + .align 4
> +main:
> +
> + mov %r0, 1
> + call %0
What is this test supposed to test exactly?
> + exit
>> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.l b/gas/testsuite/gas/bpf/indcall-badoperand.l
>> new file mode 100644
>> index 00000000000..d791435a2ac
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.l
>> @@ -0,0 +1,3 @@
>> +.*: Assembler messages:
>> +.*:7: Error: unrecognized instruction `call %0'
>> +.*:7: Error: expected register name, got '%0'
>> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.s b/gas/testsuite/gas/bpf/indcall-badoperand.s
>> new file mode 100644
>> index 00000000000..cf19c0a56b6
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.s
>> @@ -0,0 +1,8 @@
>> +
>> + .text
>> + .align 4
>> +main:
>> +
>> + mov %r0, 1
>> + call %0
>
> What is this test supposed to test exactly?
Never mind, now that I reread your mail it is pretty obvious.
I tried your patch, and I am getting some non-deterministic behavior.
Assembling indcall-badoperand.s the assembler sometimes emits:
foo.s: Assembler messages:
foo.s:7: Error: unrecognized instruction `call %0'
foo.s:7: Error: expected signed 32-bit displacement
and sometimes it emits:
foo.s: Assembler messages:
foo.s:7: Error: unrecognized instruction `call %0'
foo.s:7: Error: expected register name, got '%0'
Running under valgrind seems to settle on this latest, and expected,
output, so this seems to be a memory problem. I will apply your patch
(on your behalf) only after I find and fix this other bug, or the
buildbots will go banana.
>> + exit
>>> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.l b/gas/testsuite/gas/bpf/indcall-badoperand.l
>>> new file mode 100644
>>> index 00000000000..d791435a2ac
>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.l
>>> @@ -0,0 +1,3 @@
>>> +.*: Assembler messages:
>>> +.*:7: Error: unrecognized instruction `call %0'
>>> +.*:7: Error: expected register name, got '%0'
>>> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.s b/gas/testsuite/gas/bpf/indcall-badoperand.s
>>> new file mode 100644
>>> index 00000000000..cf19c0a56b6
>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.s
>>> @@ -0,0 +1,8 @@
>>> +
>>> + .text
>>> + .align 4
>>> +main:
>>> +
>>> + mov %r0, 1
>>> + call %0
>>
>> What is this test supposed to test exactly?
>
> Never mind, now that I reread your mail it is pretty obvious.
>
> I tried your patch, and I am getting some non-deterministic behavior.
> Assembling indcall-badoperand.s the assembler sometimes emits:
>
> foo.s: Assembler messages:
> foo.s:7: Error: unrecognized instruction `call %0'
> foo.s:7: Error: expected signed 32-bit displacement
>
> and sometimes it emits:
>
> foo.s: Assembler messages:
> foo.s:7: Error: unrecognized instruction `call %0'
> foo.s:7: Error: expected register name, got '%0'
>
> Running under valgrind seems to settle on this latest, and expected,
> output, so this seems to be a memory problem. I will apply your patch
> (on your behalf) only after I find and fix this other bug, or the
> buildbots will go banana.
Hi Will.
Found the cause and fixed it [1] then applied your patch on your behalf,
with a slightly modified ChangeLog.
Thank you!
[1] b86b514aace19799ea141514e16296fb63a089b3
On Mon, Feb 19, 2024 at 2:54 PM Jose E. Marchesi
<jose.marchesi@oracle.com> wrote:
>
>
> >>> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.l b/gas/testsuite/gas/bpf/indcall-badoperand.l
> >>> new file mode 100644
> >>> index 00000000000..d791435a2ac
> >>> --- /dev/null
> >>> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.l
> >>> @@ -0,0 +1,3 @@
> >>> +.*: Assembler messages:
> >>> +.*:7: Error: unrecognized instruction `call %0'
> >>> +.*:7: Error: expected register name, got '%0'
> >>> diff --git a/gas/testsuite/gas/bpf/indcall-badoperand.s b/gas/testsuite/gas/bpf/indcall-badoperand.s
> >>> new file mode 100644
> >>> index 00000000000..cf19c0a56b6
> >>> --- /dev/null
> >>> +++ b/gas/testsuite/gas/bpf/indcall-badoperand.s
> >>> @@ -0,0 +1,8 @@
> >>> +
> >>> + .text
> >>> + .align 4
> >>> +main:
> >>> +
> >>> + mov %r0, 1
> >>> + call %0
> >>
> >> What is this test supposed to test exactly?
> >
> > Never mind, now that I reread your mail it is pretty obvious.
> >
> > I tried your patch, and I am getting some non-deterministic behavior.
> > Assembling indcall-badoperand.s the assembler sometimes emits:
> >
> > foo.s: Assembler messages:
> > foo.s:7: Error: unrecognized instruction `call %0'
> > foo.s:7: Error: expected signed 32-bit displacement
> >
> > and sometimes it emits:
> >
> > foo.s: Assembler messages:
> > foo.s:7: Error: unrecognized instruction `call %0'
> > foo.s:7: Error: expected register name, got '%0'
> >
> > Running under valgrind seems to settle on this latest, and expected,
> > output, so this seems to be a memory problem. I will apply your patch
> > (on your behalf) only after I find and fix this other bug, or the
> > buildbots will go banana.
>
> Hi Will.
>
> Found the cause and fixed it [1] then applied your patch on your behalf,
> with a slightly modified ChangeLog.
>
> Thank you!
>
Glad that I could help! I really, really enjoy working on FOSS! Thank
you and Nick for being so welcoming!
Can't wait to hear your thoughts on the gcc patch I submitted!
Sincerely,
Will
> [1] b86b514aace19799ea141514e16296fb63a089b3
@@ -1240,7 +1240,7 @@ parse_expression (char *s, expressionS *exp)
s = input_line_pointer;
input_line_pointer = saved_input_line_pointer;
- switch (exp->X_op == O_absent || exp_parse_failed)
+ if (exp->X_op == O_absent || exp_parse_failed)
return NULL;
/* The expression parser may consume trailing whitespaces. We have
@@ -77,6 +77,9 @@ if {[istarget bpf*-*-*]} {
run_dump_test disp32-overflow
run_dump_test imm32-overflow
+ # Bad operand (regression)
+ run_dump_test indcall-badoperand
+
# In Pseudo-C it is not possible to refer to symbols
# as operands that have the same name than registers.
run_dump_test regs-for-symbols-pseudoc
new file mode 100644
@@ -0,0 +1,3 @@
+#as: -EL -mno-relax
+#source: indcall-badoperand.s
+#error_output: indcall-badoperand.l
new file mode 100644
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:7: Error: unrecognized instruction `call %0'
+.*:7: Error: expected register name, got '%0'
new file mode 100644
@@ -0,0 +1,8 @@
+
+ .text
+ .align 4
+main:
+
+ mov %r0, 1
+ call %0
+ exit