Index: llvm/trunk/docs/BitCodeFormat.rst =================================================================== --- llvm/trunk/docs/BitCodeFormat.rst +++ llvm/trunk/docs/BitCodeFormat.rst @@ -1056,6 +1056,7 @@ * code 55: ``sanitize_hwaddress`` * code 56: ``nocf_check`` * code 57: ``optforfuzzing`` +* code 58: ``shadowcallstack`` .. note:: The ``allocsize`` attribute has a special encoding for its arguments. Its two Index: llvm/trunk/docs/LangRef.rst =================================================================== --- llvm/trunk/docs/LangRef.rst +++ llvm/trunk/docs/LangRef.rst @@ -1708,6 +1708,11 @@ entity to fine grain the HW control flow protection mechanism. The flag is target independant and currently appertains to a function or function pointer. +``shadowcallstack`` + This attribute indicates that the ShadowCallStack checks are enabled for + the function. The instrumentation checks that the return address for the + function has not changed between the function prolog and eiplog. It is + currently x86_64-specific. .. _glattrs: Index: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h @@ -589,6 +589,7 @@ ATTR_KIND_SANITIZE_HWADDRESS = 55, ATTR_KIND_NOCF_CHECK = 56, ATTR_KIND_OPT_FOR_FUZZING = 57, + ATTR_KIND_SHADOWCALLSTACK = 58, }; enum ComdatSelectionKindCodes { Index: llvm/trunk/include/llvm/IR/Attributes.td =================================================================== --- llvm/trunk/include/llvm/IR/Attributes.td +++ llvm/trunk/include/llvm/IR/Attributes.td @@ -136,6 +136,9 @@ /// Safe Stack protection. def SafeStack : EnumAttr<"safestack">; +/// Shadow Call Stack protection. +def ShadowCallStack : EnumAttr<"shadowcallstack">; + /// Sign extended before/after call. def SExt : EnumAttr<"signext">; @@ -211,6 +214,7 @@ def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; +def : CompatRule<"isEqual">; class MergeRule { // The name of the function called to merge the attributes of the caller and Index: llvm/trunk/lib/AsmParser/LLLexer.cpp =================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp +++ llvm/trunk/lib/AsmParser/LLLexer.cpp @@ -665,6 +665,7 @@ KEYWORD(sspstrong); KEYWORD(strictfp); KEYWORD(safestack); + KEYWORD(shadowcallstack); KEYWORD(sanitize_address); KEYWORD(sanitize_hwaddress); KEYWORD(sanitize_thread); Index: llvm/trunk/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp +++ llvm/trunk/lib/AsmParser/LLParser.cpp @@ -1148,6 +1148,8 @@ case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break; case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break; + case lltok::kw_shadowcallstack: + B.addAttribute(Attribute::ShadowCallStack); break; case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break; case lltok::kw_sanitize_hwaddress: @@ -1485,6 +1487,7 @@ case lltok::kw_sspreq: case lltok::kw_sspstrong: case lltok::kw_safestack: + case lltok::kw_shadowcallstack: case lltok::kw_strictfp: case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); @@ -1580,6 +1583,7 @@ case lltok::kw_sspreq: case lltok::kw_sspstrong: case lltok::kw_safestack: + case lltok::kw_shadowcallstack: case lltok::kw_strictfp: case lltok::kw_uwtable: HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); Index: llvm/trunk/lib/AsmParser/LLToken.h =================================================================== --- llvm/trunk/lib/AsmParser/LLToken.h +++ llvm/trunk/lib/AsmParser/LLToken.h @@ -214,6 +214,7 @@ kw_sspreq, kw_sspstrong, kw_safestack, + kw_shadowcallstack, kw_sret, kw_sanitize_thread, kw_sanitize_memory, Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1162,6 +1162,7 @@ case Attribute::SanitizeHWAddress: return 1ULL << 56; case Attribute::NoCfCheck: return 1ULL << 57; case Attribute::OptForFuzzing: return 1ULL << 58; + case Attribute::ShadowCallStack: return 1ULL << 59; case Attribute::Dereferenceable: llvm_unreachable("dereferenceable attribute not supported in raw format"); break; @@ -1372,6 +1373,8 @@ return Attribute::StackProtectStrong; case bitc::ATTR_KIND_SAFESTACK: return Attribute::SafeStack; + case bitc::ATTR_KIND_SHADOWCALLSTACK: + return Attribute::ShadowCallStack; case bitc::ATTR_KIND_STRICT_FP: return Attribute::StrictFP; case bitc::ATTR_KIND_STRUCT_RET: Index: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -673,6 +673,8 @@ return bitc::ATTR_KIND_STACK_PROTECT_STRONG; case Attribute::SafeStack: return bitc::ATTR_KIND_SAFESTACK; + case Attribute::ShadowCallStack: + return bitc::ATTR_KIND_SHADOWCALLSTACK; case Attribute::StrictFP: return bitc::ATTR_KIND_STRICT_FP; case Attribute::StructRet: Index: llvm/trunk/lib/IR/Attributes.cpp =================================================================== --- llvm/trunk/lib/IR/Attributes.cpp +++ llvm/trunk/lib/IR/Attributes.cpp @@ -332,6 +332,8 @@ return "sspstrong"; if (hasAttribute(Attribute::SafeStack)) return "safestack"; + if (hasAttribute(Attribute::ShadowCallStack)) + return "shadowcallstack"; if (hasAttribute(Attribute::StrictFP)) return "strictfp"; if (hasAttribute(Attribute::StructRet)) Index: llvm/trunk/lib/IR/Verifier.cpp =================================================================== --- llvm/trunk/lib/IR/Verifier.cpp +++ llvm/trunk/lib/IR/Verifier.cpp @@ -1413,6 +1413,7 @@ case Attribute::StackProtectReq: case Attribute::StackProtectStrong: case Attribute::SafeStack: + case Attribute::ShadowCallStack: case Attribute::NoRedZone: case Attribute::NoImplicitFloat: case Attribute::Naked: Index: llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp +++ llvm/trunk/lib/Transforms/IPO/ForceFunctionAttrs.cpp @@ -53,6 +53,7 @@ .Case("argmemonly", Attribute::ArgMemOnly) .Case("returns_twice", Attribute::ReturnsTwice) .Case("safestack", Attribute::SafeStack) + .Case("shadowcallstack", Attribute::SafeStack) .Case("sanitize_address", Attribute::SanitizeAddress) .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress) .Case("sanitize_memory", Attribute::SanitizeMemory) Index: llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp +++ llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp @@ -688,6 +688,7 @@ case Attribute::OptimizeNone: case Attribute::OptimizeForSize: case Attribute::SafeStack: + case Attribute::ShadowCallStack: case Attribute::SanitizeAddress: case Attribute::SanitizeMemory: case Attribute::SanitizeThread: Index: llvm/trunk/test/Bitcode/attributes.ll =================================================================== --- llvm/trunk/test/Bitcode/attributes.ll +++ llvm/trunk/test/Bitcode/attributes.ll @@ -204,7 +204,7 @@ ; CHECK: define void @f34() { call void @nobuiltin() nobuiltin -; CHECK: call void @nobuiltin() #35 +; CHECK: call void @nobuiltin() #36 ret void; } @@ -345,6 +345,12 @@ ret void; } +; CHECK: define void @f59() #35 +define void @f59() shadowcallstack +{ + ret void +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } @@ -380,4 +386,5 @@ ; CHECK: attributes #32 = { writeonly } ; CHECK: attributes #33 = { speculatable } ; CHECK: attributes #34 = { sanitize_hwaddress } -; CHECK: attributes #35 = { nobuiltin } +; CHECK: attributes #35 = { shadowcallstack } +; CHECK: attributes #36 = { nobuiltin }