[ARM] Harden indirect calls against SLS
authorKristof Beyls <kristof.beyls@arm.com>
Fri, 20 Nov 2020 16:11:17 +0000 (16:11 +0000)
committerKristof Beyls <kristof.beyls@arm.com>
Sat, 19 Dec 2020 12:33:42 +0000 (12:33 +0000)
commita4c1f5160e6d1de9a9959ecbf329c2acf4f3ed31
tree87a602a7cccf7f426bad4be6b97baf0e52c93fb1
parent320fd3314e378ae6242a2dde97250a8a94d68e27
[ARM] Harden indirect calls against SLS

To make sure that no barrier gets placed on the architectural execution
path, each indirect call calling the function in register rN, it gets
transformed to a direct call to __llvm_slsblr_thunk_mode_rN.  mode is
either arm or thumb, depending on the mode of where the indirect call
happens.

The llvm_slsblr_thunk_mode_rN thunk contains:

bx rN
<speculation barrier>

Therefore, the indirect call gets split into 2; one direct call and one
indirect jump.
This transformation results in not inserting a speculation barrier on
the architectural execution path.

The mitigation is off by default and can be enabled by the
harden-sls-blr subtarget feature.

As a linker is allowed to clobber r12 on function calls, the
above code transformation is not correct in case a linker does so.
Similarly, the transformation is not correct when register lr is used.
Avoiding r12/lr being used is done in a follow-on patch to make
reviewing this code easier.

Differential Revision: https://reviews.llvm.org/D92468
llvm/lib/Target/ARM/ARM.h
llvm/lib/Target/ARM/ARM.td
llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
llvm/lib/Target/ARM/ARMBaseInstrInfo.h
llvm/lib/Target/ARM/ARMSLSHardening.cpp
llvm/lib/Target/ARM/ARMSubtarget.h
llvm/lib/Target/ARM/ARMTargetMachine.cpp
llvm/test/CodeGen/ARM/O3-pipeline.ll
llvm/test/CodeGen/ARM/speculation-hardening-sls.ll