x86: handle SVR4 escaped binary operators

PR gas/4572

When / is a comment character, its use as binary "divide" operator needs
escaping by a backslash. Besides the scrubber needing to support this
(addressed in an earlier change), there are also a few provisions needed
in target specific operator handling.

As the spec calls for % and * to also be escaped because of being
"overloaded", also recognize these, despite the overloading there not
really preventing their use as operators in most (%) or all (*) cases,
given the way how the rest of the assembler works.

To bring source and testsuite in line, also drop the TE_I386AIX part of
the respective conditional, as i?86-*-aix* support had been removed a
while ago.
This commit is contained in:
Jan Beulich
2020-07-20 08:57:18 +02:00
parent 750e4bf70f
commit b3983e5f53
6 changed files with 95 additions and 7 deletions

View File

@ -1,3 +1,15 @@
2020-07-20 Jan Beulich <jbeulich@suse.com>
PR gas/4572
* config/tc-i386.c (i386_comment_chars): Drop TE_I386AIX from
conditional around it.
(md_begin): Insert backslash into operand_chars[] when slash is
a comment character.
* config/tc-i386-intel.c (i386_operator): Recognize \/, \%, and
\* as operators when / may be a comment character.
* testsuite/gas/i386/svr4.s, testsuite/gas/i386/svr4.d: New.
* testsuite/gas/i386/i386.exp: Run new test.
2020-07-20 Jan Beulich <jbeulich@suse.com>
PR gas/4572

View File

@ -123,6 +123,16 @@ operatorT i386_operator (const char *name, unsigned int operands, char *pc)
{
unsigned int j;
#ifdef SVR4_COMMENT_CHARS
if (!name && operands == 2 && *input_line_pointer == '\\')
switch (input_line_pointer[1])
{
case '/': input_line_pointer += 2; return O_divide;
case '%': input_line_pointer += 2; return O_modulus;
case '*': input_line_pointer += 2; return O_multiply;
}
#endif
if (!intel_syntax)
return O_absent;

View File

@ -480,13 +480,12 @@ const char extra_symbol_chars[] = "*%-([{}"
#endif
;
#if (defined (TE_I386AIX) \
|| ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \
&& !defined (TE_GNU) \
&& !defined (TE_LINUX) \
&& !defined (TE_FreeBSD) \
&& !defined (TE_DragonFly) \
&& !defined (TE_NetBSD)))
#if ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \
&& !defined (TE_GNU) \
&& !defined (TE_LINUX) \
&& !defined (TE_FreeBSD) \
&& !defined (TE_DragonFly) \
&& !defined (TE_NetBSD))
/* This array holds the chars that always start a comment. If the
pre-processor is disabled, these aren't very useful. The option
--divide will remove '/' from this list. */
@ -3116,6 +3115,10 @@ md_begin (void)
mnemonic_chars[c] = c;
operand_chars[c] = c;
}
#ifdef SVR4_COMMENT_CHARS
else if (c == '\\' && strchr (i386_comment_chars, '/'))
operand_chars[c] = c;
#endif
if (ISALPHA (c) || ISDIGIT (c))
identifier_chars[c] = c;

View File

@ -692,6 +692,14 @@ if [expr [istarget "i*86-*-*"] || [istarget "x86_64-*-*"]] then {
run_dump_test "dw2-compressed-1"
run_dump_test "dw2-compressed-3a"
run_dump_test "dw2-compressed-3b"
if {![istarget "*-*-dragonfly*"]
&& ![istarget "*-*-gnu*"]
&& ![istarget "*-*-freebsd*"]
&& ![istarget "*-*-linux*"]
&& ![istarget "*-*-netbsd*"]} then {
run_dump_test "svr4"
}
}
}

View File

@ -0,0 +1,24 @@
#objdump: -dtw
#name: SVR4 comment char escape handling
.*: +file format .*
SYMBOL TABLE:
0+00 .* \.text[ ]+0+ \.text
0+00 .* \.data[ ]+0+ \.data
0+00 .* \.bss[ ]+0+ \.bss
0+00 .* \.text[ ]+0+ svr4
0+04 .* \*ABS\*[ ]+0+ a
0+03 .* \*ABS\*[ ]+0+ b
0+4c .* \*ABS\*[ ]+0+ c
Disassembly of section .text:
0+0 <svr4>:
[ ]*[0-9a-f]+:[ ]+b0 07[ ]+mov \$0x7,%al
[ ]*[0-9a-f]+:[ ]+b0 01[ ]+mov \$0x1,%al
[ ]*[0-9a-f]+:[ ]+b0 1e[ ]+mov \$0x1e,%al
[ ]*[0-9a-f]+:[ ]+b0 05[ ]+mov \$0x5,%al
[ ]*[0-9a-f]+:[ ]+b0 02[ ]+mov \$0x2,%al
[ ]*[0-9a-f]+:[ ]+b0 33[ ]+mov \$0x33,%al
#pass

View File

@ -0,0 +1,31 @@
.text
.if 1 / 2
.else
.error
.endif
.if 1 \/ 2
.error
.endif
.if 4 \% 2
.error
.endif
.if 1 \* 0
.error
.endif
svr4:
mov $(15 \/ 2), %al
mov $(15 \% 2), %al
mov $(15 \* 2), %al
.byte 0xb0, 17 \/ 3
.byte 0xb0, 17 \% 3
.byte 0xb0, 17 \* 3
.equiv a, 19 \/ 4
.equiv b, 19 \% 4
.equiv c, 19 \* 4