[COMMITTED 1/2] bpf: use the expected instruction for NOPs

Jose E. Marchesi jose.marchesi@oracle.com
Mon Sep 14 19:10:06 GMT 2020


The BPF ISA doesn't have a no-operation instruction, but in practice
the Linux kernel verifier performs some optimizations that rely on
these instructions to be encoded in a particular way.  As it turns
out, we were using the "wrong" instruction in GCC.

This patch makes GCC to generate the expected instruction for NOP (a
`ja 0') and also adds a test to make sure this is the case.

Tested in bpf-unknown-none targets.

2020-09-14  Jose E. Marchesi  <jose.marchesi@oracle.com>

gcc/

	* config/bpf/bpf.md ("nop"): Re-define as `ja 0'.

gcc/testsuite/

	* gcc.target/bpf/nop-1.c: New test.
---
 gcc/config/bpf/bpf.md                |  7 ++++++-
 gcc/testsuite/gcc.target/bpf/nop-1.c | 14 ++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/nop-1.c

diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index 41bb4fcd9a7..769d8ea0096 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -82,10 +82,15 @@ (define_mode_attr msuffix [(SI "32") (DI "")])
 
 ;;;; NOPs
 
+;; The Linux kernel verifier performs some optimizations that rely on
+;; nop instructions to be encoded as `ja 0', i.e. a jump to offset 0,
+;; which actually means to jump to the next instruction, since in BPF
+;; offsets are expressed in 64-bit words _minus one_.
+
 (define_insn "nop"
   [(const_int 0)]
   ""
-  "mov\t%%r0,%%r0"
+  "ja\t0"
   [(set_attr "type" "alu")])
 
 ;;;; Arithmetic/Logical
diff --git a/gcc/testsuite/gcc.target/bpf/nop-1.c b/gcc/testsuite/gcc.target/bpf/nop-1.c
new file mode 100644
index 00000000000..c4d274f6bad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/nop-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 --patchable-function-entry=2,1" } */
+
+/* The purpose of this test is to make sure the right instruction is
+   generated for NOPs.  See bpf.md for a description on why this is
+   important.  */
+
+int
+foo ()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler "foo:\n\t*ja\t0" } } */
-- 
2.25.0.2.g232378479e



More information about the Gcc-patches mailing list