[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-28 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

> One more overall style comment which might probably require an additional PR: 
> sometimes identifiers use `PtrAuth`, sometimes `Ptrauth`. Is this 
> intentional? If not, I suggest to use the same case style - it would keep 
> things consistent and allow for case-sensitive search.

Yeah, it's hard to avoid needing case-insensitive search because of the 
irreconcilable capitalization rules between e.g., enums generated from 
all-lowercase tablegen, opcode namespaces with a strong all-uppercase 
tradition, variable/function naming conventions, etc.

In general I try to standardize on "ptrauth" regardless of case, and would 
rather get rid of "pauth" or "pac" first, because they're just objectively 
worse names.  We can indeed pick a consistent ptrauth when the dust settles.

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-28 Thread Ahmed Bougacha via llvm-branch-commits


@@ -817,10 +817,44 @@ bool AArch64ExpandPseudo::expandCALL_RVMARKER(
   MachineInstr &MI = *MBBI;
   MachineOperand &RVTarget = MI.getOperand(0);
   assert(RVTarget.isGlobal() && "invalid operand for attached call");
-  MachineInstr *OriginalCall =
-  createCall(MBB, MBBI, TII, MI.getOperand(1),
- // Regmask starts after the RV and call targets.
- /*RegMaskStartIdx=*/2);
+
+  MachineInstr *OriginalCall = nullptr;
+
+  if (MI.getOpcode() == AArch64::BLRA_RVMARKER) {
+// Pointer auth call.
+MachineOperand &Key = MI.getOperand(2);
+assert((Key.getImm() == 0 || Key.getImm() == 1) &&
+   "invalid key for ptrauth call");
+MachineOperand &IntDisc = MI.getOperand(3);
+MachineOperand &AddrDisc = MI.getOperand(4);
+
+OriginalCall = BuildMI(MBB, MBBI, MI.getDebugLoc(), 
TII->get(AArch64::BLRA))
+   .getInstr();
+OriginalCall->addOperand(MI.getOperand(1));
+OriginalCall->addOperand(Key);
+OriginalCall->addOperand(IntDisc);
+OriginalCall->addOperand(AddrDisc);
+
+unsigned RegMaskStartIdx = 5;
+// Skip register arguments. Those are added during ISel, but are not
+// needed for the concrete branch.
+while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
+  auto MOP = MI.getOperand(RegMaskStartIdx);

ahmedbougacha wrote:

The helper indeed shouldn't use plain auto, but we can reuse that helper with a 
bit of generalization.  I'm pretty sure this code predates it ;)

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-28 Thread Ahmed Bougacha via llvm-branch-commits


@@ -1769,6 +1775,41 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const 
MachineInstr *MI) {
 OutStreamer->emitLabel(EndSym);
 }
 
+void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) {
+  unsigned InstsEmitted = 0;
+

ahmedbougacha wrote:

It's to try to isolate the InstsEmitted prologue/epilogue from the real logic.  
Ideally that could be some sort of RAII helper, which we could probably use in 
all the expanders, but for now, ad-hoc it is, without the newline I suppose

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-05-30 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha created 
https://github.com/llvm/llvm-project/pull/93902

Based on the SipHash reference implementation:
  https://github.com/veorq/SipHash
which has very graciously been licensed under our llvm license (Apache-2.0 WITH 
LLVM-exception) by Jean-Philippe Aumasson.

This lightly modifies it to fit into libSupport, and wraps it for the two main 
interfaces we're interested in (16/64-bit).

This intentionally doesn't expose a raw interface beyond that to encourage 
others to carefully consider their use.
Beyond that, I'm ambivalent about naming this ptrauth, siphash, stablehash, or 
which combination of the three (which is what this patch does for the symbols, 
but keeping SipHash for the file, for other potential usage.) 

The exact algorithm is the little-endian interpretation of the non-doubled 
(i.e. 64-bit) result of applying a SipHash-2-4 using a specific key value which 
can be found in the source.

By "stable" we mean that the result of this hash algorithm will the same across 
different compiler versions and target platforms.

The 16-bit variant is used extensively for the AArch64 ptrauth ABI, because 
AArch64 can efficiently load a 16-bit immediate into the high bits of a 
register without disturbing the remainder of the value, which serves as a nice 
blend operation.

16 bits is also sufficiently compact to not inflate a loader relocation. We 
disallow zero to guarantee a different discriminator from the places in the ABI 
that use a constant zero.

>From 42cb73fecf1033aefbe824149f3d8a5352bb2103 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:05:31 -0700
Subject: [PATCH] [Support] Add SipHash-based 16/64-bit ptrauth stable hash.

Based on the SipHash reference implementation:
  https://github.com/veorq/SipHash
which has very graciously been licensed under our llvm license
(Apache-2.0 WITH LLVM-exception) by Jean-Philippe Aumasson.

This lightly modifies it to fit into libSupport, and wraps it for the
two main interfaces we're interested in (16/64-bit).

This intentionally doesn't expose a raw interface beyond that to
encourage others to carefully consider their use.

The exact algorithm is the little-endian interpretation of the
non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
a specific key value which can be found in the source.

By "stable" we mean that the result of this hash algorithm will the same
across different compiler versions and target platforms.

The 16-bit variant is used extensively for the AArch64 ptrauth ABI,
because AArch64 can efficiently load a 16-bit immediate into the high
bits of a register without disturbing the remainder of the value, which
serves as a nice blend operation.

16 bits is also sufficiently compact to not inflate a loader relocation.
We disallow zero to guarantee a different discriminator from the places
in the ABI that use a constant zero.

Co-Authored-By: John McCall 
---
 llvm/include/llvm/Support/SipHash.h|  47 +++
 llvm/lib/Support/CMakeLists.txt|   1 +
 llvm/lib/Support/SipHash.cpp   | 174 +
 llvm/unittests/Support/CMakeLists.txt  |   1 +
 llvm/unittests/Support/SipHashTest.cpp |  43 ++
 5 files changed, 266 insertions(+)
 create mode 100644 llvm/include/llvm/Support/SipHash.h
 create mode 100644 llvm/lib/Support/SipHash.cpp
 create mode 100644 llvm/unittests/Support/SipHashTest.cpp

diff --git a/llvm/include/llvm/Support/SipHash.h 
b/llvm/include/llvm/Support/SipHash.h
new file mode 100644
index 0..fcc29c00da185
--- /dev/null
+++ b/llvm/include/llvm/Support/SipHash.h
@@ -0,0 +1,47 @@
+//===--- SipHash.h - An ABI-stable string SipHash ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// A family of ABI-stable string hash algorithms based on SipHash, currently
+// used to compute ptrauth discriminators.
+//
+//===--===//
+
+#ifndef LLVM_SUPPORT_SIPHASH_H
+#define LLVM_SUPPORT_SIPHASH_H
+
+#include 
+
+namespace llvm {
+class StringRef;
+
+/// Compute a stable 64-bit hash of the given string.
+///
+/// The exact algorithm is the little-endian interpretation of the
+/// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
+/// a specific key value which can be found in the source.
+///
+/// By "stable" we mean that the result of this hash algorithm will
+/// the same across different compiler versions and target platforms.
+uint64_t getPointerAuthStableSipHash64(StringRef S);
+
+/// Compute a stable non-zero 16-bit hash of the given string.
+///
+/// This computes the full getPointerAuthStableSipHash64, but additionally
+/// truncates it down to a non-zero 16-bit val

[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)

2024-05-30 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha created 
https://github.com/llvm/llvm-project/pull/93903

This exposes the ABI-stable hash function that allows computing a 16-bit 
discriminator from a constant string.

This allows manually matching the implicit string discriminators computed in 
the ABI (e.g., from mangled names for vtable pointer/entry signing), as well as 
enabling the use of interesting discriminators when manually annotating 
specific pointers with the __ptrauth qualifier.

>From 61be7a922397d66773a8f4a6e476ea321f52f00c Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:22:29 -0700
Subject: [PATCH] [clang] Define ptrauth_string_discriminator builtin.

This exposes the ABI-stable hash function that allows computing a 16-bit
discriminator from a constant string.

This allows manually matching the implicit string discriminators
computed in the ABI (e.g., from mangled names for vtable pointer/entry
signing), as well as enabling the use of interesting discriminators when
manually annotating specific pointers with the __ptrauth qualifier.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/AST/ExprConstant.cpp|  7 +++
 clang/lib/Headers/ptrauth.h   | 17 
 clang/lib/Sema/SemaChecking.cpp   | 20 +++
 clang/test/CodeGen/ptrauth-intrinsics.c   | 13 
 clang/test/Sema/ptrauth-intrinsics-macro.c|  5 +
 7 files changed, 70 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 11982af3fa609..836697632a3bc 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4411,6 +4411,12 @@ def PtrauthAuth : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthStringDiscriminator : Builtin {
+  let Spellings = ["__builtin_ptrauth_string_discriminator"];
+  let Attributes = [NoThrow, Const, Constexpr];
+  let Prototype = "size_t(char const*)";
+}
+
 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
 // We need the generic prototype, since the packet type could be anything.
 def ReadPipe : OCLPipeLangBuiltin {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f15cba63624ea..64add46248c69 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -928,6 +928,8 @@ def warn_ptrauth_sign_null_pointer :
 def warn_ptrauth_auth_null_pointer :
   Warning<"authenticating a null pointer will almost certainly trap">,
   InGroup;
+def err_ptrauth_string_not_literal : Error<
+  "argument must be a string literal%select{| of char type}0">;
 
 /// main()
 // static main() is not an error in C, just in C++.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f1aa19e4409e1..eafecfb5fe5b1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -58,6 +58,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/SipHash.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
@@ -12583,6 +12584,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
   case Builtin::BI__builtin_expect_with_probability:
 return Visit(E->getArg(0));
 
+  case Builtin::BI__builtin_ptrauth_string_discriminator: {
+auto literal = cast(E->getArg(0)->IgnoreParenImpCasts());
+auto result = getPointerAuthStableSipHash16(literal->getString());
+return Success(result, E);
+  }
+
   case Builtin::BI__builtin_ffs:
   case Builtin::BI__builtin_ffsl:
   case Builtin::BI__builtin_ffsll: {
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index 036665d75a91b..3e58af1802084 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -135,6 +135,17 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 #define ptrauth_auth_data(__value, __old_key, __old_data)  
\
   __builtin_ptrauth_auth(__value, __old_key, __old_data)
 
+/* Compute a constant discriminator from the given string.
+
+   The result can be used as the second argument to
+   ptrauth_blend_discriminator or the third argument to the
+   __ptrauth qualifier.  It has type size_t.
+
+   The argument must be a string literal.
+   A call to this function is an integer constant expression. */
+#define ptrauth_string_discriminator(__string) 
\
+  __builtin_ptrauth_string_discriminator(__string)
+
 /* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.
 
@@ -196,6 +207,12 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 __value; 

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-05-30 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha created 
https://github.com/llvm/llvm-project/pull/93904

This is a constant-expression equivalent to __builtin_ptrauth_sign, allowing 
its usage in global initializers, but requiring constant pointers and 
discriminators.

>From 1a23a99f23714ba6a83b354e3b9afd056b263a02 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:33:04 -0700
Subject: [PATCH] [clang] Define ptrauth_sign_constant builtin.

This is constant-expression equivalent to __builtin_ptrauth_sign,
allowing its usage in global initializers, but requiring constant
pointers and discriminators.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   6 +
 clang/lib/AST/ExprConstant.cpp|   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |   3 +
 clang/lib/CodeGen/CGExprConstant.cpp  |  62 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  77 +++
 clang/lib/CodeGen/CMakeLists.txt  |   1 +
 clang/lib/CodeGen/CodeGenModule.h |   5 +
 clang/lib/Headers/ptrauth.h   |  25 
 clang/lib/Sema/SemaChecking.cpp   | 128 --
 .../CodeGen/ptrauth-intrinsic-sign-constant.c |  20 +++
 clang/test/Sema/ptrauth-intrinsics-macro.c|   4 +
 clang/test/Sema/ptrauth.c |  29 
 14 files changed, 360 insertions(+), 14 deletions(-)
 create mode 100644 clang/lib/CodeGen/CGPointerAuth.cpp
 create mode 100644 clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 836697632a3bc..557b70172fc08 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4393,6 +4393,12 @@ def PtrauthSignUnauthenticated : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthSignConstant : Builtin {
+  let Spellings = ["__builtin_ptrauth_sign_constant"];
+  let Attributes = [CustomTypeChecking, NoThrow, Const, Constexpr];
+  let Prototype = "void*(void*,int,void*)";
+}
+
 def PtrauthSignGenericData : Builtin {
   let Spellings = ["__builtin_ptrauth_sign_generic_data"];
   let Attributes = [CustomTypeChecking, NoThrow, Const];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 64add46248c69..753e775ce0968 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -922,6 +922,13 @@ def err_ptrauth_value_bad_type :
   Error<"%select{signed value|extra discriminator|blended pointer|blended "
 "integer}0 must have %select{pointer|integer|pointer or integer}1 "
 "type; type here is %2">;
+def err_ptrauth_bad_constant_pointer :
+  Error<"argument to ptrauth_sign_constant must refer to a global variable "
+"or function">;
+def err_ptrauth_bad_constant_discriminator :
+  Error<"discriminator argument to ptrauth_sign_constant must be a constant "
+"integer, the address of the global variable where the result "
+"will be stored, or a blend of the two">;
 def warn_ptrauth_sign_null_pointer :
   Warning<"signing a null pointer will yield a non-null pointer">,
   InGroup;
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index fda0855dc8683..8c62d8597ecbe 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -104,6 +104,12 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, 
QualType T);
 unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 const RecordDecl *RD, const FieldDecl *FD);
 
+/// Return a signed constant pointer.
+llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM,
+ llvm::Constant *pointer,
+ unsigned key,
+ llvm::Constant *storageAddress,
+ llvm::Constant *otherDiscriminator);
 /// Given the language and code-generation options that Clang was configured
 /// with, set the default LLVM IR attributes for a function definition.
 /// The attributes set here are mostly global target-configuration and
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index eafecfb5fe5b1..b1cb3c323074b 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2042,6 +2042,7 @@ static bool IsNoOpCall(const CallExpr *E) {
   unsigned Builtin = E->getBuiltinCallee();
   return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
   Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
+  Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
   Builtin == Builtin::BI__bui

[llvm-branch-commits] [clang] [clang] Implement function pointer signing. (PR #93906)

2024-05-30 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha created 
https://github.com/llvm/llvm-project/pull/93906

None

>From 0e85001f6d53e63beca77a76eaba1875ec84000d Mon Sep 17 00:00:00 2001
From: Akira Hatanaka 
Date: Fri, 24 May 2024 20:23:36 -0700
Subject: [PATCH] [clang] Implement function pointer signing.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/CodeGenOptions.h|   4 +
 .../clang/Basic/DiagnosticDriverKinds.td  |   3 +
 clang/include/clang/Basic/LangOptions.h   |   2 +
 .../include/clang/Basic/PointerAuthOptions.h  | 136 ++
 .../clang/Frontend/CompilerInvocation.h   |  10 ++
 clang/lib/CodeGen/CGBuiltin.cpp   |   3 +-
 clang/lib/CodeGen/CGCall.cpp  |   3 +
 clang/lib/CodeGen/CGCall.h|  28 +++-
 clang/lib/CodeGen/CGExpr.cpp  |  17 +--
 clang/lib/CodeGen/CGExprConstant.cpp  |  19 ++-
 clang/lib/CodeGen/CGPointerAuth.cpp   |  51 +++
 clang/lib/CodeGen/CGPointerAuthInfo.h |  96 +
 clang/lib/CodeGen/CodeGenFunction.cpp |  58 
 clang/lib/CodeGen/CodeGenFunction.h   |  10 ++
 clang/lib/CodeGen/CodeGenModule.h |  34 +
 clang/lib/Frontend/CompilerInvocation.cpp |  36 +
 clang/lib/Headers/ptrauth.h   |  34 +
 .../CodeGen/ptrauth-function-attributes.c |  13 ++
 .../test/CodeGen/ptrauth-function-init-fail.c |   5 +
 clang/test/CodeGen/ptrauth-function-init.c|  31 
 .../CodeGen/ptrauth-function-lvalue-cast.c|  23 +++
 clang/test/CodeGen/ptrauth-weak_import.c  |  10 ++
 clang/test/CodeGenCXX/ptrauth.cpp |  24 
 23 files changed, 633 insertions(+), 17 deletions(-)
 create mode 100644 clang/lib/CodeGen/CGPointerAuthInfo.h
 create mode 100644 clang/test/CodeGen/ptrauth-function-attributes.c
 create mode 100644 clang/test/CodeGen/ptrauth-function-init-fail.c
 create mode 100644 clang/test/CodeGen/ptrauth-function-init.c
 create mode 100644 clang/test/CodeGen/ptrauth-function-lvalue-cast.c
 create mode 100644 clang/test/CodeGen/ptrauth-weak_import.c
 create mode 100644 clang/test/CodeGenCXX/ptrauth.cpp

diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb..502722a6ec4eb 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
 #define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
 
+#include "clang/Basic/PointerAuthOptions.h"
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/XRayInstr.h"
 #include "llvm/ADT/FloatingPointMode.h"
@@ -388,6 +389,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
 
   std::vector Reciprocals;
 
+  /// Configuration for pointer-signing.
+  PointerAuthOptions PointerAuth;
+
   /// The preferred width for auto-vectorization transforms. This is intended 
to
   /// override default transforms based on the width of the architected vector
   /// registers.
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 773b234cd68fe..6cbb0c8401c15 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -351,6 +351,9 @@ def err_drv_omp_host_ir_file_not_found : Error<
   "target regions but cannot be found">;
 def err_drv_omp_host_target_not_supported : Error<
   "target '%0' is not a supported OpenMP host target">;
+def err_drv_ptrauth_not_supported : Error<
+  "target '%0' does not support native pointer authentication">;
+
 def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
   "'-fopenmp-targets' must be used in conjunction with a '-fopenmp' option "
   "compatible with offloading; e.g., '-fopenmp=libomp' or 
'-fopenmp=libiomp5'">;
diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 75e88afbd9705..5216822e45b1b 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -346,6 +346,8 @@ class LangOptionsBase {
 BKey
   };
 
+  using PointerAuthenticationMode = ::clang::PointerAuthenticationMode;
+
   enum class ThreadModelKind {
 /// POSIX Threads.
 POSIX,
diff --git a/clang/include/clang/Basic/PointerAuthOptions.h 
b/clang/include/clang/Basic/PointerAuthOptions.h
index e5cdcc31ebfb7..32b179e3f9460 100644
--- a/clang/include/clang/Basic/PointerAuthOptions.h
+++ b/clang/include/clang/Basic/PointerAuthOptions.h
@@ -14,10 +14,146 @@
 #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H
 #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H
 
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetOptions.h"
+#include 
+#include 
+#include 
+#include 
+
 namespace clang {
 
 constexpr unsigned PointerAuthKeyNone = -1;
 
+class PointerAuthSchema {
+public:
+  enum class Kind : unsigned 

[llvm-branch-commits] [clang] [clang] Update use of checkUInt32Argument to match on main (PR #93984)

2024-05-31 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha closed 
https://github.com/llvm/llvm-project/pull/93984
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-05-31 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

> Why do we want a separate builtin, as opposed to just constant-folding calls 
> to __builtin_ptrauth_sign?

That's a good question.  Mechanically, I assumed constant-evaluating 
`__builtin_ptrauth_sign_unauthenticated` would be a challenge, but looking 
around it doesn't seem particularly difficult.

Conceptually though, the distinction does seem useful, because we treat 
`__builtin_ptrauth_sign_unauthenticated` as dangerous (because in general we 
can't guarantee that it won't get lowered to a signing oracle), and only to be 
used carefully, when absolutely necessary (e.g., in a dynamic loader.)
`__builtin_ptrauth_sign_constant` is safe, because we do always have safe ways 
to materialize signed constants (with the constants in IR, and either 
relocations or safe pseudos in the backend.)   (but cc @rjmccall @ahatanak for 
the real clang perspective ;)

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs. (PR #93907)

2024-05-31 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha closed 
https://github.com/llvm/llvm-project/pull/93907
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)

2024-06-03 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93903

>From 61be7a922397d66773a8f4a6e476ea321f52f00c Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:22:29 -0700
Subject: [PATCH 1/2] [clang] Define ptrauth_string_discriminator builtin.

This exposes the ABI-stable hash function that allows computing a 16-bit
discriminator from a constant string.

This allows manually matching the implicit string discriminators
computed in the ABI (e.g., from mangled names for vtable pointer/entry
signing), as well as enabling the use of interesting discriminators when
manually annotating specific pointers with the __ptrauth qualifier.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/AST/ExprConstant.cpp|  7 +++
 clang/lib/Headers/ptrauth.h   | 17 
 clang/lib/Sema/SemaChecking.cpp   | 20 +++
 clang/test/CodeGen/ptrauth-intrinsics.c   | 13 
 clang/test/Sema/ptrauth-intrinsics-macro.c|  5 +
 7 files changed, 70 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 11982af3fa609..836697632a3bc 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4411,6 +4411,12 @@ def PtrauthAuth : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthStringDiscriminator : Builtin {
+  let Spellings = ["__builtin_ptrauth_string_discriminator"];
+  let Attributes = [NoThrow, Const, Constexpr];
+  let Prototype = "size_t(char const*)";
+}
+
 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
 // We need the generic prototype, since the packet type could be anything.
 def ReadPipe : OCLPipeLangBuiltin {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f15cba63624ea..64add46248c69 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -928,6 +928,8 @@ def warn_ptrauth_sign_null_pointer :
 def warn_ptrauth_auth_null_pointer :
   Warning<"authenticating a null pointer will almost certainly trap">,
   InGroup;
+def err_ptrauth_string_not_literal : Error<
+  "argument must be a string literal%select{| of char type}0">;
 
 /// main()
 // static main() is not an error in C, just in C++.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f1aa19e4409e1..eafecfb5fe5b1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -58,6 +58,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/SipHash.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
@@ -12583,6 +12584,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
   case Builtin::BI__builtin_expect_with_probability:
 return Visit(E->getArg(0));
 
+  case Builtin::BI__builtin_ptrauth_string_discriminator: {
+auto literal = cast(E->getArg(0)->IgnoreParenImpCasts());
+auto result = getPointerAuthStableSipHash16(literal->getString());
+return Success(result, E);
+  }
+
   case Builtin::BI__builtin_ffs:
   case Builtin::BI__builtin_ffsl:
   case Builtin::BI__builtin_ffsll: {
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index 036665d75a91b..3e58af1802084 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -135,6 +135,17 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 #define ptrauth_auth_data(__value, __old_key, __old_data)  
\
   __builtin_ptrauth_auth(__value, __old_key, __old_data)
 
+/* Compute a constant discriminator from the given string.
+
+   The result can be used as the second argument to
+   ptrauth_blend_discriminator or the third argument to the
+   __ptrauth qualifier.  It has type size_t.
+
+   The argument must be a string literal.
+   A call to this function is an integer constant expression. */
+#define ptrauth_string_discriminator(__string) 
\
+  __builtin_ptrauth_string_discriminator(__string)
+
 /* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.
 
@@ -196,6 +207,12 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 __value;   
\
   })
 
+#define ptrauth_string_discriminator(__string) 
\
+  ({   
\
+(void)__string;
\
+((ptrauth_extra_data_t)0); 
\
+  })
+
 #define ptrauth_sign_generic

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-03 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93904

>From 1a23a99f23714ba6a83b354e3b9afd056b263a02 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:33:04 -0700
Subject: [PATCH 1/2] [clang] Define ptrauth_sign_constant builtin.

This is constant-expression equivalent to __builtin_ptrauth_sign,
allowing its usage in global initializers, but requiring constant
pointers and discriminators.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   6 +
 clang/lib/AST/ExprConstant.cpp|   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |   3 +
 clang/lib/CodeGen/CGExprConstant.cpp  |  62 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  77 +++
 clang/lib/CodeGen/CMakeLists.txt  |   1 +
 clang/lib/CodeGen/CodeGenModule.h |   5 +
 clang/lib/Headers/ptrauth.h   |  25 
 clang/lib/Sema/SemaChecking.cpp   | 128 --
 .../CodeGen/ptrauth-intrinsic-sign-constant.c |  20 +++
 clang/test/Sema/ptrauth-intrinsics-macro.c|   4 +
 clang/test/Sema/ptrauth.c |  29 
 14 files changed, 360 insertions(+), 14 deletions(-)
 create mode 100644 clang/lib/CodeGen/CGPointerAuth.cpp
 create mode 100644 clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 836697632a3bc..557b70172fc08 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4393,6 +4393,12 @@ def PtrauthSignUnauthenticated : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthSignConstant : Builtin {
+  let Spellings = ["__builtin_ptrauth_sign_constant"];
+  let Attributes = [CustomTypeChecking, NoThrow, Const, Constexpr];
+  let Prototype = "void*(void*,int,void*)";
+}
+
 def PtrauthSignGenericData : Builtin {
   let Spellings = ["__builtin_ptrauth_sign_generic_data"];
   let Attributes = [CustomTypeChecking, NoThrow, Const];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 64add46248c69..753e775ce0968 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -922,6 +922,13 @@ def err_ptrauth_value_bad_type :
   Error<"%select{signed value|extra discriminator|blended pointer|blended "
 "integer}0 must have %select{pointer|integer|pointer or integer}1 "
 "type; type here is %2">;
+def err_ptrauth_bad_constant_pointer :
+  Error<"argument to ptrauth_sign_constant must refer to a global variable "
+"or function">;
+def err_ptrauth_bad_constant_discriminator :
+  Error<"discriminator argument to ptrauth_sign_constant must be a constant "
+"integer, the address of the global variable where the result "
+"will be stored, or a blend of the two">;
 def warn_ptrauth_sign_null_pointer :
   Warning<"signing a null pointer will yield a non-null pointer">,
   InGroup;
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index fda0855dc8683..8c62d8597ecbe 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -104,6 +104,12 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, 
QualType T);
 unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 const RecordDecl *RD, const FieldDecl *FD);
 
+/// Return a signed constant pointer.
+llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM,
+ llvm::Constant *pointer,
+ unsigned key,
+ llvm::Constant *storageAddress,
+ llvm::Constant *otherDiscriminator);
 /// Given the language and code-generation options that Clang was configured
 /// with, set the default LLVM IR attributes for a function definition.
 /// The attributes set here are mostly global target-configuration and
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index eafecfb5fe5b1..b1cb3c323074b 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2042,6 +2042,7 @@ static bool IsNoOpCall(const CallExpr *E) {
   unsigned Builtin = E->getBuiltinCallee();
   return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
   Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
+  Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
   Builtin == Builtin::BI__builtin_function_start);
 }
 
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index a3c6510503324..b2e3b6fa64284 100644
--- a/clang/li

[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)

2024-06-03 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93903

>From 61be7a922397d66773a8f4a6e476ea321f52f00c Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:22:29 -0700
Subject: [PATCH 1/3] [clang] Define ptrauth_string_discriminator builtin.

This exposes the ABI-stable hash function that allows computing a 16-bit
discriminator from a constant string.

This allows manually matching the implicit string discriminators
computed in the ABI (e.g., from mangled names for vtable pointer/entry
signing), as well as enabling the use of interesting discriminators when
manually annotating specific pointers with the __ptrauth qualifier.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/AST/ExprConstant.cpp|  7 +++
 clang/lib/Headers/ptrauth.h   | 17 
 clang/lib/Sema/SemaChecking.cpp   | 20 +++
 clang/test/CodeGen/ptrauth-intrinsics.c   | 13 
 clang/test/Sema/ptrauth-intrinsics-macro.c|  5 +
 7 files changed, 70 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 11982af3fa609..836697632a3bc 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4411,6 +4411,12 @@ def PtrauthAuth : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthStringDiscriminator : Builtin {
+  let Spellings = ["__builtin_ptrauth_string_discriminator"];
+  let Attributes = [NoThrow, Const, Constexpr];
+  let Prototype = "size_t(char const*)";
+}
+
 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
 // We need the generic prototype, since the packet type could be anything.
 def ReadPipe : OCLPipeLangBuiltin {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f15cba63624ea..64add46248c69 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -928,6 +928,8 @@ def warn_ptrauth_sign_null_pointer :
 def warn_ptrauth_auth_null_pointer :
   Warning<"authenticating a null pointer will almost certainly trap">,
   InGroup;
+def err_ptrauth_string_not_literal : Error<
+  "argument must be a string literal%select{| of char type}0">;
 
 /// main()
 // static main() is not an error in C, just in C++.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f1aa19e4409e1..eafecfb5fe5b1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -58,6 +58,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/SipHash.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
@@ -12583,6 +12584,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
   case Builtin::BI__builtin_expect_with_probability:
 return Visit(E->getArg(0));
 
+  case Builtin::BI__builtin_ptrauth_string_discriminator: {
+auto literal = cast(E->getArg(0)->IgnoreParenImpCasts());
+auto result = getPointerAuthStableSipHash16(literal->getString());
+return Success(result, E);
+  }
+
   case Builtin::BI__builtin_ffs:
   case Builtin::BI__builtin_ffsl:
   case Builtin::BI__builtin_ffsll: {
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index 036665d75a91b..3e58af1802084 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -135,6 +135,17 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 #define ptrauth_auth_data(__value, __old_key, __old_data)  
\
   __builtin_ptrauth_auth(__value, __old_key, __old_data)
 
+/* Compute a constant discriminator from the given string.
+
+   The result can be used as the second argument to
+   ptrauth_blend_discriminator or the third argument to the
+   __ptrauth qualifier.  It has type size_t.
+
+   The argument must be a string literal.
+   A call to this function is an integer constant expression. */
+#define ptrauth_string_discriminator(__string) 
\
+  __builtin_ptrauth_string_discriminator(__string)
+
 /* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.
 
@@ -196,6 +207,12 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 __value;   
\
   })
 
+#define ptrauth_string_discriminator(__string) 
\
+  ({   
\
+(void)__string;
\
+((ptrauth_extra_data_t)0); 
\
+  })
+
 #define ptrauth_sign_generic

[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)

2024-06-03 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93903

>From 61be7a922397d66773a8f4a6e476ea321f52f00c Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:22:29 -0700
Subject: [PATCH 1/4] [clang] Define ptrauth_string_discriminator builtin.

This exposes the ABI-stable hash function that allows computing a 16-bit
discriminator from a constant string.

This allows manually matching the implicit string discriminators
computed in the ABI (e.g., from mangled names for vtable pointer/entry
signing), as well as enabling the use of interesting discriminators when
manually annotating specific pointers with the __ptrauth qualifier.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |  6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/AST/ExprConstant.cpp|  7 +++
 clang/lib/Headers/ptrauth.h   | 17 
 clang/lib/Sema/SemaChecking.cpp   | 20 +++
 clang/test/CodeGen/ptrauth-intrinsics.c   | 13 
 clang/test/Sema/ptrauth-intrinsics-macro.c|  5 +
 7 files changed, 70 insertions(+)

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 11982af3fa609..836697632a3bc 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4411,6 +4411,12 @@ def PtrauthAuth : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthStringDiscriminator : Builtin {
+  let Spellings = ["__builtin_ptrauth_string_discriminator"];
+  let Attributes = [NoThrow, Const, Constexpr];
+  let Prototype = "size_t(char const*)";
+}
+
 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
 // We need the generic prototype, since the packet type could be anything.
 def ReadPipe : OCLPipeLangBuiltin {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f15cba63624ea..64add46248c69 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -928,6 +928,8 @@ def warn_ptrauth_sign_null_pointer :
 def warn_ptrauth_auth_null_pointer :
   Warning<"authenticating a null pointer will almost certainly trap">,
   InGroup;
+def err_ptrauth_string_not_literal : Error<
+  "argument must be a string literal%select{| of char type}0">;
 
 /// main()
 // static main() is not an error in C, just in C++.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f1aa19e4409e1..eafecfb5fe5b1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -58,6 +58,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/SipHash.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include 
@@ -12583,6 +12584,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
   case Builtin::BI__builtin_expect_with_probability:
 return Visit(E->getArg(0));
 
+  case Builtin::BI__builtin_ptrauth_string_discriminator: {
+auto literal = cast(E->getArg(0)->IgnoreParenImpCasts());
+auto result = getPointerAuthStableSipHash16(literal->getString());
+return Success(result, E);
+  }
+
   case Builtin::BI__builtin_ffs:
   case Builtin::BI__builtin_ffsl:
   case Builtin::BI__builtin_ffsll: {
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index 036665d75a91b..3e58af1802084 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -135,6 +135,17 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 #define ptrauth_auth_data(__value, __old_key, __old_data)  
\
   __builtin_ptrauth_auth(__value, __old_key, __old_data)
 
+/* Compute a constant discriminator from the given string.
+
+   The result can be used as the second argument to
+   ptrauth_blend_discriminator or the third argument to the
+   __ptrauth qualifier.  It has type size_t.
+
+   The argument must be a string literal.
+   A call to this function is an integer constant expression. */
+#define ptrauth_string_discriminator(__string) 
\
+  __builtin_ptrauth_string_discriminator(__string)
+
 /* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.
 
@@ -196,6 +207,12 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
 __value;   
\
   })
 
+#define ptrauth_string_discriminator(__string) 
\
+  ({   
\
+(void)__string;
\
+((ptrauth_extra_data_t)0); 
\
+  })
+
 #define ptrauth_sign_generic

[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)

2024-06-03 Thread Ahmed Bougacha via llvm-branch-commits


@@ -2156,6 +2156,24 @@ static ExprResult PointerAuthAuthAndResign(Sema &S, 
CallExpr *Call) {
   return Call;
 }
 
+static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *call) {

ahmedbougacha wrote:

Clang originally had different conventions;  it usually gets (has gotten) 
updated over time for older code, I suppose now's the time for these changes.

https://github.com/llvm/llvm-project/pull/93903
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-03 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93904

>From 1a23a99f23714ba6a83b354e3b9afd056b263a02 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:33:04 -0700
Subject: [PATCH 1/3] [clang] Define ptrauth_sign_constant builtin.

This is constant-expression equivalent to __builtin_ptrauth_sign,
allowing its usage in global initializers, but requiring constant
pointers and discriminators.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   6 +
 clang/lib/AST/ExprConstant.cpp|   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |   3 +
 clang/lib/CodeGen/CGExprConstant.cpp  |  62 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  77 +++
 clang/lib/CodeGen/CMakeLists.txt  |   1 +
 clang/lib/CodeGen/CodeGenModule.h |   5 +
 clang/lib/Headers/ptrauth.h   |  25 
 clang/lib/Sema/SemaChecking.cpp   | 128 --
 .../CodeGen/ptrauth-intrinsic-sign-constant.c |  20 +++
 clang/test/Sema/ptrauth-intrinsics-macro.c|   4 +
 clang/test/Sema/ptrauth.c |  29 
 14 files changed, 360 insertions(+), 14 deletions(-)
 create mode 100644 clang/lib/CodeGen/CGPointerAuth.cpp
 create mode 100644 clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 836697632a3bc..557b70172fc08 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4393,6 +4393,12 @@ def PtrauthSignUnauthenticated : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthSignConstant : Builtin {
+  let Spellings = ["__builtin_ptrauth_sign_constant"];
+  let Attributes = [CustomTypeChecking, NoThrow, Const, Constexpr];
+  let Prototype = "void*(void*,int,void*)";
+}
+
 def PtrauthSignGenericData : Builtin {
   let Spellings = ["__builtin_ptrauth_sign_generic_data"];
   let Attributes = [CustomTypeChecking, NoThrow, Const];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 64add46248c69..753e775ce0968 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -922,6 +922,13 @@ def err_ptrauth_value_bad_type :
   Error<"%select{signed value|extra discriminator|blended pointer|blended "
 "integer}0 must have %select{pointer|integer|pointer or integer}1 "
 "type; type here is %2">;
+def err_ptrauth_bad_constant_pointer :
+  Error<"argument to ptrauth_sign_constant must refer to a global variable "
+"or function">;
+def err_ptrauth_bad_constant_discriminator :
+  Error<"discriminator argument to ptrauth_sign_constant must be a constant "
+"integer, the address of the global variable where the result "
+"will be stored, or a blend of the two">;
 def warn_ptrauth_sign_null_pointer :
   Warning<"signing a null pointer will yield a non-null pointer">,
   InGroup;
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index fda0855dc8683..8c62d8597ecbe 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -104,6 +104,12 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, 
QualType T);
 unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 const RecordDecl *RD, const FieldDecl *FD);
 
+/// Return a signed constant pointer.
+llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM,
+ llvm::Constant *pointer,
+ unsigned key,
+ llvm::Constant *storageAddress,
+ llvm::Constant *otherDiscriminator);
 /// Given the language and code-generation options that Clang was configured
 /// with, set the default LLVM IR attributes for a function definition.
 /// The attributes set here are mostly global target-configuration and
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index eafecfb5fe5b1..b1cb3c323074b 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2042,6 +2042,7 @@ static bool IsNoOpCall(const CallExpr *E) {
   unsigned Builtin = E->getBuiltinCallee();
   return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
   Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
+  Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
   Builtin == Builtin::BI__builtin_function_start);
 }
 
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index a3c6510503324..b2e3b6fa64284 100644
--- a/clang/li

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-03 Thread Ahmed Bougacha via llvm-branch-commits


@@ -2126,14 +2219,16 @@ static ExprResult PointerAuthSignGenericData(Sema &S, 
CallExpr *Call) {
 }
 
 static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call,
-PointerAuthOpKind OpKind) {
+PointerAuthOpKind OpKind,
+bool RequireConstant) {
   if (S.checkArgCount(Call, 3))
 return ExprError();
   if (checkPointerAuthEnabled(S, Call))
 return ExprError();
-  if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind) ||
+  if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind, RequireConstant) ||

ahmedbougacha wrote:

This one is actually interesting: we can't do that as-is, because the helper 
functions take an `Expr *&`, to do type conversion and placeholder expansion 
in-place;  see e.g., `convertArgumentToType`.
Another existing user makes the modification explicit using a local and 
`setArg`, but we have a lot of these calls in the checking code here.

We can rename the helper to something explicit though, perhaps 
`checkAndConvertPointerAuthValue`, and pass the call expr and arg index 
separately (same for key etc.)

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha created 
https://github.com/llvm/llvm-project/pull/94394

Start building it as part of the library, with some minor
tweaks compared to the reference implementation:
- clang-format to match libSupport
- remove tracing support
- add file header
- templatize cROUNDS/dROUNDS, as well as 8B/16B result type
- replace assert with static_assert
- return the result directly, as uint64_t/uint128_t
- remove big-endian support
- use LLVM_FALLTHROUGH
- remove tracing support

The siphash function itself isn't used yet, and will be in a follow-up
commit.

>From 12bb6238aa0e7f90342aa194e54a8286e3e35dbd Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:41:47 -0700
Subject: [PATCH 1/3] [Support] Reformat SipHash.cpp to match libSupport.

While there, give it our usual file header and an acknowledgement,
and remove the imported README.md.SipHash.
---
 llvm/lib/Support/README.md.SipHash | 126 --
 llvm/lib/Support/SipHash.cpp   | 264 ++---
 2 files changed, 129 insertions(+), 261 deletions(-)
 delete mode 100644 llvm/lib/Support/README.md.SipHash

diff --git a/llvm/lib/Support/README.md.SipHash 
b/llvm/lib/Support/README.md.SipHash
deleted file mode 100644
index 4de3cd1854681..0
--- a/llvm/lib/Support/README.md.SipHash
+++ /dev/null
@@ -1,126 +0,0 @@
-# SipHash
-
-[![License:
-CC0-1.0](https://licensebuttons.net/l/zero/1.0/80x15.png)](http://creativecommons.org/publicdomain/zero/1.0/)
-
-[![License: 
MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-
-SipHash is a family of pseudorandom functions (PRFs) optimized for speed on 
short messages.
-This is the reference C code of SipHash: portable, simple, optimized for 
clarity and debugging.
-
-SipHash was designed in 2012 by [Jean-Philippe Aumasson](https://aumasson.jp)
-and [Daniel J. Bernstein](https://cr.yp.to) as a defense against [hash-flooding
-DoS attacks](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf).
-
-SipHash is:
-
-* *Simpler and faster* on short messages than previous cryptographic
-algorithms, such as MACs based on universal hashing.
-
-* *Competitive in performance* with insecure non-cryptographic algorithms, 
such as [fhhash](https://github.com/cbreeden/fxhash).
-
-* *Cryptographically secure*, with no sign of weakness despite multiple 
[cryptanalysis](https://eprint.iacr.org/2019/865) 
[projects](https://eprint.iacr.org/2019/865) by leading cryptographers.
-
-* *Battle-tested*, with successful integration in OSs (Linux kernel, OpenBSD,
-FreeBSD, FreeRTOS), languages (Perl, Python, Ruby, etc.), libraries (OpenSSL 
libcrypto,
-Sodium, etc.) and applications (Wireguard, Redis, etc.).
-
-As a secure pseudorandom function (a.k.a. keyed hash function), SipHash can 
also be used as a secure message authentication code (MAC).
-But SipHash is *not a hash* in the sense of general-purpose key-less hash 
function such as BLAKE3 or SHA-3.
-SipHash should therefore always be used with a secret key in order to be 
secure.
-
-
-## Variants
-
-The default SipHash is *SipHash-2-4*: it takes a 128-bit key, does 2 
compression
-rounds, 4 finalization rounds, and returns a 64-bit tag.
-
-Variants can use a different number of rounds. For example, we proposed 
*SipHash-4-8* as a conservative version.
-
-The following versions are not described in the paper but were designed and 
analyzed to fulfill applications' needs:
-
-* *SipHash-128* returns a 128-bit tag instead of 64-bit. Versions with 
specified number of rounds are SipHash-2-4-128, SipHash4-8-128, and so on.
-
-* *HalfSipHash* works with 32-bit words instead of 64-bit, takes a 64-bit key,
-and returns 32-bit or 64-bit tags. For example, HalfSipHash-2-4-32 has 2
-compression rounds, 4 finalization rounds, and returns a 32-bit tag.
-
-
-## Security
-
-(Half)SipHash-*c*-*d* with *c* ≥ 2 and *d* ≥ 4 is expected to provide the 
maximum PRF
-security for any function with the same key and output size.
-
-The standard PRF security goal allow the attacker access to the output of 
SipHash on messages chosen adaptively by the attacker.
-
-Security is limited by the key size (128 bits for SipHash), such that
-attackers searching 2*s* keys have chance 2*s*−128 of 
finding
-the SipHash key. 
-Security is also limited by the output size. In particular, when
-SipHash is used as a MAC, an attacker who blindly tries 2*s* tags 
will
-succeed with probability 2*s*-*t*, if *t* is that tag's bit size.
-
-
-## Research
-
-* [Research paper](https://www.aumasson.jp/siphash/siphash.pdf) "SipHash: a 
fast short-input PRF" (accepted at INDOCRYPT 2012)
-* [Slides](https://cr.yp.to/talks/2012.12.12/slides.pdf) of the presentation 
of SipHash at INDOCRYPT 2012 (Bernstein)
-* [Slides](https://www.aumasson.jp/siphash/siphash_slides.pdf) of the 
presentation of SipHash at the DIAC workshop (Aumasson)
-
-
-## Usage
-
-Running
-
-```sh
-  make
-```
-
-will build tests for 
-
-* SipHash-2-4-64
-

[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/94394

>From 1e9a3fde97d907c3cd6be33db91d1c18c7236ffb Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:41:47 -0700
Subject: [PATCH 1/3] [Support] Reformat SipHash.cpp to match libSupport.

While there, give it our usual file header and an acknowledgement,
and remove the imported README.md.SipHash.
---
 llvm/lib/Support/README.md.SipHash | 126 --
 llvm/lib/Support/SipHash.cpp   | 264 ++---
 2 files changed, 129 insertions(+), 261 deletions(-)
 delete mode 100644 llvm/lib/Support/README.md.SipHash

diff --git a/llvm/lib/Support/README.md.SipHash 
b/llvm/lib/Support/README.md.SipHash
deleted file mode 100644
index 4de3cd1854681..0
--- a/llvm/lib/Support/README.md.SipHash
+++ /dev/null
@@ -1,126 +0,0 @@
-# SipHash
-
-[![License:
-CC0-1.0](https://licensebuttons.net/l/zero/1.0/80x15.png)](http://creativecommons.org/publicdomain/zero/1.0/)
-
-[![License: 
MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-
-SipHash is a family of pseudorandom functions (PRFs) optimized for speed on 
short messages.
-This is the reference C code of SipHash: portable, simple, optimized for 
clarity and debugging.
-
-SipHash was designed in 2012 by [Jean-Philippe Aumasson](https://aumasson.jp)
-and [Daniel J. Bernstein](https://cr.yp.to) as a defense against [hash-flooding
-DoS attacks](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf).
-
-SipHash is:
-
-* *Simpler and faster* on short messages than previous cryptographic
-algorithms, such as MACs based on universal hashing.
-
-* *Competitive in performance* with insecure non-cryptographic algorithms, 
such as [fhhash](https://github.com/cbreeden/fxhash).
-
-* *Cryptographically secure*, with no sign of weakness despite multiple 
[cryptanalysis](https://eprint.iacr.org/2019/865) 
[projects](https://eprint.iacr.org/2019/865) by leading cryptographers.
-
-* *Battle-tested*, with successful integration in OSs (Linux kernel, OpenBSD,
-FreeBSD, FreeRTOS), languages (Perl, Python, Ruby, etc.), libraries (OpenSSL 
libcrypto,
-Sodium, etc.) and applications (Wireguard, Redis, etc.).
-
-As a secure pseudorandom function (a.k.a. keyed hash function), SipHash can 
also be used as a secure message authentication code (MAC).
-But SipHash is *not a hash* in the sense of general-purpose key-less hash 
function such as BLAKE3 or SHA-3.
-SipHash should therefore always be used with a secret key in order to be 
secure.
-
-
-## Variants
-
-The default SipHash is *SipHash-2-4*: it takes a 128-bit key, does 2 
compression
-rounds, 4 finalization rounds, and returns a 64-bit tag.
-
-Variants can use a different number of rounds. For example, we proposed 
*SipHash-4-8* as a conservative version.
-
-The following versions are not described in the paper but were designed and 
analyzed to fulfill applications' needs:
-
-* *SipHash-128* returns a 128-bit tag instead of 64-bit. Versions with 
specified number of rounds are SipHash-2-4-128, SipHash4-8-128, and so on.
-
-* *HalfSipHash* works with 32-bit words instead of 64-bit, takes a 64-bit key,
-and returns 32-bit or 64-bit tags. For example, HalfSipHash-2-4-32 has 2
-compression rounds, 4 finalization rounds, and returns a 32-bit tag.
-
-
-## Security
-
-(Half)SipHash-*c*-*d* with *c* ≥ 2 and *d* ≥ 4 is expected to provide the 
maximum PRF
-security for any function with the same key and output size.
-
-The standard PRF security goal allow the attacker access to the output of 
SipHash on messages chosen adaptively by the attacker.
-
-Security is limited by the key size (128 bits for SipHash), such that
-attackers searching 2*s* keys have chance 2*s*−128 of 
finding
-the SipHash key. 
-Security is also limited by the output size. In particular, when
-SipHash is used as a MAC, an attacker who blindly tries 2*s* tags 
will
-succeed with probability 2*s*-*t*, if *t* is that tag's bit size.
-
-
-## Research
-
-* [Research paper](https://www.aumasson.jp/siphash/siphash.pdf) "SipHash: a 
fast short-input PRF" (accepted at INDOCRYPT 2012)
-* [Slides](https://cr.yp.to/talks/2012.12.12/slides.pdf) of the presentation 
of SipHash at INDOCRYPT 2012 (Bernstein)
-* [Slides](https://www.aumasson.jp/siphash/siphash_slides.pdf) of the 
presentation of SipHash at the DIAC workshop (Aumasson)
-
-
-## Usage
-
-Running
-
-```sh
-  make
-```
-
-will build tests for 
-
-* SipHash-2-4-64
-* SipHash-2-4-128
-* HalfSipHash-2-4-32
-* HalfSipHash-2-4-64
-
-
-```C
-  ./test
-```
-
-verifies 64 test vectors, and
-
-```C
-  ./debug
-```
-
-does the same and prints intermediate values.
-
-The code can be adapted to implement SipHash-*c*-*d*, the version of SipHash
-with *c* compression rounds and *d* finalization rounds, by defining `cROUNDS`
-or `dROUNDS` when compiling.  This can be done with `-D` command line arguments
-to many compilers such as below.
-
-```sh
-gcc -Wall --

[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha ready_for_review 
https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/93902
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits


@@ -0,0 +1,47 @@
+//===--- SipHash.h - An ABI-stable string SipHash ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// A family of ABI-stable string hash algorithms based on SipHash, currently
+// used to compute ptrauth discriminators.
+//
+//===--===//
+
+#ifndef LLVM_SUPPORT_SIPHASH_H
+#define LLVM_SUPPORT_SIPHASH_H
+
+#include 
+
+namespace llvm {
+class StringRef;
+
+/// Compute a stable 64-bit hash of the given string.
+///
+/// The exact algorithm is the little-endian interpretation of the
+/// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
+/// a specific key value which can be found in the source.
+///
+/// By "stable" we mean that the result of this hash algorithm will
+/// the same across different compiler versions and target platforms.
+uint64_t getPointerAuthStableSipHash64(StringRef S);
+
+/// Compute a stable non-zero 16-bit hash of the given string.
+///
+/// This computes the full getPointerAuthStableSipHash64, but additionally
+/// truncates it down to a non-zero 16-bit value.
+///
+/// We use a 16-bit discriminator because ARM64 can efficiently load
+/// a 16-bit immediate into the high bits of a register without disturbing
+/// the remainder of the value, which serves as a nice blend operation.
+/// 16 bits is also sufficiently compact to not inflate a loader relocation.
+/// We disallow zero to guarantee a different discriminator from the places
+/// in the ABI that use a constant zero.
+uint64_t getPointerAuthStableSipHash16(StringRef S);

ahmedbougacha wrote:

It's always used as a 64-bit value and in i64 contexts, but I can see how 
that's too subtle of a distinction, one that doesn't make a practical 
difference anyway.  Replaced with `uint16_t`.

https://github.com/llvm/llvm-project/pull/93902
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

I split out:
- https://github.com/llvm/llvm-project/pull/94393
- https://github.com/llvm/llvm-project/pull/94394
and rebased this on top: we're now left with only the thin wrapper (the 16-bit 
one only here) and the simple unittests.

https://github.com/llvm/llvm-project/pull/93902
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits


@@ -0,0 +1,174 @@
+//===--- StableHash.cpp - An ABI-stable string hash 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file implements an ABI-stable string hash based on SipHash, used to
+//  compute ptrauth discriminators.
+//
+//===--===//
+
+#include "llvm/Support/SipHash.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Debug.h"
+#include 
+#include 
+
+using namespace llvm;
+
+#define DEBUG_TYPE "llvm-siphash"
+
+//  Lightly adapted from the SipHash reference C implementation by
+//  Jean-Philippe Aumasson and Daniel J. Bernstein.
+
+#define SIPHASH_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b
+
+#define SIPHASH_U8TO64_LE(p)   
\
+  (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |  
\
+   ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) |   
\
+   ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) |   
\
+   ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
+
+#define SIPHASH_SIPROUND   
\
+  do { 
\
+v0 += v1;  
\
+v1 = SIPHASH_ROTL(v1, 13); 
\
+v1 ^= v0;  
\
+v0 = SIPHASH_ROTL(v0, 32); 
\
+v2 += v3;  
\
+v3 = SIPHASH_ROTL(v3, 16); 
\
+v3 ^= v2;  
\
+v0 += v3;  
\
+v3 = SIPHASH_ROTL(v3, 21); 
\
+v3 ^= v0;  
\
+v2 += v1;  
\
+v1 = SIPHASH_ROTL(v1, 17); 
\
+v1 ^= v2;  
\
+v2 = SIPHASH_ROTL(v2, 32); 
\
+  } while (0)
+
+template 
+static inline ResultTy siphash(const uint8_t *in, uint64_t inlen,
+   const uint8_t (&k)[16]) {
+  static_assert(sizeof(ResultTy) == 8 || sizeof(ResultTy) == 16,
+"result type should be uint64_t or uint128_t");
+  uint64_t v0 = 0x736f6d6570736575ULL;
+  uint64_t v1 = 0x646f72616e646f6dULL;
+  uint64_t v2 = 0x6c7967656e657261ULL;
+  uint64_t v3 = 0x7465646279746573ULL;
+  uint64_t b;
+  uint64_t k0 = SIPHASH_U8TO64_LE(k);
+  uint64_t k1 = SIPHASH_U8TO64_LE(k + 8);
+  uint64_t m;
+  int i;
+  const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
+  const int left = inlen & 7;
+  b = ((uint64_t)inlen) << 56;
+  v3 ^= k1;
+  v2 ^= k0;
+  v1 ^= k1;
+  v0 ^= k0;
+
+  if (sizeof(ResultTy) == 16) {
+v1 ^= 0xee;
+  }
+
+  for (; in != end; in += 8) {
+m = SIPHASH_U8TO64_LE(in);
+v3 ^= m;
+
+for (i = 0; i < cROUNDS; ++i)
+  SIPHASH_SIPROUND;
+
+v0 ^= m;
+  }
+
+  switch (left) {
+  case 7:
+b |= ((uint64_t)in[6]) << 48;
+LLVM_FALLTHROUGH;
+  case 6:
+b |= ((uint64_t)in[5]) << 40;
+LLVM_FALLTHROUGH;
+  case 5:
+b |= ((uint64_t)in[4]) << 32;
+LLVM_FALLTHROUGH;
+  case 4:
+b |= ((uint64_t)in[3]) << 24;
+LLVM_FALLTHROUGH;
+  case 3:
+b |= ((uint64_t)in[2]) << 16;
+LLVM_FALLTHROUGH;
+  case 2:
+b |= ((uint64_t)in[1]) << 8;
+LLVM_FALLTHROUGH;
+  case 1:
+b |= ((uint64_t)in[0]);
+break;
+  case 0:
+break;
+  }
+
+  v3 ^= b;
+
+  for (i = 0; i < cROUNDS; ++i)
+SIPHASH_SIPROUND;
+
+  v0 ^= b;
+
+  if (sizeof(ResultTy) == 8) {
+v2 ^= 0xff;
+  } else {
+v2 ^= 0xee;
+  }
+
+  for (i = 0; i < dROUNDS; ++i)
+SIPHASH_SIPROUND;
+
+  b = v0 ^ v1 ^ v2 ^ v3;
+
+  // This mess with the result type would be easier with 'if constexpr'.
+
+  uint64_t firstHalf = b;
+  if (sizeof(ResultTy) == 8)
+return firstHalf;
+
+  v1 ^= 0xdd;
+
+  for (i = 0; i < dROUNDS; ++i)
+SIPHASH_SIPROUND;
+
+  b = v0 ^ v1 ^ v2 ^ v3;
+  uint64_t secondHalf = b;
+
+  return firstHalf | (ResultTy(secondHalf) << (sizeof(ResultTy) == 8 ? 0 : 
64));
+}
+
+//===--- LLVM-specific wrappers around siphash.
+
+/// Compute an ABI-stable 64-bit hash of the given string.
+uint

[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/93902
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/93902
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16/64-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/93902
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16-bit ptrauth stable hash. (PR #93902)

2024-06-04 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/93902
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-05 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/94394

>From 1e9a3fde97d907c3cd6be33db91d1c18c7236ffb Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:41:47 -0700
Subject: [PATCH 1/4] [Support] Reformat SipHash.cpp to match libSupport.

While there, give it our usual file header and an acknowledgement,
and remove the imported README.md.SipHash.
---
 llvm/lib/Support/README.md.SipHash | 126 --
 llvm/lib/Support/SipHash.cpp   | 264 ++---
 2 files changed, 129 insertions(+), 261 deletions(-)
 delete mode 100644 llvm/lib/Support/README.md.SipHash

diff --git a/llvm/lib/Support/README.md.SipHash 
b/llvm/lib/Support/README.md.SipHash
deleted file mode 100644
index 4de3cd1854681..0
--- a/llvm/lib/Support/README.md.SipHash
+++ /dev/null
@@ -1,126 +0,0 @@
-# SipHash
-
-[![License:
-CC0-1.0](https://licensebuttons.net/l/zero/1.0/80x15.png)](http://creativecommons.org/publicdomain/zero/1.0/)
-
-[![License: 
MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-
-SipHash is a family of pseudorandom functions (PRFs) optimized for speed on 
short messages.
-This is the reference C code of SipHash: portable, simple, optimized for 
clarity and debugging.
-
-SipHash was designed in 2012 by [Jean-Philippe Aumasson](https://aumasson.jp)
-and [Daniel J. Bernstein](https://cr.yp.to) as a defense against [hash-flooding
-DoS attacks](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf).
-
-SipHash is:
-
-* *Simpler and faster* on short messages than previous cryptographic
-algorithms, such as MACs based on universal hashing.
-
-* *Competitive in performance* with insecure non-cryptographic algorithms, 
such as [fhhash](https://github.com/cbreeden/fxhash).
-
-* *Cryptographically secure*, with no sign of weakness despite multiple 
[cryptanalysis](https://eprint.iacr.org/2019/865) 
[projects](https://eprint.iacr.org/2019/865) by leading cryptographers.
-
-* *Battle-tested*, with successful integration in OSs (Linux kernel, OpenBSD,
-FreeBSD, FreeRTOS), languages (Perl, Python, Ruby, etc.), libraries (OpenSSL 
libcrypto,
-Sodium, etc.) and applications (Wireguard, Redis, etc.).
-
-As a secure pseudorandom function (a.k.a. keyed hash function), SipHash can 
also be used as a secure message authentication code (MAC).
-But SipHash is *not a hash* in the sense of general-purpose key-less hash 
function such as BLAKE3 or SHA-3.
-SipHash should therefore always be used with a secret key in order to be 
secure.
-
-
-## Variants
-
-The default SipHash is *SipHash-2-4*: it takes a 128-bit key, does 2 
compression
-rounds, 4 finalization rounds, and returns a 64-bit tag.
-
-Variants can use a different number of rounds. For example, we proposed 
*SipHash-4-8* as a conservative version.
-
-The following versions are not described in the paper but were designed and 
analyzed to fulfill applications' needs:
-
-* *SipHash-128* returns a 128-bit tag instead of 64-bit. Versions with 
specified number of rounds are SipHash-2-4-128, SipHash4-8-128, and so on.
-
-* *HalfSipHash* works with 32-bit words instead of 64-bit, takes a 64-bit key,
-and returns 32-bit or 64-bit tags. For example, HalfSipHash-2-4-32 has 2
-compression rounds, 4 finalization rounds, and returns a 32-bit tag.
-
-
-## Security
-
-(Half)SipHash-*c*-*d* with *c* ≥ 2 and *d* ≥ 4 is expected to provide the 
maximum PRF
-security for any function with the same key and output size.
-
-The standard PRF security goal allow the attacker access to the output of 
SipHash on messages chosen adaptively by the attacker.
-
-Security is limited by the key size (128 bits for SipHash), such that
-attackers searching 2*s* keys have chance 2*s*−128 of 
finding
-the SipHash key. 
-Security is also limited by the output size. In particular, when
-SipHash is used as a MAC, an attacker who blindly tries 2*s* tags 
will
-succeed with probability 2*s*-*t*, if *t* is that tag's bit size.
-
-
-## Research
-
-* [Research paper](https://www.aumasson.jp/siphash/siphash.pdf) "SipHash: a 
fast short-input PRF" (accepted at INDOCRYPT 2012)
-* [Slides](https://cr.yp.to/talks/2012.12.12/slides.pdf) of the presentation 
of SipHash at INDOCRYPT 2012 (Bernstein)
-* [Slides](https://www.aumasson.jp/siphash/siphash_slides.pdf) of the 
presentation of SipHash at the DIAC workshop (Aumasson)
-
-
-## Usage
-
-Running
-
-```sh
-  make
-```
-
-will build tests for 
-
-* SipHash-2-4-64
-* SipHash-2-4-128
-* HalfSipHash-2-4-32
-* HalfSipHash-2-4-64
-
-
-```C
-  ./test
-```
-
-verifies 64 test vectors, and
-
-```C
-  ./debug
-```
-
-does the same and prints intermediate values.
-
-The code can be adapted to implement SipHash-*c*-*d*, the version of SipHash
-with *c* compression rounds and *d* finalization rounds, by defining `cROUNDS`
-or `dROUNDS` when compiling.  This can be done with `-D` command line arguments
-to many compilers such as below.
-
-```sh
-gcc -Wall --

[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-05 Thread Ahmed Bougacha via llvm-branch-commits


@@ -58,21 +38,15 @@
 v2 = ROTL(v2, 32); 
\
   } while (0)
 
-/*

ahmedbougacha wrote:

Fair, added it back with minor tweaks;  I didn't describe the template 
parameters because, frankly, I'm not sure I would have a very useful 
description beyond the obvious ;)

https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-05 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

> Do I understand correctly that "remove big-endian support" results in this 
> code not running correctly on big-endian machines? I don't recall the LLVM 
> project claiming that it cannot run on big-endian machines. If I understand 
> this correctly, I would not remove the big-endian support. (I think it also 
> helps with keeping the source code closer to the upstream siphash version, 
> which might have some benefits?)

That's a good call;  we haven't tried to run it on BE hardware (I don't think 
we could have), but if it's supported I imagine this would have showed up on 
buildbots anyway.  The way this version returns the result directly makes it 
interesting;  I'm only assuming this would break, I haven't fully thought it 
through.  Maybe we should stick to filling out the original buffer and let it 
all get optimized away.  I'll take a look

https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-05 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

I'll also mention that I left the original variable naming but did re-format 
it, whitespace being more friendly to diffs, and this being nice and tidily 
contained.  If you or others have strong opinions, I'm happy to recapitalize 
them.

https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-11 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/94394

>From 1e9a3fde97d907c3cd6be33db91d1c18c7236ffb Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:41:47 -0700
Subject: [PATCH 1/5] [Support] Reformat SipHash.cpp to match libSupport.

While there, give it our usual file header and an acknowledgement,
and remove the imported README.md.SipHash.
---
 llvm/lib/Support/README.md.SipHash | 126 --
 llvm/lib/Support/SipHash.cpp   | 264 ++---
 2 files changed, 129 insertions(+), 261 deletions(-)
 delete mode 100644 llvm/lib/Support/README.md.SipHash

diff --git a/llvm/lib/Support/README.md.SipHash 
b/llvm/lib/Support/README.md.SipHash
deleted file mode 100644
index 4de3cd1854681..0
--- a/llvm/lib/Support/README.md.SipHash
+++ /dev/null
@@ -1,126 +0,0 @@
-# SipHash
-
-[![License:
-CC0-1.0](https://licensebuttons.net/l/zero/1.0/80x15.png)](http://creativecommons.org/publicdomain/zero/1.0/)
-
-[![License: 
MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-
-SipHash is a family of pseudorandom functions (PRFs) optimized for speed on 
short messages.
-This is the reference C code of SipHash: portable, simple, optimized for 
clarity and debugging.
-
-SipHash was designed in 2012 by [Jean-Philippe Aumasson](https://aumasson.jp)
-and [Daniel J. Bernstein](https://cr.yp.to) as a defense against [hash-flooding
-DoS attacks](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf).
-
-SipHash is:
-
-* *Simpler and faster* on short messages than previous cryptographic
-algorithms, such as MACs based on universal hashing.
-
-* *Competitive in performance* with insecure non-cryptographic algorithms, 
such as [fhhash](https://github.com/cbreeden/fxhash).
-
-* *Cryptographically secure*, with no sign of weakness despite multiple 
[cryptanalysis](https://eprint.iacr.org/2019/865) 
[projects](https://eprint.iacr.org/2019/865) by leading cryptographers.
-
-* *Battle-tested*, with successful integration in OSs (Linux kernel, OpenBSD,
-FreeBSD, FreeRTOS), languages (Perl, Python, Ruby, etc.), libraries (OpenSSL 
libcrypto,
-Sodium, etc.) and applications (Wireguard, Redis, etc.).
-
-As a secure pseudorandom function (a.k.a. keyed hash function), SipHash can 
also be used as a secure message authentication code (MAC).
-But SipHash is *not a hash* in the sense of general-purpose key-less hash 
function such as BLAKE3 or SHA-3.
-SipHash should therefore always be used with a secret key in order to be 
secure.
-
-
-## Variants
-
-The default SipHash is *SipHash-2-4*: it takes a 128-bit key, does 2 
compression
-rounds, 4 finalization rounds, and returns a 64-bit tag.
-
-Variants can use a different number of rounds. For example, we proposed 
*SipHash-4-8* as a conservative version.
-
-The following versions are not described in the paper but were designed and 
analyzed to fulfill applications' needs:
-
-* *SipHash-128* returns a 128-bit tag instead of 64-bit. Versions with 
specified number of rounds are SipHash-2-4-128, SipHash4-8-128, and so on.
-
-* *HalfSipHash* works with 32-bit words instead of 64-bit, takes a 64-bit key,
-and returns 32-bit or 64-bit tags. For example, HalfSipHash-2-4-32 has 2
-compression rounds, 4 finalization rounds, and returns a 32-bit tag.
-
-
-## Security
-
-(Half)SipHash-*c*-*d* with *c* ≥ 2 and *d* ≥ 4 is expected to provide the 
maximum PRF
-security for any function with the same key and output size.
-
-The standard PRF security goal allow the attacker access to the output of 
SipHash on messages chosen adaptively by the attacker.
-
-Security is limited by the key size (128 bits for SipHash), such that
-attackers searching 2*s* keys have chance 2*s*−128 of 
finding
-the SipHash key. 
-Security is also limited by the output size. In particular, when
-SipHash is used as a MAC, an attacker who blindly tries 2*s* tags 
will
-succeed with probability 2*s*-*t*, if *t* is that tag's bit size.
-
-
-## Research
-
-* [Research paper](https://www.aumasson.jp/siphash/siphash.pdf) "SipHash: a 
fast short-input PRF" (accepted at INDOCRYPT 2012)
-* [Slides](https://cr.yp.to/talks/2012.12.12/slides.pdf) of the presentation 
of SipHash at INDOCRYPT 2012 (Bernstein)
-* [Slides](https://www.aumasson.jp/siphash/siphash_slides.pdf) of the 
presentation of SipHash at the DIAC workshop (Aumasson)
-
-
-## Usage
-
-Running
-
-```sh
-  make
-```
-
-will build tests for 
-
-* SipHash-2-4-64
-* SipHash-2-4-128
-* HalfSipHash-2-4-32
-* HalfSipHash-2-4-64
-
-
-```C
-  ./test
-```
-
-verifies 64 test vectors, and
-
-```C
-  ./debug
-```
-
-does the same and prints intermediate values.
-
-The code can be adapted to implement SipHash-*c*-*d*, the version of SipHash
-with *c* compression rounds and *d* finalization rounds, by defining `cROUNDS`
-or `dROUNDS` when compiling.  This can be done with `-D` command line arguments
-to many compilers such as below.
-
-```sh
-gcc -Wall --

[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-11 Thread Ahmed Bougacha via llvm-branch-commits


@@ -1,185 +1,149 @@
-/*
-   SipHash reference C implementation
-
-   Copyright (c) 2012-2022 Jean-Philippe Aumasson
-   
-   Copyright (c) 2012-2014 Daniel J. Bernstein 
-
-   To the extent possible under law, the author(s) have dedicated all copyright
-   and related and neighboring rights to this software to the public domain
-   worldwide. This software is distributed without any warranty.
-
-   You should have received a copy of the CC0 Public Domain Dedication along
-   with
-   this software. If not, see
-   .
- */
-
-#include "siphash.h"
-#include 
-#include 
-#include 
-
-/* default: SipHash-2-4 */
-#ifndef cROUNDS
-#define cROUNDS 2
-#endif
-#ifndef dROUNDS
-#define dROUNDS 4
-#endif
+//===--- SipHash.cpp - An ABI-stable string hash 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
 
-#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b
+#include "llvm/Support/Compiler.h"
+#include 
 
-#define U32TO8_LE(p, v)
\
-(p)[0] = (uint8_t)((v));   
\
-(p)[1] = (uint8_t)((v) >> 8);  
\
-(p)[2] = (uint8_t)((v) >> 16); 
\
-(p)[3] = (uint8_t)((v) >> 24);
+// Lightly adapted from the SipHash reference C implementation:
+//   https://github.com/veorq/SipHash
+// by Jean-Philippe Aumasson and Daniel J. Bernstein
 
-#define U64TO8_LE(p, v)
\
-U32TO8_LE((p), (uint32_t)((v)));   
\
-U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
+#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b

ahmedbougacha wrote:

This, I'm a little more inclined to keep the macros as close to original as 
possible, it being the core of the function.  It could help to name the 
function `ROTL` to match the original;  we can turn the whole block into a 
function as well.  I don't feel strongly either way, let me know which you 
prefer.

https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-11 Thread Ahmed Bougacha via llvm-branch-commits


@@ -1,185 +1,149 @@
-/*
-   SipHash reference C implementation
-
-   Copyright (c) 2012-2022 Jean-Philippe Aumasson
-   
-   Copyright (c) 2012-2014 Daniel J. Bernstein 
-
-   To the extent possible under law, the author(s) have dedicated all copyright
-   and related and neighboring rights to this software to the public domain
-   worldwide. This software is distributed without any warranty.
-
-   You should have received a copy of the CC0 Public Domain Dedication along
-   with
-   this software. If not, see
-   .
- */
-
-#include "siphash.h"
-#include 
-#include 
-#include 
-
-/* default: SipHash-2-4 */
-#ifndef cROUNDS
-#define cROUNDS 2
-#endif
-#ifndef dROUNDS
-#define dROUNDS 4
-#endif
+//===--- SipHash.cpp - An ABI-stable string hash 
--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
 
-#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b
+#include "llvm/Support/Compiler.h"
+#include 
 
-#define U32TO8_LE(p, v)
\
-(p)[0] = (uint8_t)((v));   
\
-(p)[1] = (uint8_t)((v) >> 8);  
\
-(p)[2] = (uint8_t)((v) >> 16); 
\
-(p)[3] = (uint8_t)((v) >> 24);
+// Lightly adapted from the SipHash reference C implementation:
+//   https://github.com/veorq/SipHash
+// by Jean-Philippe Aumasson and Daniel J. Bernstein
 
-#define U64TO8_LE(p, v)
\
-U32TO8_LE((p), (uint32_t)((v)));   
\
-U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
+#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b
 
 #define U8TO64_LE(p)   
\
-(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |
\
- ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | 
\
- ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | 
\
- ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
+  (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |  
\
+   ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) |   
\
+   ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) |   
\
+   ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
 
 #define SIPROUND   
\
-do {   
\
-v0 += v1;  
\
-v1 = ROTL(v1, 13); 
\
-v1 ^= v0;  
\
-v0 = ROTL(v0, 32); 
\
-v2 += v3;  
\
-v3 = ROTL(v3, 16); 
\
-v3 ^= v2;  
\
-v0 += v3;  
\
-v3 = ROTL(v3, 21); 
\
-v3 ^= v0;  
\
-v2 += v1;  
\
-v1 = ROTL(v1, 17); 
\
-v1 ^= v2;  
\
-v2 = ROTL(v2, 32); 
\
-} while (0)
-
-#ifdef DEBUG_SIPHASH
-#include 
-
-#define TRACE  
\
-do {   
\
-printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0);   
\
-printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1);   
\
-printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2);   
\
-printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3);   
\
-} while (0)
-#else
-#define TRACE
-#endif
-
-/*
-Computes a SipHash value
-*in: pointer to input data (read-only)
-inlen: input data length in bytes (any size_t value)
-*k: pointer to the key data (read-only), must be 16 bytes 
-*out: pointer to output data (write-only), outlen bytes must be allocated
-o

[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-11 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

I think this version should work on BE hosts, but that's only by thinking 
through the code.  Only the bots will tell us one way or another ;)

https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16-bit ptrauth stable hash. (PR #93902)

2024-06-11 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93902

>From bf413d68cff5ad963c43bb584590908bf03bc3ce Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:36:33 -0700
Subject: [PATCH] [Support] Add SipHash-based 16-bit ptrauth stable hash.

This finally wraps the now-lightly-modified SipHash C reference
implementation, for the main interface we need (16-bit ptrauth
discriminators).

This intentionally doesn't expose a raw interface beyond that to
encourage others to carefully consider their use.

The exact algorithm is the little-endian interpretation of the
non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using the
constant seed `b5d4c9eb79104a796fec8b1b428781d4` (big-endian), with the
result reduced by modulo to the range of non-zero discriminators (i.e.
`(rawHash % 65535) + 1`).

By "stable" we mean that the result of this hash algorithm will the same
across different compiler versions and target platforms.

The 16-bit hashes are used extensively for the AArch64 ptrauth ABI,
because AArch64 can efficiently load a 16-bit immediate into the high
bits of a register without disturbing the remainder of the value, which
serves as a nice blend operation.

16 bits is also sufficiently compact to not inflate a loader relocation.
We disallow zero to guarantee a different discriminator from the places
in the ABI that use a constant zero.

Co-Authored-By: John McCall 
---
 llvm/include/llvm/Support/SipHash.h| 39 ++
 llvm/lib/Support/SipHash.cpp   | 35 +++
 llvm/unittests/Support/CMakeLists.txt  |  1 +
 llvm/unittests/Support/SipHashTest.cpp | 33 ++
 4 files changed, 108 insertions(+)
 create mode 100644 llvm/include/llvm/Support/SipHash.h
 create mode 100644 llvm/unittests/Support/SipHashTest.cpp

diff --git a/llvm/include/llvm/Support/SipHash.h 
b/llvm/include/llvm/Support/SipHash.h
new file mode 100644
index 0..91447b2344eeb
--- /dev/null
+++ b/llvm/include/llvm/Support/SipHash.h
@@ -0,0 +1,39 @@
+//===--- SipHash.h - An ABI-stable string SipHash ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// A family of ABI-stable string hash algorithms based on SipHash, currently
+// used to compute ptrauth discriminators.
+//
+//===--===//
+
+#ifndef LLVM_SUPPORT_SIPHASH_H
+#define LLVM_SUPPORT_SIPHASH_H
+
+#include 
+
+namespace llvm {
+class StringRef;
+
+/// Compute a stable non-zero 16-bit hash of the given string.
+///
+/// The exact algorithm is the little-endian interpretation of the
+/// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
+/// a specific seed value which can be found in the source.
+/// This 64-bit result is truncated to a non-zero 16-bit value.
+///
+/// We use a 16-bit discriminator because ARM64 can efficiently load
+/// a 16-bit immediate into the high bits of a register without disturbing
+/// the remainder of the value, which serves as a nice blend operation.
+/// 16 bits is also sufficiently compact to not inflate a loader relocation.
+/// We disallow zero to guarantee a different discriminator from the places
+/// in the ABI that use a constant zero.
+uint16_t getPointerAuthStableSipHash(StringRef S);
+
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/Support/SipHash.cpp b/llvm/lib/Support/SipHash.cpp
index ef882ae4d8745..b1b4bede7637d 100644
--- a/llvm/lib/Support/SipHash.cpp
+++ b/llvm/lib/Support/SipHash.cpp
@@ -5,10 +5,23 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 
//===--===//
+//
+//  This file implements an ABI-stable string hash based on SipHash, used to
+//  compute ptrauth discriminators.
+//
+//===--===//
 
+#include "llvm/Support/SipHash.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
 #include 
 
+using namespace llvm;
+
+#define DEBUG_TYPE "llvm-siphash"
+
 // Lightly adapted from the SipHash reference C implementation by
 // Jean-Philippe Aumasson and Daniel J. Bernstein.
 
@@ -133,3 +146,25 @@ static inline ResultTy siphash(const unsigned char *in, 
uint64_t inlen,
 
   return firstHalf | (ResultTy(secondHalf) << (sizeof(ResultTy) == 8 ? 0 : 
64));
 }
+
+//===--- LLVM-specific wrapper around siphash.
+
+/// Compute an ABI-stable 16-bit hash of the given string.
+uint16_t llvm::getPointerAuthStableSipHash(StringRef Str) {
+  static const uint8_t K[16] = {0xb5, 0xd4, 0xc9, 0xeb, 0x79, 0x10, 0x4a, 0x79,
+   

[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-11 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-13 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/94394

>From 1e9a3fde97d907c3cd6be33db91d1c18c7236ffb Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:41:47 -0700
Subject: [PATCH 1/6] [Support] Reformat SipHash.cpp to match libSupport.

While there, give it our usual file header and an acknowledgement,
and remove the imported README.md.SipHash.
---
 llvm/lib/Support/README.md.SipHash | 126 --
 llvm/lib/Support/SipHash.cpp   | 264 ++---
 2 files changed, 129 insertions(+), 261 deletions(-)
 delete mode 100644 llvm/lib/Support/README.md.SipHash

diff --git a/llvm/lib/Support/README.md.SipHash 
b/llvm/lib/Support/README.md.SipHash
deleted file mode 100644
index 4de3cd1854681..0
--- a/llvm/lib/Support/README.md.SipHash
+++ /dev/null
@@ -1,126 +0,0 @@
-# SipHash
-
-[![License:
-CC0-1.0](https://licensebuttons.net/l/zero/1.0/80x15.png)](http://creativecommons.org/publicdomain/zero/1.0/)
-
-[![License: 
MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-
-SipHash is a family of pseudorandom functions (PRFs) optimized for speed on 
short messages.
-This is the reference C code of SipHash: portable, simple, optimized for 
clarity and debugging.
-
-SipHash was designed in 2012 by [Jean-Philippe Aumasson](https://aumasson.jp)
-and [Daniel J. Bernstein](https://cr.yp.to) as a defense against [hash-flooding
-DoS attacks](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf).
-
-SipHash is:
-
-* *Simpler and faster* on short messages than previous cryptographic
-algorithms, such as MACs based on universal hashing.
-
-* *Competitive in performance* with insecure non-cryptographic algorithms, 
such as [fhhash](https://github.com/cbreeden/fxhash).
-
-* *Cryptographically secure*, with no sign of weakness despite multiple 
[cryptanalysis](https://eprint.iacr.org/2019/865) 
[projects](https://eprint.iacr.org/2019/865) by leading cryptographers.
-
-* *Battle-tested*, with successful integration in OSs (Linux kernel, OpenBSD,
-FreeBSD, FreeRTOS), languages (Perl, Python, Ruby, etc.), libraries (OpenSSL 
libcrypto,
-Sodium, etc.) and applications (Wireguard, Redis, etc.).
-
-As a secure pseudorandom function (a.k.a. keyed hash function), SipHash can 
also be used as a secure message authentication code (MAC).
-But SipHash is *not a hash* in the sense of general-purpose key-less hash 
function such as BLAKE3 or SHA-3.
-SipHash should therefore always be used with a secret key in order to be 
secure.
-
-
-## Variants
-
-The default SipHash is *SipHash-2-4*: it takes a 128-bit key, does 2 
compression
-rounds, 4 finalization rounds, and returns a 64-bit tag.
-
-Variants can use a different number of rounds. For example, we proposed 
*SipHash-4-8* as a conservative version.
-
-The following versions are not described in the paper but were designed and 
analyzed to fulfill applications' needs:
-
-* *SipHash-128* returns a 128-bit tag instead of 64-bit. Versions with 
specified number of rounds are SipHash-2-4-128, SipHash4-8-128, and so on.
-
-* *HalfSipHash* works with 32-bit words instead of 64-bit, takes a 64-bit key,
-and returns 32-bit or 64-bit tags. For example, HalfSipHash-2-4-32 has 2
-compression rounds, 4 finalization rounds, and returns a 32-bit tag.
-
-
-## Security
-
-(Half)SipHash-*c*-*d* with *c* ≥ 2 and *d* ≥ 4 is expected to provide the 
maximum PRF
-security for any function with the same key and output size.
-
-The standard PRF security goal allow the attacker access to the output of 
SipHash on messages chosen adaptively by the attacker.
-
-Security is limited by the key size (128 bits for SipHash), such that
-attackers searching 2*s* keys have chance 2*s*−128 of 
finding
-the SipHash key. 
-Security is also limited by the output size. In particular, when
-SipHash is used as a MAC, an attacker who blindly tries 2*s* tags 
will
-succeed with probability 2*s*-*t*, if *t* is that tag's bit size.
-
-
-## Research
-
-* [Research paper](https://www.aumasson.jp/siphash/siphash.pdf) "SipHash: a 
fast short-input PRF" (accepted at INDOCRYPT 2012)
-* [Slides](https://cr.yp.to/talks/2012.12.12/slides.pdf) of the presentation 
of SipHash at INDOCRYPT 2012 (Bernstein)
-* [Slides](https://www.aumasson.jp/siphash/siphash_slides.pdf) of the 
presentation of SipHash at the DIAC workshop (Aumasson)
-
-
-## Usage
-
-Running
-
-```sh
-  make
-```
-
-will build tests for 
-
-* SipHash-2-4-64
-* SipHash-2-4-128
-* HalfSipHash-2-4-32
-* HalfSipHash-2-4-64
-
-
-```C
-  ./test
-```
-
-verifies 64 test vectors, and
-
-```C
-  ./debug
-```
-
-does the same and prints intermediate values.
-
-The code can be adapted to implement SipHash-*c*-*d*, the version of SipHash
-with *c* compression rounds and *d* finalization rounds, by defining `cROUNDS`
-or `dROUNDS` when compiling.  This can be done with `-D` command line arguments
-to many compilers such as below.
-
-```sh
-gcc -Wall --

[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-13 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

[37c84b9](https://github.com/llvm/llvm-project/pull/94394/commits/37c84b9dce70f40db8a7c27b7de8232c4d10f78f)
 shows what I had in mind, let me know what you all think.  I added:
```
void getSipHash_2_4_64(const uint8_t *In, uint64_t InLen,
   const uint8_t (&K)[16], uint8_t (&Out)[8]);

void getSipHash_2_4_128(const uint8_t *In, uint64_t InLen,
const uint8_t (&K)[16], uint8_t (&Out)[16]);
```
as the core interfaces, and mimicked the ref. test harness to reuse the same 
test vectors.  If this seems reasonable to yall I'm happy to extract the 
vectors.h file from the ref. implementation into the "Import original sources" 
PR – that's why I kept it open ;)

https://github.com/llvm/llvm-project/pull/94394
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-13 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/94394

>From 1e9a3fde97d907c3cd6be33db91d1c18c7236ffb Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:41:47 -0700
Subject: [PATCH 1/7] [Support] Reformat SipHash.cpp to match libSupport.

While there, give it our usual file header and an acknowledgement,
and remove the imported README.md.SipHash.
---
 llvm/lib/Support/README.md.SipHash | 126 --
 llvm/lib/Support/SipHash.cpp   | 264 ++---
 2 files changed, 129 insertions(+), 261 deletions(-)
 delete mode 100644 llvm/lib/Support/README.md.SipHash

diff --git a/llvm/lib/Support/README.md.SipHash 
b/llvm/lib/Support/README.md.SipHash
deleted file mode 100644
index 4de3cd1854681..0
--- a/llvm/lib/Support/README.md.SipHash
+++ /dev/null
@@ -1,126 +0,0 @@
-# SipHash
-
-[![License:
-CC0-1.0](https://licensebuttons.net/l/zero/1.0/80x15.png)](http://creativecommons.org/publicdomain/zero/1.0/)
-
-[![License: 
MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-
-SipHash is a family of pseudorandom functions (PRFs) optimized for speed on 
short messages.
-This is the reference C code of SipHash: portable, simple, optimized for 
clarity and debugging.
-
-SipHash was designed in 2012 by [Jean-Philippe Aumasson](https://aumasson.jp)
-and [Daniel J. Bernstein](https://cr.yp.to) as a defense against [hash-flooding
-DoS attacks](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf).
-
-SipHash is:
-
-* *Simpler and faster* on short messages than previous cryptographic
-algorithms, such as MACs based on universal hashing.
-
-* *Competitive in performance* with insecure non-cryptographic algorithms, 
such as [fhhash](https://github.com/cbreeden/fxhash).
-
-* *Cryptographically secure*, with no sign of weakness despite multiple 
[cryptanalysis](https://eprint.iacr.org/2019/865) 
[projects](https://eprint.iacr.org/2019/865) by leading cryptographers.
-
-* *Battle-tested*, with successful integration in OSs (Linux kernel, OpenBSD,
-FreeBSD, FreeRTOS), languages (Perl, Python, Ruby, etc.), libraries (OpenSSL 
libcrypto,
-Sodium, etc.) and applications (Wireguard, Redis, etc.).
-
-As a secure pseudorandom function (a.k.a. keyed hash function), SipHash can 
also be used as a secure message authentication code (MAC).
-But SipHash is *not a hash* in the sense of general-purpose key-less hash 
function such as BLAKE3 or SHA-3.
-SipHash should therefore always be used with a secret key in order to be 
secure.
-
-
-## Variants
-
-The default SipHash is *SipHash-2-4*: it takes a 128-bit key, does 2 
compression
-rounds, 4 finalization rounds, and returns a 64-bit tag.
-
-Variants can use a different number of rounds. For example, we proposed 
*SipHash-4-8* as a conservative version.
-
-The following versions are not described in the paper but were designed and 
analyzed to fulfill applications' needs:
-
-* *SipHash-128* returns a 128-bit tag instead of 64-bit. Versions with 
specified number of rounds are SipHash-2-4-128, SipHash4-8-128, and so on.
-
-* *HalfSipHash* works with 32-bit words instead of 64-bit, takes a 64-bit key,
-and returns 32-bit or 64-bit tags. For example, HalfSipHash-2-4-32 has 2
-compression rounds, 4 finalization rounds, and returns a 32-bit tag.
-
-
-## Security
-
-(Half)SipHash-*c*-*d* with *c* ≥ 2 and *d* ≥ 4 is expected to provide the 
maximum PRF
-security for any function with the same key and output size.
-
-The standard PRF security goal allow the attacker access to the output of 
SipHash on messages chosen adaptively by the attacker.
-
-Security is limited by the key size (128 bits for SipHash), such that
-attackers searching 2*s* keys have chance 2*s*−128 of 
finding
-the SipHash key. 
-Security is also limited by the output size. In particular, when
-SipHash is used as a MAC, an attacker who blindly tries 2*s* tags 
will
-succeed with probability 2*s*-*t*, if *t* is that tag's bit size.
-
-
-## Research
-
-* [Research paper](https://www.aumasson.jp/siphash/siphash.pdf) "SipHash: a 
fast short-input PRF" (accepted at INDOCRYPT 2012)
-* [Slides](https://cr.yp.to/talks/2012.12.12/slides.pdf) of the presentation 
of SipHash at INDOCRYPT 2012 (Bernstein)
-* [Slides](https://www.aumasson.jp/siphash/siphash_slides.pdf) of the 
presentation of SipHash at the DIAC workshop (Aumasson)
-
-
-## Usage
-
-Running
-
-```sh
-  make
-```
-
-will build tests for 
-
-* SipHash-2-4-64
-* SipHash-2-4-128
-* HalfSipHash-2-4-32
-* HalfSipHash-2-4-64
-
-
-```C
-  ./test
-```
-
-verifies 64 test vectors, and
-
-```C
-  ./debug
-```
-
-does the same and prints intermediate values.
-
-The code can be adapted to implement SipHash-*c*-*d*, the version of SipHash
-with *c* compression rounds and *d* finalization rounds, by defining `cROUNDS`
-or `dROUNDS` when compiling.  This can be done with `-D` command line arguments
-to many compilers such as below.
-
-```sh
-gcc -Wall --

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-13 Thread Ahmed Bougacha via llvm-branch-commits


@@ -2061,6 +2071,58 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) {
   }
 }
 
+ConstantLValue
+ConstantLValueEmitter::emitPointerAuthSignConstant(const CallExpr *E) {
+  llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->getArg(0));
+  unsigned Key = emitPointerAuthKey(E->getArg(1));
+  llvm::Constant *StorageAddress;
+  llvm::Constant *OtherDiscriminator;
+  std::tie(StorageAddress, OtherDiscriminator) =

ahmedbougacha wrote:

Yeah, this simply predates structured bindings;  we can indeed use them now.

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-13 Thread Ahmed Bougacha via llvm-branch-commits


@@ -58,6 +58,35 @@ void test_string_discriminator(const char *str) {
 }
 
 
+void test_sign_constant(int *dp, int (*fp)(int)) {
+  __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY); // expected-error 
{{too few arguments}}
+  __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, &dv, &dv); // 
expected-error {{too many arguments}}
+
+  __builtin_ptrauth_sign_constant(mismatched_type, VALID_DATA_KEY, 0); // 
expected-error {{signed value must have pointer type; type here is 'struct A'}}
+  __builtin_ptrauth_sign_constant(&dv, mismatched_type, 0); // expected-error 
{{passing 'struct A' to parameter of incompatible type 'int'}}
+  __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, mismatched_type); // 
expected-error {{extra discriminator must have pointer or integer type; type 
here is 'struct A'}}
+
+  (void) __builtin_ptrauth_sign_constant(NULL, VALID_DATA_KEY, &dv); // 
expected-error {{argument to ptrauth_sign_constant must refer to a global 
variable or function}}

ahmedbougacha wrote:

We could special-case null pointers, but they're already covered by the 
diagnostic, which asks for global variables or functions – which NULL isn't.  
For auth/sign, we don't have that sort of constraint on the pointer: it really 
is NULL and NULL alone that's special.

Now, the more interesting question is whether we should allow null pointers at 
all here.  Since defining these original builtins we have taught the qualifier 
to have a mode that signs/authenticates null, for some specific use-cases where 
replacing a signed value with NULL (which is otherwise never signed or 
authenticated) would bypass signing in a problematic way.
We haven't had the chance or need to revisit the builtins to allow sign/auth of 
NULL, but it's reasonable to add that support in the future.  We'd have to 
consider how to expose that in the builtins, because it's probably still 
something that's almost always a mistake;  more builtins would be an easy 
solution but maybe not a sophisticated one.

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-13 Thread Ahmed Bougacha via llvm-branch-commits


@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed 
pointers signed with
 the given key, extract the raw pointer from it.  This operation does not trap
 and cannot fail, even if the pointer is not validly signed.
 
+``ptrauth_sign_constant``
+^
+
+.. code-block:: c
+
+  ptrauth_sign_constant(pointer, key, discriminator)
+
+Return a signed pointer for a constant address in a manner which guarantees
+a non-attackable sequence.

ahmedbougacha wrote:

Later additions to this document describe that in depth, you can look for
> [clang][docs] Document the ptrauth security model.

on my branch

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-13 Thread Ahmed Bougacha via llvm-branch-commits


@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed 
pointers signed with
 the given key, extract the raw pointer from it.  This operation does not trap
 and cannot fail, even if the pointer is not validly signed.
 
+``ptrauth_sign_constant``
+^
+
+.. code-block:: c
+
+  ptrauth_sign_constant(pointer, key, discriminator)
+
+Return a signed pointer for a constant address in a manner which guarantees
+a non-attackable sequence.
+
+``pointer`` must be a constant expression of pointer type which evaluates to
+a non-null pointer.  The result will have the same type as ``discriminator``.
+
+Calls to this are constant expressions if the discriminator is a null-pointer
+constant expression or an integer constant expression. Implementations may
+allow other pointer expressions as well.

ahmedbougacha wrote:

Yeah, I agree today this could simply be "it's always a constant expression";  
I'll rewrite it (cc @rjmccall if this looks like anything to you)

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)

2024-06-14 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/94394

>From 1e9a3fde97d907c3cd6be33db91d1c18c7236ffb Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:41:47 -0700
Subject: [PATCH 1/8] [Support] Reformat SipHash.cpp to match libSupport.

While there, give it our usual file header and an acknowledgement,
and remove the imported README.md.SipHash.
---
 llvm/lib/Support/README.md.SipHash | 126 --
 llvm/lib/Support/SipHash.cpp   | 264 ++---
 2 files changed, 129 insertions(+), 261 deletions(-)
 delete mode 100644 llvm/lib/Support/README.md.SipHash

diff --git a/llvm/lib/Support/README.md.SipHash 
b/llvm/lib/Support/README.md.SipHash
deleted file mode 100644
index 4de3cd1854681..0
--- a/llvm/lib/Support/README.md.SipHash
+++ /dev/null
@@ -1,126 +0,0 @@
-# SipHash
-
-[![License:
-CC0-1.0](https://licensebuttons.net/l/zero/1.0/80x15.png)](http://creativecommons.org/publicdomain/zero/1.0/)
-
-[![License: 
MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
-
-
-SipHash is a family of pseudorandom functions (PRFs) optimized for speed on 
short messages.
-This is the reference C code of SipHash: portable, simple, optimized for 
clarity and debugging.
-
-SipHash was designed in 2012 by [Jean-Philippe Aumasson](https://aumasson.jp)
-and [Daniel J. Bernstein](https://cr.yp.to) as a defense against [hash-flooding
-DoS attacks](https://aumasson.jp/siphash/siphashdos_29c3_slides.pdf).
-
-SipHash is:
-
-* *Simpler and faster* on short messages than previous cryptographic
-algorithms, such as MACs based on universal hashing.
-
-* *Competitive in performance* with insecure non-cryptographic algorithms, 
such as [fhhash](https://github.com/cbreeden/fxhash).
-
-* *Cryptographically secure*, with no sign of weakness despite multiple 
[cryptanalysis](https://eprint.iacr.org/2019/865) 
[projects](https://eprint.iacr.org/2019/865) by leading cryptographers.
-
-* *Battle-tested*, with successful integration in OSs (Linux kernel, OpenBSD,
-FreeBSD, FreeRTOS), languages (Perl, Python, Ruby, etc.), libraries (OpenSSL 
libcrypto,
-Sodium, etc.) and applications (Wireguard, Redis, etc.).
-
-As a secure pseudorandom function (a.k.a. keyed hash function), SipHash can 
also be used as a secure message authentication code (MAC).
-But SipHash is *not a hash* in the sense of general-purpose key-less hash 
function such as BLAKE3 or SHA-3.
-SipHash should therefore always be used with a secret key in order to be 
secure.
-
-
-## Variants
-
-The default SipHash is *SipHash-2-4*: it takes a 128-bit key, does 2 
compression
-rounds, 4 finalization rounds, and returns a 64-bit tag.
-
-Variants can use a different number of rounds. For example, we proposed 
*SipHash-4-8* as a conservative version.
-
-The following versions are not described in the paper but were designed and 
analyzed to fulfill applications' needs:
-
-* *SipHash-128* returns a 128-bit tag instead of 64-bit. Versions with 
specified number of rounds are SipHash-2-4-128, SipHash4-8-128, and so on.
-
-* *HalfSipHash* works with 32-bit words instead of 64-bit, takes a 64-bit key,
-and returns 32-bit or 64-bit tags. For example, HalfSipHash-2-4-32 has 2
-compression rounds, 4 finalization rounds, and returns a 32-bit tag.
-
-
-## Security
-
-(Half)SipHash-*c*-*d* with *c* ≥ 2 and *d* ≥ 4 is expected to provide the 
maximum PRF
-security for any function with the same key and output size.
-
-The standard PRF security goal allow the attacker access to the output of 
SipHash on messages chosen adaptively by the attacker.
-
-Security is limited by the key size (128 bits for SipHash), such that
-attackers searching 2*s* keys have chance 2*s*−128 of 
finding
-the SipHash key. 
-Security is also limited by the output size. In particular, when
-SipHash is used as a MAC, an attacker who blindly tries 2*s* tags 
will
-succeed with probability 2*s*-*t*, if *t* is that tag's bit size.
-
-
-## Research
-
-* [Research paper](https://www.aumasson.jp/siphash/siphash.pdf) "SipHash: a 
fast short-input PRF" (accepted at INDOCRYPT 2012)
-* [Slides](https://cr.yp.to/talks/2012.12.12/slides.pdf) of the presentation 
of SipHash at INDOCRYPT 2012 (Bernstein)
-* [Slides](https://www.aumasson.jp/siphash/siphash_slides.pdf) of the 
presentation of SipHash at the DIAC workshop (Aumasson)
-
-
-## Usage
-
-Running
-
-```sh
-  make
-```
-
-will build tests for 
-
-* SipHash-2-4-64
-* SipHash-2-4-128
-* HalfSipHash-2-4-32
-* HalfSipHash-2-4-64
-
-
-```C
-  ./test
-```
-
-verifies 64 test vectors, and
-
-```C
-  ./debug
-```
-
-does the same and prints intermediate values.
-
-The code can be adapted to implement SipHash-*c*-*d*, the version of SipHash
-with *c* compression rounds and *d* finalization rounds, by defining `cROUNDS`
-or `dROUNDS` when compiling.  This can be done with `-D` command line arguments
-to many compilers such as below.
-
-```sh
-gcc -Wall --

[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16-bit ptrauth stable hash. (PR #93902)

2024-06-14 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93902

>From bf413d68cff5ad963c43bb584590908bf03bc3ce Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Tue, 4 Jun 2024 12:36:33 -0700
Subject: [PATCH] [Support] Add SipHash-based 16-bit ptrauth stable hash.

This finally wraps the now-lightly-modified SipHash C reference
implementation, for the main interface we need (16-bit ptrauth
discriminators).

This intentionally doesn't expose a raw interface beyond that to
encourage others to carefully consider their use.

The exact algorithm is the little-endian interpretation of the
non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using the
constant seed `b5d4c9eb79104a796fec8b1b428781d4` (big-endian), with the
result reduced by modulo to the range of non-zero discriminators (i.e.
`(rawHash % 65535) + 1`).

By "stable" we mean that the result of this hash algorithm will the same
across different compiler versions and target platforms.

The 16-bit hashes are used extensively for the AArch64 ptrauth ABI,
because AArch64 can efficiently load a 16-bit immediate into the high
bits of a register without disturbing the remainder of the value, which
serves as a nice blend operation.

16 bits is also sufficiently compact to not inflate a loader relocation.
We disallow zero to guarantee a different discriminator from the places
in the ABI that use a constant zero.

Co-Authored-By: John McCall 
---
 llvm/include/llvm/Support/SipHash.h| 39 ++
 llvm/lib/Support/SipHash.cpp   | 35 +++
 llvm/unittests/Support/CMakeLists.txt  |  1 +
 llvm/unittests/Support/SipHashTest.cpp | 33 ++
 4 files changed, 108 insertions(+)
 create mode 100644 llvm/include/llvm/Support/SipHash.h
 create mode 100644 llvm/unittests/Support/SipHashTest.cpp

diff --git a/llvm/include/llvm/Support/SipHash.h 
b/llvm/include/llvm/Support/SipHash.h
new file mode 100644
index 0..91447b2344eeb
--- /dev/null
+++ b/llvm/include/llvm/Support/SipHash.h
@@ -0,0 +1,39 @@
+//===--- SipHash.h - An ABI-stable string SipHash ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// A family of ABI-stable string hash algorithms based on SipHash, currently
+// used to compute ptrauth discriminators.
+//
+//===--===//
+
+#ifndef LLVM_SUPPORT_SIPHASH_H
+#define LLVM_SUPPORT_SIPHASH_H
+
+#include 
+
+namespace llvm {
+class StringRef;
+
+/// Compute a stable non-zero 16-bit hash of the given string.
+///
+/// The exact algorithm is the little-endian interpretation of the
+/// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
+/// a specific seed value which can be found in the source.
+/// This 64-bit result is truncated to a non-zero 16-bit value.
+///
+/// We use a 16-bit discriminator because ARM64 can efficiently load
+/// a 16-bit immediate into the high bits of a register without disturbing
+/// the remainder of the value, which serves as a nice blend operation.
+/// 16 bits is also sufficiently compact to not inflate a loader relocation.
+/// We disallow zero to guarantee a different discriminator from the places
+/// in the ABI that use a constant zero.
+uint16_t getPointerAuthStableSipHash(StringRef S);
+
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/Support/SipHash.cpp b/llvm/lib/Support/SipHash.cpp
index ef882ae4d8745..b1b4bede7637d 100644
--- a/llvm/lib/Support/SipHash.cpp
+++ b/llvm/lib/Support/SipHash.cpp
@@ -5,10 +5,23 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 
//===--===//
+//
+//  This file implements an ABI-stable string hash based on SipHash, used to
+//  compute ptrauth discriminators.
+//
+//===--===//
 
+#include "llvm/Support/SipHash.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
 #include 
 
+using namespace llvm;
+
+#define DEBUG_TYPE "llvm-siphash"
+
 // Lightly adapted from the SipHash reference C implementation by
 // Jean-Philippe Aumasson and Daniel J. Bernstein.
 
@@ -133,3 +146,25 @@ static inline ResultTy siphash(const unsigned char *in, 
uint64_t inlen,
 
   return firstHalf | (ResultTy(secondHalf) << (sizeof(ResultTy) == 8 ? 0 : 
64));
 }
+
+//===--- LLVM-specific wrapper around siphash.
+
+/// Compute an ABI-stable 16-bit hash of the given string.
+uint16_t llvm::getPointerAuthStableSipHash(StringRef Str) {
+  static const uint8_t K[16] = {0xb5, 0xd4, 0xc9, 0xeb, 0x79, 0x10, 0x4a, 0x79,
+   

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93904

>From 20bbad26fa9f068910baf50b5abb60a0f4557564 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:33:04 -0700
Subject: [PATCH 1/4] [clang] Define ptrauth_sign_constant builtin.

This is constant-expression equivalent to __builtin_ptrauth_sign,
allowing its usage in global initializers, but requiring constant
pointers and discriminators.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   6 +
 clang/lib/AST/ExprConstant.cpp|   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |   3 +
 clang/lib/CodeGen/CGExprConstant.cpp  |  62 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  77 +++
 clang/lib/CodeGen/CMakeLists.txt  |   1 +
 clang/lib/CodeGen/CodeGenModule.h |   5 +
 clang/lib/Headers/ptrauth.h   |  25 
 clang/lib/Sema/SemaChecking.cpp   | 128 --
 .../CodeGen/ptrauth-intrinsic-sign-constant.c |  20 +++
 clang/test/Sema/ptrauth-intrinsics-macro.c|   4 +
 clang/test/Sema/ptrauth.c |  28 
 14 files changed, 359 insertions(+), 14 deletions(-)
 create mode 100644 clang/lib/CodeGen/CGPointerAuth.cpp
 create mode 100644 clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index e07ddf3b9b70b..9342b6bc75fc8 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4393,6 +4393,12 @@ def PtrauthSignUnauthenticated : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthSignConstant : Builtin {
+  let Spellings = ["__builtin_ptrauth_sign_constant"];
+  let Attributes = [CustomTypeChecking, NoThrow, Const, Constexpr];
+  let Prototype = "void*(void*,int,void*)";
+}
+
 def PtrauthSignGenericData : Builtin {
   let Spellings = ["__builtin_ptrauth_sign_generic_data"];
   let Attributes = [CustomTypeChecking, NoThrow, Const];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0900dad3c18cd..a5675879f45bc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -924,6 +924,13 @@ def err_ptrauth_value_bad_type :
   Error<"%select{signed value|extra discriminator|blended pointer|blended "
 "integer}0 must have %select{pointer|integer|pointer or integer}1 "
 "type; type here is %2">;
+def err_ptrauth_bad_constant_pointer :
+  Error<"argument to ptrauth_sign_constant must refer to a global variable "
+"or function">;
+def err_ptrauth_bad_constant_discriminator :
+  Error<"discriminator argument to ptrauth_sign_constant must be a constant "
+"integer, the address of the global variable where the result "
+"will be stored, or a blend of the two">;
 def warn_ptrauth_sign_null_pointer :
   Warning<"signing a null pointer will yield a non-null pointer">,
   InGroup;
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index fda0855dc8683..8c62d8597ecbe 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -104,6 +104,12 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, 
QualType T);
 unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 const RecordDecl *RD, const FieldDecl *FD);
 
+/// Return a signed constant pointer.
+llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM,
+ llvm::Constant *pointer,
+ unsigned key,
+ llvm::Constant *storageAddress,
+ llvm::Constant *otherDiscriminator);
 /// Given the language and code-generation options that Clang was configured
 /// with, set the default LLVM IR attributes for a function definition.
 /// The attributes set here are mostly global target-configuration and
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 97b4c2080e14f..799872fe13c08 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2042,6 +2042,7 @@ static bool IsNoOpCall(const CallExpr *E) {
   unsigned Builtin = E->getBuiltinCallee();
   return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
   Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
+  Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
   Builtin == Builtin::BI__builtin_function_start);
 }
 
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 08a89bd123d03..fd4fe1633ea29 100644
--- a/clang/li

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93904

>From 20bbad26fa9f068910baf50b5abb60a0f4557564 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:33:04 -0700
Subject: [PATCH 1/5] [clang] Define ptrauth_sign_constant builtin.

This is constant-expression equivalent to __builtin_ptrauth_sign,
allowing its usage in global initializers, but requiring constant
pointers and discriminators.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   6 +
 clang/lib/AST/ExprConstant.cpp|   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |   3 +
 clang/lib/CodeGen/CGExprConstant.cpp  |  62 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  77 +++
 clang/lib/CodeGen/CMakeLists.txt  |   1 +
 clang/lib/CodeGen/CodeGenModule.h |   5 +
 clang/lib/Headers/ptrauth.h   |  25 
 clang/lib/Sema/SemaChecking.cpp   | 128 --
 .../CodeGen/ptrauth-intrinsic-sign-constant.c |  20 +++
 clang/test/Sema/ptrauth-intrinsics-macro.c|   4 +
 clang/test/Sema/ptrauth.c |  28 
 14 files changed, 359 insertions(+), 14 deletions(-)
 create mode 100644 clang/lib/CodeGen/CGPointerAuth.cpp
 create mode 100644 clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index e07ddf3b9b70b..9342b6bc75fc8 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4393,6 +4393,12 @@ def PtrauthSignUnauthenticated : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthSignConstant : Builtin {
+  let Spellings = ["__builtin_ptrauth_sign_constant"];
+  let Attributes = [CustomTypeChecking, NoThrow, Const, Constexpr];
+  let Prototype = "void*(void*,int,void*)";
+}
+
 def PtrauthSignGenericData : Builtin {
   let Spellings = ["__builtin_ptrauth_sign_generic_data"];
   let Attributes = [CustomTypeChecking, NoThrow, Const];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0900dad3c18cd..a5675879f45bc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -924,6 +924,13 @@ def err_ptrauth_value_bad_type :
   Error<"%select{signed value|extra discriminator|blended pointer|blended "
 "integer}0 must have %select{pointer|integer|pointer or integer}1 "
 "type; type here is %2">;
+def err_ptrauth_bad_constant_pointer :
+  Error<"argument to ptrauth_sign_constant must refer to a global variable "
+"or function">;
+def err_ptrauth_bad_constant_discriminator :
+  Error<"discriminator argument to ptrauth_sign_constant must be a constant "
+"integer, the address of the global variable where the result "
+"will be stored, or a blend of the two">;
 def warn_ptrauth_sign_null_pointer :
   Warning<"signing a null pointer will yield a non-null pointer">,
   InGroup;
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index fda0855dc8683..8c62d8597ecbe 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -104,6 +104,12 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, 
QualType T);
 unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 const RecordDecl *RD, const FieldDecl *FD);
 
+/// Return a signed constant pointer.
+llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM,
+ llvm::Constant *pointer,
+ unsigned key,
+ llvm::Constant *storageAddress,
+ llvm::Constant *otherDiscriminator);
 /// Given the language and code-generation options that Clang was configured
 /// with, set the default LLVM IR attributes for a function definition.
 /// The attributes set here are mostly global target-configuration and
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 97b4c2080e14f..799872fe13c08 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2042,6 +2042,7 @@ static bool IsNoOpCall(const CallExpr *E) {
   unsigned Builtin = E->getBuiltinCallee();
   return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
   Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
+  Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
   Builtin == Builtin::BI__builtin_function_start);
 }
 
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 08a89bd123d03..fd4fe1633ea29 100644
--- a/clang/li

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits


@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-intrinsics -emit-llvm %s  
-o - | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-elf -fptrauth-intrinsics -emit-llvm %s  
-o - | FileCheck %s
+
+extern int external;
+
+// CHECK: @ptr1 = global ptr ptrauth (ptr @external, i32 0, i64 26)
+void *ptr1 = __builtin_ptrauth_sign_constant(&external, 0, 26);
+
+// CHECK: @ptr2 = global ptr ptrauth (ptr @external, i32 2, i64 26, ptr @ptr2)
+void *ptr2 = __builtin_ptrauth_sign_constant(&external, 2, 
__builtin_ptrauth_blend_discriminator(&ptr2, 26));
+
+// CHECK: @ptr3 = global ptr null
+void *ptr3;

ahmedbougacha wrote:

(1) is an old artifact that I fixed separately, but (2) is interesting if we 
test real pointers, not necessarily just `NULL`;  added that and a few others

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits


@@ -2074,16 +2091,91 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg,
   if (convertArgumentToType(S, Arg, ExpectedTy))
 return true;
 
-  // Warn about null pointers for non-generic sign and auth operations.
-  if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
-  Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) {
-S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign
-  ? diag::warn_ptrauth_sign_null_pointer
-  : diag::warn_ptrauth_auth_null_pointer)
-<< Arg->getSourceRange();
+  if (!RequireConstant) {
+// Warn about null pointers for non-generic sign and auth operations.
+if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
+Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) 
{
+  S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign
+? diag::warn_ptrauth_sign_null_pointer
+: diag::warn_ptrauth_auth_null_pointer)
+  << Arg->getSourceRange();
+}
+
+return false;
   }
 
-  return false;
+  // Perform special checking on the arguments to ptrauth_sign_constant.
+
+  // The main argument.
+  if (OpKind == PAO_Sign) {
+// Require the value we're signing to have a special form.
+auto BaseOffsetPair = findConstantBaseAndOffset(S, Arg);
+bool Invalid;
+
+// Must be rooted in a declaration reference.
+if (!BaseOffsetPair.first) {
+  Invalid = true;
+
+  // If it's a function declaration, we can't have an offset.
+} else if (isa(BaseOffsetPair.first)) {
+  Invalid = !BaseOffsetPair.second.isZero();
+
+  // Otherwise we're fine.
+} else {
+  Invalid = false;
+}
+
+if (Invalid) {
+  S.Diag(Arg->getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
+}
+return Invalid;
+  }
+
+  // The discriminator argument.
+  assert(OpKind == PAO_Discriminator);
+
+  // Must be a pointer or integer or blend thereof.
+  Expr *Pointer = nullptr;
+  Expr *Integer = nullptr;
+  if (auto *Call = dyn_cast(Arg->IgnoreParens())) {
+if (Call->getBuiltinCallee() ==
+Builtin::BI__builtin_ptrauth_blend_discriminator) {
+  Pointer = Call->getArg(0);
+  Integer = Call->getArg(1);
+}
+  }
+  if (!Pointer && !Integer) {
+if (Arg->getType()->isPointerType())
+  Pointer = Arg;
+else
+  Integer = Arg;
+  }
+
+  // Check the pointer.
+  bool Invalid = false;
+  if (Pointer) {
+assert(Pointer->getType()->isPointerType());
+
+// TODO: if we're initializing a global, check that the address is
+// somehow related to what we're initializing.  This probably will
+// never really be feasible and we'll have to catch it at link-time.
+auto BaseOffsetPair = findConstantBaseAndOffset(S, Pointer);
+if (!BaseOffsetPair.first || !isa(BaseOffsetPair.first)) {
+  Invalid = true;

ahmedbougacha wrote:

The missing base was covered, but the VarDecl check wasn't I think;  I added 
tests where the discriminator is a function decl

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits


@@ -2074,16 +2091,91 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg,
   if (convertArgumentToType(S, Arg, ExpectedTy))
 return true;
 
-  // Warn about null pointers for non-generic sign and auth operations.
-  if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
-  Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) {
-S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign
-  ? diag::warn_ptrauth_sign_null_pointer
-  : diag::warn_ptrauth_auth_null_pointer)
-<< Arg->getSourceRange();
+  if (!RequireConstant) {
+// Warn about null pointers for non-generic sign and auth operations.
+if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
+Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) 
{
+  S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign
+? diag::warn_ptrauth_sign_null_pointer
+: diag::warn_ptrauth_auth_null_pointer)
+  << Arg->getSourceRange();
+}
+
+return false;
   }
 
-  return false;
+  // Perform special checking on the arguments to ptrauth_sign_constant.
+
+  // The main argument.
+  if (OpKind == PAO_Sign) {
+// Require the value we're signing to have a special form.
+auto BaseOffsetPair = findConstantBaseAndOffset(S, Arg);
+bool Invalid;
+
+// Must be rooted in a declaration reference.
+if (!BaseOffsetPair.first) {
+  Invalid = true;

ahmedbougacha wrote:

Heh yeah, we can probably add more in the future, but TBH this is obscure 
enough that we can do it if asked

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits


@@ -2030,8 +2030,25 @@ bool Sema::checkConstantPointerAuthKey(Expr *Arg, 
unsigned &Result) {
   return false;
 }
 
+static std::pair
+findConstantBaseAndOffset(Sema &S, Expr *E) {
+  // Must evaluate as a pointer.
+  Expr::EvalResult Result;
+  if (!E->EvaluateAsRValue(Result, S.Context) || !Result.Val.isLValue())
+return std::make_pair(nullptr, CharUnits());
+
+  // Base must be a declaration and can't be weakly imported.

ahmedbougacha wrote:

I removed the weakref base pointer check because that's currently supported in 
the qualifier (and I think this should have also checked for weakimport as well 
for the cases I care about), so the backend has to deal with ptrauth weak refs 
anyway.  There's a higher-level set of problems around how we deal with weak 
refs in general, but that's a separate topic.

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits


@@ -938,6 +938,11 @@ class CodeGenModule : public CodeGenTypeCache {
   // Return the function body address of the given function.
   llvm::Constant *GetFunctionStart(const ValueDecl *Decl);
 
+  llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer,
+   unsigned Key,
+   llvm::Constant *StorageAddress,
+   llvm::Constant *ExtraDiscrim);

ahmedbougacha wrote:

Different people name these differently;  we can settle on OtherDiscriminator 
here yeah.  I think `extra`  as more of a common user-facing term for 
"discriminator", as in "extra data";  a lot of the PAC crowd coming from the 
security world thinks of it in those terms

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits


@@ -1856,6 +1856,12 @@ class ConstantLValueEmitter : public 
ConstStmtVisitor

ahmedbougacha wrote:

The more interesting question is the usage of Constant;  I think we can safely 
assume the integer component is always going to be a ConstantInt (because it's 
going to have to fit in a ConstantInt-shaped hole in CPA anyway.)  That 
hopefully makes this obvious here, and I'll propagate that in the various users 
separately

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-18 Thread Ahmed Bougacha via llvm-branch-commits


@@ -2126,14 +2219,16 @@ static ExprResult PointerAuthSignGenericData(Sema &S, 
CallExpr *Call) {
 }
 
 static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call,
-PointerAuthOpKind OpKind) {
+PointerAuthOpKind OpKind,
+bool RequireConstant) {
   if (S.checkArgCount(Call, 3))
 return ExprError();
   if (checkPointerAuthEnabled(S, Call))
 return ExprError();
-  if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind) ||
+  if (checkPointerAuthValue(S, Call->getArgs()[0], OpKind, RequireConstant) ||

ahmedbougacha wrote:

Let's do that in a separate PR and adopt it for the other builtins there

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-20 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/93904

>From 20bbad26fa9f068910baf50b5abb60a0f4557564 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 30 May 2024 17:33:04 -0700
Subject: [PATCH 1/6] [clang] Define ptrauth_sign_constant builtin.

This is constant-expression equivalent to __builtin_ptrauth_sign,
allowing its usage in global initializers, but requiring constant
pointers and discriminators.

Co-Authored-By: John McCall 
---
 clang/include/clang/Basic/Builtins.td |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   7 +
 clang/include/clang/CodeGen/CodeGenABITypes.h |   6 +
 clang/lib/AST/ExprConstant.cpp|   1 +
 clang/lib/CodeGen/CGBuiltin.cpp   |   3 +
 clang/lib/CodeGen/CGExprConstant.cpp  |  62 +
 clang/lib/CodeGen/CGPointerAuth.cpp   |  77 +++
 clang/lib/CodeGen/CMakeLists.txt  |   1 +
 clang/lib/CodeGen/CodeGenModule.h |   5 +
 clang/lib/Headers/ptrauth.h   |  25 
 clang/lib/Sema/SemaChecking.cpp   | 128 --
 .../CodeGen/ptrauth-intrinsic-sign-constant.c |  20 +++
 clang/test/Sema/ptrauth-intrinsics-macro.c|   4 +
 clang/test/Sema/ptrauth.c |  28 
 14 files changed, 359 insertions(+), 14 deletions(-)
 create mode 100644 clang/lib/CodeGen/CGPointerAuth.cpp
 create mode 100644 clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index e07ddf3b9b70b..9342b6bc75fc8 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4393,6 +4393,12 @@ def PtrauthSignUnauthenticated : Builtin {
   let Prototype = "void*(void*,int,void*)";
 }
 
+def PtrauthSignConstant : Builtin {
+  let Spellings = ["__builtin_ptrauth_sign_constant"];
+  let Attributes = [CustomTypeChecking, NoThrow, Const, Constexpr];
+  let Prototype = "void*(void*,int,void*)";
+}
+
 def PtrauthSignGenericData : Builtin {
   let Spellings = ["__builtin_ptrauth_sign_generic_data"];
   let Attributes = [CustomTypeChecking, NoThrow, Const];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0900dad3c18cd..a5675879f45bc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -924,6 +924,13 @@ def err_ptrauth_value_bad_type :
   Error<"%select{signed value|extra discriminator|blended pointer|blended "
 "integer}0 must have %select{pointer|integer|pointer or integer}1 "
 "type; type here is %2">;
+def err_ptrauth_bad_constant_pointer :
+  Error<"argument to ptrauth_sign_constant must refer to a global variable "
+"or function">;
+def err_ptrauth_bad_constant_discriminator :
+  Error<"discriminator argument to ptrauth_sign_constant must be a constant "
+"integer, the address of the global variable where the result "
+"will be stored, or a blend of the two">;
 def warn_ptrauth_sign_null_pointer :
   Warning<"signing a null pointer will yield a non-null pointer">,
   InGroup;
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h 
b/clang/include/clang/CodeGen/CodeGenABITypes.h
index fda0855dc8683..8c62d8597ecbe 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -104,6 +104,12 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, 
QualType T);
 unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 const RecordDecl *RD, const FieldDecl *FD);
 
+/// Return a signed constant pointer.
+llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM,
+ llvm::Constant *pointer,
+ unsigned key,
+ llvm::Constant *storageAddress,
+ llvm::Constant *otherDiscriminator);
 /// Given the language and code-generation options that Clang was configured
 /// with, set the default LLVM IR attributes for a function definition.
 /// The attributes set here are mostly global target-configuration and
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 97b4c2080e14f..799872fe13c08 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2042,6 +2042,7 @@ static bool IsNoOpCall(const CallExpr *E) {
   unsigned Builtin = E->getBuiltinCallee();
   return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
   Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
+  Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
   Builtin == Builtin::BI__builtin_function_start);
 }
 
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 08a89bd123d03..fd4fe1633ea29 100644
--- a/clang/li

[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)

2024-06-20 Thread Ahmed Bougacha via llvm-branch-commits


@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed 
pointers signed with
 the given key, extract the raw pointer from it.  This operation does not trap
 and cannot fail, even if the pointer is not validly signed.
 
+``ptrauth_sign_constant``
+^
+
+.. code-block:: c
+
+  ptrauth_sign_constant(pointer, key, discriminator)
+
+Return a signed pointer for a constant address in a manner which guarantees
+a non-attackable sequence.
+
+``pointer`` must be a constant expression of pointer type which evaluates to
+a non-null pointer.  The result will have the same type as ``discriminator``.

ahmedbougacha wrote:

These two lines are just leftovers;  I deleted them in 1201821dc1e4.  The below 
is the same.

https://github.com/llvm/llvm-project/pull/93904
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] [clang] Implement pointer authentication for C++ virtual functions, v-tables, and VTTs (PR #94056)

2024-06-21 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha reopened 
https://github.com/llvm/llvm-project/pull/94056
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] Add some brief LLVM 19 release notes for Pointer Authentication ABI support (PR #104657)

2024-08-19 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha approved this pull request.


https://github.com/llvm/llvm-project/pull/104657
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-03-18 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha created 
https://github.com/llvm/llvm-project/pull/85736

This adds codegen support for the "ptrauth" operand bundles, which can
be used to augment indirect calls with the equivalent of an
`@llvm.ptrauth.auth` intrinsic call on the call target (possibly
preceded by an `@llvm.ptrauth.blend` on the auth discriminator if
applicable.)

This allows the generation of combined authenticating calls
on AArch64 (in the BLRA* PAuth instructions), while avoiding
the raw just-authenticated function pointer from being
exposed to attackers.

This is done by threading a PtrAuthInfo descriptor through
the call lowering infrastructure.

Note that this also applies to the other forms of indirect calls,
notably invokes, rvmarker, and tail calls.  Tail-calls in particular
bring some additional complexity, with the intersecting register
constraints of BTI and PAC discriminator computation.

This also adopts an x8+ allocation order for GPR64noip, matching GPR64.

>From ad3c074aa9a8d527edb34dd69b690afb5e4f6011 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Mon, 27 Sep 2021 08:00:00 -0700
Subject: [PATCH 1/2] [AArch64] Adopt x8+ allocation order for GPR64noip.

73078ecd381 added GPR64noip for hwasan pseudos.
Give it an allocation order that prefers allocating from x8 and up,
to match GPR64: this allows for easier regalloc, as x0-x7 are
likely to be used for parameter passing.
---
 llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td 
b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index fef1748021b07c..9240ad479cbd63 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -234,7 +234,10 @@ def tcGPRnotx16 : RegisterClass<"AArch64", [i64], 64, (sub 
tcGPR64, X16)>;
 // Register set that excludes registers that are reserved for procedure calls.
 // This is used for pseudo-instructions that are actually implemented using a
 // procedure call.
-def GPR64noip : RegisterClass<"AArch64", [i64], 64, (sub GPR64, X16, X17, LR)>;
+def GPR64noip : RegisterClass<"AArch64", [i64], 64, (sub GPR64, X16, X17, LR)> 
{
+  let AltOrders = [(rotl GPR64noip, 8)];
+  let AltOrderSelect = [{ return 1; }];
+}
 
 // GPR register classes for post increment amount of vector load/store that
 // has alternate printing when Rm=31 and prints a constant immediate value

>From 25cb02dc4441fac54b7a69af833ba0bf18b1696c Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Wed, 24 Jan 2024 15:03:49 -0800
Subject: [PATCH 2/2] [AArch64][PAC] Lower authenticated calls with ptrauth
 bundles.

This adds codegen support for the "ptrauth" operand bundles, which can
be used to augment indirect calls with the equivalent of an
`@llvm.ptrauth.auth` intrinsic call on the call target (possibly
preceded by an `@llvm.ptrauth.blend` on the auth discriminator if
applicable.)

This allows the generation of combined authenticating calls
on AArch64 (in the BLRA* PAuth instructions), while avoiding
the raw just-authenticated function pointer from being
exposed to attackers.

This is done by threading a PtrAuthInfo descriptor through
the call lowering infrastructure.

Note that this also applies to the other forms of indirect calls,
notably invokes, rvmarker, and tail calls.  Tail-calls in particular
bring some additional complexity, with the intersecting register
constraints of BTI and PAC discriminator computation.
---
 .../llvm/CodeGen/GlobalISel/CallLowering.h|   7 +
 llvm/include/llvm/CodeGen/TargetLowering.h|  18 ++
 llvm/lib/CodeGen/GlobalISel/CallLowering.cpp  |   2 +
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  |  16 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp  |  51 -
 .../SelectionDAG/SelectionDAGBuilder.h|   6 +-
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |  90 
 .../AArch64/AArch64ExpandPseudoInsts.cpp  |  43 +++-
 .../Target/AArch64/AArch64ISelLowering.cpp| 103 ++---
 llvm/lib/Target/AArch64/AArch64ISelLowering.h |  12 ++
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  |   2 +
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  80 +++
 .../AArch64/GISel/AArch64CallLowering.cpp |  88 ++--
 .../AArch64/GISel/AArch64GlobalISelUtils.cpp  |   2 +-
 .../AArch64/GlobalISel/ptrauth-invoke.ll  | 183 
 ...ranch-target-enforcement-indirect-calls.ll |   4 +-
 llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll | 105 ++
 .../CodeGen/AArch64/ptrauth-call-rv-marker.ll | 154 ++
 llvm/test/CodeGen/AArch64/ptrauth-call.ll | 195 ++
 llvm/test/CodeGen/AArch64/ptrauth-invoke.ll   | 189 +
 20 files changed, 1291 insertions(+), 59 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-invoke.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll
 create 

[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-10 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

ping

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [clang-tools-extra] [llvm] [mlir] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-10 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/85736

error: too big or took too long to generate
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-10 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-14 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/85736

>From 75825f36ec58a2cf5d1a3f2d4de6a49ad06c02d8 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Mon, 27 Sep 2021 08:00:00 -0700
Subject: [PATCH 1/2] [AArch64] Adopt x8+ allocation order for GPR64noip.

73078ecd381 added GPR64noip for hwasan pseudos.
Give it an allocation order that prefers allocating from x8 and up,
to match GPR64: this allows for easier regalloc, as x0-x7 are
likely to be used for parameter passing.
---
 llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td 
b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 80d0f9c57f4b3..dfaa67dd1959d 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -234,7 +234,10 @@ def tcGPRnotx16 : RegisterClass<"AArch64", [i64], 64, (sub 
tcGPR64, X16)>;
 // Register set that excludes registers that are reserved for procedure calls.
 // This is used for pseudo-instructions that are actually implemented using a
 // procedure call.
-def GPR64noip : RegisterClass<"AArch64", [i64], 64, (sub GPR64, X16, X17, LR)>;
+def GPR64noip : RegisterClass<"AArch64", [i64], 64, (sub GPR64, X16, X17, LR)> 
{
+  let AltOrders = [(rotl GPR64noip, 8)];
+  let AltOrderSelect = [{ return 1; }];
+}
 
 // GPR register classes for post increment amount of vector load/store that
 // has alternate printing when Rm=31 and prints a constant immediate value

>From 536ab53e4a300841db5850efaf0ecc5b29733e6d Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Wed, 24 Jan 2024 15:03:49 -0800
Subject: [PATCH 2/2] [AArch64][PAC] Lower authenticated calls with ptrauth
 bundles.

This adds codegen support for the "ptrauth" operand bundles, which can
be used to augment indirect calls with the equivalent of an
`@llvm.ptrauth.auth` intrinsic call on the call target (possibly
preceded by an `@llvm.ptrauth.blend` on the auth discriminator if
applicable.)

This allows the generation of combined authenticating calls
on AArch64 (in the BLRA* PAuth instructions), while avoiding
the raw just-authenticated function pointer from being
exposed to attackers.

This is done by threading a PtrAuthInfo descriptor through
the call lowering infrastructure.

Note that this also applies to the other forms of indirect calls,
notably invokes, rvmarker, and tail calls.  Tail-calls in particular
bring some additional complexity, with the intersecting register
constraints of BTI and PAC discriminator computation.
---
 .../llvm/CodeGen/GlobalISel/CallLowering.h|   8 +
 llvm/include/llvm/CodeGen/TargetLowering.h|  18 ++
 llvm/lib/CodeGen/GlobalISel/CallLowering.cpp  |   2 +
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  |  16 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp  |  51 -
 .../SelectionDAG/SelectionDAGBuilder.h|   6 +-
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |  90 
 .../AArch64/AArch64ExpandPseudoInsts.cpp  |  43 +++-
 .../Target/AArch64/AArch64ISelLowering.cpp| 103 ++---
 llvm/lib/Target/AArch64/AArch64ISelLowering.h |  12 ++
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  |   2 +
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  80 +++
 .../AArch64/GISel/AArch64CallLowering.cpp |  88 ++--
 .../AArch64/GISel/AArch64GlobalISelUtils.cpp  |   2 +-
 .../AArch64/GlobalISel/ptrauth-invoke.ll  | 183 
 ...ranch-target-enforcement-indirect-calls.ll |   4 +-
 llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll | 105 ++
 .../CodeGen/AArch64/ptrauth-call-rv-marker.ll | 154 ++
 llvm/test/CodeGen/AArch64/ptrauth-call.ll | 195 ++
 llvm/test/CodeGen/AArch64/ptrauth-invoke.ll   | 189 +
 20 files changed, 1292 insertions(+), 59 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-invoke.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-call.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-invoke.ll

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h 
b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 4c187a3068d82..fb298898304eb 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -99,6 +99,11 @@ class CallLowering {
 ArgInfo() = default;
   };
 
+  struct PointerAuthInfo {
+Register Discriminator;
+uint64_t Key;
+  };
+
   struct CallLoweringInfo {
 /// Calling convention to be used for the call.
 CallingConv::ID CallConv = CallingConv::C;
@@ -125,6 +130,8 @@ class CallLowering {
 
 MDNode *KnownCallees = nullptr;
 
+std::optional PAI;
+
 /// True if the call must be tail call optimized.
 bool IsMustTailCall = false;
 
@@ -587,6 +594,

[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha updated 
https://github.com/llvm/llvm-project/pull/85736

>From 75825f36ec58a2cf5d1a3f2d4de6a49ad06c02d8 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Mon, 27 Sep 2021 08:00:00 -0700
Subject: [PATCH 1/3] [AArch64] Adopt x8+ allocation order for GPR64noip.

73078ecd381 added GPR64noip for hwasan pseudos.
Give it an allocation order that prefers allocating from x8 and up,
to match GPR64: this allows for easier regalloc, as x0-x7 are
likely to be used for parameter passing.
---
 llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td 
b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 80d0f9c57f4b3..dfaa67dd1959d 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -234,7 +234,10 @@ def tcGPRnotx16 : RegisterClass<"AArch64", [i64], 64, (sub 
tcGPR64, X16)>;
 // Register set that excludes registers that are reserved for procedure calls.
 // This is used for pseudo-instructions that are actually implemented using a
 // procedure call.
-def GPR64noip : RegisterClass<"AArch64", [i64], 64, (sub GPR64, X16, X17, LR)>;
+def GPR64noip : RegisterClass<"AArch64", [i64], 64, (sub GPR64, X16, X17, LR)> 
{
+  let AltOrders = [(rotl GPR64noip, 8)];
+  let AltOrderSelect = [{ return 1; }];
+}
 
 // GPR register classes for post increment amount of vector load/store that
 // has alternate printing when Rm=31 and prints a constant immediate value

>From 536ab53e4a300841db5850efaf0ecc5b29733e6d Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Wed, 24 Jan 2024 15:03:49 -0800
Subject: [PATCH 2/3] [AArch64][PAC] Lower authenticated calls with ptrauth
 bundles.

This adds codegen support for the "ptrauth" operand bundles, which can
be used to augment indirect calls with the equivalent of an
`@llvm.ptrauth.auth` intrinsic call on the call target (possibly
preceded by an `@llvm.ptrauth.blend` on the auth discriminator if
applicable.)

This allows the generation of combined authenticating calls
on AArch64 (in the BLRA* PAuth instructions), while avoiding
the raw just-authenticated function pointer from being
exposed to attackers.

This is done by threading a PtrAuthInfo descriptor through
the call lowering infrastructure.

Note that this also applies to the other forms of indirect calls,
notably invokes, rvmarker, and tail calls.  Tail-calls in particular
bring some additional complexity, with the intersecting register
constraints of BTI and PAC discriminator computation.
---
 .../llvm/CodeGen/GlobalISel/CallLowering.h|   8 +
 llvm/include/llvm/CodeGen/TargetLowering.h|  18 ++
 llvm/lib/CodeGen/GlobalISel/CallLowering.cpp  |   2 +
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  |  16 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp  |  51 -
 .../SelectionDAG/SelectionDAGBuilder.h|   6 +-
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |  90 
 .../AArch64/AArch64ExpandPseudoInsts.cpp  |  43 +++-
 .../Target/AArch64/AArch64ISelLowering.cpp| 103 ++---
 llvm/lib/Target/AArch64/AArch64ISelLowering.h |  12 ++
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  |   2 +
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  80 +++
 .../AArch64/GISel/AArch64CallLowering.cpp |  88 ++--
 .../AArch64/GISel/AArch64GlobalISelUtils.cpp  |   2 +-
 .../AArch64/GlobalISel/ptrauth-invoke.ll  | 183 
 ...ranch-target-enforcement-indirect-calls.ll |   4 +-
 llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll | 105 ++
 .../CodeGen/AArch64/ptrauth-call-rv-marker.ll | 154 ++
 llvm/test/CodeGen/AArch64/ptrauth-call.ll | 195 ++
 llvm/test/CodeGen/AArch64/ptrauth-invoke.ll   | 189 +
 20 files changed, 1292 insertions(+), 59 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-invoke.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-call.ll
 create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-invoke.ll

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h 
b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 4c187a3068d82..fb298898304eb 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -99,6 +99,11 @@ class CallLowering {
 ArgInfo() = default;
   };
 
+  struct PointerAuthInfo {
+Register Discriminator;
+uint64_t Key;
+  };
+
   struct CallLoweringInfo {
 /// Calling convention to be used for the call.
 CallingConv::ID CallConv = CallingConv::C;
@@ -125,6 +130,8 @@ class CallLowering {
 
 MDNode *KnownCallees = nullptr;
 
+std::optional PAI;
+
 /// True if the call must be tail call optimized.
 bool IsMustTailCall = false;
 
@@ -587,6 +594,

[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits


@@ -1694,6 +1718,35 @@ let Predicates = [HasPAuth] in {
 def BLRABZ  : AuthOneOperand<0b001, 1, "blrabz">;
   }
 
+  // BLRA pseudo, generalized version of BLRAA/BLRAB/Z.
+  // This directly manipulates x16/x17, which are the only registers the OS
+  // guarantees are safe to use for sensitive operations.

ahmedbougacha wrote:

Unfortunately this sort of thing isn't documented.  We do describe the general 
contract in the security model sections of the clang docs.
For ELF it might make sense to have a formalization in the PAuth ABI, but that 
would have to be actually honored in an OS;  I imagine it currently isn't 
anywhere other than Darwin.

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits


@@ -0,0 +1,183 @@
+; RUN: llc -mtriple arm64e-apple-darwin -o - -global-isel -global-isel-abort=1 
-verify-machineinstrs %s | FileCheck %s --check-prefixes=CHECK

ahmedbougacha wrote:

It's not standard practice to test other platforms, but sure, I added ELF 
checks.  Now you folks owe me darwin tests for future PAC changes you make ;)

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits


@@ -8640,6 +8642,15 @@ void SelectionDAGBuilder::LowerCallTo(const CallBase 
&CB, SDValue Callee,
   CB.countOperandBundlesOfType(LLVMContext::OB_preallocated) != 0)
   .setCFIType(CFIType)
   .setConvergenceControlToken(ConvControlToken);
+
+  // Set the pointer authentication info if we have it.
+  if (PAI) {
+if (!TLI.supportPtrAuthBundles())
+  report_fatal_error(

ahmedbougacha wrote:

I don't think testing this one is reasonable;  we couldn't even put it in 
AArch64 and would have to pollute another innocent backend

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits

ahmedbougacha wrote:

Thanks for taking a look;  updated

https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][PAC] Lower authenticated calls with ptrauth bundles. (PR #85736)

2024-05-23 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/85736
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] [clang-tools-extra] [llvm] [clang] [builtins][arm64] Build __init_cpu_features_resolver on Apple platforms (PR #73685)

2023-12-05 Thread Ahmed Bougacha via llvm-branch-commits


@@ -1259,6 +1270,72 @@ struct {
   // As features grows new fields could be added
 } __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));
 
+#if defined(__APPLE__)
+#include 
+#if TARGET_OS_OSX || TARGET_OS_IPHONE
+#include 
+#include 
+
+static bool isKnownAndSupported(const char *name) {
+  int32_t val = 0;
+  size_t size = sizeof(val);
+  if (sysctlbyname(name, &val, &size, NULL, 0))
+return false;
+  return val;
+}
+
+void __init_cpu_features_resolver(void) {
+  // On Darwin platforms, this may be called concurrently by multiple threads
+  // because the resolvers that use it are called lazily at runtime (unlike on
+  // ELF platforms, where IFuncs are resolved serially at load time).  This
+  // function's effect on __aarch64_cpu_features should be idempotent, but even
+  // so we need dispatch_once to resolve the race condition.  Dispatch is
+  // available through libSystem, which we need anyway for the sysctl, so this
+  // does not add a new dependency.
+
+  static dispatch_once_t onceToken = 0;
+  dispatch_once(&onceToken, ^{
+// 
https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
+static struct {
+  const char *sysctl_name;
+  enum CPUFeatures feature;
+} features[] = {
+{"hw.optional.arm.FEAT_FlagM", FEAT_FLAGM},
+{"hw.optional.arm.FEAT_FlagM2", FEAT_FLAGM2},
+{"hw.optional.arm.FEAT_FHM", FEAT_FP16FML},
+{"hw.optional.arm.FEAT_DotProd", FEAT_DOTPROD},
+{"hw.optional.arm.FEAT_RDM", FEAT_RDM},
+{"hw.optional.arm.FEAT_LSE", FEAT_LSE},
+{"hw.optional.floatingpoint", FEAT_FP},
+{"hw.optional.AdvSIMD", FEAT_SIMD},
+{"hw.optional.armv8_crc32", FEAT_CRC},
+{"hw.optional.arm.FEAT_SHA1", FEAT_SHA1},
+{"hw.optional.arm.FEAT_SHA256", FEAT_SHA2},
+{"hw.optional.armv8_2_sha3", FEAT_SHA3},

ahmedbougacha wrote:

I think you want `FEAT_SHA3` instead of `armv8_2_sha3` (and technically, sha512 
also, but that shouldn't matter; crypto's a mess).  I thought we had one for 
crc32 as well, but looks like we don't.  I assume FP/SIMD are unneeded but 
harmless.

Otherwise, sysctl `FEAT_SPECRES` should map to enum `PREDRES`, and DIT, 
DPB/DPB2 are missing (DIT is vaguely plausibly useful, DPB not really.)  Rest 
LGTM!

https://github.com/llvm/llvm-project/pull/73685
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [clang] [clang-tools-extra] [clang] Support __attribute__((ifunc(...))) on Darwin platforms (PR #73687)

2023-12-05 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha approved this pull request.


https://github.com/llvm/llvm-project/pull/73687
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [libcxx] [libc] [lldb] [flang] [mlir] [libcxxabi] [compiler-rt] [lld] [clang] [llvm] [openmp] [clang-tools-extra] [builtins][arm64] Build __init_cpu_features_resolver on Apple pl

2023-12-08 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha approved this pull request.

LG, ty

https://github.com/llvm/llvm-project/pull/73685
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] release/19.x: [AArch64] Make apple-m4 armv8.7-a again (from armv9.2-a). (#106312) (PR #106599)

2024-08-29 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha created 
https://github.com/llvm/llvm-project/pull/106599

This is a partial revert of c66e1d6f3429.  Even though that allowed us to 
declare v9.2-a support without picking up SVE2 in both the backend and the 
driver, the frontend itself still enabled SVE via the arch version's default 
extensions.

Avoid that by reverting back to v8.7-a while we look into longer-term solutions.

(cherry picked from commit e5e38ddf1b8043324175868831da21e941c00aff)

>From f1da254b87458ef10ea7389d890bfa351b5058c7 Mon Sep 17 00:00:00 2001
From: Ahmed Bougacha 
Date: Thu, 29 Aug 2024 09:50:44 -0700
Subject: [PATCH] [AArch64] Make apple-m4 armv8.7-a again (from armv9.2-a). 
 (#106312)

This is a partial revert of c66e1d6f3429.  Even though that
allowed us to declare v9.2-a support without picking up SVE2
in both the backend and the driver, the frontend itself still
enabled SVE via the arch version's default extensions.

Avoid that by reverting back to v8.7-a while we look into
longer-term solutions.

(cherry picked from commit e5e38ddf1b8043324175868831da21e941c00aff)
---
 clang/test/CodeGen/aarch64-targetattr.c  | 9 +
 llvm/lib/Target/AArch64/AArch64Processors.td | 7 ++-
 llvm/unittests/TargetParser/TargetParserTest.cpp | 2 +-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/clang/test/CodeGen/aarch64-targetattr.c 
b/clang/test/CodeGen/aarch64-targetattr.c
index d6227be2ebef83..a5f94b46cbb172 100644
--- a/clang/test/CodeGen/aarch64-targetattr.c
+++ b/clang/test/CodeGen/aarch64-targetattr.c
@@ -191,6 +191,14 @@ __attribute__((target("no-v9.3a")))
 //
 void minusarch() {}
 
+__attribute__((target("cpu=apple-m4")))
+// CHECK-LABEL: define {{[^@]+}}@applem4
+// CHECK-SAME: () #[[ATTR18:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret void
+//
+void applem4() {}
+
 //.
 // CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-features"="+crc,+fp-armv8,+lse,+neon,+ras,+rdm,+v8.1a,+v8.2a,+v8a" }
 // CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sve,+v8.1a,+v8.2a,+v8a"
 }
@@ -210,6 +218,7 @@ void minusarch() {}
 // CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone 
"branch-target-enforcement" "guarded-control-stack" "no-trapping-math"="true" 
"sign-return-address"="non-leaf" "sign-return-address-key"="a_key" 
"stack-protector-buffer-size"="8" "target-cpu"="neoverse-n1" 
"target-features"="+aes,+bf16,+bti,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+spe,+ssbs,+sve,+sve2,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8a"
 "tune-cpu"="cortex-a710" }
 // CHECK: attributes #[[ATTR16]] = { noinline nounwind optnone 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" }
 // CHECK: attributes #[[ATTR17]] = { noinline nounwind optnone 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-features"="-v9.3a" }
+// CHECK: attributes #[[ATTR18]] = { noinline nounwind optnone 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-cpu"="apple-m4" 
"target-features"="+aes,+bf16,+bti,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fullfp16,+i8mm,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+sme,+sme-f64f64,+sme-i16i64,+sme2,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8.7a,+v8a,+wfxt"
 }
 //.
 // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
 // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
diff --git a/llvm/lib/Target/AArch64/AArch64Processors.td 
b/llvm/lib/Target/AArch64/AArch64Processors.td
index 6df87fc6a815f7..410b53e14de22e 100644
--- a/llvm/lib/Target/AArch64/AArch64Processors.td
+++ b/llvm/lib/Target/AArch64/AArch64Processors.td
@@ -895,7 +895,12 @@ def ProcessorFeatures {
  FeatureLSE, FeaturePAuth,
  FeatureRAS, FeatureRCPC, FeatureRDM,
  FeatureBF16, FeatureDotProd, 
FeatureMatMulInt8, FeatureSSBS];
-  list AppleM4 = [HasV9_2aOps, FeatureSHA2, FeatureFPARMv8,
+  // Technically apple-m4 is v9.2a, but we can't use that here.
+  // Historically, llvm defined v9.0a as requiring SVE, but it's optional
+  // according to the Arm ARM, and not supported by the core.  We decoupled the
+  // two in the clang driver and in the backend subtarget features, but it's
+  // still an issue in the clang frontend.  v8.7a is the next closest choice.
+  list AppleM4 = [HasV8_7aOps, FeatureSHA2, FeatureFPARMv8,
 FeatureNEON, FeaturePerfMon, FeatureSHA3,
 FeatureFullFP16, FeatureFP16FML,
 FeatureAES, FeatureBF16,
diff --git a/llvm/unittests/

[llvm-branch-commits] [clang] [llvm] release/19.x: [AArch64] Make apple-m4 armv8.7-a again (from armv9.2-a). (PR #106599)

2024-08-29 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha edited 
https://github.com/llvm/llvm-project/pull/106599
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] release/19.x: [AArch64] Make apple-m4 armv8.7-a again (from armv9.2-a). (PR #106599)

2024-08-29 Thread Ahmed Bougacha via llvm-branch-commits

https://github.com/ahmedbougacha milestoned 
https://github.com/llvm/llvm-project/pull/106599
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] f77c948 - [Triple][MachO] Define "arm64e", an AArch64 subarch for Pointer Auth.

2020-12-03 Thread Ahmed Bougacha via llvm-branch-commits

Author: Ahmed Bougacha
Date: 2020-12-03T07:53:59-08:00
New Revision: f77c948d56b09b839262e258af5c6ad701e5b168

URL: 
https://github.com/llvm/llvm-project/commit/f77c948d56b09b839262e258af5c6ad701e5b168
DIFF: 
https://github.com/llvm/llvm-project/commit/f77c948d56b09b839262e258af5c6ad701e5b168.diff

LOG: [Triple][MachO] Define "arm64e", an AArch64 subarch for Pointer Auth.

This also teaches MachO writers/readers about the MachO cpu subtype,
beyond the minimal subtype reader support present at the moment.

This also defines a preprocessor macro to allow users to distinguish
__arm64__ from __arm64e__.

arm64e defaults to an "apple-a12" CPU, which supports v8.3a, allowing
pointer-authentication codegen.
It also currently defaults to ios14 and macos11.

Differential Revision: https://reviews.llvm.org/D87095

Added: 
clang/test/Preprocessor/arm64e.c
llvm/test/MC/AArch64/arm64e-subtype.s
llvm/test/MC/AArch64/arm64e.s
llvm/test/tools/llvm-dwarfdump/AArch64/arm64e.ll
llvm/test/tools/llvm-readobj/macho-arm64e.test

Modified: 
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/Driver/ToolChain.cpp
clang/lib/Driver/ToolChains/Arch/AArch64.cpp
clang/lib/Driver/ToolChains/Darwin.cpp
clang/test/Driver/aarch64-cpus.c
clang/test/Driver/arclite-link.c
clang/test/Driver/target-triple-deployment.c
llvm/include/llvm/ADT/Triple.h
llvm/lib/BinaryFormat/MachO.cpp
llvm/lib/LTO/LTOCodeGenerator.cpp
llvm/lib/LTO/LTOModule.cpp
llvm/lib/Object/MachOObjectFile.cpp
llvm/lib/Support/ARMTargetParser.cpp
llvm/lib/Support/Triple.cpp
llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
llvm/test/MC/MachO/AArch64/arm-darwin-version-min-load-command.s
llvm/test/tools/llvm-objdump/MachO/universal-arm64.test
llvm/unittests/ADT/TripleTest.cpp
llvm/utils/UpdateTestChecks/asm.py

Removed: 




diff  --git a/clang/lib/Basic/Targets/AArch64.cpp 
b/clang/lib/Basic/Targets/AArch64.cpp
index abdd424ea048..c8162dd55220 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -874,6 +874,9 @@ void DarwinAArch64TargetInfo::getOSDefines(const 
LangOptions &Opts,
   Builder.defineMacro("__arm64", "1");
   Builder.defineMacro("__arm64__", "1");
 
+  if (Triple.isArm64e())
+Builder.defineMacro("__arm64e__", "1");
+
   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
 }
 

diff  --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 85ab05cb7021..11b78a14fe47 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -232,8 +232,11 @@ StringRef ToolChain::getDefaultUniversalArchName() const {
   // the same as the ones that appear in the triple. Roughly speaking, this is
   // an inverse of the darwin::getArchTypeForDarwinArchName() function.
   switch (Triple.getArch()) {
-  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64: {
+if (getTriple().isArm64e())
+  return "arm64e";
 return "arm64";
+  }
   case llvm::Triple::aarch64_32:
 return "arm64_32";
   case llvm::Triple::ppc:
@@ -706,6 +709,9 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList 
&Args,
 if (!Triple.isOSBinFormatMachO())
   return getTripleString();
 
+if (Triple.isArm64e())
+  return getTripleString();
+
 // FIXME: older versions of ld64 expect the "arm64" component in the actual
 // triple string and query it to determine whether an LTO file can be
 // handled. Remove this when we don't care any more.

diff  --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp 
b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 06bb705a3721..0fc531b8c3a0 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -40,7 +40,12 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
   // Handle CPU name is 'native'.
   if (CPU == "native")
 return std::string(llvm::sys::getHostCPUName());
-  else if (CPU.size())
+
+  // arm64e requires v8.3a and only runs on apple-a12 and later CPUs.
+  if (Triple.isArm64e())
+return "apple-a12";
+
+  if (CPU.size())
 return CPU;
 
   if (Triple.isTargetMachineMac() &&

diff  --git a/clang/lib/Driver/ToolChains/Darwin.cpp 
b/clang/lib/Driver/ToolChains/Darwin.cpp
index 9f8560356405..eb7bd4aec898 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "Darwin.h"
+#include "Arch/AArch64.h"
 #include "Arch/ARM.h"
 #include "CommonArgs.h"
 #include "clang/Basic/AlignedAllocation.h"
@@ -58,7 +59,7 @@ llvm::Triple::ArchType 
darwin::getArchTypeForMachOArchName(StringRef Str) {
   .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)