diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index f29396749305942a8de9a8512f7d211d4a1d312d..41fb8f7259eb4c90575b0335ce91704baa9241bd 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2506,13 +2506,17 @@ Enable stack protectors for some functions vulnerable to stack smashing. This us Enable stack protectors for all functions -.. option:: -fstack-protector-strong +.. option:: -fstack-protector-ret-all -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 +Enable stack protectors for all functions with return address check -.. option:: -fstack-protector-ret +.. option:: -fstack-protector-ret-strong -Enable stack protectors for all functions with return address check +Enable stack protectors for some functions vulnerable to stack smashing with return address check + +.. option:: -fstack-protector-strong + +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-size-section, -fno-stack-size-section diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index ef7957979dccd2595d3af35d0ede650a8d7f41d4..5d4aec842db3f5ad4fb552348ce31a852d30e7c2 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -373,6 +373,11 @@ VALUE_CODEGENOPT(SmallDataLimit, 32, 0) /// The lower bound for a buffer to be considered for stack protection. VALUE_CODEGENOPT(SSPBufferSize, 32, 0) +/// OHOS_LOCAL begin +/// The maximum total of cookies used by backward cfi for stack protection. +VALUE_CODEGENOPT(SSPRetCookieSize, 32, 1) +/// OHOS_LOCAL end + /// The kind of generated debug info. ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 4, codegenoptions::NoDebugInfo) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 4faec655636cb98d9f24f6b5c0b3ba42a610bdcf..c58c45416107e5dabd6d210b063aa2b118512a8f 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -358,6 +358,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") +/// OHOS_LOCAL ENUM_LANGOPT(StackProtector, StackProtectorMode, 3, SSPOff, "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 04677596490567521aecc4f0d0660c31e95da5b4..10b8260b34895e73cd20fb10f4b04b348a81f43d 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -81,7 +81,7 @@ public: using RoundingMode = llvm::RoundingMode; enum GCMode { NonGC, GCOnly, HybridGC }; - enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq, SSPRet }; + enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq, SSPRetStrong, SSPRetReq }; // OHOS_LOCAL // 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 1b96288ff225892e5ee755fe071ef1db1723f83f..7d0d72700b710d4833f027377d4e3d30eab75227 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2738,8 +2738,12 @@ defm split_stack : BoolFOption<"split-stack", PosFlag>; 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, +// OHOS_LOCAL begin +def fstack_protector_ret_all : Flag<["-"], "fstack-protector-ret-all">, Group, HelpText<"Enable stack protectors for all functions with return address check">; +def fstack_protector_ret_strong : Flag<["-"], "fstack-protector-ret-strong">, Group, + HelpText<"Enable stack protectors for some functions vulnerable to stack smashing with return address check">; +// OHOS_LOCAL end defm stack_clash_protection : BoolFOption<"stack-clash-protection", CodeGenOpts<"StackClashProtector">, DefaultFalse, PosFlag, NegFlag, @@ -6052,13 +6056,18 @@ def static_define : Flag<["-"], "static-define">, MarshallingInfoFlag>; def stack_protector : Separate<["-"], "stack-protector">, HelpText<"Enable stack protectors">, - Values<"0,1,2,3,4">, + Values<"0,1,2,3,4,5">, // OHOS_LOCAL NormalizedValuesScope<"LangOptions">, - NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq", "SSPRet"]>, + NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq", "SSPRetStrong", "SSPRetReq"]>, // OHOS_LOCAL MarshallingInfoEnum, "SSPOff">; def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, HelpText<"Lower bound for a buffer to be considered for stack protection">, MarshallingInfoInt, "8">; +// OHOS_LOCAL begin +def stack_protector_ret_cookie_size : Separate<["-"], "stack-protector-ret-cookie-size">, + HelpText<"Maximum number of cookies for return address check to be considered for stack protection">, + MarshallingInfoInt, "1">; +// OHOS_LOCAL end def fvisibility : Separate<["-"], "fvisibility">, HelpText<"Default type and symbol visibility">, MarshallingInfoVisibility, "DefaultVisibility">; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index dfa78bf59c65808acaadf4c0d1371c090afe2b11..996fe6c1bd2062982f133dbcdb6f3ebf0172ee15 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1866,6 +1866,8 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, FuncAttrs.addAttribute("use-soft-float", "true"); FuncAttrs.addAttribute("stack-protector-buffer-size", llvm::utostr(CodeGenOpts.SSPBufferSize)); + FuncAttrs.addAttribute("stack-protector-ret-cookie-size", + llvm::utostr(CodeGenOpts.SSPRetCookieSize)); // OHOS_LOCAL if (LangOpts.NoSignedZero) FuncAttrs.addAttribute("no-signed-zeros-fp-math", "true"); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c67643c43a7d1d13591bb3ea8c47711bab317b47..f5f0d56515c2e768a2ce6cd6fd90a9734625cc93 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1951,8 +1951,12 @@ 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); + // OHOS_LOCAL begin + else if (LangOpts.getStackProtector() == LangOptions::SSPRetStrong) + B.addAttribute(llvm::Attribute::StackProtectRetStrong); + else if (LangOpts.getStackProtector() == LangOptions::SSPRetReq) + B.addAttribute(llvm::Attribute::StackProtectRetReq); + // OHOS_LOCAL end } if (!D) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c4355b9d52ec60e4a42f0fd47b69e7bb3d0ada31..d54dd6e1dfec353106bd6cb3404f81cd5a142597 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3259,7 +3259,10 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector, options::OPT_fstack_protector_all, - options::OPT_fstack_protector_ret, + // OHOS_LOCAL begin + options::OPT_fstack_protector_ret_all, + options::OPT_fstack_protector_ret_strong, + // OHOS_LOCAL end options::OPT_fstack_protector_strong, options::OPT_fstack_protector)) { if (A->getOption().matches(options::OPT_fstack_protector)) @@ -3267,8 +3270,12 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, std::max<>(LangOptions::SSPOn, DefaultStackProtectorLevel); else if (A->getOption().matches(options::OPT_fstack_protector_strong)) StackProtectorLevel = LangOptions::SSPStrong; - else if (A->getOption().matches(options::OPT_fstack_protector_ret)) - StackProtectorLevel = LangOptions::SSPRet; + // OHOS_LOCAL begin + else if (A->getOption().matches(options::OPT_fstack_protector_ret_strong)) + StackProtectorLevel = LangOptions::SSPRetStrong; + else if (A->getOption().matches(options::OPT_fstack_protector_ret_all)) + StackProtectorLevel = LangOptions::SSPRetReq; + // OHOS_LOCAL end else if (A->getOption().matches(options::OPT_fstack_protector_all)) StackProtectorLevel = LangOptions::SSPReq; } else { @@ -3280,7 +3287,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel))); } - // --param ssp-buffer-size= + // --param ssp-buffer-size= && ssp-ret-cookie-size=, OHOS_LOCAL for (const Arg *A : Args.filtered(options::OPT__param)) { StringRef Str(A->getValue()); if (Str.startswith("ssp-buffer-size=")) { @@ -3291,6 +3298,28 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC, } A->claim(); } + // OHOS_LOCAL begin + if (Str.startswith("ssp-ret-cookie-size=")) { + unsigned int SSPRetCookieSize = 0; + // Currently only supports AArch64 architecture. + if (!EffectiveTriple.isAArch64() || !EffectiveTriple.isOSBinFormatELF()) { + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Str.take_front(19) << EffectiveTriple.getTriple(); + continue; + } + // The parameter must be greater than 0. + if (Str.drop_front(20).getAsInteger(10, SSPRetCookieSize) || !SSPRetCookieSize) { + D.Diag(diag::err_drv_invalid_int_value) + << Str.take_front(19) << Str.drop_front(20); + continue; + } + if (StackProtectorLevel) { + CmdArgs.push_back("-stack-protector-ret-cookie-size"); + CmdArgs.push_back(Args.MakeArgString(Str.drop_front(20))); + } + A->claim(); + } + // OHOS_LOCAL end } const std::string &TripleStr = EffectiveTriple.getTriple(); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 34f8c91fb79d478db7657076f38dcbdad40253b3..cf40036385f22fb691f8ae7b847967aff29ddbbe 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1185,8 +1185,12 @@ 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"); + // OHOS_LOCAL begin + else if (LangOpts.getStackProtector() == LangOptions::SSPRetStrong) + Builder.defineMacro("__SSP_RET_STRONG__", "4"); + else if (LangOpts.getStackProtector() == LangOptions::SSPRetReq) + Builder.defineMacro("__SSP_RET_ALL__", "5"); + // OHOS_LOCAL end if (PPOpts.SetUpStaticAnalyzer) Builder.defineMacro("__clang_analyzer__"); diff --git a/clang/test/CodeGen/stack-protector.c b/clang/test/CodeGen/stack-protector.c index e880f4b2a3aa64b9d2e094da1701b499b879c1d1..6085e4844be17b9c75ca9a4f0bc019d99ba1ca86 100644 --- a/clang/test/CodeGen/stack-protector.c +++ b/clang/test/CodeGen/stack-protector.c @@ -2,12 +2,20 @@ // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -stack-protector 1 | FileCheck -check-prefix=DEF -check-prefix=SSP %s // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -stack-protector 2 | FileCheck -check-prefix=DEF -check-prefix=SSPSTRONG %s // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -stack-protector 3 | FileCheck -check-prefix=DEF -check-prefix=SSPREQ %s +// OHOS_LOCAL begin +// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -stack-protector 4 | FileCheck -check-prefix=DEF -check-prefix=SSPRETSTRONG %s +// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -stack-protector 5 | FileCheck -check-prefix=DEF -check-prefix=SSPRETREQ %s +// OHOS_LOCAL end // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -fsanitize=safe-stack | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-NOSSP %s // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 0 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-NOSSP %s // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 1 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-SSP %s // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 2 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-SSPSTRONG %s // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 3 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-SSPREQ %s +// OHOS_LOCAL begin +// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 4 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-SSPRETSTRONG %s +// RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -o - %s -fsanitize=safe-stack -stack-protector 5 | FileCheck -check-prefix=DEF -check-prefix=SAFESTACK-SSPRETREQ %s +// OHOS_LOCAL end typedef __SIZE_TYPE__ size_t; @@ -34,6 +42,10 @@ void test2(const char *msg) { // SSP: attributes #[[A]] = {{.*}} ssp{{ }} // SSPSTRONG: attributes #[[A]] = {{.*}} sspstrong // SSPREQ: attributes #[[A]] = {{.*}} sspreq +// OHOS_LOCAL begin +// SSPRETSTRONG: attributes #[[A]] = {{.*}} sspretstrong +// SSPRETREQ: attributes #[[A]] = {{.*}} sspretreq +// OHOS_LOCAL end // SAFESTACK-NOSSP: attributes #[[A]] = {{.*}} safestack // SAFESTACK-NOSSP-NOT: ssp @@ -41,6 +53,10 @@ void test2(const char *msg) { // SAFESTACK-SSP: attributes #[[A]] = {{.*}} safestack ssp{{ }} // SAFESTACK-SSPSTRONG: attributes #[[A]] = {{.*}} safestack sspstrong // SAFESTACK-SSPREQ: attributes #[[A]] = {{.*}} safestack sspreq +// OHOS_LOCAL begin +// SAFESTACK-SSPRETSTRONG: attributes #[[A]] = {{.*}} safestack sspretstrong +// SAFESTACK-SSPRETREQ: attributes #[[A]] = {{.*}} safestack sspretreq +// OHOS_LOCAL end // NOSSP-NOT: attributes #[[B]] = {{.*}} ssp // SSP-NOT: attributes #[[B]] = {{.*}} ssp{{ }} @@ -53,3 +69,9 @@ void test2(const char *msg) { // SAFESTACK-SSPSTRONG-NOT: attributes #[[B]] = {{.*}} safestack sspstrong // SAFESTACK-SSPREQ: attributes #[[B]] = {{.*}} safestack // SAFESTACK-SSPREQ-NOT: attributes #[[B]] = {{.*}} safestack sspreq +// OHOS_LOCAL begin +// SAFESTACK-SSPRETSTRONG: attributes #[[B]] = {{.*}} safestack +// SAFESTACK-SSPRETSTRONG-NOT: attributes #[[B]] = {{.*}} safestack sspretstrong +// SAFESTACK-SSPRETREQ: attributes #[[B]] = {{.*}} safestack +// SAFESTACK-SSPRETREQ-NOT: attributes #[[B]] = {{.*}} safestack sspretreq +// OHOS_LOCAL end diff --git a/clang/test/Driver/claim-unused.c b/clang/test/Driver/claim-unused.c index c7b798934b3c690222b0a8dca7738d2fd5afb5f7..19ad9a4d38f68e29bdc85c50e3690d8662a1735b 100644 --- a/clang/test/Driver/claim-unused.c +++ b/clang/test/Driver/claim-unused.c @@ -1,3 +1,7 @@ // RUN: touch %t.o // RUN: %clang --param ssp-buffer-size=1 %t.o -### 2>&1 | FileCheck %s // CHECK-NOT: warning: argument unused during compilation: '--param ssp-buffer-size=1' +// OHOS_LOCAL begin +// RUN: %clang --param ssp-ret-cookie-size=1 %t.o -### 2>&1 | FileCheck %s +// CHECK-NOT: warning: argument unused during compilation: '--param ssp-ret-cookie-size=1' +// OHOS_LOCAL end diff --git a/clang/test/Driver/stack-protector.c b/clang/test/Driver/stack-protector.c index 169376919a717a38ffad4d3d2e1b54978d7c241e..db3172d7e869b6145d5b55462651af2454a4d1bf 100644 --- a/clang/test/Driver/stack-protector.c +++ b/clang/test/Driver/stack-protector.c @@ -24,6 +24,24 @@ // SSP-ALL: "-stack-protector" "3" // SSP-ALL-NOT: "-stack-protector-buffer-size" +// OHOS_LOCAL begin +// RUN: %clang -fstack-protector-ret-strong -### %s 2>&1 | FileCheck %s -check-prefix=SSP-RET-STRONG +// SSP-RET-STRONG: "-stack-protector" "4" +// SSP-RET-STRONG-NOT: "-stack-protector-buffer-size" + +// RUN: %clang -fstack-protector-ret-all -### %s 2>&1 | FileCheck %s -check-prefix=SSP-RET-ALL +// SSP-RET-ALL: "-stack-protector" "5" +// SSP-RET-ALL-NOT: "-stack-protector-buffer-size" + +// RUN: %clang -target aarch64-linux-ohos -fstack-protector-ret-strong --param ssp-ret-cookie-size=10 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-RET-COOKIE-STRONG +// SSP-RET-COOKIE-STRONG: "-stack-protector" "4" +// SSP-RET-COOKIE-STRONG: "-stack-protector-ret-cookie-size" "10" + +// RUN: %clang -target aarch64-linux-ohos -fstack-protector-ret-all --param ssp-ret-cookie-size=-1 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-RET-COOKIE-ALL +// SSP-RET-COOKIE-ALL: invalid integral value +// SSP-RET-COOKIE-ALL: "-stack-protector" "5" +// OHOS_LOCAL end + // RUN: %clang -target x86_64-scei-ps4 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-PS4 // RUN: %clang -target x86_64-scei-ps4 -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP-PS4 // SSP-PS4: "-stack-protector" "2" diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 9f30117c0279b0d6e6599ec1247b4eaedf422dc8..51c505d159d53a811172e360a0a2065ea49a5c25 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -103,7 +103,7 @@ static StringRef getOutputSectionName(const InputSectionBase *s) { for (StringRef v : {".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss", ".gcc_except_table", ".init_array", ".fini_array", ".tbss", ".tdata", - ".ARM.exidx", ".ARM.extab", ".ctors", ".dtors"}) + ".ARM.exidx", ".ARM.extab", ".ctors", ".dtors", ".ohos.randomdata"}) // OHOS_LOCAL if (isSectionPrefix(v, s->name)) return v; diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 0576c6e66f4d325fa0b6887b6a7a754c66edd6af..e37faf90e132d36e2ebc7a107556932281af43b6 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -1578,7 +1578,7 @@ unsigned ScriptParser::readPhdrType() { .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) - .Case("PT_OHOS_RANDOMDATA", PT_OHOS_RANDOMDATA) + .Case("PT_OHOS_RANDOMDATA", PT_OHOS_RANDOMDATA) // OHOS_LOCAL .Default(-1); if (ret == (unsigned)-1) { diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index bf213b199d4fed4da2c19d4c4ffebec134647659..e27e656d43c712b18ce1c8a63629382e589c840d 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -833,7 +833,7 @@ static bool isRelroSection(const OutputSection *sec) { s == ".dtors" || s == ".jcr" || s == ".eh_frame" || s == ".fini_array" || s == ".init_array" || s == ".openbsd.randomdata" || s == ".preinit_array" || - s == ".ohos.randomdata"; + s == ".ohos.randomdata"; // OHOS_LOCAL } // We compute a rank for each section. The rank indicates where the @@ -2428,8 +2428,10 @@ SmallVector Writer::createPhdrs(Partition &part) { if (OutputSection *cmd = findSection(".note.gnu.property", partNo)) addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd); + // OHOS_LOCAL if (OutputSection *cmd = findSection(".ohos.randomdata", partNo)) addHdr(PT_OHOS_RANDOMDATA, cmd->getPhdrFlags())->add(cmd); + // OHOS_LOCAL // Create one PT_NOTE per a group of contiguous SHT_NOTE sections with the // same alignment. diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index f98c95526c9e0c3fcb039fd51ca8a91a680a4534..d98ea1d71b7a9998392de1fa794b8fcbc7a0210f 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -868,6 +868,10 @@ static StringRef getOutputDataSegmentName(const InputChunk &seg) { return ".bss"; if (seg.name.startswith(".rodata.")) return ".rodata"; + // OHOS_LOCAL begin + if (seg.name.startswith(".ohos.randomdata.")) + return ".ohos.randomdata"; + // OHOS_LOCAL end return seg.name; } diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index bc1f63f272f3de8e288e74f4b4e32268abbf54e5..9d6ad6699fbfc083a249e2b4f918495bcc854e00 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2126,6 +2126,67 @@ example: function which has an ``ssp`` or ``sspstrong`` attribute, the calling function's attribute will be upgraded to ``sspreq``. +.. OHOS_LOCAL begin +``sspretstrong`` + This attribute indicates that the function should emit a stack smashing + protector with return address check for backward cfi. This attribute + causes a strong heuristic to be used when determining if a function needs + stack protectors. This overrides the ``sspstrong`` function attributes. + + Variables that are identified as requiring a protector will be arranged + on the stack such that they are adjacent to the stack protector guard. + The specific layout rules are: + + #. Large arrays and structures containing large arrays + (``>= ssp-buffer-size``) are closest to the stack protector. + #. Small arrays and structures containing small arrays + (``< ssp-buffer-size``) are 2nd closest to the protector. + #. Variables that have had their address taken are 3rd closest to the + protector. + + The rules for the number of cookies used by additional backward cfi + protection are: + + #. If ``ssp-ret-cookie-size`` is not specified, the functions protected + by ``sspretstrong`` in each object share the one cookie. + #. The maximum number of cookies used by ``sspretstrong`` in each object + does not exceed ``ssp-ret-cookie-size``. + + This overrides the ``ssp`` function attribute. + + If a function with an ``sspretstrong`` attribute is inlined into a calling + function which has an ``ssp`` or ``sspstrong`` attribute, the calling function's attribute + will be upgraded to ``sspretstrong``. + +``sspretreq`` + This attribute indicates that the function should *always* emit a stack + smashing protector with return address check for backward cfi. This + overrides the ``sspreq`` and ``sspstrong`` function attributes. + + Variables that are identified as requiring a protector will be arranged + on the stack such that they are adjacent to the stack protector guard. + The specific layout rules are: + + #. Large arrays and structures containing large arrays + (``>= ssp-buffer-size``) are closest to the stack protector. + #. Small arrays and structures containing small arrays + (``< ssp-buffer-size``) are 2nd closest to the protector. + #. Variables that have had their address taken are 3rd closest to the + protector. + + The rules for the number of cookies used by additional backward cfi + protection are: + + #. If ``ssp-ret-cookie-size`` is not specified, the functions protected + by ``sspretreq`` in each object share the one cookie. + #. The maximum number of cookies used by ``sspretreq`` in each object + does not exceed ``ssp-ret-cookie-size``. + + If a function with an ``sspretreq`` attribute is inlined into a calling + function which has an ``sspreq`` or ``sspretstrong`` attribute, the calling + function's attribute will be upgraded to ``sspretreq``. +.. OHOS_LOCAL end + ``strictfp`` This attribute indicates that the function was called from a scope that requires strict floating-point semantics. LLVM will not attempt any diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 9d4b9e9878dec18a0a4a9afb551052540c6a4e6b..556fe9c6a1a042caac23002459a5c12fefc438ef 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1381,7 +1381,7 @@ enum { PT_OPENBSD_WXNEEDED = 0x65a3dbe7, // Program does W^X violations. PT_OPENBSD_BOOTDATA = 0x65a41be6, // Section for boot arguments. - PT_OHOS_RANDOMDATA = 0x6788FC60, // Fill with random data. + PT_OHOS_RANDOMDATA = 0x6788FC60, // Fill with random data. OHOS_LOCAL // ARM program header types. PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility info diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 104068e0c2a0cca799d58c92e4e414294092c9dd..6cd0011085e0654c7b662577ae4653e4654c788f 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -689,7 +689,10 @@ enum AttributeKindCodes { ATTR_KIND_ALLOC_KIND = 82, ATTR_KIND_PRESPLIT_COROUTINE = 83, ATTR_KIND_FNRETTHUNK_EXTERN = 84, - ATTR_KIND_STACK_PROTECT_RET = 85, + /// OHOS_LOCAL begin + ATTR_KIND_STACK_PROTECT_RET_REQ = 85, + ATTR_KIND_STACK_PROTECT_RET_STRONG = 86, + /// OHOS_LOCAL end }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h index 1c603e2ccdb209b96bae3f5690723dfabe77cb83..c5adc1b254bb5688a6d2352f3f2edcc993507b1f 100644 --- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -272,12 +272,14 @@ private: /// The frame index for the stack protector. int StackProtectorIdx = -1; + /// OHOS_LOCAL begin struct StackProtectorRet { /// The register to use for stack protector & backwrad cfi calculations unsigned Register = 0; /// Set to true if this function needs stack-protector-ret bool Needed = false; } SPR; + /// OHOS_LOCAL end /// The frame index for the function context. Used for SjLj exceptions. int FunctionContextIdx = -1; @@ -365,6 +367,7 @@ public: void setStackProtectorIndex(int I) { StackProtectorIdx = I; } bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; } + /// OHOS_LOCAL begin /// Get / Set stack protector ret calculation register unsigned getStackProtectorRetRegister() const { return SPR.Register; } void setStackProtectorRetRegister(unsigned I) { SPR.Register = I; } @@ -372,6 +375,7 @@ public: /// Get / Set if this frame needs backward cfi protect. void setStackProtectorRetNeeded(bool I) { SPR.Needed = I; } bool getStackProtectorRetNeeded() const { return SPR.Needed; } + /// OHOS_LOCAL end /// Return the index for the function context object. /// This object is used for SjLj exceptions. diff --git a/llvm/include/llvm/CodeGen/StackProtector.h b/llvm/include/llvm/CodeGen/StackProtector.h index aac31eafc65dc6733f11647c1fa19801f45cccbe..555c8ac8a271ceed974afab53739c1eb13340ccb 100644 --- a/llvm/include/llvm/CodeGen/StackProtector.h +++ b/llvm/include/llvm/CodeGen/StackProtector.h @@ -60,6 +60,11 @@ private: /// protection when -fstack-protection is used. unsigned SSPBufferSize = 0; + /// OHOS_LOCAL begin + /// The total of cookies that -fstack-protector-ret used. + unsigned SSPRetCookieSize = 1; + /// OHOS_LOCAL end + /// VisitedPHIs - The set of PHI nodes visited when determining /// if a variable's reference has been taken. This set /// is maintained to ensure we don't visit the same PHI node multiple @@ -100,7 +105,7 @@ private: /// stack protector based upon the stack protector level. bool RequiresStackProtector(); - bool CreateSSPRetCookie(); + bool CreateSSPRetCookie(); // OHOS_LOCAL public: static char ID; // Pass identification, replacement for typeid. diff --git a/llvm/include/llvm/CodeGen/StackProtectorRetLowering.h b/llvm/include/llvm/CodeGen/StackProtectorRetLowering.h index 667d0f04ceea3f9b121095ca35e3eec3418afc42..f6048d826568612ac8175931c05145bd24ce6cfa 100644 --- a/llvm/include/llvm/CodeGen/StackProtectorRetLowering.h +++ b/llvm/include/llvm/CodeGen/StackProtectorRetLowering.h @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +/// OHOS_LOCAL begin #ifndef LLVM_CODEGEN_STACKPROTECTORRETLOWERING_H #define LLVM_CODEGEN_STACKPROTECTORRETLOWERING_H @@ -55,3 +56,4 @@ public: } // namespace llvm #endif +/// OHOS_LOCAL end diff --git a/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/llvm/include/llvm/CodeGen/TargetFrameLowering.h index 9a8bc4bd517ab8a8cd294a507bc8c321786321b1..e37c118c212489d3706c7cd511b7584ed6a34906 100644 --- a/llvm/include/llvm/CodeGen/TargetFrameLowering.h +++ b/llvm/include/llvm/CodeGen/TargetFrameLowering.h @@ -14,7 +14,7 @@ #define LLVM_CODEGEN_TARGETFRAMELOWERING_H #include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/StackProtectorRetLowering.h" +#include "llvm/CodeGen/StackProtectorRetLowering.h" // OHOS_LOCAL #include "llvm/Support/TypeSize.h" #include @@ -218,9 +218,12 @@ public: virtual void emitZeroCallUsedRegs(BitVector RegsToZero, MachineBasicBlock &MBB) const {} + /// OHOS_LOCAL begin + /// Instances about backward cfi and stack protection provided by different architectures. virtual const StackProtectorRetLowering *getStackProtectorRet() const { return nullptr; } + /// OHOS_LOCAL begin /// With basic block sections, emit callee saved frame moves for basic blocks /// that are in a different section. diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index ce99b289bdbd7ba5f9e46a2f50c90e2eb0b294dd..a10d9d9c6b235efc262dcdff82f2605262c3b737 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -244,8 +244,13 @@ def Speculatable : EnumAttr<"speculatable", [FnAttr]>; /// Stack protection. def StackProtect : EnumAttr<"ssp", [FnAttr]>; -/// Stack protection for return address. -def StackProtectRet : EnumAttr<"sspret", [FnAttr]>; +/// OHOS_LOCAL begin +/// Stack protection required with return address check. +def StackProtectRetReq : EnumAttr<"sspretreq", [FnAttr]>; + +/// Strong Stack protection with return address check. +def StackProtectRetStrong : EnumAttr<"sspretstrong", [FnAttr]>; +/// OHOS_LOCAL end /// Stack protection required. def StackProtectReq : EnumAttr<"sspreq", [FnAttr]>; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index e661a11a7b7558964d70d75eb6a8c5d9fe06fed7..f423e38325148256af999b3b01a7623710cae38f 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -418,9 +418,11 @@ public: return AttributeSets.getFnStackAlignment(); } - /// Returns true if the function has ssp, sspstrong, sspret or sspreq fn - /// attrs. + /// OHOS_LOCAL begin + /// Returns true if the function has ssp, sspstrong, sspretstrong, + /// sspretreq or sspreq fn attrs. bool hasStackProtectorFnAttr() const; + /// OHOS_LOCAL end /// adds the dereferenceable attribute to the list of attributes for /// the given arg. diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 106d2b78170f1f711c181fe672dc3b5975b4dd02..4e88d10e7f65cde12a173ea4e440b2eae4983a54 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1725,8 +1725,6 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { return 1ULL << 62; case Attribute::NoFree: return 1ULL << 63; - case Attribute::StackProtectRet: - return 1ULL << 64; default: // Other attributes are not supported in the raw format, // as we ran out of space. @@ -1951,8 +1949,12 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::StackAlignment; case bitc::ATTR_KIND_STACK_PROTECT: return Attribute::StackProtect; - case bitc::ATTR_KIND_STACK_PROTECT_RET: - return Attribute::StackProtectRet; + /// OHOS_LOCAL begin + case bitc::ATTR_KIND_STACK_PROTECT_RET_REQ: + return Attribute::StackProtectRetReq; + case bitc::ATTR_KIND_STACK_PROTECT_RET_STRONG: + return Attribute::StackProtectRetStrong; + /// OHOS_LOCAL end case bitc::ATTR_KIND_STACK_PROTECT_REQ: return Attribute::StackProtectReq; case bitc::ATTR_KIND_STACK_PROTECT_STRONG: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 4fac16a7491db6db1e542d481a4af76f3bad39a1..5e05ff26647e3d0576e1eb28465980184cccbe6c 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -728,8 +728,12 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_STACK_ALIGNMENT; case Attribute::StackProtect: return bitc::ATTR_KIND_STACK_PROTECT; - case Attribute::StackProtectRet: - return bitc::ATTR_KIND_STACK_PROTECT_RET; + /// OHOS_LOCAL begin + case Attribute::StackProtectRetReq: + return bitc::ATTR_KIND_STACK_PROTECT_RET_REQ; + case Attribute::StackProtectRetStrong: + return bitc::ATTR_KIND_STACK_PROTECT_RET_STRONG; + /// OHOS_LOCAL end case Attribute::StackProtectReq: return bitc::ATTR_KIND_STACK_PROTECT_REQ; case Attribute::StackProtectStrong: diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index 5f0a919f97a10bc4501baff5b3aab27c8790abb0..530d5c1decc2a3cee41c7dfa0c2d66c9d23c3769 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -206,7 +206,7 @@ add_llvm_component_library(LLVMCodeGen StackMapLivenessAnalysis.cpp StackMaps.cpp StackProtector.cpp - StackProtectorRetLowering.cpp + StackProtectorRetLowering.cpp # OHOS_LOCAL StackSlotColoring.cpp SwiftErrorValueTracking.cpp SwitchLoweringUtils.cpp diff --git a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp index cbde664ef459881cef9a5863c21537028149954f..e2d3349938b7661005cf15bc837631bc45006348 100644 --- a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp +++ b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp @@ -27,7 +27,7 @@ #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/IR/Function.h" +#include "llvm/IR/Function.h" // OHOS_LOCAL #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" @@ -195,7 +195,7 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { // Make sure that the stack protector comes before the local variables on the // stack. - Function &F = Fn.getFunction(); + Function &F = Fn.getFunction(); // OHOS_LOCAL SmallSet ProtectedObjs; if (MFI.hasStackProtectorIndex()) { @@ -248,7 +248,9 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { Offset, MaxAlign); AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign); - } else if (F.hasFnAttribute(Attribute::StackProtectRet)) { + /// OHOS_LOCAL begin + } else if (F.hasFnAttribute(Attribute::StackProtectRetReq) || + F.hasFnAttribute(Attribute::StackProtectRetStrong)) { StackObjSet LargeArrayObjs; StackObjSet SmallArrayObjs; StackObjSet AddrOfObjs; @@ -279,6 +281,7 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { Offset, MaxAlign); AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign); + /// OHOS_LOCAL end } // Then assign frame offsets to stack objects that are not used to spill diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 2d831819791ef0d08d3770f6d3cbf7d76cbc1835..504861c7c7c7be6df6801498b66bda2e88313d61 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -212,10 +212,12 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) { const Function &F = MF.getFunction(); const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); - const StackProtectorRetLowering *SPRL = TFI->getStackProtectorRet(); + // OHOS_LOCAL begin + const StackProtectorRetLowering *SPRL = TFI->getStackProtectorRet(); if (SPRL) SPRL->setupStackProtectorRet(MF); + // OHOS_LOCAL end RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr; FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(MF); @@ -254,9 +256,11 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) { if (!F.hasFnAttribute(Attribute::Naked)) insertPrologEpilogCode(MF); + // OHOS_LOCAL begin // Add StackProtectorRets if using them if (SPRL) SPRL->insertStackProtectorRets(MF); + // OHOS_LOCAL end // Reinsert stashed debug values at the start of the entry blocks. for (auto &I : EntryDbgValues) @@ -367,9 +371,11 @@ void PEI::calculateCallFrameInfo(MachineFunction &MF) { /// Compute the sets of entry and return blocks for saving and restoring /// callee-saved registers, and placing prolog and epilog code. void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) { + // OHOS_LOCAL begin MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); const StackProtectorRetLowering *SPRL = TFI->getStackProtectorRet(); + // OHOS_LOCAL end // Even when we do not change any CSR, we still want to insert the // prologue and epilogue of the function. @@ -386,6 +392,7 @@ void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) { if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock()) RestoreBlocks.push_back(RestoreBlock); + // OHOS_LOCAL begin // If we are adding stack-protector-rets ensure we can find a available // register for CFI verification. if (SPRL && !SPRL->determineStackProtectorRetRegister(MF)) { @@ -395,8 +402,9 @@ void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) { MFI.setSavePoint(nullptr); MFI.setRestorePoint(nullptr); } else { + // OHOS_LOCAL end return; - } + } // OHOS_LOCAL } // Save refs to entry and return blocks. @@ -408,8 +416,10 @@ void PEI::calculateSaveRestoreBlocks(MachineFunction &MF) { RestoreBlocks.push_back(&MBB); } + // OHOS_LOCAL begin if (SPRL) SPRL->determineStackProtectorRetRegister(MF); + // OHOS_LOCAL end } static void assignCalleeSavedSpillSlots(MachineFunction &F, @@ -446,9 +456,11 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F, } const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering(); + MachineFrameInfo &MFI = F.getFrameInfo(); + // OHOS_LOCAL begin if (TFI->getStackProtectorRet()) TFI->getStackProtectorRet()->saveStackProtectorRetRegister(F, CSI); - MachineFrameInfo &MFI = F.getFrameInfo(); + // OHOS_LOCAL end if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI, MinCSFrameIndex, MaxCSFrameIndex)) { // If target doesn't implement this, use generic code. @@ -957,7 +969,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { // Make sure that the stack protector comes before the local variables on the // stack. - Function &F = MF.getFunction(); + Function &F = MF.getFunction(); // OHOS_LOCAL SmallSet ProtectedObjs; if (MFI.hasStackProtectorIndex()) { int StackProtectorFI = MFI.getStackProtectorIndex(); @@ -1027,13 +1039,15 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { llvm_unreachable("Found protected stack objects not pre-allocated by " "LocalStackSlotPass."); + // OHOS_LOCAL begin 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)) { + } else if (F.hasFnAttribute(Attribute::StackProtectRetReq) || + F.hasFnAttribute(Attribute::StackProtectRetStrong)) { StackObjSet LargeArrayObjs; StackObjSet SmallArrayObjs; StackObjSet AddrOfObjs; @@ -1067,6 +1081,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) { } llvm_unreachable("Unexpected SSPLayoutKind."); } + // OHOS_LOCAL end AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, Offset, MaxAlign, Skew); diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index 4afe09b621813c021e8ea4548a74232d9828e4e6..6ec99ed8631e2b2e15168d1c48dbe16c05ba0151 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -809,7 +809,10 @@ bool SafeStack::run() { if (F.hasFnAttribute(Attribute::StackProtect) || F.hasFnAttribute(Attribute::StackProtectStrong) || F.hasFnAttribute(Attribute::StackProtectReq) || - F.hasFnAttribute(Attribute::StackProtectRet)) { + // OHOS_LOCAL begin + F.hasFnAttribute(Attribute::StackProtectRetStrong) || + F.hasFnAttribute(Attribute::StackProtectRetReq)) { + // OHOS_LOCAL end 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 1a9e8f54461eac3db9a0f591aaf63307f4c1dce9..bf48cee310ff338bd00669ab63091a8f29fd2d9d 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -96,6 +96,14 @@ bool StackProtector::runOnFunction(Function &Fn) { Attr.getValueAsString().getAsInteger(10, SSPBufferSize)) return false; // Invalid integer string + // OHOS_LOCAL begin + Attr = Fn.getFnAttribute("stack-protector-ret-cookie-size"); + if (Attr.isStringAttribute()) { + if ((Attr.getValueAsString().getAsInteger(10, SSPRetCookieSize)) || (!SSPRetCookieSize)) + return false; // Invalid integer string + } + // OHOS_LOCAL end + if (!RequiresStackProtector()) return false; @@ -109,20 +117,26 @@ bool StackProtector::runOnFunction(Function &Fn) { ++NumFunProtected; - if (Fn.hasFnAttribute(Attribute::StackProtectRet)) { + // OHOS_LOCAL begin + if (Fn.hasFnAttribute(Attribute::StackProtectRetReq) || + Fn.hasFnAttribute(Attribute::StackProtectRetStrong)) { HasIRCheck = true; CreateSSPRetCookie(); // StackProtectRet requires special code generation methods for backward // cfi. return false; } + // OHOS_LOCAL end return InsertStackProtectors(); } +// OHOS_LOCAL begin bool StackProtector::CreateSSPRetCookie() { - std::string cookiename = "__sspret_cookie"; Type *cookietype = Type::getInt8PtrTy(M->getContext()); + std::hash hasher; + std::string hash = std::to_string(hasher((M->getName() + F->getName()).str()) % SSPRetCookieSize); + std::string cookiename = "__sspret_cookie_" + hash; GlobalVariable *cookie = dyn_cast_or_null( M->getOrInsertGlobal(cookiename, cookietype)); @@ -137,6 +151,7 @@ bool StackProtector::CreateSSPRetCookie() { return true; } +// OHOS_LOCAL end /// \param [out] IsLarge is set to true if a protectable array is found and /// it is "large" ( >= ssp-buffer-size). In the case of a structure with @@ -323,9 +338,13 @@ bool StackProtector::RequiresStackProtector() { }); NeedsProtector = true; Strong = true; // Use the same heuristic as strong to determine SSPLayout - } else if (F->hasFnAttribute(Attribute::StackProtectRet)) { + // OHOS_LOCAL begin + } else if (F->hasFnAttribute(Attribute::StackProtectRetReq)) { NeedsProtector = true; Strong = true; + } else if (F->hasFnAttribute(Attribute::StackProtectRetStrong)) { + Strong = true; + // OHOS_LOCAL end } else if (F->hasFnAttribute(Attribute::StackProtectStrong)) Strong = true; else if (!F->hasFnAttribute(Attribute::StackProtect)) diff --git a/llvm/lib/CodeGen/StackProtectorRetLowering.cpp b/llvm/lib/CodeGen/StackProtectorRetLowering.cpp index 4b068995c7437b5b08314c5be60536749a6ffc8d..e299a24ab9a46945e143d7f15973f21cad65b5f0 100644 --- a/llvm/lib/CodeGen/StackProtectorRetLowering.cpp +++ b/llvm/lib/CodeGen/StackProtectorRetLowering.cpp @@ -5,7 +5,15 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// This is an enhanced function of OHOS for the stack protection. It has made +// special backward cfi protection measures against ROP attacks by adding LR/FP +// checks in the function's prologue and epilogue. It can greatly reduce the +// number of ROP gadgets in the object. +// +//===----------------------------------------------------------------------===// +/// OHOS_LOCAL begin #include "llvm/CodeGen/StackProtectorRetLowering.h" #include "llvm/ADT/SmallSet.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -23,7 +31,7 @@ using namespace llvm; /// Check if backward CFI protection is required. void StackProtectorRetLowering::setupStackProtectorRet(MachineFunction &MF) const { - if (MF.getFunction().hasFnAttribute(Attribute::StackProtectRet)) { + if (MF.getFunction().hasFnAttribute("sspret-randomdata")) { for (auto &MBB : MF) { for (auto &T : MBB.terminators()) { if (instrIsRet(T.getOpcode())) { @@ -109,3 +117,4 @@ void StackProtectorRetLowering::insertStackProtectorRets(MachineFunction &MF) co MF.front().addLiveIn(Reg); } } +/// OHOS_LOCAL end diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 2badbe34ae6a71dc9a31c17adcf4542829199601..56308d7808622a8a3be1ce65336d9d37b9c25e8c 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -498,6 +498,12 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) { if (hasPrefix(Name, ".preinit_array")) return ELF::SHT_PREINIT_ARRAY; + // OHOS_LOCAL begin + // ohos customized section, does not occupy ROM in ELF. + if (Name == ".ohos.randomdata") + return ELF::SHT_NOBITS; + // OHOS_LOCAL end + if (hasPrefix(Name, ".llvm.offloading")) return ELF::SHT_LLVM_OFFLOADING; diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 0143f625903c39f3c0f991cbeed19541feadd3b3..b70b6fafe8ece558dc64c651c9a3c413a8121e43 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1910,26 +1910,37 @@ static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { AttributeMask OldSSPAttr; OldSSPAttr.addAttribute(Attribute::StackProtect) .addAttribute(Attribute::StackProtectStrong) + .addAttribute(Attribute::StackProtectRetStrong) // OHOS_LOCAL .addAttribute(Attribute::StackProtectReq) - .addAttribute(Attribute::StackProtectRet); + .addAttribute(Attribute::StackProtectRetReq); // OHOS_LOCAL - if (Callee.hasFnAttribute(Attribute::StackProtectRet) && - !Caller.hasFnAttribute(Attribute::StackProtect) && - !Caller.hasFnAttribute(Attribute::StackProtectReq) && - !Caller.hasFnAttribute(Attribute::StackProtectStrong)) { + // OHOS_LOCAL begin + // sspretreq > sspreq > sspretstrong > sspstrong > ssp + if (Callee.hasFnAttribute(Attribute::StackProtectRetReq)) { Caller.removeFnAttrs(OldSSPAttr); - Caller.addFnAttr(Attribute::StackProtectRet); - } else if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { + Caller.addFnAttr(Attribute::StackProtectRetReq); + } else if (Callee.hasFnAttribute(Attribute::StackProtectReq) && + !Caller.hasFnAttribute(Attribute::StackProtectRetReq)) { Caller.removeFnAttrs(OldSSPAttr); Caller.addFnAttr(Attribute::StackProtectReq); - } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && + } else if (Callee.hasFnAttribute(Attribute::StackProtectRetStrong) && + !Caller.hasFnAttribute(Attribute::StackProtectRetReq) && !Caller.hasFnAttribute(Attribute::StackProtectReq)) { Caller.removeFnAttrs(OldSSPAttr); + Caller.addFnAttr(Attribute::StackProtectRetStrong); + } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && + !Caller.hasFnAttribute(Attribute::StackProtectRetReq) && + !Caller.hasFnAttribute(Attribute::StackProtectReq) && + !Caller.hasFnAttribute(Attribute::StackProtectRetStrong)) { + Caller.removeFnAttrs(OldSSPAttr); Caller.addFnAttr(Attribute::StackProtectStrong); } else if (Callee.hasFnAttribute(Attribute::StackProtect) && !Caller.hasFnAttribute(Attribute::StackProtectReq) && - !Caller.hasFnAttribute(Attribute::StackProtectStrong)) + !Caller.hasFnAttribute(Attribute::StackProtectStrong) && + !Caller.hasFnAttribute(Attribute::StackProtectRetReq) && + !Caller.hasFnAttribute(Attribute::StackProtectRetStrong)) Caller.addFnAttr(Attribute::StackProtect); + // OHOS_LOCAL end } /// If the inlined function required stack probes, then ensure that diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 300592a38b16335d04a04a985182787c8af77692..5a073632d385bd97b8a2d7ecc8dccf8a066c63e7 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -707,7 +707,10 @@ bool Function::hasStackProtectorFnAttr() const { return hasFnAttribute(Attribute::StackProtect) || hasFnAttribute(Attribute::StackProtectStrong) || hasFnAttribute(Attribute::StackProtectReq) || - hasFnAttribute(Attribute::StackProtectRet); + /// OHOS_LOCAL begin + hasFnAttribute(Attribute::StackProtectRetStrong) || + hasFnAttribute(Attribute::StackProtectRetReq); + /// OHOS_LOCAL end } /// Copy all additional attributes (those not needed to create a Function) from diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 38977b7641a090a905bcf56ab85378bcebbce5b4..758a29bc10b708f5dbc9c454dd5c6b1a5ee547be 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -549,7 +549,8 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { hasPrefix(SectionName, ".bss") || hasPrefix(SectionName, ".init_array") || hasPrefix(SectionName, ".fini_array") || - hasPrefix(SectionName, ".preinit_array")) + hasPrefix(SectionName, ".preinit_array") || + SectionName == ".ohos.randomdata") // OHOS_LOCAL Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; else if (hasPrefix(SectionName, ".tdata") || hasPrefix(SectionName, ".tbss")) Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS; @@ -632,6 +633,10 @@ EndStmt: Type = ELF::SHT_FINI_ARRAY; else if (hasPrefix(SectionName, ".preinit_array")) Type = ELF::SHT_PREINIT_ARRAY; + // OHOS_LOCAL begin + else if (hasPrefix(SectionName, ".ohos.randomdata")) + Type = ELF::SHT_NOBITS; + // OHOS_LOCAL end } else { if (TypeName == "init_array") Type = ELF::SHT_INIT_ARRAY; diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 8ed54a6703cf0110566bd4abd773557b86871ace..68ae9b5b41f7b8ada4dd21a1b7cdba0186aacdda 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1402,6 +1402,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { return; } + // OHOS_LOCAL begin case AArch64::SSP_RET_TRAP: { MCSymbol *TempSymbol = OutContext.createTempSymbol(); /* Compare and branch */ @@ -1413,6 +1414,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { OutStreamer->emitLabel(TempSymbol); return; } + // OHOS_LOCAL end case AArch64::JumpTableDest32: case AArch64::JumpTableDest16: diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index a7a1c969faf5e7d11c7d27b3bf639ff1d840e27f..bed7aa3d9ca6f7f1a536617ac882b820b4ae74a4 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -189,7 +189,7 @@ #include "AArch64InstrInfo.h" #include "AArch64MachineFunctionInfo.h" #include "AArch64RegisterInfo.h" -#include "AArch64StackProtectorRetLowering.h" +#include "AArch64StackProtectorRetLowering.h" // OHOS_LOCAL #include "AArch64Subtarget.h" #include "AArch64TargetMachine.h" #include "MCTargetDesc/AArch64AddressingModes.h" @@ -2969,9 +2969,11 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, ? RegInfo->getBaseRegister() : (unsigned)AArch64::NoRegister; + // OHOS_LOCAL begin if (MFI.hasStackProtectorRetRegister()) { SavedRegs.set(MFI.getStackProtectorRetRegister()); } + // OHOS_LOCAL end unsigned ExtraCSSpill = 0; // Figure out which callee-saved registers to save/restore. @@ -3787,10 +3789,12 @@ unsigned AArch64FrameLowering::getWinEHFuncletFrameSize( getStackAlign()); } +/// OHOS_LOCAL begin const StackProtectorRetLowering * AArch64FrameLowering::getStackProtectorRet() const { return &SPRL; } +/// OHOS_LOCAL end namespace { struct FrameObject { diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h index 3bfecc6cc7680e558cec2d275e41a08be6def2bd..bab56e9f8645d110be6dbc79bbaff49956b23bbe 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h @@ -13,7 +13,7 @@ #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H #define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H -#include "AArch64StackProtectorRetLowering.h" +#include "AArch64StackProtectorRetLowering.h" // OHOS_LOCAL #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/Support/TypeSize.h" @@ -23,12 +23,11 @@ class MCCFIInstruction; class AArch64FrameLowering : public TargetFrameLowering { public: - const AArch64StackProtectorRetLowering SPRL; + const AArch64StackProtectorRetLowering SPRL; // OHOS_LOCAL explicit AArch64FrameLowering() : TargetFrameLowering(StackGrowsDown, Align(16), 0, Align(16), - true /*StackRealignable*/), - SPRL() {} + true /*StackRealignable*/), SPRL() {} // OHOS_LOCAL void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const; @@ -44,7 +43,7 @@ public: void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; - const StackProtectorRetLowering *getStackProtectorRet() const override; + const StackProtectorRetLowering *getStackProtectorRet() const override; // OHOS_LOCAL bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 4976f51b82e16cee9784bab0ad4882be7ab283d6..312999eda7933fc09b5e3756dab4e943355f156d 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -853,6 +853,7 @@ def ADDlowTLS } // isReMaterializable, isCodeGenOnly +// OHOS_LOCAL begin //===----------------------------------------------------------------------===// // Pseudo instruction used by stack protector ret for backward cfi let isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in { @@ -860,6 +861,7 @@ let isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in { def SSP_RET_TRAP: Pseudo<(outs), (ins GPR64:$reg), []>; } } +// OHOS_LOCAL end def : Pat<(AArch64LOADgot tglobaltlsaddr:$addr), (LOADgot tglobaltlsaddr:$addr)>; diff --git a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp index c5f67968a2121d9857936748983c6a948b1b4393..06e6ed56aec0c7c0cc8d50ab23b4307e237c007c 100644 --- a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.cpp @@ -5,7 +5,13 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// This file contains a stack-protector-ret function to insert code to mitigate +// against ROP attacks. +// +//===----------------------------------------------------------------------===// +/// OHOS_LOCAL begin #include "AArch64InstrInfo.h" #include "AArch64MachineFunctionInfo.h" #include "AArch64RegisterInfo.h" @@ -37,7 +43,10 @@ void AArch64StackProtectorRetLowering::insertStackProtectorRetPrologue( BuildMI(MBB, MI, MBBDL, TII->get(AArch64::LDRXui), REG) .addReg(REG) .addGlobalAddress(cookie, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC); - BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ANDXrr), REG) + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), REG) + .addReg(REG) + .addReg(AArch64::FP); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), REG) .addReg(REG) .addReg(AArch64::LR); } @@ -56,7 +65,10 @@ void AArch64StackProtectorRetLowering::insertStackProtectorRetEpilogue( BuildMI(MBB, MI, MBBDL, TII->get(AArch64::LDRXui), AArch64::X9) .addReg(AArch64::X9) .addGlobalAddress(cookie, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC); - BuildMI(MBB, MI, MBBDL, TII->get(AArch64::ANDXrr), AArch64::X9) + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), AArch64::X9) + .addReg(AArch64::X9) + .addReg(AArch64::FP); + BuildMI(MBB, MI, MBBDL, TII->get(AArch64::EORXrr), AArch64::X9) .addReg(AArch64::X9) .addReg(AArch64::LR); BuildMI(MBB, MI, MBBDL, TII->get(AArch64::SUBSXrr), REG) @@ -97,3 +109,4 @@ void AArch64StackProtectorRetLowering::saveStackProtectorRetRegister( CSI.insert(CSI.begin(), CalleeSavedInfo(Reg)); } +/// OHOS_LOCAL end diff --git a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h index 835b4b90fd2a27a456dbaf907050c2f91f4b0e8c..29a22a3d2f0bd3d718c5f6d84ae9352102d844a7 100644 --- a/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h +++ b/llvm/lib/Target/AArch64/AArch64StackProtectorRetLowering.h @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +/// OHOS_LOCAL begin #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64STACKPROTECTORRETLOWERING_H #define LLVM_LIB_TARGET_AARCH64_AARCH64STACKPROTECTORRETLOWERING_H @@ -37,3 +38,4 @@ public: } // namespace llvm #endif +/// OHOS_LOCAL end diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt index e7aba115d6a631bb310e9d2994df575ad07eefa0..1104955f16bea5d87d313bd0713b73c226e1a255 100644 --- a/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/llvm/lib/Target/AArch64/CMakeLists.txt @@ -75,7 +75,7 @@ add_llvm_target(AArch64CodeGen AArch64SLSHardening.cpp AArch64SelectionDAGInfo.cpp AArch64SpeculationHardening.cpp - AArch64StackProtectorRetLowering.cpp + AArch64StackProtectorRetLowering.cpp # OHOS_LOCAL AArch64StackTagging.cpp AArch64StackTaggingPreRA.cpp AArch64StorePairSuppress.cpp diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 47366f0f2f2f59d5524192f997b65814312c2158..10134e26671f31603a1416d03f224fdbfcefaa2c 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -955,7 +955,10 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::SanitizeMemTag: case Attribute::SpeculativeLoadHardening: case Attribute::StackProtect: - case Attribute::StackProtectRet: + // OHOS_LOCAL begin + case Attribute::StackProtectRetReq: + case Attribute::StackProtectRetStrong: + // OHOS_LOCAL end case Attribute::StackProtectReq: case Attribute::StackProtectStrong: case Attribute::StrictFP: diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index 78b54a5cf5c3955981a8f1d91b3d305785b45e93..2b8883f6c82ee63b657fd73516ed7255b4557d69 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -535,6 +535,20 @@ define void @f86() nosanitize_bounds ; CHECK: define void @f87() [[FNRETTHUNKEXTERN:#[0-9]+]] define void @f87() fn_ret_thunk_extern { ret void } +; OHOS_LOCAL begin +define void @f88() sspretreq +; CHECK: define void @f88() #54 +{ + ret void; +} + +define void @f89() sspretstrong +; CHECK: define void @f89() #55 +{ + ret void; +} +; OHOS_LOCAL end + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } @@ -589,4 +603,8 @@ define void @f87() fn_ret_thunk_extern { ret void } ; CHECK: attributes #51 = { uwtable(sync) } ; CHECK: attributes #52 = { nosanitize_bounds } ; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern } +; OHOS_LOCAL begin +; CHECK: attributes #54 = { sspretreq } +; CHECK: attributes #55 = { sspretstrong } +; OHOS_LOCAL end ; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin } diff --git a/llvm/test/CodeGen/AArch64/stack-protector-ret-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-ret-target.ll new file mode 100644 index 0000000000000000000000000000000000000000..9dec7a1959432403dce0ae9aad440d3c761a9f5e --- /dev/null +++ b/llvm/test/CodeGen/AArch64/stack-protector-ret-target.ll @@ -0,0 +1,31 @@ +; OHOS_LOCAL +; Test target-specific stack cookie location. +; RUN: llc -mtriple=aarch64-linux-ohos < %s -o - | FileCheck --check-prefix=OHOS-AARCH64 %s + +define void @_Z1fv() sspretreq { +entry: + %x = alloca i32, align 4 + %0 = bitcast i32* %x to i8* + call void @_Z7CapturePi(i32* nonnull %x) + ret void +} + +declare void @_Z7CapturePi(i32*) + +; OHOS-AARCH64: adrp x15, __sspret_cookie_ +; OHOS-AARCH64: ldr x15, [x15, :lo12:__sspret_cookie_ +; OHOS-AARCH64: eor x15, x15, x29 +; OHOS-AARCH64: eor x15, x15, x30 +; OHOS-AARCH64: sub sp, sp, +; OHOS-AARCH64: stp x30, x15, [sp, +; OHOS-AARCH64: ] +; OHOS-AARCH64: ldp x30, x15, [sp, +; OHOS-AARCH64: add sp, +; OHOS-AARCH64: adrp x9, __sspret_cookie_ +; OHOS-AARCH64: ldr x9, [x9, :lo12:__sspret_cookie_ +; OHOS-AARCH64: eor x9, x9, x29 +; OHOS-AARCH64: eor x9, x9, x30 +; OHOS-AARCH64: subs x15, x15, x9 +; OHOS-AARCH64: cbz x15, +; OHOS-AARCH64: brk #0x1 +; OHOS-AARCH64: ret diff --git a/llvm/test/Transforms/Inline/inline_sspret.ll b/llvm/test/Transforms/Inline/inline_sspret.ll new file mode 100644 index 0000000000000000000000000000000000000000..3f7d4bea0d4536df1445b5aa9089c679a77d1f55 --- /dev/null +++ b/llvm/test/Transforms/Inline/inline_sspret.ll @@ -0,0 +1,176 @@ +; OHOS_LOCAL +; RUN: opt -inline %s -S | FileCheck %s +; RUN: opt -passes='cgscc(inline)' %s -S | FileCheck %s +; Ensure SSPRET attributes are propagated correctly when inlining. + +@.str = private unnamed_addr constant [11 x i8] c"fun_nossp\0A\00", align 1 +@.str1 = private unnamed_addr constant [9 x i8] c"fun_ssp\0A\00", align 1 +@.str2 = private unnamed_addr constant [18 x i8] c"fun_sspretstrong\0A\00", align 1 +@.str3 = private unnamed_addr constant [15 x i8] c"fun_sspretreq\0A\00", align 1 + +; These first four functions (@fun_sspretreq, @fun_sspretstrong, @fun_ssp, @fun_nossp) +; are used by the remaining functions to ensure that the SSP attributes are +; propagated correctly. If the caller had an SSP attribute before inlining, it +; should have its new SSP attribute set as: +; strictest(caller-ssp-attr, callee-ssp-attr), where strictness is ordered as: +; sspretreq > sspretstrong > ssp + +define internal void @fun_sspretreq() sspretreq { +entry: + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str3, i32 0, i32 0)) + ret void +} + +define internal void @fun_sspretreq_alwaysinline() sspretreq alwaysinline { +entry: + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str3, i32 0, i32 0)) + ret void +} + +define internal void @fun_sspretstrong() sspretstrong { +entry: + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str2, i32 0, i32 0)) + ret void +} + +define internal void @fun_ssp() ssp { +entry: + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str1, i32 0, i32 0)) + ret void +} + +define internal void @fun_nossp() { +entry: + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0)) + ret void +} + +; Tests start below. + +define void @inline_retreq_retreq() sspretreq { +entry: +; CHECK: @inline_retreq_retreq() #[[SSPRETREQ:[0-9]]] + call void @fun_sspretreq() + ret void +} + +define void @inline_retreq_retstrong() sspretstrong { +entry: +; CHECK: @inline_retreq_retstrong() #[[SSPRETREQ]] + call void @fun_sspretreq() + ret void +} + +define void @inline_retreq_ssp() ssp { +entry: +; CHECK: @inline_retreq_ssp() #[[SSPRETREQ]] + call void @fun_sspretreq() + ret void +} + +define void @inline_retreq_nossp() { +entry: +; CHECK: @inline_retreq_nossp() { + call void @fun_sspretreq() + ret void +} + +define void @alwaysinline_retreq_nossp() { +entry: +; CHECK: @alwaysinline_retreq_nossp() { + call void @fun_sspretreq_alwaysinline() + ret void +} + +define void @inline_retstrong_retreq() sspretreq { +entry: +; CHECK: @inline_retstrong_retreq() #[[SSPRETREQ]] + call void @fun_sspretstrong() + ret void +} + + +define void @inline_retstrong_retstrong() sspretstrong { +entry: +; CHECK: @inline_retstrong_retstrong() #[[SSPRETSTRONG:[0-9]]] + call void @fun_sspretstrong() + ret void +} + +define void @inline_retstrong_ssp() ssp { +entry: +; CHECK: @inline_retstrong_ssp() #[[SSPRETSTRONG]] + call void @fun_sspretstrong() + ret void +} + +define void @inline_retstrong_nossp() { +entry: +; CHECK: @inline_retstrong_nossp() { + call void @fun_sspretstrong() + ret void +} + +define void @inline_ssp_retreq() sspretreq { +entry: +; CHECK: @inline_ssp_retreq() #[[SSPRETREQ]] + call void @fun_ssp() + ret void +} + + +define void @inline_ssp_retstrong() sspretstrong { +entry: +; CHECK: @inline_ssp_retstrong() #[[SSPRETSTRONG]] + call void @fun_ssp() + ret void +} + +define void @inline_ssp_ssp() ssp { +entry: +; CHECK: @inline_ssp_ssp() #[[SSP:[0-9]]] + call void @fun_ssp() + ret void +} + +define void @inline_ssp_nossp() { +entry: +; CHECK: @inline_ssp_nossp() { + call void @fun_ssp() + ret void +} + +define void @inline_nossp_retreq() sspretreq { +entry: +; CHECK: @inline_nossp_retreq() #[[SSPRETREQ]] + call void @fun_nossp() + ret void +} + + +define void @inline_nossp_retstrong() sspretstrong { +entry: +; CHECK: @inline_nossp_retstrong() #[[SSPRETSTRONG]] + call void @fun_nossp() + ret void +} + +define void @inline_nossp_ssp() ssp { +entry: +; CHECK: @inline_nossp_ssp() #[[SSP]] + call void @fun_nossp() + ret void +} + +define void @inline_nossp_nossp() { +entry: +; CHECK: @inline_nossp_nossp() { + call void @fun_nossp() + ret void +} + +declare i32 @printf(i8*, ...) + +; CHECK: attributes #[[SSPRETREQ]] = { sspretreq } +; CHECK: attributes #[[SSPRETSTRONG]] = { sspretstrong } +; CHECK: attributes #[[SSP]] = { ssp } diff --git a/llvm/test/tools/llvm-objdump/ohos-headers.test b/llvm/test/tools/llvm-objdump/ohos-headers.test index 045f54fac3592edc956a1888c5579664f30f7238..b9e7e8c225d6fa4f9b7139ceebf7cef3624753c3 100644 --- a/llvm/test/tools/llvm-objdump/ohos-headers.test +++ b/llvm/test/tools/llvm-objdump/ohos-headers.test @@ -1,3 +1,4 @@ +## OHOS_LOCAL ## Check that llvm-objdump dumps OHOS program headers correctly. # RUN: yaml2obj %s -o %t diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp index dcc851ad1650c0a4695707a06840427726ccbcde..68c635abf99c43ada159ed57acd1a2a4116d62b7 100644 --- a/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/llvm/tools/llvm-objdump/ELFDump.cpp @@ -256,9 +256,11 @@ static void printProgramHeaders(const ELFFile &Obj, StringRef FileName) { case ELF::PT_OPENBSD_WXNEEDED: outs() << " OPENBSD_WXNEEDED "; break; + // OHOS_LOCAL begin case ELF::PT_OHOS_RANDOMDATA: outs() << " OHOS_RANDOMDATA "; break; + // OHOS_LOCAL end case ELF::PT_PHDR: outs() << " PHDR "; break; diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 37810feabc11e92d7aa6919f950db5a8f5e94c15..c9a239f785d2ebceeb33208d8eddf52032dae619 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -1415,7 +1415,7 @@ static StringRef segmentTypeToString(unsigned Arch, unsigned Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA); - LLVM_READOBJ_ENUM_CASE(ELF, PT_OHOS_RANDOMDATA); + LLVM_READOBJ_ENUM_CASE(ELF, PT_OHOS_RANDOMDATA); // OHOS_LOCAL default: return ""; }