aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJose E. Marchesi <jose.marchesi@oracle.com>2020-09-14 20:35:22 +0200
committerJose E. Marchesi <jose.marchesi@oracle.com>2020-09-14 20:55:13 +0200
commit5bcc0fa05ef713594f6c6d55d5c837e13a9c9803 (patch)
tree336921426970c02b302f8df7f7e68c5157d364b6 /gcc
parent0a3e6e975abd2b19fc12da7e5430e2a05e92ebcc (diff)
downloadgcc-5bcc0fa05ef713594f6c6d55d5c837e13a9c9803.zip
gcc-5bcc0fa05ef713594f6c6d55d5c837e13a9c9803.tar.gz
gcc-5bcc0fa05ef713594f6c6d55d5c837e13a9c9803.tar.bz2
bpf: use the expected instruction for NOPs
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/bpf/bpf.md7
-rw-r--r--gcc/testsuite/gcc.target/bpf/nop-1.c14
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index 41bb4fc..769d8ea 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -82,10 +82,15 @@
;;;; 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 0000000..c4d274f
--- /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" } } */