diff options
author | Christoph Muellner <christoph.muellner@theobroma-systems.com> | 2018-03-02 17:09:19 +0100 |
---|---|---|
committer | Christoph Muellner <christoph.muellner@theobroma-systems.com> | 2018-08-08 16:21:39 +0200 |
commit | e18301133ea622f6d6796ded1d15466e70475cf8 (patch) | |
tree | 1e3c2b0f6d5563422922e679bdf2696b33a5549b /gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c | |
parent | 9fb89fa845c1b2e0a18d85ada0b077c84508ab78 (diff) |
aarch64: Retpoline (Spectre-V2 mitigation) for aarch64.
The compiler option -mindirect-branch=<value> converts indirect
branch-and-link-register and branch-register instructions according to <value>.
The default is ``keep``, which keeps indirect branch-and-link-register and
branch-register instructions unmodified.
``thunk`` converts indirect branch-and-link-register/branch-register
instructions to a branch-and-link/branch to a function containing a retpoline
(to stop speculative execution) followed by a branch-register to the target.
``thunk-inline`` is similar to ``thunk``, but inlines the retpoline
before the branch-and-link-register/branch-register instruction.
``thunk-extern`` is also similar to ``thunk``, but does not insert the
functions containing the retpoline. When using this option, these functions
need to be provided in a separate object file. The retpoline functions exist
for each register and are named ``__aarch64_indirect_thunk_xN`` (N being the
register number).
It is also possible to override the indirect-branch setting for
individual fuctions using the function attribute ``indirect_branch``.
The actual retpoline instruction sequence, which prevents speculative
indirect branches looks like this::
str x30, [sp, #-16]!
bl 101f
100: //speculation trap
wfe
b 100b
101: //do ROP
adr x30, 102f
ret
102: //non-spec code
ldr x30, [sp], #16
This patch has been tested with the included testcases and various other
source bases (benchmarks, retpoline-patched arm64 kernel, etc.).
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Diffstat (limited to 'gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c')
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c new file mode 100644 index 000000000000..3c5c263b5e6f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/indirect-thunk-inline-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-inline -fno-pic" } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch[256]; + +void +male_indirect_jump (long offset) +{ + dispatch[offset](offset); +} + +/* { dg-final { scan-assembler "adrp\[ \t\]*x1, dispatch" } } */ +/* { dg-final { scan-assembler "add\[ \t\]*x1, x1, :lo12:dispatch" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x1, \\\[x1, x0, lsl 3\\\]" } } */ +/* { dg-final { scan-assembler "str\[ \t\]*x30, \\\[sp, #-16\\\]!" } } */ +/* { dg-final { scan-assembler "bl\[ \t\]*\.LIND1" } } */ +/* { dg-final { scan-assembler "wfe" } } */ +/* { dg-final { scan-assembler "b\[ \t\]*\.LIND0" } } */ +/* { dg-final { scan-assembler "adr\[ \t\]*x30, .LIND2" } } */ +/* { dg-final { scan-assembler "ret" } } */ +/* { dg-final { scan-assembler "ldr\[ \t\]*x30, \\\[sp\\\], #16" } } */ +/* { dg-final { scan-assembler "br\[ \t\]*x1" } } */ + +/* { dg-final { scan-assembler-not "__aarch64_indirect_thunk" } } */ |