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

--- Comment #2 from Sourceware Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Vineet Gupta <[email protected]>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=92529f776514b54b109021bbd4cde8471dd5ab14

commit 92529f776514b54b109021bbd4cde8471dd5ab14
Author: Vineet Gupta <[email protected]>
Date:   Thu Sep 10 09:14:22 2026 +0530

    PR 34558: bpf: don't mis-assemble `gotol' with signed offset

    `gotol +1' is assembled as if it were `goto l +1'

    This is the canonical form in the ISA documentation and also emitted by
    LLVM, thus needs to be fixed.

    The reason is the asm templates for the two unconditional jumps:
    (where %w matches zero or more whitespace characters).

      BPF_INSN_JAR   "goto%w%d16"
      BPF_INSN_JAL   "gotol%w%d32"

    In the opcode table JAR sorts before JAL and matches first, succeeding as
    `goto' and `l +1'.  The result is JA (opcode 0x05, displacement in the
    16-bit `off' field) plus an R_BPF_GNU_64_16 relocation against an
    undefined symbol `l', rather than JAL (opcode 0x06, displacement in the
    32-bit `imm' field).  No diagnostic is emitted.  The signed form -1 is
    similarly affected.

    For non-signed forms, `gotol 1' or `gotol 1f', the remainder does not
    parse as a single expression, the JAR template fails, and JAL is reached
    and matched correctly.  The normal dialect is not affected either, as
    `ja%W%d16' requires at least one whitespace character after the mnemonic.

    The uppercase `%W' exists as a potential solution (one or more spaces
    instead of zero), but switching JAR to it does not work since the
    pseudo-C dialect deliberately supports flexible spacing so it breaks
    `goto+1' and `goto1'; and gas removes the whitespace next to a
    sign in the operand field before md_assemble sees the line, which breaks
    the extremely common `if rX > N goto +M' outright.

    What the templates lack is a way to say that a mnemonic ends here even
    though no white space need follow it.  Add %t for that, and write it
    after `goto': `goto%t%w%d16' no longer matches `gotol +1', so JAL gets
    its turn.  This also covers the compound conditional jumps, whose
    templates embed `goto%w%d16'.

    %t tests is_name_beginner rather than is_part_of_name: a digit continues
    an operand rather than a mnemonic, and the pseudo-C dialect accepts it
    with no separating space, as in `goto1'.

    Only the `goto' templates are involved in this bug; the rest of the
    opcode table has the same latent problem and is converted separately.

    Existing coverage exercised `gotol' only with a label operand, which is
    why this went unnoticed.

            PR gas/34558

    include/
            * opcode/bpf.h (struct bpf_opcode): Document %t.

    opcodes/
            * bpf-opc.c (bpf_opcodes): Use %t after `goto'.
            * bpf-dis.c (print_insn_bpf): Print %t to nothing.

    gas/
            * config/tc-bpf.c (md_assemble): Handle %t.
            * testsuite/gas/bpf/jump-gotol-signed-pseudoc.s: New test.
            * testsuite/gas/bpf/jump-gotol-signed-pseudoc.d: New test.
            * testsuite/gas/bpf/bpf.exp: Run it.

    Signed-off-by: Vineet Gupta <[email protected]>

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

Reply via email to