diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index 1f596184f3d6..24ea92cc6865 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -21,6 +21,7 @@ def isOSOpenBSD : RuntimeLibcallPredicate<"TT.isOSOpenBSD()">; def isNotOSOpenBSD : RuntimeLibcallPredicate<"!TT.isOSOpenBSD()">; def isOSWindows : RuntimeLibcallPredicate<"TT.isOSWindows()">; def isNotOSWindows : RuntimeLibcallPredicate<"!TT.isOSWindows()">; +def isNotOSLinux : RuntimeLibcallPredicate<[{!TT.isOSLinux()}]>; def isNotOSMSVCRT : RuntimeLibcallPredicate<"!TT.isOSMSVCRT()">; def isPS : RuntimeLibcallPredicate<"TT.isPS()">; def isNotOSWindowsOrIsCygwinMinGW @@ -28,6 +29,12 @@ def isNotOSWindowsOrIsCygwinMinGW def isWindowsMSVCEnvironment : RuntimeLibcallPredicate< [{TT.isWindowsMSVCEnvironment()}]>; +def isNotOSLinuxAndNotOSOpenBSD : RuntimeLibcallPredicate< + [{!TT.isOSLinux() && !TT.isOSOpenBSD()}]>; + +def isWindowsMSVCOrItaniumEnvironment : RuntimeLibcallPredicate< + [{TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment()}]>; + def isGNUEnvironment : RuntimeLibcallPredicate<"TT.isGNUEnvironment()">; def darwinHasSinCosStret : RuntimeLibcallPredicate<"darwinHasSinCosStret(TT)">; def darwinHasExp10 : RuntimeLibcallPredicate<"darwinHasExp10(TT)">; @@ -471,6 +478,16 @@ def OBJC_RETAIN_AUTORELEASE : RuntimeLibcall; def OBJC_SYNC_ENTER : RuntimeLibcall; def OBJC_SYNC_EXIT : RuntimeLibcall; +//-------------------------------------------------------------------- +// Global variable references +//-------------------------------------------------------------------- +// +// TODO: These are not libcalls and probably should be distinguished +// in some way from callable functions. +// -------------------------------------------------------------------- + +def STACK_CHECK_GUARD : RuntimeLibcall; + //-------------------------------------------------------------------- // Define implementation default libcalls //-------------------------------------------------------------------- @@ -1103,6 +1120,21 @@ defset list LibmF128FiniteLibcalls = { def __powf128_finite : RuntimeLibcallImpl; } +//-------------------------------------------------------------------- +// Global variable references +//-------------------------------------------------------------------- + +def __stack_chk_guard : RuntimeLibcallImpl; + +// Name used on OpenBSD +def __guard_local : RuntimeLibcallImpl; + +// Name used with Windows MSVC +def __security_cookie : RuntimeLibcallImpl; + +// Name used on AIX +def __ssp_canary_word : RuntimeLibcallImpl; + //===----------------------------------------------------------------------===// // Common Libcall Sets //===----------------------------------------------------------------------===// @@ -1159,7 +1191,8 @@ defvar DarwinSinCosStret = LibcallImpls<(add __sincosf_stret, __sincos_stret), defvar DarwinExp10 = LibcallImpls<(add __exp10f, __exp10), darwinHasExp10>; defvar SecurityCheckCookieIfWinMSVC = - LibcallImpls<(add __security_check_cookie), isWindowsMSVCEnvironment>; + LibcallImpls<(add __security_check_cookie, __security_cookie), + isWindowsMSVCOrItaniumEnvironment>; defvar LibmHasSinCosF32 = LibcallImpls<(add sincosf), hasSinCos>; defvar LibmHasSinCosF64 = LibcallImpls<(add sincos), hasSinCos>; @@ -1205,10 +1238,13 @@ defvar LibmHasFrexpF128 = LibcallImpls<(add frexp_f128), isNotOSWindowsOrIsCygwi defvar LibmHasLdexpF128 = LibcallImpls<(add ldexp_f128), isNotOSWindowsOrIsCygwinMinGW>; defvar has__stack_chk_fail = LibcallImpls<(add __stack_chk_fail), isNotOSOpenBSD>; +defvar has__stack_chk_guard = + LibcallImpls<(add __stack_chk_guard), isNotOSOpenBSD>; defvar has__stack_smash_handler = LibcallImpls<(add __stack_smash_handler), isOSOpenBSD>; +defvar has___guard_local = LibcallImpls<(add __guard_local), isOSOpenBSD>; -defvar DefaultStackProtector = (add has__stack_chk_fail, - has__stack_smash_handler); +defvar DefaultStackProtector = (add has__stack_chk_fail, has__stack_chk_guard, + has__stack_smash_handler, has___guard_local); //===----------------------------------------------------------------------===// // Objective-C Runtime Libcalls @@ -1357,7 +1393,9 @@ def WindowsARM64ECSystemLibrary : SystemRuntimeLibrary, ExceptionModelCallsArm64EC)>; @@ -1848,7 +1886,7 @@ def HexagonSystemLibrary __umoddi3, __divdf3, __muldf3, __divsi3, __subdf3, sqrtf, __divdi3, __umodsi3, __moddi3, __modsi3), HexagonLibcalls, LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, - exp10f, exp10, exp10l_f128, __stack_chk_fail)>; + exp10f, exp10, exp10l_f128, __stack_chk_fail, __stack_chk_guard)>; //===----------------------------------------------------------------------===// // Lanai Runtime Libcalls @@ -1859,7 +1897,7 @@ def isLanai : RuntimeLibcallPredicate<"TT.getArch() == Triple::lanai">; // Use fast calling convention for library functions. def LanaiSystemLibrary : SystemRuntimeLibrary { + __stack_chk_fail, __stack_chk_guard)> { let DefaultLibcallCallingConv = FASTCC; } @@ -2157,7 +2195,8 @@ def MSP430SystemLibrary __mspabi_slll, // __mspabi_[srlll/srall/sllll/rlli/rlll] are NOT implemented in libgcc - __stack_chk_fail + __stack_chk_fail, + __stack_chk_guard ) >; @@ -2251,7 +2290,11 @@ def PPCSystemLibrary LibmHasSinCosPPCF128, AvailableIf, LibcallImpls<(add Int128RTLibcalls), isPPC64>, - DefaultStackProtector)>; + has__stack_chk_fail, + has__stack_smash_handler, + has___guard_local, + AvailableIf<__ssp_canary_word, isAIX>, + AvailableIf<__stack_chk_guard, isNotAIX>)>; //===----------------------------------------------------------------------===// // RISCV Runtime Libcalls @@ -2334,7 +2377,10 @@ def SPARCSystemLibrary LibcallImpls<(add _Q_qtoll, _Q_qtoull, _Q_lltoq, _Q_ulltoq), isSPARC32>, LibcallImpls<(add SPARC64_MulDivCalls, Int128RTLibcalls), isSPARC64>, LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, - DefaultStackProtector) + has__stack_chk_fail, + has__stack_smash_handler, + has___guard_local, + AvailableIf<__stack_chk_guard, isNotOSLinuxAndNotOSOpenBSD>) >; //===----------------------------------------------------------------------===// @@ -2544,7 +2590,7 @@ def WasmSystemLibrary exp10f, exp10, _Unwind_CallPersonality, emscripten_return_address, - __stack_chk_fail)>; + __stack_chk_fail, __stack_chk_guard)>; //===----------------------------------------------------------------------===// // Legacy Default Runtime Libcalls diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 350948a92a3a..9ffced80b07f 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -2059,29 +2059,37 @@ Value *TargetLoweringBase::getIRStackGuard(IRBuilderBase &IRB) const { // Currently only support "standard" __stack_chk_guard. // TODO: add LOAD_STACK_GUARD support. void TargetLoweringBase::insertSSPDeclarations(Module &M) const { - if (!M.getNamedValue("__stack_chk_guard")) { - auto *GV = new GlobalVariable(M, PointerType::getUnqual(M.getContext()), - false, GlobalVariable::ExternalLinkage, - nullptr, "__stack_chk_guard"); + RTLIB::LibcallImpl StackGuardImpl = getLibcallImpl(RTLIB::STACK_CHECK_GUARD); + if (StackGuardImpl == RTLIB::Unsupported) + return; - // FreeBSD has "__stack_chk_guard" defined externally on libc.so - if (M.getDirectAccessExternalData() && - !TM.getTargetTriple().isOSCygMing() && - !(TM.getTargetTriple().isPPC64() && - TM.getTargetTriple().isOSFreeBSD()) && - (!TM.getTargetTriple().isOSDarwin() || - TM.getRelocationModel() == Reloc::Static)) - GV->setDSOLocal(true); - } + StringRef StackGuardVarName = getLibcallImplName(StackGuardImpl); + M.getOrInsertGlobal( + StackGuardVarName, PointerType::getUnqual(M.getContext()), [=, &M]() { + auto *GV = new GlobalVariable(M, PointerType::getUnqual(M.getContext()), + false, GlobalVariable::ExternalLinkage, + nullptr, StackGuardVarName); + + // FreeBSD has "__stack_chk_guard" defined externally on libc.so + if (M.getDirectAccessExternalData() && + !TM.getTargetTriple().isOSCygMing() && + !(TM.getTargetTriple().isPPC64() && + TM.getTargetTriple().isOSFreeBSD()) && + (!TM.getTargetTriple().isOSDarwin() || + TM.getRelocationModel() == Reloc::Static)) + GV->setDSOLocal(true); + + return GV; + }); } // Currently only support "standard" __stack_chk_guard. // TODO: add LOAD_STACK_GUARD support. Value *TargetLoweringBase::getSDagStackGuard(const Module &M) const { - if (getTargetMachine().getTargetTriple().isOSOpenBSD()) { - return M.getNamedValue("__guard_local"); - } - return M.getNamedValue("__stack_chk_guard"); + RTLIB::LibcallImpl GuardVarImpl = getLibcallImpl(RTLIB::STACK_CHECK_GUARD); + if (GuardVarImpl == RTLIB::Unsupported) + return nullptr; + return M.getNamedValue(getLibcallImplName(GuardVarImpl)); } Function *TargetLoweringBase::getSSPStackGuardCheck(const Module &M) const { diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp index 0043f02107fb..a45b34eb2e70 100644 --- a/llvm/lib/Object/IRSymtab.cpp +++ b/llvm/lib/Object/IRSymtab.cpp @@ -46,18 +46,6 @@ static cl::opt DisableBitcodeVersionUpgrade( "disable-bitcode-version-upgrade", cl::Hidden, cl::desc("Disable automatic bitcode upgrade for version mismatch")); -static constexpr StringLiteral PreservedSymbols[] = { - // There are global variables, so put it here instead of in - // RuntimeLibcalls.td. - // TODO: Are there similar such variables? - "__ssp_canary_word", - "__stack_chk_guard", -}; - -static bool isPreservedGlobalVarName(StringRef Name) { - return PreservedSymbols[0] == Name || PreservedSymbols[1] == Name; -} - namespace { const char *getExpectedProducerName() { @@ -106,7 +94,7 @@ struct Builder { std::vector DependentLibraries; - bool isPreservedLibFuncName(StringRef Name) { + bool isPreservedName(StringRef Name) { return Libcalls.getSupportedLibcallImpl(Name) != RTLIB::Unsupported; } @@ -281,8 +269,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab, StringRef GVName = GV->getName(); setStr(Sym.IRName, GVName); - if (Used.count(GV) || isPreservedLibFuncName(GVName) || - isPreservedGlobalVarName(GVName)) + if (Used.count(GV) || isPreservedName(GVName)) Sym.Flags |= 1 << storage::Symbol::FB_used; if (GV->isThreadLocal()) Sym.Flags |= 1 << storage::Symbol::FB_tls; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index f6b214078f58..fbd8f7a979d6 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28686,9 +28686,13 @@ void AArch64TargetLowering::insertSSPDeclarations(Module &M) const { // MSVC CRT provides functionalities for stack protection. RTLIB::LibcallImpl SecurityCheckCookieLibcall = getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE); - if (SecurityCheckCookieLibcall != RTLIB::Unsupported) { + + RTLIB::LibcallImpl SecurityCookieVar = + getLibcallImpl(RTLIB::STACK_CHECK_GUARD); + if (SecurityCheckCookieLibcall != RTLIB::Unsupported && + SecurityCookieVar != RTLIB::Unsupported) { // MSVC CRT has a global variable holding security cookie. - M.getOrInsertGlobal("__security_cookie", + M.getOrInsertGlobal(getLibcallImplName(SecurityCookieVar), PointerType::getUnqual(M.getContext())); // MSVC CRT has a function to validate security cookie. @@ -28705,13 +28709,6 @@ void AArch64TargetLowering::insertSSPDeclarations(Module &M) const { 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); -} - Function *AArch64TargetLowering::getSSPStackGuardCheck(const Module &M) const { // MSVC CRT has a function to validate security cookie. RTLIB::LibcallImpl SecurityCheckCookieLibcall = diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h index 071e96e19428..6c6ae782f779 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -354,7 +354,6 @@ public: Value *getIRStackGuard(IRBuilderBase &IRB) const override; void insertSSPDeclarations(Module &M) const override; - Value *getSDagStackGuard(const Module &M) const override; Function *getSSPStackGuardCheck(const Module &M) const override; /// If the target has a standard location for the unsafe stack pointer, diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 830156359e9e..12d2d678ff63 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -21341,20 +21341,6 @@ void ARMTargetLowering::insertSSPDeclarations(Module &M) const { F->addParamAttr(0, Attribute::AttrKind::InReg); } -Value *ARMTargetLowering::getSDagStackGuard(const Module &M) const { - RTLIB::LibcallImpl SecurityCheckCookieLibcall = - getLibcallImpl(RTLIB::SECURITY_CHECK_COOKIE); - if (SecurityCheckCookieLibcall != RTLIB::Unsupported) { - // MSVC CRT has a global variable holding security cookie. - // - // FIXME: We have a libcall entry for the correlated check function, but not - // the global name. - 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. RTLIB::LibcallImpl SecurityCheckCookie = diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index 778595e93f84..0185c8ddd492 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -704,7 +704,6 @@ class VectorType; bool useLoadStackGuardNode(const Module &M) 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, diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index d6fe89a1904d..4f11fe45cf94 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -158,8 +158,6 @@ static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int); static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl); -static const char AIXSSPCanaryWordName[] = "__ssp_canary_word"; - // A faster local-[exec|dynamic] TLS access sequence (enabled with the // -maix-small-local-[exec|dynamic]-tls option) can be produced for TLS // variables; consistent with the IBM XL compiler, we apply a max size of @@ -18656,24 +18654,6 @@ bool PPCTargetLowering::useLoadStackGuardNode(const Module &M) const { return TargetLowering::useLoadStackGuardNode(M); } -// Override to disable global variable loading on Linux and insert AIX canary -// word declaration. -void PPCTargetLowering::insertSSPDeclarations(Module &M) const { - if (Subtarget.isAIXABI()) { - M.getOrInsertGlobal(AIXSSPCanaryWordName, - PointerType::getUnqual(M.getContext())); - return; - } - if (!Subtarget.isTargetLinux()) - return TargetLowering::insertSSPDeclarations(M); -} - -Value *PPCTargetLowering::getSDagStackGuard(const Module &M) const { - if (Subtarget.isAIXABI()) - return M.getGlobalVariable(AIXSSPCanaryWordName); - return TargetLowering::getSDagStackGuard(M); -} - bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const { if (!VT.isSimple() || !Subtarget.hasVSX()) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 5e0d6bf184f2..559d58309692 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -1141,8 +1141,6 @@ namespace llvm { /// Override to support customized stack guard loading. bool useLoadStackGuardNode(const Module &M) const override; - void insertSSPDeclarations(Module &M) const override; - Value *getSDagStackGuard(const Module &M) const override; bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override; diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index dd221327dbdc..d01218f573dc 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -3549,12 +3549,6 @@ bool SparcTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, return Subtarget->isUA2007() && !Subtarget->useSoftFloat(); } -// Override to disable global variable loading on Linux. -void SparcTargetLowering::insertSSPDeclarations(Module &M) const { - if (!Subtarget->isTargetLinux()) - return TargetLowering::insertSSPDeclarations(M); -} - void SparcTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const { assert(MI.getOpcode() == SP::SUBCCrr || MI.getOpcode() == SP::SUBCCri); diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h index 7fffb7c9823f..e7040f770e25 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -79,7 +79,6 @@ namespace llvm { /// Override to support customized stack guard loading. bool useLoadStackGuardNode(const Module &M) const override; - void insertSSPDeclarations(Module &M) const override; /// getSetCCResultType - Return the ISD::SETCC ValueType EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 3dd79b324951..97d3b6e2420d 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1591,7 +1591,6 @@ namespace llvm { bool useLoadStackGuardNode(const Module &M) const override; bool useStackGuardXorFP() const override; void insertSSPDeclarations(Module &M) const override; - Value *getSDagStackGuard(const Module &M) const override; Function *getSSPStackGuardCheck(const Module &M) const override; SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL) const override; diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp index 7c594d04f3c2..1c745a338a61 100644 --- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp +++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp @@ -632,15 +632,6 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const { TargetLowering::insertSSPDeclarations(M); } -Value *X86TargetLowering::getSDagStackGuard(const Module &M) const { - // MSVC CRT has a global variable holding security cookie. - if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() || - Subtarget.getTargetTriple().isWindowsItaniumEnvironment()) { - return M.getGlobalVariable("__security_cookie"); - } - return TargetLowering::getSDagStackGuard(M); -} - Function *X86TargetLowering::getSSPStackGuardCheck(const Module &M) const { // MSVC CRT has a function to validate security cookie. if (Subtarget.getTargetTriple().isWindowsMSVCEnvironment() || diff --git a/llvm/test/CodeGen/PowerPC/stack-protector-target.ll b/llvm/test/CodeGen/PowerPC/stack-protector-target.ll index 03ffa0b4c142..9b93040acb1c 100644 --- a/llvm/test/CodeGen/PowerPC/stack-protector-target.ll +++ b/llvm/test/CodeGen/PowerPC/stack-protector-target.ll @@ -65,8 +65,8 @@ define void @func() sspreq nounwind { ; LINUX32: # %bb.0: ; LINUX32-NEXT: mflr 0 ; LINUX32-NEXT: stwu 1, -16(1) -; LINUX32-NEXT: stw 0, 20(1) ; LINUX32-NEXT: lwz 3, -28680(2) +; LINUX32-NEXT: stw 0, 20(1) ; LINUX32-NEXT: stw 3, 12(1) ; LINUX32-NEXT: addi 3, 1, 8 ; LINUX32-NEXT: bl capture @@ -86,8 +86,8 @@ define void @func() sspreq nounwind { ; LINUX64: # %bb.0: ; LINUX64-NEXT: mflr 0 ; LINUX64-NEXT: stdu 1, -128(1) -; LINUX64-NEXT: std 0, 144(1) ; LINUX64-NEXT: ld 3, -28688(13) +; LINUX64-NEXT: std 0, 144(1) ; LINUX64-NEXT: std 3, 120(1) ; LINUX64-NEXT: addi 3, 1, 116 ; LINUX64-NEXT: bl capture