bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/25750] GNU as has inconsistent behavior when expanding .ma


From: i at maskray dot me
Subject: [Bug binutils/25750] GNU as has inconsistent behavior when expanding .macro that takes as input directives with arguments
Date: Mon, 13 Apr 2020 00:12:55 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=25750

--- Comment #10 from Fangrui Song <i at maskray dot me> ---
(In reply to Jian Cai from comment #8)
Hi Jian,

> I did however find a variation that worked and did not have any behavioural 
> inconsistencies:

For

  .macro memorize a
  \a
  .endm
  memorize .long (19371226)

The x86 backend rejects it while most other backends accept it. This is
actually unintentional.

gas/config/tc-i386.c defines

  /* List of chars besides those in app.c:symbol_chars that can start an
     operand.  Used to prevent the scrubber eating vital white-space.  */
  const char extra_symbol_chars[] = "*%-([{}"

The type of these symbols are considered LEX_IS_SYMBOL_COMPONENT.

Before the input is fed to the parser, gas runs do_scrub_chars() to perform
some preprocessing.

* For other backends, lex['('] is 0, even though the state is 10, no space is
kept
  macro_expand() will see `.long(19371226)` and the string will be parsed as an
argument.
* For the x86 backend, lex['('] is LEX_IS_SYMBOL_COMPONENT, the space before
'(' is kept (state is 10).
  macro_expand() will see `.long (19371226)` and the string will be parsed as
two arguments.
  If the argument does not have the `:vararg` qualifier, gas will error
  `Error: too many positional arguments`


There is one feature not documented in
https://sourceware.org/binutils/docs/as/Macro.html
For a string literal argument, gas will remove the quotes when evaluation the
argument.
This makes the following example work:

  .macro foo a
  \a
  .endm
  foo ".section sec"

For the Linux kernel, __emit_insn may be used as either a directive or an
operand.
Its reliance on `.inst (x)` being parsed as a whole is brittle.

  arch/arm64/include/asm/sysreg.h
  52:#define __emit_inst(x)                       .inst (x)

  arch/arm64/include/asm/sysreg.h
  93:#define SET_PSTATE_PAN(x)            __emit_inst(0xd500401f | PSTATE_PAN |
((!!x) << PSTATE_Imm_shift))

  arch/arm64/kvm/hyp/entry.S
  112:     ALTERNATIVE(nop, SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)

#define __emit_inst(x) .inst(x)
may be the most suitable workaround for clang integrated assembler.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]