From 3815be6b4e992b112ff1caf01d61b08aa1fa2974 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Sun, 7 Jul 2019 18:57:31 +0000 Subject: [PATCH] [ARM] Add support for MSVC stack cookie checking Heavily based on the same for AArch64, from SVN r346469. Differential Revision: https://reviews.llvm.org/D64292 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365283 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 30 +++++++++++++++++++ lib/Target/ARM/ARMISelLowering.h | 4 +++ .../ARM/Windows/stack-protector-msvc.ll | 20 +++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 test/CodeGen/ARM/Windows/stack-protector-msvc.ll diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c66b8ce094a..2505cf71688 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -15237,6 +15237,36 @@ bool ARMTargetLowering::useLoadStackGuardNode() const { return Subtarget->isTargetMachO(); } +void ARMTargetLowering::insertSSPDeclarations(Module &M) const { + if (!Subtarget->getTargetTriple().isWindowsMSVCEnvironment()) + return TargetLowering::insertSSPDeclarations(M); + + // MSVC CRT has a global variable holding security cookie. + M.getOrInsertGlobal("__security_cookie", + Type::getInt8PtrTy(M.getContext())); + + // MSVC CRT has a function to validate security cookie. + FunctionCallee SecurityCheckCookie = M.getOrInsertFunction( + "__security_check_cookie", Type::getVoidTy(M.getContext()), + Type::getInt8PtrTy(M.getContext())); + if (Function *F = dyn_cast(SecurityCheckCookie.getCallee())) + F->addAttribute(1, Attribute::AttrKind::InReg); +} + +Value *ARMTargetLowering::getSDagStackGuard(const Module &M) const { + // MSVC CRT has a global variable holding security cookie. + if (Subtarget->getTargetTriple().isWindowsMSVCEnvironment()) + return M.getGlobalVariable("__security_cookie"); + return TargetLowering::getSDagStackGuard(M); +} + +Function *ARMTargetLowering::getSSPStackGuardCheck(const Module &M) const { + // MSVC CRT has a function to validate security cookie. + if (Subtarget->getTargetTriple().isWindowsMSVCEnvironment()) + return M.getFunction("__security_check_cookie"); + return TargetLowering::getSSPStackGuardCheck(M); +} + bool ARMTargetLowering::canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const { // If we do not have NEON, vector types are not natively supported. diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index efc074cb1f5..4f9f33e9854 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -555,6 +555,10 @@ class VectorType; bool useLoadStackGuardNode() const override; + void insertSSPDeclarations(Module &M) const override; + Value *getSDagStackGuard(const Module &M) const override; + Function *getSSPStackGuardCheck(const Module &M) const override; + bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx, unsigned &Cost) const override; diff --git a/test/CodeGen/ARM/Windows/stack-protector-msvc.ll b/test/CodeGen/ARM/Windows/stack-protector-msvc.ll new file mode 100644 index 00000000000..3a38aa01b2a --- /dev/null +++ b/test/CodeGen/ARM/Windows/stack-protector-msvc.ll @@ -0,0 +1,20 @@ +; RUN: llc -mtriple=thumbv7-windows-msvc < %s -o - | FileCheck --check-prefix=MSVC %s +; RUN: llc -mtriple=thumbv7-windows-msvc -O0 < %s -o - | FileCheck --check-prefix=MSVC %s + +define void @_Z1fv() sspreq { +entry: + %x = alloca i32, align 4 + %0 = bitcast i32* %x to i8* + call void @_Z7CapturePi(i32* nonnull %x) + ret void +} + +declare void @_Z7CapturePi(i32*) + +; MSVC: movw r0, :lower16:__security_cookie +; MSVC: movt r0, :upper16:__security_cookie +; MSVC: ldr r0, [r0] +; MSVC: str r0, [sp, #4] +; MSVC: bl _Z7CapturePi +; MSVC: ldr r0, [sp, #4] +; MSVC: bl __security_check_cookie -- 2.50.0