diff options
author | Jose E. Marchesi <jose.marchesi@oracle.com> | 2020-09-14 20:35:22 +0200 |
---|---|---|
committer | Jose E. Marchesi <jose.marchesi@oracle.com> | 2020-09-14 20:55:13 +0200 |
commit | 5bcc0fa05ef713594f6c6d55d5c837e13a9c9803 (patch) | |
tree | 336921426970c02b302f8df7f7e68c5157d364b6 | |
parent | 0a3e6e975abd2b19fc12da7e5430e2a05e92ebcc (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/config/bpf/bpf.md | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/bpf/nop-1.c | 14 |
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" } } */ |