Author: manojgupta Date: Wed May 9 14:41:18 2018 New Revision: 331925 URL: http://llvm.org/viewvc/llvm-project?rev=331925&view=rev Log: [Clang] Implement function attribute no_stack_protector.
Summary: This attribute tells clang to skip this function from stack protector when -stack-protector option is passed. GCC option for this is: __attribute__((__optimize__("no-stack-protector"))) and the equivalent clang syntax would be: __attribute__((no_stack_protector)) This is used in Linux kernel to selectively disable stack protector in certain functions. Reviewers: aaron.ballman, rsmith, rnk, probinson Reviewed By: aaron.ballman Subscribers: probinson, srhines, cfe-commits Differential Revision: https://reviews.llvm.org/D46300 Added: cfe/trunk/test/Sema/no_stack_protector.c Modified: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/CodeGen/stack-protector.c Modified: cfe/trunk/include/clang/Basic/Attr.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=331925&r1=331924&r2=331925&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Attr.td (original) +++ cfe/trunk/include/clang/Basic/Attr.td Wed May 9 14:41:18 2018 @@ -1495,6 +1495,12 @@ def NotTailCalled : InheritableAttr { let Documentation = [NotTailCalledDocs]; } +def NoStackProtector : InheritableAttr { + let Spellings = [Clang<"no_stack_protector">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [NoStackProtectorDocs]; +} + def NoThrow : InheritableAttr { let Spellings = [GCC<"nothrow">, Declspec<"nothrow">]; let Subjects = SubjectList<[Function]>; Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=331925&r1=331924&r2=331925&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed May 9 14:41:18 2018 @@ -2740,6 +2740,28 @@ The syntax of the declare target directi }]; } +def NoStackProtectorDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``__attribute__((no_stack_protector))`` attribute which disables +the stack protector on the specified function. This attribute is useful for +selectively disabling the stack protector on some functions when building with +``-fstack-protector`` compiler option. + +For example, it disables the stack protector for the function ``foo`` but function +``bar`` will still be built with the stack protector with the ``-fstack-protector`` +option. + +.. code-block:: c + + int __attribute__((no_stack_protector)) + foo (int x); // stack protection will be disabled for foo. + + int bar(int y); // bar can be built with the stack protector. + + }]; +} + def NotTailCalledDocs : Documentation { let Category = DocCatFunction; let Content = [{ Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=331925&r1=331924&r2=331925&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed May 9 14:41:18 2018 @@ -1142,12 +1142,14 @@ void CodeGenModule::SetLLVMFunctionAttri if (!hasUnwindExceptions(LangOpts)) B.addAttribute(llvm::Attribute::NoUnwind); - if (LangOpts.getStackProtector() == LangOptions::SSPOn) - B.addAttribute(llvm::Attribute::StackProtect); - else if (LangOpts.getStackProtector() == LangOptions::SSPStrong) - B.addAttribute(llvm::Attribute::StackProtectStrong); - else if (LangOpts.getStackProtector() == LangOptions::SSPReq) - B.addAttribute(llvm::Attribute::StackProtectReq); + if (!D || !D->hasAttr<NoStackProtectorAttr>()) { + if (LangOpts.getStackProtector() == LangOptions::SSPOn) + B.addAttribute(llvm::Attribute::StackProtect); + else if (LangOpts.getStackProtector() == LangOptions::SSPStrong) + B.addAttribute(llvm::Attribute::StackProtectStrong); + else if (LangOpts.getStackProtector() == LangOptions::SSPReq) + B.addAttribute(llvm::Attribute::StackProtectReq); + } if (!D) { // If we don't have a declaration to control inlining, the function isn't Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=331925&r1=331924&r2=331925&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed May 9 14:41:18 2018 @@ -6230,6 +6230,10 @@ static void ProcessDeclAttribute(Sema &S case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg. handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, AL); break; + case AttributeList::AT_NoStackProtector: + // Interacts with -fstack-protector options. + handleSimpleAttribute<NoStackProtectorAttr>(S, D, AL); + break; case AttributeList::AT_StdCall: case AttributeList::AT_CDecl: case AttributeList::AT_FastCall: Modified: cfe/trunk/test/CodeGen/stack-protector.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/stack-protector.c?rev=331925&r1=331924&r2=331925&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/stack-protector.c (original) +++ cfe/trunk/test/CodeGen/stack-protector.c Wed May 9 14:41:18 2018 @@ -22,6 +22,14 @@ void test1(const char *msg) { printf("%s\n", a); } +// DEF: define {{.*}}void @test2(i8* %msg) #[[B:.*]] { +__attribute__((no_stack_protector)) +void test2(const char *msg) { + char a[strlen(msg) + 1]; + strcpy(a, msg); + printf("%s\n", a); +} + // NOSSP-NOT: attributes #[[A]] = {{.*}} ssp // SSP: attributes #[[A]] = {{.*}} ssp{{ }} // SSPSTRONG: attributes #[[A]] = {{.*}} sspstrong @@ -33,3 +41,15 @@ void test1(const char *msg) { // SAFESTACK-SSP: attributes #[[A]] = {{.*}} safestack ssp{{ }} // SAFESTACK-SSPSTRONG: attributes #[[A]] = {{.*}} safestack sspstrong // SAFESTACK-SSPREQ: attributes #[[A]] = {{.*}} safestack sspreq + +// NOSSP-NOT: attributes #[[B]] = {{.*}} ssp +// SSP-NOT: attributes #[[B]] = {{.*}} ssp{{ }} +// SSPSTRONG-NOT: attributes #[[B]] = {{.*}} sspstrong +// SSPREQ-NOT: attributes #[[B]] = {{.*}} sspreq + +// SAFESTACK-SSP: attributes #[[B]] = {{.*}} safestack +// SAFESTACK-SSP-NOT: attributes #[[B]] = {{.*}} safestack ssp{{ }} +// SAFESTACK-SSPSTRONG: attributes #[[B]] = {{.*}} safestack +// SAFESTACK-SSPSTRONG-NOT: attributes #[[B]] = {{.*}} safestack sspstrong +// SAFESTACK-SSPREQ: attributes #[[B]] = {{.*}} safestack +// SAFESTACK-SSPREQ-NOT: attributes #[[B]] = {{.*}} safestack sspreq Added: cfe/trunk/test/Sema/no_stack_protector.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/no_stack_protector.c?rev=331925&view=auto ============================================================================== --- cfe/trunk/test/Sema/no_stack_protector.c (added) +++ cfe/trunk/test/Sema/no_stack_protector.c Wed May 9 14:41:18 2018 @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void __attribute__((no_stack_protector)) foo() {} +int __attribute__((no_stack_protector)) var; // expected-warning {{'no_stack_protector' attribute only applies to functions}} +void __attribute__((no_stack_protector(2))) bar() {} // expected-error {{'no_stack_protector' attribute takes no arguments}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits