[clang] [compiler-rt] [llvm] [PAC][AArch64] Support init/fini array signing (PR #96478)
kovdan01 wrote: Ping: this PR blocks merging already approved #96159 (see https://github.com/llvm/llvm-project/pull/96159#issuecomment-2211411440), which transitively also blocks merging already approved dependent #96164. Would be glad to see feedback on the changes from those who are interested. https://github.com/llvm/llvm-project/pull/96478 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -8210,6 +8228,70 @@ static void HandleNeonVectorTypeAttr(QualType , const ParsedAttr , CurType = S.Context.getVectorType(CurType, numElts, VecKind); } +/// Handle the __ptrauth qualifier. +static void HandlePtrAuthQualifier(ASTContext , QualType , + const ParsedAttr , Sema ) { kovdan01 wrote: Nit ```suggestion const ParsedAttr , Sema ) { ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2196,6 +2196,58 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { return V; } +static bool isDeclRefKnownNonNull(CodeGenFunction , const ValueDecl *D) { + return !D->isWeak(); +} + +static bool isLValueKnownNonNull(CodeGenFunction , const Expr *E) { + E = E->IgnoreParens(); + + if (auto *UO = dyn_cast(E)) { kovdan01 wrote: Nit: you can probably omit braces in this if and in the if inside. https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2196,6 +2196,58 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { return V; } +static bool isDeclRefKnownNonNull(CodeGenFunction , const ValueDecl *D) { + return !D->isWeak(); +} + +static bool isLValueKnownNonNull(CodeGenFunction , const Expr *E) { + E = E->IgnoreParens(); + + if (auto *UO = dyn_cast(E)) { +if (UO->getOpcode() == UO_Deref) { + return CGF.isPointerKnownNonNull(UO->getSubExpr()); +} + } + + if (auto *DRE = dyn_cast(E)) { kovdan01 wrote: Nit ```suggestion if (const auto *DRE = dyn_cast(E)) { ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify -fptrauth-intrinsics %s + +#include kovdan01 wrote: It looks like this include is not needed https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify -fptrauth-intrinsics %s + +#include + +#if __has_feature(ptrauth_qualifier) +#warning __ptrauth qualifier enabled! +// expected-warning@-1 {{__ptrauth qualifier enabled!}} +#endif + +#if __aarch64__ +#define VALID_CODE_KEY 0 +#define VALID_DATA_KEY 2 +#define INVALID_KEY 200 +#else +#error Provide these constants if you port this test +#endif + +int * __ptrauth(VALID_DATA_KEY) valid0; + +typedef int *intp; + +int nonConstantGlobal = 5; + +__ptrauth int invalid0; // expected-error{{expected '('}} +__ptrauth() int invalid1; // expected-error{{expected expression}} +__ptrauth(INVALID_KEY) int invalid2; // expected-error{{200 does not identify a valid pointer authentication key for the current target}} +__ptrauth(VALID_DATA_KEY) int invalid3; // expected-error{{__ptrauth qualifier may only be applied to pointer types}} +__ptrauth(VALID_DATA_KEY) int *invalid4; // expected-error{{__ptrauth qualifier may only be applied to pointer types}} +int * (__ptrauth(VALID_DATA_KEY) invalid5); // expected-error{{expected identifier or '('}} expected-error{{expected ')'}} expected-note {{to match this '('}} +int *__ptrauth(VALID_DATA_KEY) __ptrauth(VALID_DATA_KEY) invalid6; // expected-error{{type 'int *__ptrauth(2,0,0)' is already __ptrauth-qualified}} +int * __ptrauth(VALID_DATA_KEY, 2) invalid7; // expected-error{{address discrimination flag for __ptrauth must be 0 or 1; value is 2}} +int * __ptrauth(VALID_DATA_KEY, -1) invalid8; // expected-error{{address discrimination flag for __ptrauth must be 0 or 1; value is -1}} +int * __ptrauth(VALID_DATA_KEY, 1, -1) invalid9; // expected-error{{extra discriminator for __ptrauth must be between 0 and 65535; value is -1}} +int * __ptrauth(VALID_DATA_KEY, 1, 10) invalid10; // expected-error{{extra discriminator for __ptrauth must be between 0 and 65535; value is 10}} +int * __ptrauth(VALID_DATA_KEY, 1, nonConstantGlobal) invalid12; // expected-error{{argument to __ptrauth must be an integer constant expression}} kovdan01 wrote: Can we also test non-constant-expression for key and address discrimination fields? https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2196,6 +2196,58 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { return V; } +static bool isDeclRefKnownNonNull(CodeGenFunction , const ValueDecl *D) { + return !D->isWeak(); +} + +static bool isLValueKnownNonNull(CodeGenFunction , const Expr *E) { + E = E->IgnoreParens(); + + if (auto *UO = dyn_cast(E)) { kovdan01 wrote: Nit ```suggestion if (const auto *UO = dyn_cast(E)) { ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2196,6 +2196,58 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { return V; } +static bool isDeclRefKnownNonNull(CodeGenFunction , const ValueDecl *D) { + return !D->isWeak(); +} + +static bool isLValueKnownNonNull(CodeGenFunction , const Expr *E) { + E = E->IgnoreParens(); + + if (auto *UO = dyn_cast(E)) { +if (UO->getOpcode() == UO_Deref) { + return CGF.isPointerKnownNonNull(UO->getSubExpr()); +} + } + + if (auto *DRE = dyn_cast(E)) { +return isDeclRefKnownNonNull(CGF, DRE->getDecl()); + } else if (auto *ME = dyn_cast(E)) { kovdan01 wrote: Nit: avoid else after return https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify -fptrauth-intrinsics %s + +#include + +#if __has_feature(ptrauth_qualifier) +#warning __ptrauth qualifier enabled! +// expected-warning@-1 {{__ptrauth qualifier enabled!}} +#endif + +#if __aarch64__ kovdan01 wrote: Nit: I'm OK with such preprocessor if statement, but it looks a bit over-engineering. For non-AArch64, it looks like that many tests would require such intervention, not only this one. So, probably just providing defines would also be fine. Feel free to ignore. https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -1758,6 +1758,34 @@ Also see the documentation for `@available }]; } +def PtrAuthDocs : Documentation { + let Category = DocCatVariable; + let Heading = "__ptrauth, __ptrauth_restricted_intptr"; + let Content = [{ +The ``__ptrauth`` qualifier allows the programmer to directly control +how pointers are signed when they are stored in a particular variable. +This can be used to strengthen the default protections of pointer +authentication and make it more difficult for an attacker to escalate +an ability to alter memory into full control of a process. + +.. code-block:: c + + #include + + typedef void (*my_callback)(const void*); + my_callback __ptrauth(ptrauth_key_process_dependent_code, 1, 0xe27a) callback; + +The first argument to ``__ptrauth`` is the name of the signing key. +Valid key names for the target are defined in . + +The second argument to ``__ptrauth`` is a flag (0 or 1) specifying whether +the object should use address discrimination. + +The third argument to ``__ptrauth`` is a small non-negative integer kovdan01 wrote: > a small non-negative integer Nit: it's probably worth providing explicit integer width (e.g. 16 bits) rather than just saying "small". It looks like 16 bits is the only allowed max width now (see `PointerAuthQualifier::DiscriminatorBits`) https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -,6 +5579,27 @@ CGCallee CodeGenFunction::EmitCallee(const Expr *E) { return EmitCallee(ICE->getSubExpr()); } +// Try to remember the original __ptrauth qualifier for loads of +// function pointers. +if (ICE->getCastKind() == CK_LValueToRValue) { + auto *SubExpr = ICE->getSubExpr(); + if (auto *PtrType = SubExpr->getType()->getAs()) { kovdan01 wrote: Nit ```suggestion if (const auto *PtrType = SubExpr->getType()->getAs()) { ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s + +#include + +// Constant initializers for data pointers. +extern int external_int; + +// CHECK: @g1 = global ptr ptrauth (ptr @external_int, i32 1, i64 56) +int * __ptrauth(1,0,56) g1 = _int; kovdan01 wrote: Just for my information: how are discriminators chosen in this file? Are these just random different integers, or do these values have any special meaning (beside being different from each other so we can distinguish them)? https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -0,0 +1,132 @@ +// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s kovdan01 wrote: Nit: it's probably worth to also have tests without `-fptrauth-function-pointer-type-discrimination` to ensure that some or resigns go away when equal zero discrimination is used for non-ptrauth-qualified function pointers. https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios \ +// RUN: -fptrauth-calls -fptrauth-intrinsics -emit-llvm -fblocks \ +// RUN: %s -debug-info-kind=limited -o - | FileCheck %s + +// Constant initializers for data pointers. +extern int external_int; + +int *__ptrauth(1, 0, 1234) g1 = _int; +// CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, +// CHECK-SAME: ptrAuthKey: 1, kovdan01 wrote: I suppose it would be nice to have different keys for two test cases present. https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -0,0 +1,132 @@ +// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s kovdan01 wrote: Nit: it looks like you can use arm64-apple-ios13 triple instead of arm64e-apple-ios13. You anyway enable desired options manually. In other tests, just arm64 is used, so it's probably better to keep things consistent here. ```suggestion // RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)
kovdan01 wrote: Submitted an issue #101716 describing incorrect behavior in terms of address discrimination (see also comments above) https://github.com/llvm/llvm-project/pull/99726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -166,6 +193,92 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) { return ::getPointerAuthInfoForType(*this, T); } +static std::pair +emitLoadOfOrigPointerRValue(CodeGenFunction , const LValue , +SourceLocation Loc) { + auto *Value = CGF.EmitLoadOfScalar(LV, Loc); + CGPointerAuthInfo AuthInfo; + if (PointerAuthQualifier PtrAuth = LV.getQuals().getPointerAuth()) { +AuthInfo = CGF.EmitPointerAuthInfo(PtrAuth, LV.getAddress()); + } else { +AuthInfo = getPointerAuthInfoForType(CGF.CGM, LV.getType()); + } + return {Value, AuthInfo}; +} + +/// Retrieve a pointer rvalue and its ptrauth info. When possible, avoid +/// needlessly resigning the pointer. +std::pair +CodeGenFunction::EmitOrigPointerRValue(const Expr *E) { + assert(E->getType()->isSignableType()); + + E = E->IgnoreParens(); + if (auto *Load = dyn_cast(E)) { +if (Load->getCastKind() == CK_LValueToRValue) { + E = Load->getSubExpr()->IgnoreParens(); + + // We're semantically required to not emit loads of certain DREs naively. + if (auto *RefExpr = dyn_cast(const_cast(E))) { +if (auto Result = tryEmitAsConstant(RefExpr)) { + // Fold away a use of an intermediate variable. + if (!Result.isReference()) +return {Result.getValue(), +getPointerAuthInfoForType(CGM, RefExpr->getType())}; + + // Fold away a use of an intermediate reference. + auto LV = Result.getReferenceLValue(*this, RefExpr); + return emitLoadOfOrigPointerRValue(*this, LV, RefExpr->getLocation()); +} + } + + // Otherwise, load and use the pointer + auto LV = EmitCheckedLValue(E, CodeGenFunction::TCK_Load); + return emitLoadOfOrigPointerRValue(*this, LV, E->getExprLoc()); +} + } + + // Fallback: just use the normal rules for the type. + auto *Value = EmitScalarExpr(E); + return {Value, getPointerAuthInfoForType(CGM, E->getType())}; +} + +llvm::Value * +CodeGenFunction::EmitPointerAuthQualify(PointerAuthQualifier DestQualifier, +const Expr *E, +Address DestStorageAddress) { + assert(DestQualifier); + + auto Src = EmitOrigPointerRValue(E); + auto *Value = Src.first; + auto CurAuthInfo = Src.second; kovdan01 wrote: Nit: you could probably just you structured bindings https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -166,6 +193,92 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) { return ::getPointerAuthInfoForType(*this, T); } +static std::pair +emitLoadOfOrigPointerRValue(CodeGenFunction , const LValue , +SourceLocation Loc) { + auto *Value = CGF.EmitLoadOfScalar(LV, Loc); + CGPointerAuthInfo AuthInfo; + if (PointerAuthQualifier PtrAuth = LV.getQuals().getPointerAuth()) { +AuthInfo = CGF.EmitPointerAuthInfo(PtrAuth, LV.getAddress()); + } else { +AuthInfo = getPointerAuthInfoForType(CGF.CGM, LV.getType()); + } + return {Value, AuthInfo}; +} + +/// Retrieve a pointer rvalue and its ptrauth info. When possible, avoid +/// needlessly resigning the pointer. +std::pair +CodeGenFunction::EmitOrigPointerRValue(const Expr *E) { + assert(E->getType()->isSignableType()); + + E = E->IgnoreParens(); + if (auto *Load = dyn_cast(E)) { kovdan01 wrote: Nit ```suggestion if (const auto *Load = dyn_cast(E)) { ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -1460,6 +1467,12 @@ class QualType { return getQualifiers().getPointerAuth(); } + bool hasAddressDiscriminatedPointerAuth() const { +if (PointerAuthQualifier ptrauth = getPointerAuth()) kovdan01 wrote: Nit ```suggestion if (PointerAuthQualifier PtrAuth = getPointerAuth()) ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2196,6 +2196,58 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { return V; } +static bool isDeclRefKnownNonNull(CodeGenFunction , const ValueDecl *D) { + return !D->isWeak(); +} + +static bool isLValueKnownNonNull(CodeGenFunction , const Expr *E) { + E = E->IgnoreParens(); + + if (auto *UO = dyn_cast(E)) { +if (UO->getOpcode() == UO_Deref) { + return CGF.isPointerKnownNonNull(UO->getSubExpr()); +} + } + + if (auto *DRE = dyn_cast(E)) { +return isDeclRefKnownNonNull(CGF, DRE->getDecl()); + } else if (auto *ME = dyn_cast(E)) { +if (isa(ME->getMemberDecl())) + return true; +return isDeclRefKnownNonNull(CGF, ME->getMemberDecl()); + } + + // Array subscripts? Anything else? + + return false; +} + +bool CodeGenFunction::isPointerKnownNonNull(const Expr *E) { + assert(E->getType()->isSignableType()); + + E = E->IgnoreParens(); + + if (isa(E)) +return true; + + if (auto *UO = dyn_cast(E)) { +if (UO->getOpcode() == UO_AddrOf) { + return isLValueKnownNonNull(*this, UO->getSubExpr()); +} + } + + if (auto *CE = dyn_cast(E)) { kovdan01 wrote: Nit ```suggestion if (const auto *CE = dyn_cast(E)) { ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -166,6 +193,92 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) { return ::getPointerAuthInfoForType(*this, T); } +static std::pair +emitLoadOfOrigPointerRValue(CodeGenFunction , const LValue , +SourceLocation Loc) { + auto *Value = CGF.EmitLoadOfScalar(LV, Loc); + CGPointerAuthInfo AuthInfo; + if (PointerAuthQualifier PtrAuth = LV.getQuals().getPointerAuth()) { +AuthInfo = CGF.EmitPointerAuthInfo(PtrAuth, LV.getAddress()); + } else { +AuthInfo = getPointerAuthInfoForType(CGF.CGM, LV.getType()); + } + return {Value, AuthInfo}; +} + +/// Retrieve a pointer rvalue and its ptrauth info. When possible, avoid +/// needlessly resigning the pointer. +std::pair +CodeGenFunction::EmitOrigPointerRValue(const Expr *E) { + assert(E->getType()->isSignableType()); + + E = E->IgnoreParens(); + if (auto *Load = dyn_cast(E)) { +if (Load->getCastKind() == CK_LValueToRValue) { + E = Load->getSubExpr()->IgnoreParens(); + + // We're semantically required to not emit loads of certain DREs naively. + if (auto *RefExpr = dyn_cast(const_cast(E))) { kovdan01 wrote: I do not think that having a `const_cast` here is a good idea. I was able to transform this into ```suggestion if (const auto *RefExpr = dyn_cast(E)) { ``` by introducing the following changes: - `CodeGenFunction::tryEmitAsConstant`: add `const` qualifier for `DeclRefExpr *` argument (and also add `const` inside the function where needed) - `getReferenceLValue`: add `const` qualifier for `Expr *` argument https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2196,6 +2196,58 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { return V; } +static bool isDeclRefKnownNonNull(CodeGenFunction , const ValueDecl *D) { + return !D->isWeak(); +} + +static bool isLValueKnownNonNull(CodeGenFunction , const Expr *E) { + E = E->IgnoreParens(); + + if (auto *UO = dyn_cast(E)) { +if (UO->getOpcode() == UO_Deref) { + return CGF.isPointerKnownNonNull(UO->getSubExpr()); +} + } + + if (auto *DRE = dyn_cast(E)) { +return isDeclRefKnownNonNull(CGF, DRE->getDecl()); + } else if (auto *ME = dyn_cast(E)) { +if (isa(ME->getMemberDecl())) + return true; +return isDeclRefKnownNonNull(CGF, ME->getMemberDecl()); + } + + // Array subscripts? Anything else? + + return false; +} + +bool CodeGenFunction::isPointerKnownNonNull(const Expr *E) { + assert(E->getType()->isSignableType()); + + E = E->IgnoreParens(); + + if (isa(E)) +return true; + + if (auto *UO = dyn_cast(E)) { kovdan01 wrote: Nit: you can probably omit braces in this if and in the if inside. https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2190,6 +2198,15 @@ RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, AggValueSlot Slot, /// method emits the address of the lvalue, then loads the result as an rvalue, /// returning the rvalue. RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) { + // Load from __ptrauth. + if (PointerAuthQualifier PtrAuth = LV.getQuals().getPointerAuth()) { +LV.getQuals().removePointerAuth(); +auto value = EmitLoadOfLValue(LV, Loc).getScalarVal(); kovdan01 wrote: Nit ```suggestion auto Value = EmitLoadOfLValue(LV, Loc).getScalarVal(); ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -166,6 +193,92 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) { return ::getPointerAuthInfoForType(*this, T); } +static std::pair +emitLoadOfOrigPointerRValue(CodeGenFunction , const LValue , +SourceLocation Loc) { + auto *Value = CGF.EmitLoadOfScalar(LV, Loc); + CGPointerAuthInfo AuthInfo; + if (PointerAuthQualifier PtrAuth = LV.getQuals().getPointerAuth()) { kovdan01 wrote: Nit: you can probably omit braces in this if/else chain https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -956,6 +956,25 @@ def err_ptrauth_indirect_goto_addrlabel_arithmetic : Error< "%select{subtraction|addition}0 of address-of-label expressions is not " "supported with ptrauth indirect gotos">; +// __ptrauth qualifier +def err_ptrauth_qualifier_invalid : Error< + "%select{return types|parameter types|properties}2 may not be qualified with %select{__ptrauth|__ptrauth_restricted_intptr}1; type is %0">; +def err_ptrauth_qualifier_cast : Error< + "cast types may not be qualified with __ptrauth; type is %0">; +def err_ptrauth_qualifier_nonpointer : Error< + "__ptrauth qualifier may only be applied to pointer types; type here is %0">; +def err_ptrauth_qualifier_redundant : Error< + "type %0 is already %1-qualified">; +def err_ptrauth_qualifier_bad_arg_count : Error< kovdan01 wrote: Is there a test for this error message? https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)
@@ -2196,6 +2196,58 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { return V; } +static bool isDeclRefKnownNonNull(CodeGenFunction , const ValueDecl *D) { + return !D->isWeak(); +} + +static bool isLValueKnownNonNull(CodeGenFunction , const Expr *E) { + E = E->IgnoreParens(); + + if (auto *UO = dyn_cast(E)) { +if (UO->getOpcode() == UO_Deref) { + return CGF.isPointerKnownNonNull(UO->getSubExpr()); +} + } + + if (auto *DRE = dyn_cast(E)) { +return isDeclRefKnownNonNull(CGF, DRE->getDecl()); + } else if (auto *ME = dyn_cast(E)) { +if (isa(ME->getMemberDecl())) + return true; +return isDeclRefKnownNonNull(CGF, ME->getMemberDecl()); + } + + // Array subscripts? Anything else? + + return false; +} + +bool CodeGenFunction::isPointerKnownNonNull(const Expr *E) { + assert(E->getType()->isSignableType()); + + E = E->IgnoreParens(); + + if (isa(E)) +return true; + + if (auto *UO = dyn_cast(E)) { kovdan01 wrote: Nit ```suggestion if (const auto *UO = dyn_cast(E)) ``` https://github.com/llvm/llvm-project/pull/100830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [llvm] [PAC][AArch64] Support init/fini array signing (PR #96478)
kovdan01 wrote: Ping: would be glad to see feedback on the changes from those who are interested. https://github.com/llvm/llvm-project/pull/96478 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [llvm] [PAC][AArch64] Support init/fini array signing (PR #96478)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96478 >From 5399237a71c0ccd872821034d83ea2c3a04bed3f Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Fri, 21 Jun 2024 12:32:51 +0300 Subject: [PATCH 1/7] [PAC][AArch64] Support init/fini array signing If both `-fptrauth-init-fini` and `-fptrauth-calls` are passed, sign function pointers in `llvm.global_ctors` and `llvm.global_dtors` with constant discriminator 0xD9D4 (`ptrauth_string_discriminator("init_fini")`). Additionally, if `-fptrauth-init-fini-address-discrimination` is passed, address discrimination is used for signing (otherwise, just constant discriminator is used). --- clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Basic/LangOptions.def | 1 + .../include/clang/Basic/PointerAuthOptions.h | 7 ++ clang/include/clang/Driver/Options.td | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 63 +-- clang/lib/Driver/ToolChains/Clang.cpp | 3 + clang/lib/Frontend/CompilerInvocation.cpp | 9 +++ clang/lib/Headers/ptrauth.h | 8 ++ clang/test/CodeGen/aarch64-elf-pauthabi.c | 12 ++- clang/test/CodeGen/ptrauth-init-fini.c| 39 ++ clang/test/Driver/aarch64-ptrauth.c | 6 +- clang/test/Preprocessor/ptrauth_feature.c | 52 + compiler-rt/lib/builtins/crtbegin.c | 16 llvm/include/llvm/BinaryFormat/ELF.h | 3 +- .../AArch64/note-gnu-property-elf-pauthabi.ll | 2 +- .../test/CodeGen/AArch64/ptrauth-init-fini.ll | 77 +++ .../ELF/AArch64/aarch64-feature-pauth.s | 18 ++--- llvm/tools/llvm-readobj/ELFDumper.cpp | 4 +- 18 files changed, 268 insertions(+), 54 deletions(-) create mode 100644 clang/test/CodeGen/ptrauth-init-fini.c create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-init-fini.ll diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 53f410d3cb4bd..5dca40b261655 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination) FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls) FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini) +FEATURE(ptrauth_init_fini_address_discrimination, LangOpts.PointerAuthInitFiniAddressDiscrimination) EXTENSION(swiftcc, PP.getTargetInfo().checkCallingConvention(CC_Swift) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6dd6b5614f44c..2de854731 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -168,6 +168,7 @@ LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps") LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers") LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers") LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays") +LANGOPT(PointerAuthInitFiniAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated function pointers in init/fini arrays") LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") LANGOPT(ExperimentalLateParseAttributes, 1, 0, "experimental late parsing of attributes") diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index aaad4a2b2b5ae..9e2b64111e461 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -23,6 +23,10 @@ namespace clang { +/// Constant discriminator to be used with function pointers in .init_array and +/// .fini_array. The value is ptrauth_string_discriminator("init_fini") +constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4; + constexpr unsigned PointerAuthKeyNone = -1; class PointerAuthSchema { @@ -150,6 +154,9 @@ class PointerAuthSchema { struct PointerAuthOptions { /// The ABI for C function pointers. PointerAuthSchema FunctionPointers; + + /// The ABI for function addresses in .init_array and .fini_array + PointerAuthSchema InitFiniPointers; }; } // end namespace clang diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c529cc9506667..5b8d4139d975b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4228,6 +4228,7 @@ defm ptrauth_vtable_pointer_address_discrimination : defm ptrauth_vtable_pointer_type_discrimination :
[clang] [llvm] [PAC][clang][Driver] Add signed GOT flag (PR #96160)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96160 >From f891f791dfe882389d83d3c4c4fb57d67a845c04 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 18 Jun 2024 15:38:18 +0300 Subject: [PATCH 1/3] [PAC][clang][Driver] Add signed GOT flag Add `-fptrauth-elf-got` clang driver flag and set `ptrauth_elf_got` preprocessor feature and `PointerAuthELFGOT` LangOption correspondingly. For non-ELF triples, the driver flag is ignored and a warning is emitted. --- .../clang/Basic/DiagnosticDriverKinds.td | 4 ++ clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Driver/Options.td | 1 + clang/lib/Driver/ToolChains/Clang.cpp | 7 +++ clang/lib/Frontend/CompilerInvocation.cpp | 4 ++ clang/test/CodeGen/aarch64-elf-pauthabi.c | 11 +++- clang/test/Driver/aarch64-ptrauth.c | 9 +++- clang/test/Preprocessor/ptrauth_feature.c | 52 ++- 8 files changed, 72 insertions(+), 17 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 1ca2cb85565a1..28667b1eb239e 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -742,6 +742,10 @@ def warn_drv_fjmc_for_elf_only : Warning< "-fjmc works only for ELF; option ignored">, InGroup; +def warn_drv_ptrauth_elf_got_for_elf_only : Warning< + "-fptrauth-elf-got works only for ELF; option ignored">, + InGroup; + def warn_target_override_arm64ec : Warning< "/arm64EC has been overridden by specified target: %0; option ignored">, InGroup; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 53f410d3cb4bd..569f4e1715af5 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination) FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls) FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini) +FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT) EXTENSION(swiftcc, PP.getTargetInfo().checkCallingConvention(CC_Swift) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 112eb286eb075..e16c1a0d06a1b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4222,6 +4222,7 @@ defm ptrauth_vtable_pointer_address_discrimination : defm ptrauth_vtable_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">; defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">; +defm ptrauth_elf_got : OptInCC1FFlag<"ptrauth-elf-got", "Enable authentication of pointers from GOT (ELF only)">; } def fenable_matrix : Flag<["-"], "fenable-matrix">, Group, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 331cf6e713d89..5f55e79ec206b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1788,6 +1788,13 @@ void Clang::AddAArch64TargetArgs(const ArgList , options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini, options::OPT_fno_ptrauth_init_fini); + + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_elf_got, +options::OPT_fno_ptrauth_elf_got); + + if (Args.hasArg(options::OPT_fptrauth_elf_got)) +getToolChain().getDriver().Diag( +diag::warn_drv_ptrauth_elf_got_for_elf_only); } void Clang::AddLoongArchTargetArgs(const ArgList , diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 58694e5399d58..97a5408a4c1e0 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3361,6 +3361,8 @@ static void GeneratePointerAuthArgs(const LangOptions , GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination); if (Opts.PointerAuthInitFini) GenerateArg(Consumer, OPT_fptrauth_init_fini); + if (Opts.PointerAuthELFGOT) +GenerateArg(Consumer, OPT_fptrauth_elf_got); } static void ParsePointerAuthArgs(LangOptions , ArgList , @@ -3374,6 +3376,7 @@ static void ParsePointerAuthArgs(LangOptions , ArgList , Opts.PointerAuthVTPtrTypeDiscrimination = Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination); Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini); + Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got); } /// Check if input file kind and language standard are
[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)
@@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -DENABLE_TID=0 -I%S -std=c++11 -triple=arm64e-apple-darwin \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NODISC + +// RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=arm64e-apple-darwin \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -fptrauth-type-info-vtable-pointer-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC + +// copied from typeinfo +namespace std { + +#if __has_cpp_attribute(clang::ptrauth_vtable_pointer) +# if __has_feature(ptrauth_type_info_vtable_pointer_discrimination) +#define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ + [[clang::ptrauth_vtable_pointer(process_independent, address_discrimination, type_discrimination)]] +# else +#define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ + [[clang::ptrauth_vtable_pointer(process_independent, no_address_discrimination, no_extra_discrimination)]] +# endif +#else +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH +#endif + + class _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info + { +type_info& operator=(const type_info&); +type_info(const type_info&); + + protected: + explicit type_info(const char* __n); + + public: + virtual ~type_info(); + + virtual void test_method(); + }; +} // namespace std + +static_assert(__has_feature(ptrauth_type_info_vtable_pointer_discrimination) == ENABLE_TID, "incorrect feature state"); + +// CHECK: @disc_std_type_info = global i32 [[STDTYPEINFO_DISC:45546]] +extern "C" int disc_std_type_info = __builtin_ptrauth_string_discriminator("_ZTVSt9type_info"); + +// CHECK: @_ZTV10TestStruct = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI10TestStruct, ptr ptrauth (ptr @_ZN10TestStructD1Ev, i32 0, i64 52216, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN10TestStructD0Ev, i32 0, i64 39671, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 3))] }, align 8 +// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] +// CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1 + +// NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS10TestStruct }, align 8 + +// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]]), ptr @_ZTS10TestStruct }, align 8 kovdan01 wrote: @ahmedbougacha Here, we have ``` ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]]) ``` This has constant discriminator, but does not have address discrimination, while it should be enabled with `-fptrauth-type-info-vtable-pointer-discrimination`. The correct output should be smth like (if we use a placeholder value `ptr inttoptr (i64 1 to ptr)` as storage address) ``` ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]], ptr inttoptr (i64 1 to ptr)) ``` The root cause is described in my previous comment https://github.com/llvm/llvm-project/pull/99726/#issuecomment-2259839809. https://github.com/llvm/llvm-project/pull/99726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)
kovdan01 wrote: @ahmedbougacha It looks like there is some missing codegen logic. Particularly, in `ItaniumRTTIBuilder::BuildVTablePointer` (clang/lib/CodeGen/ItaniumCXXABI.cpp), there is the following piece of code: ``` if (auto = CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer) VTable = CGM.getConstantSignedPointer(VTable, Schema, nullptr, GlobalDecl(), QualType(Ty, 0)); ``` Here, `nullptr` is used as `StorageAddress` unconditionally, so, address discrimination is not actually enabled even if requested. It caused test-suite failures in several EH-related tests. I was able to fix that locally by just using a dummy `ptr inttoptr (i64 1 to ptr)` value as `StorageAddress` (just like you did with coroutines and as I did with init/fini, see https://github.com/llvm/llvm-project/pull/96478#issuecomment-2196819332), and tests became passing. I'm not sure how to get a proper `StorageAddress` here, so I've used that dummy placeholder which actually seems to do the job. Do you have some logic for this locally that you've not upstreamed yet? If yes, could you please open a PR adding that? If no, I'm happy to submit a PR with a fix described above by myself. Also tagging @asl https://github.com/llvm/llvm-project/pull/99726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
kovdan01 wrote: /cherry-pick 70c6e79 https://github.com/llvm/llvm-project/pull/100206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
https://github.com/kovdan01 milestoned https://github.com/llvm/llvm-project/pull/100206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
kovdan01 wrote: /cherry-pick 70c6e79e6d3e897418f3556a25e22e66ff018dc4 https://github.com/llvm/llvm-project/pull/100206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang] Enable `-fptrauth-indirect-gotos` as part of pauthtest ABI (PR #100480)
https://github.com/kovdan01 closed https://github.com/llvm/llvm-project/pull/100480 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang] Enable `-fptrauth-indirect-gotos` as part of pauthtest ABI (PR #100480)
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/100480 None >From b6604c33428a6c0e337212a0e33fbb85d2687a97 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Thu, 25 Jul 2024 01:27:47 +0300 Subject: [PATCH] [PAC][clang] Enable `-fptrauth-indirect-gotos` as part of `pauthtest` ABI --- clang/lib/Driver/ToolChains/Clang.cpp | 4 clang/test/Driver/aarch64-ptrauth.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 752a71739eeb5..d3edda3f10543 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1512,6 +1512,10 @@ static void handlePAuthABI(const ArgList , ArgStringList ) { options::OPT_fno_ptrauth_vtable_pointer_type_discrimination)) CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination"); + if (!DriverArgs.hasArg(options::OPT_fptrauth_indirect_gotos, + options::OPT_fno_ptrauth_indirect_gotos)) +CC1Args.push_back("-fptrauth-indirect-gotos"); + if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini, options::OPT_fno_ptrauth_init_fini)) CC1Args.push_back("-fptrauth-init-fini"); diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index 20899b8920cf9..c8e3aeef1640a 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -21,16 +21,16 @@ // RUN: %clang -### -c --target=aarch64-linux-pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1 // PAUTHABI1: "-cc1"{{.*}} "-triple" "aarch64-unknown-linux-pauthtest" // PAUTHABI1-SAME: "-target-abi" "pauthtest" -// PAUTHABI1-SAME: "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini" +// PAUTHABI1-SAME: "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-indirect-gotos" "-fptrauth-init-fini" // RUN: %clang -### -c --target=aarch64 -mabi=pauthtest -fno-ptrauth-intrinsics \ // RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \ // RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \ -// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 +// RUN: -fno-ptrauth-indirect-gotos -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 // RUN: %clang -### -c --target=aarch64-pauthtest -fno-ptrauth-intrinsics \ // RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \ // RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \ -// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 +// RUN: -fno-ptrauth-indirect-gotos -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 // PAUTHABI2: "-cc1" // PAUTHABI2-NOT: "-fptrauth- ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
https://github.com/kovdan01 closed https://github.com/llvm/llvm-project/pull/100206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
kovdan01 wrote: Buildkite failures look unrelated, so merging https://github.com/llvm/llvm-project/pull/100206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)
https://github.com/kovdan01 approved this pull request. LGTM, thanks! https://github.com/llvm/llvm-project/pull/100204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)
@@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++17 -Wno-vla -fsyntax-only -verify -fptrauth-intrinsics %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++17 -Wno-vla -fsyntax-only -verify -fptrauth-intrinsics %s + +// RUN: not %clang_cc1 -triple arm64-apple-ios -std=c++17 -Wno-vla -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: this target does not support pointer authentication + +struct S { + virtual int foo(); +}; + +template +constexpr unsigned dependentOperandDisc() { + return __builtin_ptrauth_type_discriminator(T); +} + +void test_builtin_ptrauth_type_discriminator(unsigned s) { + typedef int (S::*MemFnTy)(); + MemFnTy memFnPtr; + int (S::*memFnPtr2)(); + constexpr unsigned d0 = __builtin_ptrauth_type_discriminator(MemFnTy); + static_assert(d0 == __builtin_ptrauth_string_discriminator("_ZTSM1SFivE")); + static_assert(d0 == 60844); + static_assert(__builtin_ptrauth_type_discriminator(int (S::*)()) == d0); + static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr)) == d0); + static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr2)) == d0); + static_assert(__builtin_ptrauth_type_discriminator(decltype(::foo)) == d0); + static_assert(dependentOperandDisc() == d0); + + constexpr unsigned d1 = __builtin_ptrauth_type_discriminator(void (S::*)(int)); + static_assert(__builtin_ptrauth_string_discriminator("_ZTSM1SFviE") == d1); + static_assert(d1 == 39121); + + constexpr unsigned d2 = __builtin_ptrauth_type_discriminator(void (S::*)(float)); + static_assert(__builtin_ptrauth_string_discriminator("_ZTSM1SFvfE") == d2); + static_assert(d2 == 52453); + + constexpr unsigned d3 = __builtin_ptrauth_type_discriminator(int (*())[s]); + static_assert(__builtin_ptrauth_string_discriminator("FPE") == d3); + static_assert(d3 == 34128); + + int f4(float); + constexpr unsigned d4 = __builtin_ptrauth_type_discriminator(decltype(f4)); + static_assert(__builtin_ptrauth_type_discriminator(int (*)(float)) == d4); + static_assert(__builtin_ptrauth_string_discriminator("FifE") == d4); + static_assert(d4 == 48468); + + int f5(int); + constexpr unsigned d5 = __builtin_ptrauth_type_discriminator(decltype(f5)); + static_assert(__builtin_ptrauth_type_discriminator(int (*)(int)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(short (*)(short)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(char (*)(char)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(long (*)(long)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(unsigned int (*)(unsigned int)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(int (&)(int)) == d5); + static_assert(__builtin_ptrauth_string_discriminator("FiiE") == d5); + static_assert(d5 == 2981); + + int t; + int vmarray[s]; + (void)__builtin_ptrauth_type_discriminator(t); // expected-error {{unknown type name 't'}} + (void)__builtin_ptrauth_type_discriminator(); // expected-error {{expected a type}} + (void)__builtin_ptrauth_type_discriminator(decltype(vmarray)); // expected-error {{cannot pass undiscriminated type 'decltype(vmarray)' (aka 'int[s]')}} + (void)__builtin_ptrauth_type_discriminator(int *); // expected-error {{cannot pass undiscriminated type 'int *' to '__builtin_ptrauth_type_discriminator'}} kovdan01 wrote: No, I just mean a very dummy test case when we try to compile smth like `__builtin_ptrauth_type_discriminator()` or `__builtin_ptrauth_type_discriminator(int (*)(int), int (*)(int))`. https://github.com/llvm/llvm-project/pull/100204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/100204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)
@@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -std=c++17 -Wno-vla -fsyntax-only -verify -fptrauth-intrinsics %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++17 -Wno-vla -fsyntax-only -verify -fptrauth-intrinsics %s + +// RUN: not %clang_cc1 -triple arm64-apple-ios -std=c++17 -Wno-vla -fsyntax-only %s 2>&1 | FileCheck %s +// CHECK: this target does not support pointer authentication + +struct S { + virtual int foo(); +}; + +template +constexpr unsigned dependentOperandDisc() { + return __builtin_ptrauth_type_discriminator(T); +} + +void test_builtin_ptrauth_type_discriminator(unsigned s) { + typedef int (S::*MemFnTy)(); + MemFnTy memFnPtr; + int (S::*memFnPtr2)(); + constexpr unsigned d0 = __builtin_ptrauth_type_discriminator(MemFnTy); + static_assert(d0 == __builtin_ptrauth_string_discriminator("_ZTSM1SFivE")); + static_assert(d0 == 60844); + static_assert(__builtin_ptrauth_type_discriminator(int (S::*)()) == d0); + static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr)) == d0); + static_assert(__builtin_ptrauth_type_discriminator(decltype(memFnPtr2)) == d0); + static_assert(__builtin_ptrauth_type_discriminator(decltype(::foo)) == d0); + static_assert(dependentOperandDisc() == d0); + + constexpr unsigned d1 = __builtin_ptrauth_type_discriminator(void (S::*)(int)); + static_assert(__builtin_ptrauth_string_discriminator("_ZTSM1SFviE") == d1); + static_assert(d1 == 39121); + + constexpr unsigned d2 = __builtin_ptrauth_type_discriminator(void (S::*)(float)); + static_assert(__builtin_ptrauth_string_discriminator("_ZTSM1SFvfE") == d2); + static_assert(d2 == 52453); + + constexpr unsigned d3 = __builtin_ptrauth_type_discriminator(int (*())[s]); + static_assert(__builtin_ptrauth_string_discriminator("FPE") == d3); + static_assert(d3 == 34128); + + int f4(float); + constexpr unsigned d4 = __builtin_ptrauth_type_discriminator(decltype(f4)); + static_assert(__builtin_ptrauth_type_discriminator(int (*)(float)) == d4); + static_assert(__builtin_ptrauth_string_discriminator("FifE") == d4); + static_assert(d4 == 48468); + + int f5(int); + constexpr unsigned d5 = __builtin_ptrauth_type_discriminator(decltype(f5)); + static_assert(__builtin_ptrauth_type_discriminator(int (*)(int)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(short (*)(short)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(char (*)(char)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(long (*)(long)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(unsigned int (*)(unsigned int)) == d5); + static_assert(__builtin_ptrauth_type_discriminator(int (&)(int)) == d5); + static_assert(__builtin_ptrauth_string_discriminator("FiiE") == d5); + static_assert(d5 == 2981); + + int t; + int vmarray[s]; + (void)__builtin_ptrauth_type_discriminator(t); // expected-error {{unknown type name 't'}} + (void)__builtin_ptrauth_type_discriminator(); // expected-error {{expected a type}} + (void)__builtin_ptrauth_type_discriminator(decltype(vmarray)); // expected-error {{cannot pass undiscriminated type 'decltype(vmarray)' (aka 'int[s]')}} + (void)__builtin_ptrauth_type_discriminator(int *); // expected-error {{cannot pass undiscriminated type 'int *' to '__builtin_ptrauth_type_discriminator'}} kovdan01 wrote: Nit: it's probably worth adding tests when 0 or >=2 arguments are passed while 1 is expected. https://github.com/llvm/llvm-project/pull/100204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)
https://github.com/kovdan01 commented: Mostly LGTM, but the mangle-fail test should be fixed before merging - now it just does not look correct (see corresponding comment for details). Otherwise, this looks nice, and I'm OK with merging as soon as the test is fixed (and if nobody else has other concerns) https://github.com/llvm/llvm-project/pull/100204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)
@@ -1,5 +1,6 @@ // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=1 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=2 +// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=3 kovdan01 wrote: Using `-triple %itanium_abi_triple` does not look correct in this context - for most people who do not have arm64e triple set as default one, the test would fail with the following error: ``` error: 'expected-error' diagnostics expected but not seen: File /path/to/llvm-project/clang/test/CodeGenCXX/mangle-fail.cpp Line 23: cannot yet mangle __builtin_ptrauth_type_discriminator expression error: 'expected-error' diagnostics seen but not expected: File /path/to/llvm-project/clang/test/CodeGenCXX/mangle-fail.cpp Line 27: this target does not support pointer authentication ``` You probably want to use smth like `-triple aarch64-linux-gnu -fptrauth-intrinsics` instead of `-triple %itanium_abi_triple`. If I'm not mistaken, it'll need `// REQUIRES: aarch64-registered-target`, and maybe it's better to put this test case into a separate file in order to have other tests running for all targets. https://github.com/llvm/llvm-project/pull/100204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Define __builtin_ptrauth_type_discriminator (PR #100204)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/100204 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
https://github.com/kovdan01 ready_for_review https://github.com/llvm/llvm-project/pull/100206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
kovdan01 wrote: Also tagging @ojhunt https://github.com/llvm/llvm-project/pull/100206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][test] Implement missing tests for some PAuth features (PR #100206)
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/100206 Implement tests for the following PAuth-related features: - driver, preprocessor and ELF codegen tests for type_info vtable pointer discrimination #99726; - driver, preprocessor, and ELF codegen (emitting function attributes) + sema (emitting errors) tests for indirect gotos signing #97647; - ELF codegen tests for ubsan type checks + auth #99590; - ELF codegen tests for constant global init with polymorphic MI #99741; - ELF codegen tests for C++ member function pointers auth #99576. >From 6813589e337c28b998de86565431f8c739d13193 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 23 Jul 2024 23:47:22 +0300 Subject: [PATCH] [PAC][clang][test] Implement missing tests for some PAuth features Implement tests for the following PAuth-related features: - driver, preprocessor and ELF codegen tests for type_info vtable pointer discrimination #99726; - driver, preprocessor, and ELF codegen (emitting function attributes) + sema (emitting errors) tests for indirect gotos signing #97647; - ELF codegen tests for ubsan type checks + auth #99590; - ELF codegen tests for constant global init with polymorphic MI #99741; - ELF codegen tests for C++ member function pointers auth #99576. --- clang/lib/Driver/ToolChains/Clang.cpp | 3 + .../CodeGen/ptrauth-function-attributes.c | 5 +- clang/test/CodeGen/ubsan-function.cpp | 7 +- .../ptrauth-global-constant-initializers.cpp | 77 +++ .../ptrauth-member-function-pointer.cpp | 55 +++-- .../CodeGenCXX/ptrauth-type-info-vtable.cpp | 17 +++- clang/test/Driver/aarch64-ptrauth.c | 9 ++- clang/test/Preprocessor/ptrauth_feature.c | 36 +++-- clang/test/Sema/ptrauth-indirect-goto.c | 1 + 9 files changed, 137 insertions(+), 73 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 78936fd634f33..1314def18fda3 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1843,6 +1843,9 @@ void Clang::AddAArch64TargetArgs(const ArgList , Args.addOptInFlag( CmdArgs, options::OPT_fptrauth_vtable_pointer_type_discrimination, options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_type_info_vtable_pointer_discrimination, + options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination); Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini, options::OPT_fno_ptrauth_init_fini); Args.addOptInFlag( diff --git a/clang/test/CodeGen/ptrauth-function-attributes.c b/clang/test/CodeGen/ptrauth-function-attributes.c index 7f93ccc7c4bce..6a09cd37bf485 100644 --- a/clang/test/CodeGen/ptrauth-function-attributes.c +++ b/clang/test/CodeGen/ptrauth-function-attributes.c @@ -4,8 +4,9 @@ // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS -// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS -// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS +// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS // ALL: define {{(dso_local )?}}void @test() #0 void test() { diff --git a/clang/test/CodeGen/ubsan-function.cpp b/clang/test/CodeGen/ubsan-function.cpp index 8478f05a10b78..76d4237383f83 100644 --- a/clang/test/CodeGen/ubsan-function.cpp +++ b/clang/test/CodeGen/ubsan-function.cpp @@ -4,7 +4,8 @@ // RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,GNU,64 // RUN: %clang_cc1 -triple arm-none-eabi -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,ARM,GNU,32 -// RUN: %clang_cc1 -triple arm64e-apple-ios -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all -fptrauth-calls | FileCheck %s --check-prefixes=CHECK,GNU,64,64e +// RUN: %clang_cc1 -triple arm64e-apple-ios -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all -fptrauth-calls | FileCheck %s --check-prefixes=CHECK,GNU,64,AUTH +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all -fptrauth-calls | FileCheck %s
[clang] [llvm] [PAC][ELF][AArch64] Encode signed GOT flag in PAuth core info (PR #96159)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96159 >From 4eeb1b4e82941681b6cafda8579d136e3e7cb09f Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 18 Jun 2024 15:37:18 +0300 Subject: [PATCH 1/2] [PAC][ELF][AArch64] Encode signed GOT flag in PAuth core info Treat 7th bit of version value for llvm_linux platform as signed GOT flag. - clang: define `PointerAuthELFGOT` LangOption and set 7th bit of `aarch64-elf-pauthabi-version` LLVM module flag correspondingly; - llvm-readobj: print `PointerAuthELFGOT` or `!PointerAuthELFGOT` in version description of llvm_linux platform depending on whether the flag is set. --- clang/include/clang/Basic/LangOptions.def | 1 + clang/lib/CodeGen/CodeGenModule.cpp| 6 -- llvm/include/llvm/BinaryFormat/ELF.h | 3 ++- .../AArch64/note-gnu-property-elf-pauthabi.ll | 2 +- .../ELF/AArch64/aarch64-feature-pauth.s| 18 +- llvm/tools/llvm-readobj/ELFDumper.cpp | 3 ++- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6dd6b5614f44c..bc99dad5cd55e 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -168,6 +168,7 @@ LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps") LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers") LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers") LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays") +LANGOPT(PointerAuthELFGOT, 1, 0, "authenticate pointers from GOT") LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") LANGOPT(ExperimentalLateParseAttributes, 1, 0, "experimental late parsing of attributes") diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index dd4a665ebc78b..feac291e01b50 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1210,8 +1210,10 @@ void CodeGenModule::Release() { (LangOpts.PointerAuthVTPtrTypeDiscrimination << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR) | (LangOpts.PointerAuthInitFini - << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI); - static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI == + << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI) | + (LangOpts.PointerAuthELFGOT + << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT); + static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT == AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST, "Update when new enum items are defined"); if (PAuthABIVersion != 0) { diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index dfba180149916..2aa37bbed6656 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1774,8 +1774,9 @@ enum : unsigned { AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR = 4, AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR = 5, AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI = 6, + AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT = 7, AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST = - AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI, + AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT, }; // x86 processor feature bits. diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-elf-pauthabi.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-elf-pauthabi.ll index 728cffeba02a2..fb69a12b2f906 100644 --- a/llvm/test/CodeGen/AArch64/note-gnu-property-elf-pauthabi.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-elf-pauthabi.ll @@ -27,7 +27,7 @@ ; OBJ: Displaying notes found in: .note.gnu.property ; OBJ-NEXT: Owner Data size Description ; OBJ-NEXT: GNU 0x0018 NT_GNU_PROPERTY_TYPE_0 (property note) -; OBJ-NEXT: AArch64 PAuth ABI core info: platform 0x1002 (llvm_linux), version 0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini) +; OBJ-NEXT: AArch64 PAuth ABI core info: platform 0x1002 (llvm_linux), version 0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini, !PointerAuthELFGOT) ; ERR: either both or no 'aarch64-elf-pauthabi-platform' and 'aarch64-elf-pauthabi-version' module flags must be present diff --git
[clang] [llvm] [PAC][clang][Driver] Add signed GOT flag (PR #96160)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96160 >From f891f791dfe882389d83d3c4c4fb57d67a845c04 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 18 Jun 2024 15:38:18 +0300 Subject: [PATCH 1/3] [PAC][clang][Driver] Add signed GOT flag Add `-fptrauth-elf-got` clang driver flag and set `ptrauth_elf_got` preprocessor feature and `PointerAuthELFGOT` LangOption correspondingly. For non-ELF triples, the driver flag is ignored and a warning is emitted. --- .../clang/Basic/DiagnosticDriverKinds.td | 4 ++ clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Driver/Options.td | 1 + clang/lib/Driver/ToolChains/Clang.cpp | 7 +++ clang/lib/Frontend/CompilerInvocation.cpp | 4 ++ clang/test/CodeGen/aarch64-elf-pauthabi.c | 11 +++- clang/test/Driver/aarch64-ptrauth.c | 9 +++- clang/test/Preprocessor/ptrauth_feature.c | 52 ++- 8 files changed, 72 insertions(+), 17 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 1ca2cb85565a1..28667b1eb239e 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -742,6 +742,10 @@ def warn_drv_fjmc_for_elf_only : Warning< "-fjmc works only for ELF; option ignored">, InGroup; +def warn_drv_ptrauth_elf_got_for_elf_only : Warning< + "-fptrauth-elf-got works only for ELF; option ignored">, + InGroup; + def warn_target_override_arm64ec : Warning< "/arm64EC has been overridden by specified target: %0; option ignored">, InGroup; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 53f410d3cb4bd..569f4e1715af5 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination) FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls) FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini) +FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT) EXTENSION(swiftcc, PP.getTargetInfo().checkCallingConvention(CC_Swift) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 112eb286eb075..e16c1a0d06a1b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4222,6 +4222,7 @@ defm ptrauth_vtable_pointer_address_discrimination : defm ptrauth_vtable_pointer_type_discrimination : OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">; defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">; +defm ptrauth_elf_got : OptInCC1FFlag<"ptrauth-elf-got", "Enable authentication of pointers from GOT (ELF only)">; } def fenable_matrix : Flag<["-"], "fenable-matrix">, Group, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 331cf6e713d89..5f55e79ec206b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1788,6 +1788,13 @@ void Clang::AddAArch64TargetArgs(const ArgList , options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini, options::OPT_fno_ptrauth_init_fini); + + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_elf_got, +options::OPT_fno_ptrauth_elf_got); + + if (Args.hasArg(options::OPT_fptrauth_elf_got)) +getToolChain().getDriver().Diag( +diag::warn_drv_ptrauth_elf_got_for_elf_only); } void Clang::AddLoongArchTargetArgs(const ArgList , diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 58694e5399d58..97a5408a4c1e0 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3361,6 +3361,8 @@ static void GeneratePointerAuthArgs(const LangOptions , GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination); if (Opts.PointerAuthInitFini) GenerateArg(Consumer, OPT_fptrauth_init_fini); + if (Opts.PointerAuthELFGOT) +GenerateArg(Consumer, OPT_fptrauth_elf_got); } static void ParsePointerAuthArgs(LangOptions , ArgList , @@ -3374,6 +3376,7 @@ static void ParsePointerAuthArgs(LangOptions , ArgList , Opts.PointerAuthVTPtrTypeDiscrimination = Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination); Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini); + Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got); } /// Check if input file kind and language standard are
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -1036,9 +1155,32 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // least significant bit of adj then makes exactly the same // discrimination as the least significant bit of ptr does for // Itanium. - MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - 2 * ThisAdjustment.getQuantity() + 1); + + // We cannot use the Itanium ABI's representation for virtual member + // function pointers under pointer authentication because it would + // require us to store both the virtual offset and the constant + // discriminator in the pointer, which would be immediately vulnerable + // to attack. Instead we introduce a thunk that does the virtual dispatch + // and store it as if it were a non-virtual member function. This means + // that virtual function pointers may not compare equal anymore, but + // fortunately they aren't required to by the standard, and we do make + // a best-effort attempt to re-use the thunk. + // + // To support interoperation with code in which pointer authentication + // is disabled, derefencing a member function pointer must still handle + // the virtual case, but it can use a discriminator which should never + // be valid. + const auto = + CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers; + if (Schema) +MemPtr[0] = llvm::ConstantExpr::getPtrToInt( +getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy); + else +MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); + // Don't set the LSB of adj to 1 if pointer authentication for member kovdan01 wrote: Thanks @rjmccall for explanation! https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -1036,9 +1155,32 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // least significant bit of adj then makes exactly the same // discrimination as the least significant bit of ptr does for // Itanium. - MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - 2 * ThisAdjustment.getQuantity() + 1); + + // We cannot use the Itanium ABI's representation for virtual member + // function pointers under pointer authentication because it would + // require us to store both the virtual offset and the constant + // discriminator in the pointer, which would be immediately vulnerable + // to attack. Instead we introduce a thunk that does the virtual dispatch + // and store it as if it were a non-virtual member function. This means + // that virtual function pointers may not compare equal anymore, but + // fortunately they aren't required to by the standard, and we do make + // a best-effort attempt to re-use the thunk. + // + // To support interoperation with code in which pointer authentication + // is disabled, derefencing a member function pointer must still handle + // the virtual case, but it can use a discriminator which should never + // be valid. + const auto = + CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers; + if (Schema) +MemPtr[0] = llvm::ConstantExpr::getPtrToInt( +getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy); + else +MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); + // Don't set the LSB of adj to 1 if pointer authentication for member kovdan01 wrote: > @kovdan01 what do you mean here? the use of a thunk in general? I'm not sure that I correctly understand the logic behind not setting the LSB of adj to 1 with pauth for member function pointers enabled - see the comment in code. What's the purpose of this least significant bit value and how and where it's interpreted after being set here? https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -71,6 +71,15 @@ void has_ptrauth_vtable_pointer_type_discrimination() {} void no_ptrauth_vtable_pointer_type_discrimination() {} #endif +// This is always enabled when ptrauth_calls is enabled, on new enough clangs. kovdan01 wrote: > Weird mismerge I guess? Yep, I guess so https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][Driver] Support `pauthtest` ABI for AArch64 Linux triples (PR #97237)
https://github.com/kovdan01 closed https://github.com/llvm/llvm-project/pull/97237 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][clang][Driver] Add signed GOT flag (PR #96160)
kovdan01 wrote: > and lack of upstream runtime linker (rtld) support @MaskRay We actually have proof-of-concept support for musl https://github.com/access-softek/musl/commit/cbf25fbb2aaff125e232d5126dce7936f70a6453 (probably not ready for meaningful production usage though), and the signed GOT implementation which is submitted to upstream via multiple PRs (including this one) is actually working: I'm able to run binaries compiled and linked with signed GOT (and also `-z pac-plt` for signed PLT GOT, but it's a different story). So, as for me we can expose the flag right now. https://github.com/llvm/llvm-project/pull/96160 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][clang][Driver] Add signed GOT flag (PR #96160)
kovdan01 wrote: > Does this need a clang command line option at this point? Would it be > possible to live with a {{-mllvm}} option to turn on signed GOT? I would > expect signed GOT (or not) would be part of a higher-level signing schema and > not toggled at a low-level via clang. > > I know that there are existing command-line options for other signing schema > affecting options, but I'm not sure if we want to add more to them. @smithp35 Theoretically, we can use `-mllvm` and it was actually used for some time during downstream implementation and testing. I agree that a ton of `-fptrauth-*` flags is pretty annoying (and there was already a discussion in this PR which I've transformed into an issue #97320). However, as you correctly mentioned, we already have other similar flags and they are also not intended to be used manually and, instead, should be a part of high-level signing schema. As for me, it's better to keep things consistent at each moment - if we use clang driver flags, we use them everywhere, and if we want to refactor that and move to `-mllvm`, we want to do that for all the ptrauth flags as well. So, if it's not a very huge concern right now, I'd prefer to introduce `-fptrauth-elf-got` flag in this PR and, after further discussion, probably refactor all the flags logic in subsequent PRs (either move to comma-separeted flags as discussed above or use `-mllvm` or, maybe, we'll find other ways to enhance this - it's still needs to be discussed). https://github.com/llvm/llvm-project/pull/96160 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -0,0 +1,35 @@ +; This file contains the new semantic of the branch-target-enforcement, sign-return-address. +; Used for test mixing a mixed link case and also verify the import too in llc. + +; RUN: llc %s -o - | FileCheck %s + +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +define dso_local void @bar() #0 { +entry: + ret void +} +; CHECK-LABEL: bar: +; CHECK-NOT: hint +; CHECK-NOT: bti +; CHECK: ret + +define dso_local void @baz() #1 { +entry: + ret void +} + +; CHECK-LABEL: baz: +; CHECK: hint +; CHECK: ret + +attributes #0 = { noinline nounwind optnone uwtable } +attributes #1 = { noinline nounwind optnone uwtable "branch-target-enforcement" } + +!llvm.module.flags = !{!0, !1, !2, !3} + +!0 = !{i32 8, !"branch-target-enforcement", i32 2} kovdan01 wrote: In CodeGenModule.cpp, you have the following comment: > 2 now means function attributes already set for all functions in this module Here, "branch-target-enforcement" is only set for baz and not for bar. Is this intended? https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -0,0 +1,86 @@ +;; Test verifies inlining happens cross module when module flags are upgraded. +;; `foo` and `main` are both old semantic while bar is the new semantic. +;; Regression test for #82763 + +; RUN: split-file %s %t +; RUN: opt -module-summary %t/foo.s -o %t/foo.o +; RUN: opt -module-summary %t/bar.s -o %t/bar.o +; RUN: opt -module-summary %t/main.s -o %t/main.o +; RUN: llvm-lto2 run %t/main.o %t/foo.o %t/bar.o -save-temps \ +; RUN: -o %t/t.exe \ +; RUN: -r=%t/foo.o,foo,plx \ +; RUN: -r=%t/bar.o,bar,plx \ +; RUN: -r=%t/main.o,foo,l \ +; RUN: -r=%t/main.o,bar,l \ +; RUN: -r=%t/main.o,main,plx 2>&1 +; RUN: llvm-dis %t/t.exe.1.4.opt.bc -o - | FileCheck %s + +; CHECK: define dso_local noundef i32 @main() local_unnamed_addr #0 { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32 35 +; CHECK-NEXT: } + +; CHECK: attributes #0 = { {{.*}}"branch-target-enforcement" "sign-return-address"="all" "sign-return-address-key"="b_key" } + +; CHECK: !llvm.module.flags = !{!0, !1, !2, !3} + +; CHECK: !0 = !{i32 8, !"branch-target-enforcement", i32 2} +; CHECK: !1 = !{i32 8, !"sign-return-address", i32 2} +; CHECK: !2 = !{i32 8, !"sign-return-address-all", i32 2} +; CHECK: !3 = !{i32 8, !"sign-return-address-with-bkey", i32 2} + + +;--- foo.s kovdan01 wrote: Nit: maybe foo.ll? Also applies below https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -0,0 +1,35 @@ +; This file contains the new semantic of the branch-target-enforcement, sign-return-address. kovdan01 wrote: Nit: in llvm/test/Bitcode/upgrade-branch-protection.ll, you use ';;' for actual comments and ';' for special RUN and CHECK lines. New tests seem to often use ';;' for actual comments, so it's better to use this convention here as well IMHO. Also applies to other newly introduced tests. https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -0,0 +1,35 @@ +; This file contains the new semantic of the branch-target-enforcement, sign-return-address. +; Used for test mixing a mixed link case and also verify the import too in llc. + +; RUN: llc %s -o - | FileCheck %s kovdan01 wrote: I suppose it might be worth to add `-mattr=+pauth -mattr=+bti` to have actual pac/bti instruction in llc output rather than hint ones. Alternatively, you can leave current RUN line and add a new one. Also applies to other test files. https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -5278,6 +5278,106 @@ void llvm::UpgradeFunctionAttributes(Function ) { } } +// Check if the module attribute is present and set to one. +static bool isModuleAttributeOne(Module , const StringRef ) { + const auto *Attr = + mdconst::extract_or_null(M.getModuleFlag(ModAttr)); + return Attr && Attr->isOne(); +} + +// Check if the module attribute is present and set to two. +static bool isModuleAttributeTwo(Module , const StringRef ) { + const auto *Attr = + mdconst::extract_or_null(M.getModuleFlag(ModAttr)); + return Attr && Attr->getZExtValue() == 2; +} + +// Check if the function attribute is not present and set it. +static void SetFunctionAttrIfNotSet(Function , StringRef FnAttrName, +StringRef Value) { + if (!F.hasFnAttribute(FnAttrName)) +F.addFnAttr(FnAttrName, Value); +} + +// Check if the function attribute is not present and set it if needed. +// If the attribute is "false" then removes it. +// If the attribute is "true" resets it to a valueless attribute. +static void ConvertFunctionAttr(Function , bool Set, StringRef FnAttrName) { + if (!F.hasFnAttribute(FnAttrName)) { +if (Set) + F.addFnAttr(FnAttrName); + } else { +auto A = F.getFnAttribute(FnAttrName); +if ("false" == A.getValueAsString()) + F.removeFnAttr(FnAttrName); +else if ("true" == A.getValueAsString()) { + F.removeFnAttr(FnAttrName); + F.addFnAttr(FnAttrName); +} + } +} + +void llvm::CopyModuleAttrToFunctions(Module ) { + Triple T(M.getTargetTriple()); + if (!T.isThumb() && !T.isARM() && !T.isAArch64()) +return; + + if (isModuleAttributeTwo(M, "branch-target-enforcement")) +return; + if (isModuleAttributeTwo(M, "branch-protection-pauth-lr")) +return; + if (isModuleAttributeTwo(M, "guarded-control-stack")) +return; + if (isModuleAttributeTwo(M, "sign-return-address")) +return; + + bool BTE = isModuleAttributeOne(M, "branch-target-enforcement"); + bool BPPLR = isModuleAttributeOne(M, "branch-protection-pauth-lr"); + bool GCS = isModuleAttributeOne(M, "guarded-control-stack"); + bool SRA = isModuleAttributeOne(M, "sign-return-address"); + + StringRef SignTypeValue = "non-leaf"; + if (SRA && isModuleAttributeOne(M, "sign-return-address-all")) +SignTypeValue = "all"; + + StringRef SignKeyValue = "a_key"; kovdan01 wrote: Is there a test case for "a_key" value of "sign-return-address-key" function attribute? https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -5278,6 +5278,106 @@ void llvm::UpgradeFunctionAttributes(Function ) { } } +// Check if the module attribute is present and set to one. +static bool isModuleAttributeOne(Module , const StringRef ) { + const auto *Attr = + mdconst::extract_or_null(M.getModuleFlag(ModAttr)); + return Attr && Attr->isOne(); +} + +// Check if the module attribute is present and set to two. +static bool isModuleAttributeTwo(Module , const StringRef ) { + const auto *Attr = + mdconst::extract_or_null(M.getModuleFlag(ModAttr)); + return Attr && Attr->getZExtValue() == 2; +} + +// Check if the function attribute is not present and set it. +static void SetFunctionAttrIfNotSet(Function , StringRef FnAttrName, +StringRef Value) { + if (!F.hasFnAttribute(FnAttrName)) +F.addFnAttr(FnAttrName, Value); +} + +// Check if the function attribute is not present and set it if needed. +// If the attribute is "false" then removes it. +// If the attribute is "true" resets it to a valueless attribute. +static void ConvertFunctionAttr(Function , bool Set, StringRef FnAttrName) { + if (!F.hasFnAttribute(FnAttrName)) { +if (Set) + F.addFnAttr(FnAttrName); + } else { +auto A = F.getFnAttribute(FnAttrName); +if ("false" == A.getValueAsString()) + F.removeFnAttr(FnAttrName); +else if ("true" == A.getValueAsString()) { + F.removeFnAttr(FnAttrName); + F.addFnAttr(FnAttrName); +} + } +} + +void llvm::CopyModuleAttrToFunctions(Module ) { + Triple T(M.getTargetTriple()); + if (!T.isThumb() && !T.isARM() && !T.isAArch64()) +return; + + if (isModuleAttributeTwo(M, "branch-target-enforcement")) +return; + if (isModuleAttributeTwo(M, "branch-protection-pauth-lr")) +return; + if (isModuleAttributeTwo(M, "guarded-control-stack")) +return; + if (isModuleAttributeTwo(M, "sign-return-address")) +return; + + bool BTE = isModuleAttributeOne(M, "branch-target-enforcement"); + bool BPPLR = isModuleAttributeOne(M, "branch-protection-pauth-lr"); + bool GCS = isModuleAttributeOne(M, "guarded-control-stack"); + bool SRA = isModuleAttributeOne(M, "sign-return-address"); + + StringRef SignTypeValue = "non-leaf"; kovdan01 wrote: Is there a test case for "non-leaf" value of "sign-return-address" function attribute? https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -0,0 +1,35 @@ +; This file contains the new semantic of the branch-target-enforcement, sign-return-address. +; Used for test mixing a mixed link case and also verify the import too in llc. + +; RUN: llc %s -o - | FileCheck %s + +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +define dso_local void @bar() #0 { +entry: + ret void +} +; CHECK-LABEL: bar: kovdan01 wrote: Isn't bar intended to have signed return address since we have `!2 = !{i32 8, !"sign-return-address-all", i32 2}` module flag? The assembly output is just `ret` which looks incorrect. Please let me know if I miss smth https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM][AArch64] BTI, GCS, PAC Module flag update. (PR #86212)
@@ -89,6 +89,9 @@ namespace llvm { /// info. Return true if module is modified. bool UpgradeDebugInfo(Module ); + /// Copies module attributes to the functions in the module. + void CopyModuleAttrToFunctions(Module ); kovdan01 wrote: Nit: it's probably worth having a more detailed comment here. For example, to explicitly say that this function will only have effect on thumb, arm and aarch64 (on other architectures, it just returns at the very beginning) and list attributes which are taken into account. https://github.com/llvm/llvm-project/pull/86212 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [llvm] [PAC][AArch64] Support init/fini array signing (PR #96478)
kovdan01 wrote: Ping: would be glad to see feedback on the changes from those who are interested. https://github.com/llvm/llvm-project/pull/96478 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][clang][Driver] Add signed GOT flag (PR #96160)
kovdan01 wrote: Ping: would be glad to see feedback on the changes from those who are interested. Tagging @MaskRay @smithp35 https://github.com/llvm/llvm-project/pull/96160 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/99726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)
@@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -DENABLE_TID=0 -I%S -std=c++11 -triple=arm64e-apple-darwin \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NODISC + +// RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=arm64e-apple-darwin \ +// RUN: -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -fptrauth-type-info-vtable-pointer-discrimination \ +// RUN: %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC + +// copied from typeinfo +namespace std { + +#if __has_cpp_attribute(clang::ptrauth_vtable_pointer) +# if __has_feature(ptrauth_type_info_vtable_pointer_discrimination) +#define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ + [[clang::ptrauth_vtable_pointer(process_independent, address_discrimination, type_discrimination)]] +# else +#define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \ + [[clang::ptrauth_vtable_pointer(process_independent, no_address_discrimination, no_extra_discrimination)]] +# endif +#else +# define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH +#endif + + class _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info + { +type_info& operator=(const type_info&); +type_info(const type_info&); + + protected: + explicit type_info(const char* __n); + + public: + virtual ~type_info(); + + virtual void test_method(); + }; +} kovdan01 wrote: ```suggestion } // namespace std ``` https://github.com/llvm/llvm-project/pull/99726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)
https://github.com/kovdan01 approved this pull request. LGTM, thanks! https://github.com/llvm/llvm-project/pull/99726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/99726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -365,6 +365,40 @@ llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD, return getFunctionPointer(getRawFunctionPointer(GD, Ty), FuncType); } +CGPointerAuthInfo CodeGenModule::getMemberFunctionPointerAuthInfo(QualType FT) { + assert(FT->getAs() && "MemberPointerType expected"); + auto = getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers; kovdan01 wrote: Nit ```suggestion const auto = getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers; ``` https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -0,0 +1,433 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -o - %s | FileCheck -check-prefixes=CHECK,NODEBUG %s +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -debug-info-kind=limited -o - %s | FileCheck -check-prefixes=CHECK %s +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 1 -o - %s | FileCheck %s -check-prefix=STACK-PROT +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 2 -o - %s | FileCheck %s -check-prefix=STACK-PROT +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 3 -o - %s | FileCheck %s -check-prefix=STACK-PROT + + +// CHECK: @gmethod0 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1:35591]]) to i64), i64 0 }, align 8 kovdan01 wrote: Nit: it's probably worth to re-order C++ sources and/or CHECK lines in a way that CHECK lines are close to corresponding source code lines. For example, `gmethod*` are defined in the next "code section" (while it's possible to define them here), but tested here. It looks like that we can't achive such "test locality" for all the definitions, but some enhancements seem possible. However, such change might not be very trivial, and I'm OK with postponing it to the next tests enhancements patch - I'll submit a one adding checks against ELF triples anyway. https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -3417,11 +3417,13 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const { if (T->isFunctionPointerType() || T->isFunctionReferenceType()) T = T->getPointeeType(); - if (T->isFunctionType()) + if (T->isFunctionType()) { encodeTypeForFunctionPointerAuth(*this, Out, T); - else -llvm_unreachable( -"type discrimination of non-function type not implemented yet"); + } else { kovdan01 wrote: What can go here except member functions? Can we add assertions or smth checking a closed list of allowed type kinds here, or every type can potentially go here? Feel free to ignore. https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -853,6 +877,25 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress( "memptr.offset"); } +// See if it's possible to return a constant signed pointer. +static llvm::Constant *pointerAuthResignConstant( +llvm::Value *Ptr, const CGPointerAuthInfo , +const CGPointerAuthInfo , CodeGenModule ) { + auto *CPA = dyn_cast(Ptr); kovdan01 wrote: Nit ```suggestion const auto *CPA = dyn_cast(Ptr); ``` https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -1036,9 +1155,32 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // least significant bit of adj then makes exactly the same // discrimination as the least significant bit of ptr does for // Itanium. - MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - 2 * ThisAdjustment.getQuantity() + 1); + + // We cannot use the Itanium ABI's representation for virtual member + // function pointers under pointer authentication because it would + // require us to store both the virtual offset and the constant + // discriminator in the pointer, which would be immediately vulnerable kovdan01 wrote: > which would be immediately vulnerable to attack Nit: it's probably worth adding a bit more explanation for future code readers who are not deeply integrated into pauth context. Feel free to ignore. https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -1036,9 +1155,32 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // least significant bit of adj then makes exactly the same // discrimination as the least significant bit of ptr does for // Itanium. - MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - 2 * ThisAdjustment.getQuantity() + 1); + + // We cannot use the Itanium ABI's representation for virtual member + // function pointers under pointer authentication because it would + // require us to store both the virtual offset and the constant + // discriminator in the pointer, which would be immediately vulnerable + // to attack. Instead we introduce a thunk that does the virtual dispatch + // and store it as if it were a non-virtual member function. This means + // that virtual function pointers may not compare equal anymore, but + // fortunately they aren't required to by the standard, and we do make + // a best-effort attempt to re-use the thunk. + // + // To support interoperation with code in which pointer authentication + // is disabled, derefencing a member function pointer must still handle + // the virtual case, but it can use a discriminator which should never + // be valid. + const auto = + CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers; + if (Schema) +MemPtr[0] = llvm::ConstantExpr::getPtrToInt( +getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy); + else +MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset); + // Don't set the LSB of adj to 1 if pointer authentication for member kovdan01 wrote: Could you please explain the rationale for such a solution? It's probably worth adding more detailed comments here and in other places where the LSB of adj value is significant. https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -5877,119 +5882,130 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo , CallArgs.freeArgumentMemory(*this); // Extract the return value. - RValue Ret = [&] { -switch (RetAI.getKind()) { -case ABIArgInfo::CoerceAndExpand: { - auto coercionType = RetAI.getCoerceAndExpandType(); - - Address addr = SRetPtr.withElementType(coercionType); - - assert(CI->getType() == RetAI.getUnpaddedCoerceAndExpandType()); - bool requiresExtract = isa(CI->getType()); + RValue Ret; - unsigned unpaddedIndex = 0; - for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) { -llvm::Type *eltType = coercionType->getElementType(i); -if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue; -Address eltAddr = Builder.CreateStructGEP(addr, i); -llvm::Value *elt = CI; -if (requiresExtract) - elt = Builder.CreateExtractValue(elt, unpaddedIndex++); -else - assert(unpaddedIndex == 0); -Builder.CreateStore(elt, eltAddr); + // If the current function is a virtual function pointer thunk, avoid copying + // the return value of the musttail call to a temporary. + if (IsVirtualFunctionPointerThunk) kovdan01 wrote: Nit: it's probably worth adding braces since else branch is long (while still being one statement). https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
@@ -71,6 +71,15 @@ void has_ptrauth_vtable_pointer_type_discrimination() {} void no_ptrauth_vtable_pointer_type_discrimination() {} #endif +// This is always enabled when ptrauth_calls is enabled, on new enough clangs. kovdan01 wrote: We already have this tested above (see lines 41..48), so this can be deleted. https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement authentication for C++ member function pointers (PR #99576)
https://github.com/kovdan01 commented: LGTM with minor non-blocking nits. However, I'd prefer to wait for @asl 's review before merging the PR. I'm OK with merging whenever @asl is. https://github.com/llvm/llvm-project/pull/99576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Incorrect codegen for constant global init with polymorphic MI (PR #99741)
https://github.com/kovdan01 approved this pull request. https://github.com/llvm/llvm-project/pull/99741 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [llvm] [PAC][AArch64] Support init/fini array signing (PR #96478)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96478 >From 5399237a71c0ccd872821034d83ea2c3a04bed3f Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Fri, 21 Jun 2024 12:32:51 +0300 Subject: [PATCH 1/4] [PAC][AArch64] Support init/fini array signing If both `-fptrauth-init-fini` and `-fptrauth-calls` are passed, sign function pointers in `llvm.global_ctors` and `llvm.global_dtors` with constant discriminator 0xD9D4 (`ptrauth_string_discriminator("init_fini")`). Additionally, if `-fptrauth-init-fini-address-discrimination` is passed, address discrimination is used for signing (otherwise, just constant discriminator is used). --- clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Basic/LangOptions.def | 1 + .../include/clang/Basic/PointerAuthOptions.h | 7 ++ clang/include/clang/Driver/Options.td | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 63 +-- clang/lib/Driver/ToolChains/Clang.cpp | 3 + clang/lib/Frontend/CompilerInvocation.cpp | 9 +++ clang/lib/Headers/ptrauth.h | 8 ++ clang/test/CodeGen/aarch64-elf-pauthabi.c | 12 ++- clang/test/CodeGen/ptrauth-init-fini.c| 39 ++ clang/test/Driver/aarch64-ptrauth.c | 6 +- clang/test/Preprocessor/ptrauth_feature.c | 52 + compiler-rt/lib/builtins/crtbegin.c | 16 llvm/include/llvm/BinaryFormat/ELF.h | 3 +- .../AArch64/note-gnu-property-elf-pauthabi.ll | 2 +- .../test/CodeGen/AArch64/ptrauth-init-fini.ll | 77 +++ .../ELF/AArch64/aarch64-feature-pauth.s | 18 ++--- llvm/tools/llvm-readobj/ELFDumper.cpp | 4 +- 18 files changed, 268 insertions(+), 54 deletions(-) create mode 100644 clang/test/CodeGen/ptrauth-init-fini.c create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-init-fini.ll diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 53f410d3cb4bd..5dca40b261655 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination) FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls) FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini) +FEATURE(ptrauth_init_fini_address_discrimination, LangOpts.PointerAuthInitFiniAddressDiscrimination) EXTENSION(swiftcc, PP.getTargetInfo().checkCallingConvention(CC_Swift) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6dd6b5614f44c..2de854731 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -168,6 +168,7 @@ LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps") LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers") LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers") LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays") +LANGOPT(PointerAuthInitFiniAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated function pointers in init/fini arrays") LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") LANGOPT(ExperimentalLateParseAttributes, 1, 0, "experimental late parsing of attributes") diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index aaad4a2b2b5ae..9e2b64111e461 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -23,6 +23,10 @@ namespace clang { +/// Constant discriminator to be used with function pointers in .init_array and +/// .fini_array. The value is ptrauth_string_discriminator("init_fini") +constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4; + constexpr unsigned PointerAuthKeyNone = -1; class PointerAuthSchema { @@ -150,6 +154,9 @@ class PointerAuthSchema { struct PointerAuthOptions { /// The ABI for C function pointers. PointerAuthSchema FunctionPointers; + + /// The ABI for function addresses in .init_array and .fini_array + PointerAuthSchema InitFiniPointers; }; } // end namespace clang diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c529cc9506667..5b8d4139d975b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4228,6 +4228,7 @@ defm ptrauth_vtable_pointer_address_discrimination : defm ptrauth_vtable_pointer_type_discrimination :
[clang] [compiler-rt] [llvm] [PAC][AArch64] Support init/fini array signing (PR #96478)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96478 >From 5399237a71c0ccd872821034d83ea2c3a04bed3f Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Fri, 21 Jun 2024 12:32:51 +0300 Subject: [PATCH 1/4] [PAC][AArch64] Support init/fini array signing If both `-fptrauth-init-fini` and `-fptrauth-calls` are passed, sign function pointers in `llvm.global_ctors` and `llvm.global_dtors` with constant discriminator 0xD9D4 (`ptrauth_string_discriminator("init_fini")`). Additionally, if `-fptrauth-init-fini-address-discrimination` is passed, address discrimination is used for signing (otherwise, just constant discriminator is used). --- clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Basic/LangOptions.def | 1 + .../include/clang/Basic/PointerAuthOptions.h | 7 ++ clang/include/clang/Driver/Options.td | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 63 +-- clang/lib/Driver/ToolChains/Clang.cpp | 3 + clang/lib/Frontend/CompilerInvocation.cpp | 9 +++ clang/lib/Headers/ptrauth.h | 8 ++ clang/test/CodeGen/aarch64-elf-pauthabi.c | 12 ++- clang/test/CodeGen/ptrauth-init-fini.c| 39 ++ clang/test/Driver/aarch64-ptrauth.c | 6 +- clang/test/Preprocessor/ptrauth_feature.c | 52 + compiler-rt/lib/builtins/crtbegin.c | 16 llvm/include/llvm/BinaryFormat/ELF.h | 3 +- .../AArch64/note-gnu-property-elf-pauthabi.ll | 2 +- .../test/CodeGen/AArch64/ptrauth-init-fini.ll | 77 +++ .../ELF/AArch64/aarch64-feature-pauth.s | 18 ++--- llvm/tools/llvm-readobj/ELFDumper.cpp | 4 +- 18 files changed, 268 insertions(+), 54 deletions(-) create mode 100644 clang/test/CodeGen/ptrauth-init-fini.c create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-init-fini.ll diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 53f410d3cb4bd..5dca40b261655 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -110,6 +110,7 @@ FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtr FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination) FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls) FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini) +FEATURE(ptrauth_init_fini_address_discrimination, LangOpts.PointerAuthInitFiniAddressDiscrimination) EXTENSION(swiftcc, PP.getTargetInfo().checkCallingConvention(CC_Swift) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6dd6b5614f44c..2de854731 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -168,6 +168,7 @@ LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps") LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers") LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers") LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays") +LANGOPT(PointerAuthInitFiniAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated function pointers in init/fini arrays") LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") LANGOPT(ExperimentalLateParseAttributes, 1, 0, "experimental late parsing of attributes") diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index aaad4a2b2b5ae..9e2b64111e461 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -23,6 +23,10 @@ namespace clang { +/// Constant discriminator to be used with function pointers in .init_array and +/// .fini_array. The value is ptrauth_string_discriminator("init_fini") +constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4; + constexpr unsigned PointerAuthKeyNone = -1; class PointerAuthSchema { @@ -150,6 +154,9 @@ class PointerAuthSchema { struct PointerAuthOptions { /// The ABI for C function pointers. PointerAuthSchema FunctionPointers; + + /// The ABI for function addresses in .init_array and .fini_array + PointerAuthSchema InitFiniPointers; }; } // end namespace clang diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c529cc9506667..5b8d4139d975b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4228,6 +4228,7 @@ defm ptrauth_vtable_pointer_address_discrimination : defm ptrauth_vtable_pointer_type_discrimination :
[clang] [test][PAC][clang] Add missing tests against linux triples (PR #99482)
https://github.com/kovdan01 closed https://github.com/llvm/llvm-project/pull/99482 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Authenticate function pointers in UBSan type checks (PR #99590)
https://github.com/kovdan01 approved this pull request. https://github.com/llvm/llvm-project/pull/99590 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Fix a crash when signing a pointer to a function with an incomplete enum parameter (PR #99595)
https://github.com/kovdan01 approved this pull request. https://github.com/llvm/llvm-project/pull/99595 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [test][PAC][clang] Add missing tests against linux triples (PR #99482)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/99482 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [test][PAC][clang] Add missing tests against linux triples (PR #99482)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/99482 >From f2709fc1530537974a7fe8036f28558b9fb30bb5 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Thu, 18 Jul 2024 15:26:30 +0300 Subject: [PATCH 1/2] [test][PAC][clang] Add missing tests against linux triples --- .../ptrauth-function-type-discriminator.c | 33 ++--- clang/test/CodeGen/ptrauth-ubsan-vptr.cpp | 3 + ...trauth-explicit-vtable-pointer-control.cpp | 62 ++--- clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp | 14 ++-- .../CodeGenCXX/ptrauth-static-destructors.cpp | 15 ++-- clang/test/CodeGenCXX/ptrauth-throw.cpp | 15 ++-- clang/test/CodeGenCXX/ptrauth-thunks.cpp | 3 +- .../CodeGenCXX/ptrauth-virtual-function.cpp | 69 +++ ...rauth-vtable-virtual-inheritance-thunk.cpp | 20 -- clang/test/CodeGenCXX/ubsan-vtable-checks.cpp | 4 +- ...irtual-member-function-return-arg-type.cpp | 3 +- ...table_pointer_authentication_attribute.cpp | 3 +- 12 files changed, 156 insertions(+), 88 deletions(-) diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c b/clang/test/CodeGen/ptrauth-function-type-discriminator.c index 5dea48fe5915b..58717015adb6c 100644 --- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c +++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c @@ -1,7 +1,18 @@ -// RUN: %clang_cc1 %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKC -// RUN: %clang_cc1 -xc++ %s -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics -disable-llvm-passes -emit-llvm -o- | FileCheck %s --check-prefix=CHECK -// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast -// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm -x ast -o - %t.ast | FileCheck -check-prefix=CHECK --check-prefix=CHECKC %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm %s -o- | FileCheck --check-prefixes=CHECK,CHECKC %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck --check-prefix=CHECK %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios-fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple arm64-apple-ios-fptrauth-calls -fptrauth-intrinsics \ +// RUN: -emit-llvm -x ast -o - %t.ast | FileCheck --check-prefixes=CHECK,CHECKC %s + +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm %s -o- | FileCheck --check-prefixes=CHECK,CHECKC %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck --check-prefix=CHECK %s +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast +// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \ +// RUN: -emit-llvm -x ast -o - %t.ast | FileCheck --check-prefixes=CHECK,CHECKC %s #ifdef __cplusplus extern "C" { @@ -47,14 +58,14 @@ void (*fptr3)(void) = __builtin_ptrauth_sign_constant(_function, 2, 26) // CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4) void (*fptr4)(void) = __builtin_ptrauth_sign_constant(_function, 2, __builtin_ptrauth_blend_discriminator(, 26)); -// CHECK-LABEL: define void @test_call() +// CHECK-LABEL: define{{.*}} void @test_call() void test_call() { // CHECK: [[T0:%.*]] = load ptr, ptr @fnptr, // CHECK-NEXT: call void [[T0]]() [ "ptrauth"(i32 0, i64 18983) ] fnptr(); } -// CHECK-LABEL: define ptr @test_function_pointer() +// CHECK-LABEL: define{{.*}} ptr @test_function_pointer() // CHECK: ret ptr ptrauth (ptr @external_function, i32 0, i64 18983) void (*test_function_pointer())(void) { return external_function; @@ -62,14 +73,14 @@ void (*test_function_pointer())(void) { struct InitiallyIncomplete; extern struct InitiallyIncomplete returns_initially_incomplete(void); -// CHECK-LABEL: define void @use_while_incomplete() +// CHECK-LABEL: define{{.*}} void @use_while_incomplete()
[clang] [test][PAC][clang] Add missing tests against linux triples (PR #99482)
kovdan01 wrote: Also tagging @ojhunt (GitHub doesn't let to add as a reviewer for some unknown reason) https://github.com/llvm/llvm-project/pull/99482 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [test][PAC][clang] Add missing tests against linux triples (PR #99482)
https://github.com/kovdan01 ready_for_review https://github.com/llvm/llvm-project/pull/99482 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][Driver] Support `pauthtest` ABI for AArch64 Linux triples (PR #97237)
@@ -1546,16 +1581,28 @@ static void CollectARMPACBTIOptions(const ToolChain , const ArgList , CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address=") + Scope)); - if (Scope != "none") + if (Scope != "none") { +if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address-key=") + Key)); - if (BranchProtectionPAuthLR) + } + if (BranchProtectionPAuthLR) { +if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back( Args.MakeArgString(Twine("-mbranch-protection-pauth-lr"))); + } if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); - if (GuardedControlStack) + if (GuardedControlStack) { kovdan01 wrote: Added a comment, thanks! See 4f3da9e51338aec21b8bfe8dd08598507edcea38 https://github.com/llvm/llvm-project/pull/97237 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][Driver] Support `pauthtest` ABI for AArch64 Linux triples (PR #97237)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/97237 >From 3b4b1b1739b810d758e68f30c48b648963cff740 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Mon, 1 Jul 2024 00:50:21 +0300 Subject: [PATCH 1/8] [PAC][Driver] Implement `-mbranch-protection=pauthabi` option Enable the following ptrauth flags when `pauthabi` is passed as branch protection: - `intrinsics`; - `calls`; - `returns`; - `auth-traps`; - `vtable-pointer-address-discrimination`; - `vtable-pointer-type-discrimination`; - `init-fini`. Co-authored-by: Anatoly Trosinenko --- clang/lib/Driver/ToolChains/Clang.cpp | 38 +++ clang/test/Driver/aarch64-ptrauth.c | 36 ++ .../llvm/TargetParser/ARMTargetParserCommon.h | 1 + .../TargetParser/ARMTargetParserCommon.cpp| 6 ++- 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 1b7cc82ea816e..4ed1ece22b7aa 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1484,6 +1484,39 @@ void AddUnalignedAccessWarning(ArgStringList ) { } } +static void handlePAuthABIOption(const ArgList , + ArgStringList , const Driver ) { + if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics, + options::OPT_fno_ptrauth_intrinsics)) +CC1Args.push_back("-fptrauth-intrinsics"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_calls, + options::OPT_fno_ptrauth_calls)) +CC1Args.push_back("-fptrauth-calls"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_returns, + options::OPT_fno_ptrauth_returns)) +CC1Args.push_back("-fptrauth-returns"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps, + options::OPT_fno_ptrauth_auth_traps)) +CC1Args.push_back("-fptrauth-auth-traps"); + + if (!DriverArgs.hasArg( + options::OPT_fptrauth_vtable_pointer_address_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_address_discrimination)) +CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination"); + + if (!DriverArgs.hasArg( + options::OPT_fptrauth_vtable_pointer_type_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_type_discrimination)) +CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini, + options::OPT_fno_ptrauth_init_fini)) +CC1Args.push_back("-fptrauth-init-fini"); +} + static void CollectARMPACBTIOptions(const ToolChain , const ArgList , ArgStringList , bool isAArch64) { const Arg *A = isAArch64 @@ -1537,11 +1570,16 @@ static void CollectARMPACBTIOptions(const ToolChain , const ArgList , if (!isAArch64 && PBP.Key == "b_key") D.Diag(diag::warn_unsupported_branch_protection) << "b-key" << A->getAsString(Args); +if (!isAArch64 && PBP.HasPauthABI) + D.Diag(diag::warn_unsupported_branch_protection) + << "pauthabi" << A->getAsString(Args); Scope = PBP.Scope; Key = PBP.Key; BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; IndirectBranches = PBP.BranchTargetEnforcement; GuardedControlStack = PBP.GuardedControlStack; +if (isAArch64 && PBP.HasPauthABI) + handlePAuthABIOption(Args, CmdArgs, D); } CmdArgs.push_back( diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index fa0125f4b22a9..dc63545a47a86 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -13,13 +13,33 @@ // RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL // ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini" +// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=PAUTHABI1 +// PAUTHABI1: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini" + +// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi -fno-ptrauth-intrinsics \ +// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \ +// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 +// PAUTHABI2-NOT: "-fptrauth-intrinsics" +// PAUTHABI2-NOT: "-fptrauth-calls" +// PAUTHABI2-NOT: "-fptrauth-returns" +// PAUTHABI2-NOT: "-fptrauth-auth-traps" +// PAUTHABI2-NOT:
[clang] [PAC] Implement function pointer re-signing (PR #98847)
https://github.com/kovdan01 approved this pull request. LGTM, thanks @ahatanak ! https://github.com/llvm/llvm-project/pull/98847 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Ensure pointers passed to runtime support functions are correctly signed (PR #98276)
https://github.com/kovdan01 approved this pull request. https://github.com/llvm/llvm-project/pull/98276 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][Driver] Support `pauthtest` ABI for AArch64 Linux triples (PR #97237)
@@ -324,6 +324,9 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple , case llvm::Triple::GNU: setABI("apcs-gnu"); break; +case llvm::Triple::PAuthTest: kovdan01 wrote: No, we do not need that, thanks for bringing attention to this. Deleted here and in `ARM::computeDefaultTargetABI`, see eae6f7c54145b19148a0ca7de639b4400db8fae9 https://github.com/llvm/llvm-project/pull/97237 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PAC][Driver] Support `pauthtest` ABI for AArch64 Linux triples (PR #97237)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/97237 >From 3b4b1b1739b810d758e68f30c48b648963cff740 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Mon, 1 Jul 2024 00:50:21 +0300 Subject: [PATCH 1/7] [PAC][Driver] Implement `-mbranch-protection=pauthabi` option Enable the following ptrauth flags when `pauthabi` is passed as branch protection: - `intrinsics`; - `calls`; - `returns`; - `auth-traps`; - `vtable-pointer-address-discrimination`; - `vtable-pointer-type-discrimination`; - `init-fini`. Co-authored-by: Anatoly Trosinenko --- clang/lib/Driver/ToolChains/Clang.cpp | 38 +++ clang/test/Driver/aarch64-ptrauth.c | 36 ++ .../llvm/TargetParser/ARMTargetParserCommon.h | 1 + .../TargetParser/ARMTargetParserCommon.cpp| 6 ++- 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 1b7cc82ea816e..4ed1ece22b7aa 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1484,6 +1484,39 @@ void AddUnalignedAccessWarning(ArgStringList ) { } } +static void handlePAuthABIOption(const ArgList , + ArgStringList , const Driver ) { + if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics, + options::OPT_fno_ptrauth_intrinsics)) +CC1Args.push_back("-fptrauth-intrinsics"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_calls, + options::OPT_fno_ptrauth_calls)) +CC1Args.push_back("-fptrauth-calls"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_returns, + options::OPT_fno_ptrauth_returns)) +CC1Args.push_back("-fptrauth-returns"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps, + options::OPT_fno_ptrauth_auth_traps)) +CC1Args.push_back("-fptrauth-auth-traps"); + + if (!DriverArgs.hasArg( + options::OPT_fptrauth_vtable_pointer_address_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_address_discrimination)) +CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination"); + + if (!DriverArgs.hasArg( + options::OPT_fptrauth_vtable_pointer_type_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_type_discrimination)) +CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination"); + + if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini, + options::OPT_fno_ptrauth_init_fini)) +CC1Args.push_back("-fptrauth-init-fini"); +} + static void CollectARMPACBTIOptions(const ToolChain , const ArgList , ArgStringList , bool isAArch64) { const Arg *A = isAArch64 @@ -1537,11 +1570,16 @@ static void CollectARMPACBTIOptions(const ToolChain , const ArgList , if (!isAArch64 && PBP.Key == "b_key") D.Diag(diag::warn_unsupported_branch_protection) << "b-key" << A->getAsString(Args); +if (!isAArch64 && PBP.HasPauthABI) + D.Diag(diag::warn_unsupported_branch_protection) + << "pauthabi" << A->getAsString(Args); Scope = PBP.Scope; Key = PBP.Key; BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; IndirectBranches = PBP.BranchTargetEnforcement; GuardedControlStack = PBP.GuardedControlStack; +if (isAArch64 && PBP.HasPauthABI) + handlePAuthABIOption(Args, CmdArgs, D); } CmdArgs.push_back( diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index fa0125f4b22a9..dc63545a47a86 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -13,13 +13,33 @@ // RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL // ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini" +// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=PAUTHABI1 +// PAUTHABI1: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini" + +// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi -fno-ptrauth-intrinsics \ +// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \ +// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 +// PAUTHABI2-NOT: "-fptrauth-intrinsics" +// PAUTHABI2-NOT: "-fptrauth-calls" +// PAUTHABI2-NOT: "-fptrauth-returns" +// PAUTHABI2-NOT: "-fptrauth-auth-traps" +// PAUTHABI2-NOT:
[clang] [PAC] Implement function pointer re-signing (PR #98847)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/98847 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement function pointer re-signing (PR #98847)
https://github.com/kovdan01 commented: Mostly LGTM. There are several new pretty minor comments, but they can be addressed in a follor-up PR. The thing which is better to be addressed as a part of this PR is deleting three unneeded member functions from `CodeGenFunction`. IMHO there is no reason to ship this changes right now. https://github.com/llvm/llvm-project/pull/98847 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC] Implement function pointer re-signing (PR #98847)
@@ -351,3 +434,125 @@ CodeGenModule::getVTablePointerAuthInfo(CodeGenFunction *CGF, /* IsIsaPointer */ false, /* AuthenticatesNullValues */ false, Discriminator); } + +llvm::Value *CodeGenFunction::AuthPointerToPointerCast(llvm::Value *ResultPtr, + QualType SourceType, + QualType DestType) { + CGPointerAuthInfo CurAuthInfo, NewAuthInfo; + if (SourceType->isSignableType()) +CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType); + + if (DestType->isSignableType()) +NewAuthInfo = getPointerAuthInfoForType(CGM, DestType); + + if (!CurAuthInfo && !NewAuthInfo) +return ResultPtr; + + // If only one side of the cast is a function pointer, then we still need to + // resign to handle casts to/from opaque pointers. + if (!CurAuthInfo && DestType->isFunctionPointerType()) +CurAuthInfo = CGM.getFunctionPointerAuthInfo(SourceType); + + if (!NewAuthInfo && SourceType->isFunctionPointerType()) +NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType); + + return EmitPointerAuthResign(ResultPtr, DestType, CurAuthInfo, NewAuthInfo, + /*IsKnownNonNull=*/false); +} + +Address CodeGenFunction::AuthPointerToPointerCast(Address Ptr, + QualType SourceType, + QualType DestType) { + CGPointerAuthInfo CurAuthInfo, NewAuthInfo; + if (SourceType->isSignableType()) +CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType); + + if (DestType->isSignableType()) +NewAuthInfo = getPointerAuthInfoForType(CGM, DestType); + + if (!CurAuthInfo && !NewAuthInfo) +return Ptr; + + if (!CurAuthInfo && DestType->isFunctionPointerType()) { +// When casting a non-signed pointer to a function pointer, just set the +// auth info on Ptr to the assumed schema. The pointer will be resigned to +// the effective type when used. +Ptr.setPointerAuthInfo(CGM.getFunctionPointerAuthInfo(SourceType)); +return Ptr; + } + + if (!NewAuthInfo && SourceType->isFunctionPointerType()) { +NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType); +Ptr = Ptr.getResignedAddress(NewAuthInfo, *this); +Ptr.setPointerAuthInfo(CGPointerAuthInfo()); +return Ptr; + } + + return Ptr; +} + +Address CodeGenFunction::EmitPointerAuthSign(Address Addr, + QualType PointeeType) { + CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType); + llvm::Value *Ptr = EmitPointerAuthSign(Info, Addr.emitRawPointer(*this)); + return Address(Ptr, Addr.getElementType(), Addr.getAlignment()); +} + +Address CodeGenFunction::EmitPointerAuthAuth(Address Addr, + QualType PointeeType) { + CGPointerAuthInfo Info = getPointerAuthInfoForPointeeType(CGM, PointeeType); + llvm::Value *Ptr = EmitPointerAuthAuth(Info, Addr.emitRawPointer(*this)); + return Address(Ptr, Addr.getElementType(), Addr.getAlignment()); +} + +Address CodeGenFunction::getAsNaturalAddressOf(Address Addr, + QualType PointeeTy) { + CGPointerAuthInfo Info = + PointeeTy.isNull() ? CGPointerAuthInfo() + : CGM.getPointerAuthInfoForPointeeType(PointeeTy); + return Addr.getResignedAddress(Info, *this); +} + +Address Address::getResignedAddress(const CGPointerAuthInfo , +CodeGenFunction ) const { + assert(isValid() && "pointer isn't valid"); + CGPointerAuthInfo CurInfo = getPointerAuthInfo(); + llvm::Value *Val; + + // Nothing to do if neither the current or the new ptrauth info needs signing. + if (!CurInfo.isSigned() && !NewInfo.isSigned()) +return Address(getBasePointer(), getElementType(), getAlignment(), + isKnownNonNull()); + + assert(ElementType && "Effective type has to be set"); + + // If the current and the new ptrauth infos are the same and the offset is + // null, just cast the base pointer to the effective type. + if (CurInfo == NewInfo && !hasOffset()) +Val = getBasePointer(); + else { +assert(!Offset && "unexpected non-null offset"); +Val = CGF.EmitPointerAuthResign(getBasePointer(), QualType(), CurInfo, +NewInfo, isKnownNonNull()); + } + + Val = CGF.Builder.CreateBitCast(Val, getType()); + return Address(Val, getElementType(), getAlignment(), NewInfo, nullptr, + isKnownNonNull()); +} + +llvm::Value *LValue::getPointer(CodeGenFunction ) const { + assert(isSimple()); + return emitResignedPointer(getType(), CGF); kovdan01 wrote: I suppose it might be worth to have a "short-path" for non-signed pointers. Most code is compile w/o pauth, but we'll always have overhead of calling these pauth-related functions
[clang] [PAC] Implement function pointer re-signing (PR #98847)
@@ -3126,3 +3137,57 @@ CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo , return EmitPointerAuthCommon(*this, PointerAuth, Pointer, llvm::Intrinsic::ptrauth_auth); } + +llvm::Value *CodeGenFunction::EmitPointerAuthSign(QualType pointeeType, kovdan01 wrote: Just in case if I missed smth: why are some PAuth-related member functions of `CodeGenFunction` defined in CGPointerAuth.cpp, and some are defined here in CodeGenFunction.cpp? Could you please describe the logic behind this choice? https://github.com/llvm/llvm-project/pull/98847 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits