mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
Add the ShadowCallStack attribute
Summary: Introduce the ShadowCallStack function attribute. It's added to functions compiled with -fsanitize=shadow-call-stack in order to mark functions to be instrumented by a ShadowCallStack pass to be submitted in a separate change. Reviewers: pcc, kcc, kubamracek Reviewed By: pcc, kcc Subscribers: cryptoad, mehdi_amini, javed.absar, llvm-commits, kcc Differential Revision: https://reviews.llvm.org/D44800 llvm-svn: 329108
This commit is contained in:
parent
6d33e6f11c
commit
505d68d60f
@ -1056,6 +1056,7 @@ The integer codes are mapped to well-known attributes as follows.
|
|||||||
* code 55: ``sanitize_hwaddress``
|
* code 55: ``sanitize_hwaddress``
|
||||||
* code 56: ``nocf_check``
|
* code 56: ``nocf_check``
|
||||||
* code 57: ``optforfuzzing``
|
* code 57: ``optforfuzzing``
|
||||||
|
* code 58: ``shadowcallstack``
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The ``allocsize`` attribute has a special encoding for its arguments. Its two
|
The ``allocsize`` attribute has a special encoding for its arguments. Its two
|
||||||
|
@ -1708,6 +1708,11 @@ example:
|
|||||||
entity to fine grain the HW control flow protection mechanism. The flag
|
entity to fine grain the HW control flow protection mechanism. The flag
|
||||||
is target independant and currently appertains to a function or function
|
is target independant and currently appertains to a function or function
|
||||||
pointer.
|
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:
|
.. _glattrs:
|
||||||
|
|
||||||
|
@ -589,6 +589,7 @@ enum AttributeKindCodes {
|
|||||||
ATTR_KIND_SANITIZE_HWADDRESS = 55,
|
ATTR_KIND_SANITIZE_HWADDRESS = 55,
|
||||||
ATTR_KIND_NOCF_CHECK = 56,
|
ATTR_KIND_NOCF_CHECK = 56,
|
||||||
ATTR_KIND_OPT_FOR_FUZZING = 57,
|
ATTR_KIND_OPT_FOR_FUZZING = 57,
|
||||||
|
ATTR_KIND_SHADOWCALLSTACK = 58,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ComdatSelectionKindCodes {
|
enum ComdatSelectionKindCodes {
|
||||||
|
@ -136,6 +136,9 @@ def ReturnsTwice : EnumAttr<"returns_twice">;
|
|||||||
/// Safe Stack protection.
|
/// Safe Stack protection.
|
||||||
def SafeStack : EnumAttr<"safestack">;
|
def SafeStack : EnumAttr<"safestack">;
|
||||||
|
|
||||||
|
/// Shadow Call Stack protection.
|
||||||
|
def ShadowCallStack : EnumAttr<"shadowcallstack">;
|
||||||
|
|
||||||
/// Sign extended before/after call.
|
/// Sign extended before/after call.
|
||||||
def SExt : EnumAttr<"signext">;
|
def SExt : EnumAttr<"signext">;
|
||||||
|
|
||||||
@ -211,6 +214,7 @@ def : CompatRule<"isEqual<SanitizeThreadAttr>">;
|
|||||||
def : CompatRule<"isEqual<SanitizeMemoryAttr>">;
|
def : CompatRule<"isEqual<SanitizeMemoryAttr>">;
|
||||||
def : CompatRule<"isEqual<SanitizeHWAddressAttr>">;
|
def : CompatRule<"isEqual<SanitizeHWAddressAttr>">;
|
||||||
def : CompatRule<"isEqual<SafeStackAttr>">;
|
def : CompatRule<"isEqual<SafeStackAttr>">;
|
||||||
|
def : CompatRule<"isEqual<ShadowCallStackAttr>">;
|
||||||
|
|
||||||
class MergeRule<string F> {
|
class MergeRule<string F> {
|
||||||
// The name of the function called to merge the attributes of the caller and
|
// The name of the function called to merge the attributes of the caller and
|
||||||
|
@ -665,6 +665,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||||||
KEYWORD(sspstrong);
|
KEYWORD(sspstrong);
|
||||||
KEYWORD(strictfp);
|
KEYWORD(strictfp);
|
||||||
KEYWORD(safestack);
|
KEYWORD(safestack);
|
||||||
|
KEYWORD(shadowcallstack);
|
||||||
KEYWORD(sanitize_address);
|
KEYWORD(sanitize_address);
|
||||||
KEYWORD(sanitize_hwaddress);
|
KEYWORD(sanitize_hwaddress);
|
||||||
KEYWORD(sanitize_thread);
|
KEYWORD(sanitize_thread);
|
||||||
|
@ -1148,6 +1148,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
|
|||||||
case lltok::kw_sspstrong:
|
case lltok::kw_sspstrong:
|
||||||
B.addAttribute(Attribute::StackProtectStrong); break;
|
B.addAttribute(Attribute::StackProtectStrong); break;
|
||||||
case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break;
|
case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break;
|
||||||
|
case lltok::kw_shadowcallstack:
|
||||||
|
B.addAttribute(Attribute::ShadowCallStack); break;
|
||||||
case lltok::kw_sanitize_address:
|
case lltok::kw_sanitize_address:
|
||||||
B.addAttribute(Attribute::SanitizeAddress); break;
|
B.addAttribute(Attribute::SanitizeAddress); break;
|
||||||
case lltok::kw_sanitize_hwaddress:
|
case lltok::kw_sanitize_hwaddress:
|
||||||
@ -1485,6 +1487,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
|
|||||||
case lltok::kw_sspreq:
|
case lltok::kw_sspreq:
|
||||||
case lltok::kw_sspstrong:
|
case lltok::kw_sspstrong:
|
||||||
case lltok::kw_safestack:
|
case lltok::kw_safestack:
|
||||||
|
case lltok::kw_shadowcallstack:
|
||||||
case lltok::kw_strictfp:
|
case lltok::kw_strictfp:
|
||||||
case lltok::kw_uwtable:
|
case lltok::kw_uwtable:
|
||||||
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
|
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
|
||||||
@ -1580,6 +1583,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
|
|||||||
case lltok::kw_sspreq:
|
case lltok::kw_sspreq:
|
||||||
case lltok::kw_sspstrong:
|
case lltok::kw_sspstrong:
|
||||||
case lltok::kw_safestack:
|
case lltok::kw_safestack:
|
||||||
|
case lltok::kw_shadowcallstack:
|
||||||
case lltok::kw_strictfp:
|
case lltok::kw_strictfp:
|
||||||
case lltok::kw_uwtable:
|
case lltok::kw_uwtable:
|
||||||
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
|
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
|
||||||
|
@ -214,6 +214,7 @@ enum Kind {
|
|||||||
kw_sspreq,
|
kw_sspreq,
|
||||||
kw_sspstrong,
|
kw_sspstrong,
|
||||||
kw_safestack,
|
kw_safestack,
|
||||||
|
kw_shadowcallstack,
|
||||||
kw_sret,
|
kw_sret,
|
||||||
kw_sanitize_thread,
|
kw_sanitize_thread,
|
||||||
kw_sanitize_memory,
|
kw_sanitize_memory,
|
||||||
|
@ -1162,6 +1162,7 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) {
|
|||||||
case Attribute::SanitizeHWAddress: return 1ULL << 56;
|
case Attribute::SanitizeHWAddress: return 1ULL << 56;
|
||||||
case Attribute::NoCfCheck: return 1ULL << 57;
|
case Attribute::NoCfCheck: return 1ULL << 57;
|
||||||
case Attribute::OptForFuzzing: return 1ULL << 58;
|
case Attribute::OptForFuzzing: return 1ULL << 58;
|
||||||
|
case Attribute::ShadowCallStack: return 1ULL << 59;
|
||||||
case Attribute::Dereferenceable:
|
case Attribute::Dereferenceable:
|
||||||
llvm_unreachable("dereferenceable attribute not supported in raw format");
|
llvm_unreachable("dereferenceable attribute not supported in raw format");
|
||||||
break;
|
break;
|
||||||
@ -1372,6 +1373,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
|
|||||||
return Attribute::StackProtectStrong;
|
return Attribute::StackProtectStrong;
|
||||||
case bitc::ATTR_KIND_SAFESTACK:
|
case bitc::ATTR_KIND_SAFESTACK:
|
||||||
return Attribute::SafeStack;
|
return Attribute::SafeStack;
|
||||||
|
case bitc::ATTR_KIND_SHADOWCALLSTACK:
|
||||||
|
return Attribute::ShadowCallStack;
|
||||||
case bitc::ATTR_KIND_STRICT_FP:
|
case bitc::ATTR_KIND_STRICT_FP:
|
||||||
return Attribute::StrictFP;
|
return Attribute::StrictFP;
|
||||||
case bitc::ATTR_KIND_STRUCT_RET:
|
case bitc::ATTR_KIND_STRUCT_RET:
|
||||||
|
@ -673,6 +673,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
|
|||||||
return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
|
return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
|
||||||
case Attribute::SafeStack:
|
case Attribute::SafeStack:
|
||||||
return bitc::ATTR_KIND_SAFESTACK;
|
return bitc::ATTR_KIND_SAFESTACK;
|
||||||
|
case Attribute::ShadowCallStack:
|
||||||
|
return bitc::ATTR_KIND_SHADOWCALLSTACK;
|
||||||
case Attribute::StrictFP:
|
case Attribute::StrictFP:
|
||||||
return bitc::ATTR_KIND_STRICT_FP;
|
return bitc::ATTR_KIND_STRICT_FP;
|
||||||
case Attribute::StructRet:
|
case Attribute::StructRet:
|
||||||
|
@ -332,6 +332,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
|
|||||||
return "sspstrong";
|
return "sspstrong";
|
||||||
if (hasAttribute(Attribute::SafeStack))
|
if (hasAttribute(Attribute::SafeStack))
|
||||||
return "safestack";
|
return "safestack";
|
||||||
|
if (hasAttribute(Attribute::ShadowCallStack))
|
||||||
|
return "shadowcallstack";
|
||||||
if (hasAttribute(Attribute::StrictFP))
|
if (hasAttribute(Attribute::StrictFP))
|
||||||
return "strictfp";
|
return "strictfp";
|
||||||
if (hasAttribute(Attribute::StructRet))
|
if (hasAttribute(Attribute::StructRet))
|
||||||
|
@ -1413,6 +1413,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
|
|||||||
case Attribute::StackProtectReq:
|
case Attribute::StackProtectReq:
|
||||||
case Attribute::StackProtectStrong:
|
case Attribute::StackProtectStrong:
|
||||||
case Attribute::SafeStack:
|
case Attribute::SafeStack:
|
||||||
|
case Attribute::ShadowCallStack:
|
||||||
case Attribute::NoRedZone:
|
case Attribute::NoRedZone:
|
||||||
case Attribute::NoImplicitFloat:
|
case Attribute::NoImplicitFloat:
|
||||||
case Attribute::Naked:
|
case Attribute::Naked:
|
||||||
|
@ -53,6 +53,7 @@ static Attribute::AttrKind parseAttrKind(StringRef Kind) {
|
|||||||
.Case("argmemonly", Attribute::ArgMemOnly)
|
.Case("argmemonly", Attribute::ArgMemOnly)
|
||||||
.Case("returns_twice", Attribute::ReturnsTwice)
|
.Case("returns_twice", Attribute::ReturnsTwice)
|
||||||
.Case("safestack", Attribute::SafeStack)
|
.Case("safestack", Attribute::SafeStack)
|
||||||
|
.Case("shadowcallstack", Attribute::SafeStack)
|
||||||
.Case("sanitize_address", Attribute::SanitizeAddress)
|
.Case("sanitize_address", Attribute::SanitizeAddress)
|
||||||
.Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
|
.Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
|
||||||
.Case("sanitize_memory", Attribute::SanitizeMemory)
|
.Case("sanitize_memory", Attribute::SanitizeMemory)
|
||||||
|
@ -688,6 +688,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
|
|||||||
case Attribute::OptimizeNone:
|
case Attribute::OptimizeNone:
|
||||||
case Attribute::OptimizeForSize:
|
case Attribute::OptimizeForSize:
|
||||||
case Attribute::SafeStack:
|
case Attribute::SafeStack:
|
||||||
|
case Attribute::ShadowCallStack:
|
||||||
case Attribute::SanitizeAddress:
|
case Attribute::SanitizeAddress:
|
||||||
case Attribute::SanitizeMemory:
|
case Attribute::SanitizeMemory:
|
||||||
case Attribute::SanitizeThread:
|
case Attribute::SanitizeThread:
|
||||||
|
@ -204,7 +204,7 @@ define void @f34()
|
|||||||
; CHECK: define void @f34()
|
; CHECK: define void @f34()
|
||||||
{
|
{
|
||||||
call void @nobuiltin() nobuiltin
|
call void @nobuiltin() nobuiltin
|
||||||
; CHECK: call void @nobuiltin() #35
|
; CHECK: call void @nobuiltin() #36
|
||||||
ret void;
|
ret void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,6 +345,12 @@ define void @f58() sanitize_hwaddress
|
|||||||
ret void;
|
ret void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK: define void @f59() #35
|
||||||
|
define void @f59() shadowcallstack
|
||||||
|
{
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
; CHECK: attributes #0 = { noreturn }
|
; CHECK: attributes #0 = { noreturn }
|
||||||
; CHECK: attributes #1 = { nounwind }
|
; CHECK: attributes #1 = { nounwind }
|
||||||
; CHECK: attributes #2 = { readnone }
|
; CHECK: attributes #2 = { readnone }
|
||||||
@ -380,4 +386,5 @@ define void @f58() sanitize_hwaddress
|
|||||||
; CHECK: attributes #32 = { writeonly }
|
; CHECK: attributes #32 = { writeonly }
|
||||||
; CHECK: attributes #33 = { speculatable }
|
; CHECK: attributes #33 = { speculatable }
|
||||||
; CHECK: attributes #34 = { sanitize_hwaddress }
|
; CHECK: attributes #34 = { sanitize_hwaddress }
|
||||||
; CHECK: attributes #35 = { nobuiltin }
|
; CHECK: attributes #35 = { shadowcallstack }
|
||||||
|
; CHECK: attributes #36 = { nobuiltin }
|
||||||
|
Loading…
Reference in New Issue
Block a user