From: Jan Beulich Date: Mon, 20 Jul 2020 06:57:18 +0000 (+0200) Subject: x86: handle SVR4 escaped binary operators X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b3983e5f53caad175563f8c842f2ab2a1277c2bc;p=binutils-gdb.git 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 67fabb9eabb..2aed48f181d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,15 @@ +2020-07-20 Jan Beulich + + 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 PR gas/4572 diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c index b326d30fff7..a98771bfef1 100644 --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -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; diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 5b0a014eaab..9ab841383c5 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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; diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index f4017322cb5..a91ad798660 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -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" + } } } diff --git a/gas/testsuite/gas/i386/svr4.d b/gas/testsuite/gas/i386/svr4.d new file mode 100644 index 00000000000..3a463541928 --- /dev/null +++ b/gas/testsuite/gas/i386/svr4.d @@ -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 : +[ ]*[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 diff --git a/gas/testsuite/gas/i386/svr4.s b/gas/testsuite/gas/i386/svr4.s new file mode 100644 index 00000000000..4565e0134e9 --- /dev/null +++ b/gas/testsuite/gas/i386/svr4.s @@ -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