diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 0ec99315a1307cf1f6bd00703a82c2e292df2121..2a9b3fc031231eb4591cfb7cd5f0d84df743a7c9 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2185,6 +2185,10 @@ Enable stack protectors for all functions Enable stack protectors for some functions vulnerable to stack smashing. Compared to -fstack-protector, this uses a stronger heuristic that includes functions containing arrays of any size (and any type), as well as any calls to alloca or the taking of an address from a local variable +.. option:: -fstack-protector-ret + +Enable stack protectors for all functions with return address check + .. option:: -fstack-size-section, -fno-stack-size-section Emit section containing metadata on function stack sizes diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index c01f0cca9c9c2d91c0540b21d106eef3df99ba19..02375ba9d0b700c64ec986158436b5acb2fde02d 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -324,7 +324,7 @@ ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibil BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition") BENIGN_LANGOPT(HalfNoSemanticInterposition, 1, 0, "Like -fno-semantic-interposition but don't use local aliases") -ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, +ENUM_LANGOPT(StackProtector, StackProtectorMode, 3, SSPOff, "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, "trivial automatic variable initialization") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index d8bd2a8b52fcd7dea4e9dff5e03e4edf158b7162..a16ac81f785d53b2a1dd41e80190d28e389782c4 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -61,7 +61,7 @@ public: using RoundingMode = llvm::RoundingMode; enum GCMode { NonGC, GCOnly, HybridGC }; - enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; + enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq, SSPRet }; // Automatic variables live on the stack, and when trivial they're usually // uninitialized because it's undefined behavior to use them without diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9019ea8f72980b5af59f1c27789fd262383347ad..d710897c0f29fbc77db557d29f13ff41346f59a4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2258,6 +2258,8 @@ defm signed_char : OptOutFFlag<"signed-char", "char is signed", "char is unsigne def fsplit_stack : Flag<["-"], "fsplit-stack">, Group; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; +def fstack_protector_ret : Flag<["-"], "fstack-protector-ret">, Group, + HelpText<"Enable stack protectors for all functions with return address check">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", CodeGenOpts<"StackClashProtector">, DefaultFalse, PosFlag, NegFlag, @@ -5115,9 +5117,9 @@ def static_define : Flag<["-"], "static-define">, HelpText<"Should __STATIC__ be defined">, MarshallingInfoFlag>; def stack_protector : Separate<["-"], "stack-protector">, - HelpText<"Enable stack protectors">, Values<"0,1,2,3">, + HelpText<"Enable stack protectors">, Values<"0,1,2,3,4">, NormalizedValuesScope<"LangOptions">, - NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq"]>, + NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq", "SSPRet"]>, MarshallingInfoString, "SSPOff">, AutoNormalizeEnum; def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, HelpText<"Lower bound for a buffer to be considered for stack protection">, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 9c9bd4e374af7bfd6026d864ca12c78f51ed83ea..0b9932785d856814cac35eb419b55f8b22499835 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1677,6 +1677,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::StackProtectStrong); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) B.addAttribute(llvm::Attribute::StackProtectReq); + else if (LangOpts.getStackProtector() == LangOptions::SSPRet) + B.addAttribute(llvm::Attribute::StackProtectRet); } if (!D) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 32397abf1b54051a2d2d9898f28d2f35cf53980c..5ff82d9557e9708acd01a74d3fef3b53280fce4d 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3006,6 +3006,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, TC.GetDefaultStackProtectorLevel(KernelOrKext); if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, + options::OPT_fstack_protector_ret, options::OPT_fstack_protector_all, options::OPT_fstack_protector_strong, options::OPT_fstack_protector)) { @@ -3016,6 +3017,8 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, StackProtectorLevel = LangOptions::SSPStrong; else if (A->getOption().matches(options::OPT_fstack_protector_all)) StackProtectorLevel = LangOptions::SSPReq; + else if (A->getOption().matches(options::OPT_fstack_protector_ret)) + StackProtectorLevel = LangOptions::SSPRet; } else { StackProtectorLevel = DefaultStackProtectorLevel; } diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index c64a912ce919d878de31301f555c6c04e029b084..1b783ac5d152c755f3954d7850e58aa8bd20dee8 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1038,6 +1038,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__SSP_STRONG__", "2"); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) Builder.defineMacro("__SSP_ALL__", "3"); + else if (LangOpts.getStackProtector() == LangOptions::SSPRet) + Builder.defineMacro("__SSP_RET__", "4"); if (PPOpts.SetUpStaticAnalyzer) Builder.defineMacro("__clang_analyzer__"); diff --git a/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/lldb/source/Plugins/Platform/Android/AdbClient.cpp index ffccd6d628aade32c5a8e394e4f816c40ed2bffa..50a4a07a9bab429fe4dcb6c6059d279aced2894a 100644 --- a/lldb/source/Plugins/Platform/Android/AdbClient.cpp +++ b/lldb/source/Plugins/Platform/Android/AdbClient.cpp @@ -134,7 +134,7 @@ Status AdbClient::Connect() { Status error; m_conn = std::make_unique(); std::string port = "5037"; - if (const char *env_port = std::getenv("ANDROID_ADB_SERVER_PORT")) { + if (const char *env_port = std::getenv("HDC_SERVER_PORT")) { port = env_port; } std::string uri = "connect://127.0.0.1:" + port; diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp index 249cd5e9d801a55fbf5fafa4b2201b49f3be5eac..d28a73e3ec0dd756630a28007bbe9f9bd054b5bf 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -221,6 +221,9 @@ Status PlatformOHOS::DisconnectRemote() { if (error.Success()) { m_device_id.clear(); m_sdk_version = 0; + if (m_remote_platform_sp) { + m_remote_platform_sp = nullptr; + } } return error; } diff --git a/llvm-build/env_prepare.sh b/llvm-build/env_prepare.sh index 527c69a51fd988e0e3261614b8b6c65a1d6c8f8d..acfc3d247f5d3fc1dc9dafc8a121f6684b5a7f98 100755 --- a/llvm-build/env_prepare.sh +++ b/llvm-build/env_prepare.sh @@ -36,7 +36,7 @@ function download_and_archive() { archive_dir=$1 download_source_url=$2 bin_file=$(basename ${download_source_url}) - #wget -t3 -T10 -O "${bin_dir}/${bin_file}" "${download_source_url}" + wget -t3 -T10 -O "${bin_dir}/${bin_file}" "${download_source_url}" if [ ! -d "${code_dir}/${archive_dir}" ];then mkdir -p "${code_dir}/${archive_dir}" fi @@ -51,20 +51,20 @@ function download_and_archive() { copy_config=""" -prebuilts/clang/ohos/${host_platform}-${host_cpu},https://mirrors.huaweicloud.com/openharmony/compiler/clang/12.0.1-530132/${host_platform}/clang-530132-${host_platform}-x86_64.tar.bz2 """ copy_config_linux_x86_64=""" prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://mirrors.huaweicloud.com/openharmony/compiler/clang/10.0.1-62608/${host_platform}/llvm.tar.gz prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz """ copy_config_darwin_x86_64=""" prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz -prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-apple-darwin.tar.xz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-apple-darwin.tar.xz """ -# + if [[ "${host_platform}" == "linux" ]]; then if [[ "${host_cpu}" == "x86_64" ]]; then copy_config+=${copy_config_linux_x86_64} @@ -86,7 +86,6 @@ else fi - for i in $(echo ${copy_config}) do unzip_dir=$(echo $i|awk -F ',' '{print $1}') @@ -95,30 +94,19 @@ do done -if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-530132" ];then +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-62608" ];then rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" - mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-530132" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" - ln -snf 12.0.1 "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-62608" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" + ln -snf 10.0.1 "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current" fi -if [ -d "${code_dir}/prebuilts/clang/ohos/darwin-${host_cpu}/clang-530132" ];then - if [[ "${host_cpu}" == "arm64" ]]; then - rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-arm64/llvm" - mv "${code_dir}/prebuilts/clang/ohos/darwin-arm64/clang-530132" "${code_dir}/prebuilts/clang/ohos/darwin-arm64/llvm" - ln -snf 12.0.1 "${code_dir}/prebuilts/clang/ohos/darwin-arm64/llvm/lib/clang/current" - else - rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/llvm" - mv "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-530132" "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/llvm" - ln -snf 12.0.1 "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/llvm/lib/clang/current" - fi -fi -if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-gnu-ubuntu-16.04.tar.xz" ];then +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04" ];then rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" - mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-gnu-ubuntu-16.04" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" fi -if [ -d "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-10.0.1-x86_64-apple-darwin" ];then +if [ -d "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-12.0.0-x86_64-apple-darwin" ];then rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" - mv "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-10.0.1-x86_64-apple-darwin" "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-12.0.0-x86_64-apple-darwin" "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" fi diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 5b4854d6c95e0f9af584028ec30770ebac0896ca..830f1792de58a23baa166a6541a9770f8ebfa83a 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -657,6 +657,7 @@ enum AttributeKindCodes { ATTR_KIND_NO_CALLBACK = 71, ATTR_KIND_HOT = 72, ATTR_KIND_NO_PROFILE = 73, + ATTR_KIND_STACK_PROTECT_RET = 74, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index f7ffc888c65a95dad997b767b5a1935f49028cb4..d188980201f274e7f7ed3e39e274e6251e20b0f3 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -203,6 +203,9 @@ def Speculatable : EnumAttr<"speculatable">; /// Stack protection. def StackProtect : EnumAttr<"ssp">; +/// Stack protection for return address. +def StackProtectRet : EnumAttr<"sspret">; + /// Stack protection required. def StackProtectReq : EnumAttr<"sspreq">; diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 5149f861837adab3b54a2498e9c02eab5650ce53..a93cdfff73ca550c2fefffabfa2d0aa7d16366b8 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -228,6 +228,7 @@ enum Kind { kw_signext, kw_speculatable, kw_ssp, + kw_sspret, kw_sspreq, kw_sspstrong, kw_safestack, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index f2800201e871114ccbb5f1da1fe164dbbd0d94be..1363e30412d139d8f4ce840c05013960c5c2a6d9 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1495,6 +1495,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::StackProtect; case bitc::ATTR_KIND_STACK_PROTECT_REQ: return Attribute::StackProtectReq; + case bitc::ATTR_KIND_STACK_PROTECT_RET: + return Attribute::StackProtectRet; case bitc::ATTR_KIND_STACK_PROTECT_STRONG: return Attribute::StackProtectStrong; case bitc::ATTR_KIND_SAFESTACK: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 37ecb9992e44abf803e0fb4ce846ff7facc268b4..379830eb0aff6f08a06821e462f839629ba18ee4 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -710,6 +710,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_STACK_PROTECT; case Attribute::StackProtectReq: return bitc::ATTR_KIND_STACK_PROTECT_REQ; + case Attribute::StackProtectRet: + return bitc::ATTR_KIND_STACK_PROTECT_RET; case Attribute::StackProtectStrong: return bitc::ATTR_KIND_STACK_PROTECT_STRONG; case Attribute::SafeStack: diff --git a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp index ec6e693e8a46abd22dff1ca497ba5f54e3dbd2ff..7f959ee6831f19cd8b5aea0637947cabb04aefbd 100644 --- a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp +++ b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp @@ -29,6 +29,7 @@ #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/InitializePasses.h" +#include "llvm/IR/Function.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -197,7 +198,12 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { // Make sure that the stack protector comes before the local variables on the // stack. + Function &F = Fn.getFunction(); SmallSet ProtectedObjs; + StackObjSet LargeArrayObjs; + StackObjSet SmallArrayObjs; + StackObjSet AddrOfObjs; + if (MFI.hasStackProtectorIndex()) { int StackProtectorFI = MFI.getStackProtectorIndex(); @@ -208,10 +214,6 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { assert(!MFI.isObjectPreAllocated(StackProtectorFI) && "Stack protector pre-allocated in LocalStackSlotAllocation"); - StackObjSet LargeArrayObjs; - StackObjSet SmallArrayObjs; - StackObjSet AddrOfObjs; - AdjustStackOffset(MFI, StackProtectorFI, Offset, StackGrowsDown, MaxAlign); // Assign large stack objects first. @@ -238,14 +240,32 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { } llvm_unreachable("Unexpected SSPLayoutKind."); } - - AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, - Offset, MaxAlign); - AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, - Offset, MaxAlign); - AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, - Offset, MaxAlign); + } else if (F.hasFnAttribute(Attribute::StackProtectRet)) { + // Assign large stack objects first. + for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { + if (MFI.isDeadObjectIndex(i)) + continue; + if (!TFI.isStackIdSafeForLocalArea(MFI.getStackID(i))) + continue; + switch (MFI.getObjectSSPLayout(i)) { + case MachineFrameInfo::SSPLK_None: + continue; + case MachineFrameInfo::SSPLK_SmallArray: + SmallArrayObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_AddrOf: + AddrOfObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_LargeArray: + LargeArrayObjs.insert(i); + continue; + } + llvm_unreachable("Unexpected SSPLayoutKind."); + } } + AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign); + AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign); + AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign); // Then assign frame offsets to stack objects that are not used to spill // callee saved registers. diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 378aaba2a65f15164eea97efd1127d094e053289..4de2a3bf277ebc02fd0e905a911b64389fd04b88 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -926,12 +926,13 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { // Make sure that the stack protector comes before the local variables on the // stack. + Function &F = MF.getFunction(); + StackObjSet LargeArrayObjs; + StackObjSet SmallArrayObjs; + StackObjSet AddrOfObjs; SmallSet ProtectedObjs; if (MFI.hasStackProtectorIndex()) { int StackProtectorFI = MFI.getStackProtectorIndex(); - StackObjSet LargeArrayObjs; - StackObjSet SmallArrayObjs; - StackObjSet AddrOfObjs; // If we need a stack protector, we need to make sure that // LocalStackSlotPass didn't already allocate a slot for it. @@ -984,14 +985,41 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { AddrOfObjs.empty())) llvm_unreachable("Found protected stack objects not pre-allocated by " "LocalStackSlotPass."); - - AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, - Offset, MaxAlign, Skew); - AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, - Offset, MaxAlign, Skew); - AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, - Offset, MaxAlign, Skew); + } else if (F.hasFnAttribute(Attribute::StackProtectRet)) { + // Assign large stack objects first. + for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { + if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock()) + continue; + if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) + continue; + if (RS && RS->isScavengingFrameIndex((int)i)) + continue; + if (MFI.isDeadObjectIndex(i)) + continue; + if (EHRegNodeFrameIndex == (int)i) + continue; + if (MFI.getStackID(i) != + TargetStackID::Default) // Only allocate objects on the default stack. + continue; + switch (MFI.getObjectSSPLayout(i)) { + case MachineFrameInfo::SSPLK_None: + continue; + case MachineFrameInfo::SSPLK_SmallArray: + SmallArrayObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_AddrOf: + AddrOfObjs.insert(i); + continue; + case MachineFrameInfo::SSPLK_LargeArray: + LargeArrayObjs.insert(i); + continue; + } + llvm_unreachable("Unexpected SSPLayoutKind."); + } } + AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign, Skew); + AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign, Skew); + AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign, Skew); SmallVector ObjectsToAllocate; diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index 31797631c97b317fb828f34f1d042e831a95cfd9..3f14f68707b7c41d22ec16cfb1a76c0412850bac 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -809,7 +809,8 @@ bool SafeStack::run() { // FIXME: implement weaker forms of stack protector. if (F.hasFnAttribute(Attribute::StackProtect) || F.hasFnAttribute(Attribute::StackProtectStrong) || - F.hasFnAttribute(Attribute::StackProtectReq)) { + F.hasFnAttribute(Attribute::StackProtectReq) || + F.hasFnAttribute(Attribute::StackProtectRet)) { Value *StackGuard = getStackGuard(IRB, F); StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr); IRB.CreateStore(StackGuard, StackGuardSlot); diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index 10c6dcbdb049ea78c3671185b43c9f460d61c913..0a5963dfa5c02a990e2b7f348054a9957c41a2d6 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -108,6 +108,11 @@ bool StackProtector::runOnFunction(Function &Fn) { return false; } + if (Fn.hasFnAttribute(Attribute::StackProtectRet)) { + HasIRCheck = true; + return false; + } + ++NumFunProtected; return InsertStackProtectors(); } @@ -294,6 +299,8 @@ bool StackProtector::RequiresStackProtector() { Strong = true; // Use the same heuristic as strong to determine SSPLayout } else if (F->hasFnAttribute(Attribute::StackProtectStrong)) Strong = true; + else if (F->hasFnAttribute(Attribute::StackProtectRet)) + Strong = true; else if (!F->hasFnAttribute(Attribute::StackProtect)) return false; diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index c4629decc6d98ebd14e81ead95bfbd9df0259ca5..6ff77f8a35fb5579456c64b5a6123e31a3f6ad00 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1966,9 +1966,16 @@ static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { AttrBuilder OldSSPAttr; OldSSPAttr.addAttribute(Attribute::StackProtect) .addAttribute(Attribute::StackProtectStrong) - .addAttribute(Attribute::StackProtectReq); + .addAttribute(Attribute::StackProtectReq) + .addAttribute(Attribute::StackProtectRet); - if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { + if (Callee.hasFnAttribute(Attribute::StackProtectRet) && + !Caller.hasFnAttribute(Attribute::StackProtect) && + !Caller.hasFnAttribute(Attribute::StackProtectReq) && + !Caller.hasFnAttribute(Attribute::StackProtectStrong)) { + Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); + Caller.addFnAttr(Attribute::StackProtectRet); + } else if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); Caller.addFnAttr(Attribute::StackProtectReq); } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 17247123f87f887b81dea4f561bd3aa9b8e24455..d6862c2dcc6e00e3a482cc7f8fbce06279671ca5 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -615,7 +615,8 @@ void Function::clearGC() { bool Function::hasStackProtectorFnAttr() const { return hasFnAttribute(Attribute::StackProtect) || hasFnAttribute(Attribute::StackProtectStrong) || - hasFnAttribute(Attribute::StackProtectReq); + hasFnAttribute(Attribute::StackProtectReq) || + hasFnAttribute(Attribute::StackProtectRet); } /// Copy all additional attributes (those not needed to create a Function) from diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 390925a03b73c3fae20249ec5a26c13596f5f27c..cccf36ae9831dd98766d6a9300be8a7efc541688 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -967,6 +967,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::SanitizeMemTag: case Attribute::SpeculativeLoadHardening: case Attribute::StackProtect: + case Attribute::StackProtectRet: case Attribute::StackProtectReq: case Attribute::StackProtectStrong: case Attribute::StrictFP: