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.
