Index: lib/Target/AArch64/AArch64ISelLowering.h =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.h +++ lib/Target/AArch64/AArch64ISelLowering.h @@ -407,6 +407,10 @@ /// returns the address of that location. Otherwise, returns nullptr. Value *getIRStackGuard(IRBuilder<> &IRB) const override; + void insertSSPDeclarations(Module &M) const override; + Value *getSDagStackGuard(const Module &M) const override; + Value *getSSPStackGuardCheck(const Module &M) const override; + /// If the target has a standard location for the unsafe stack pointer, /// returns the address of that location. Otherwise, returns nullptr. Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const override; Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11687,6 +11687,39 @@ return TargetLowering::getIRStackGuard(IRB); } +void AArch64TargetLowering::insertSSPDeclarations(Module &M) const { + // MSVC CRT provides functionalities for stack protection. + if (Subtarget->getTargetTriple().isWindowsMSVCEnvironment()) { + // 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. + auto *SecurityCheckCookie = cast( + M.getOrInsertFunction("__security_check_cookie", + Type::getVoidTy(M.getContext()), + Type::getInt8PtrTy(M.getContext()))); + SecurityCheckCookie->setCallingConv(CallingConv::Win64); + SecurityCheckCookie->addAttribute(1, Attribute::AttrKind::InReg); + return; + } + TargetLowering::insertSSPDeclarations(M); +} + +Value *AArch64TargetLowering::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); +} + +Value *AArch64TargetLowering::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); +} + Value *AArch64TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const { // Android provides a fixed TLS slot for the SafeStack pointer. See the // definition of TLS_SLOT_SAFESTACK in Index: test/CodeGen/AArch64/stack-protector-target.ll =================================================================== --- test/CodeGen/AArch64/stack-protector-target.ll +++ test/CodeGen/AArch64/stack-protector-target.ll @@ -2,6 +2,7 @@ ; RUN: llc -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefix=ANDROID-AARCH64 %s ; RUN: llc -mtriple=aarch64-fuchsia < %s -o - | FileCheck --check-prefixes=FUCHSIA-AARCH64-COMMON,FUCHSIA-AARCH64-USER %s ; RUN: llc -mtriple=aarch64-fuchsia -code-model=kernel < %s -o - | FileCheck --check-prefixes=FUCHSIA-AARCH64-COMMON,FUCHSIA-AARCH64-KERNEL %s +; RUN: llc -mtriple=aarch64-windows < %s -o - | FileCheck --check-prefix=WINDOWS-AARCH64 %s define void @_Z1fv() sspreq { entry: @@ -27,3 +28,10 @@ ; FUCHSIA-AARCH64-COMMON: ldur [[C:.*]], {{\[}}[[A]], #-16] ; FUCHSIA-AARCH64-COMMON: ldr [[D:.*]], [sp, ; FUCHSIA-AARCH64-COMMON: cmp [[C]], [[D]] + +; WINDOWS-AARCH64: adrp x8, __security_cookie +; WINDOWS-AARCH64: ldr x8, [x8, __security_cookie] +; WINDOWS-AARCH64: str x8, [sp, #8] +; WINDOWS-AARCH64: bl _Z7CapturePi +; WINDOWS-AARCH64: ldr x0, [sp, #8] +; WINDOWS-AARCH64: bl __security_check_cookie