[compiler-rt] [llvm] Reapply "compiler-rt: Introduce runtime functions for emulated PAC." (PR #148094)
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 11 13:55:08 PDT 2025
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/148094
>From 39c6ac3d68dcfa3bfdc6364cd50aae8a7f07f03c Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <pcc at google.com>
Date: Thu, 10 Jul 2025 17:57:59 -0700
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
---
compiler-rt/cmake/Modules/AddCompilerRT.cmake | 12 +-
compiler-rt/cmake/builtin-config-ix.cmake | 1 +
compiler-rt/lib/builtins/CMakeLists.txt | 9 +-
compiler-rt/lib/builtins/aarch64/emupac.cpp | 146 ++++++++++++++++++
compiler-rt/lib/builtins/int_types.h | 2 +-
.../test/builtins/Unit/aarch64/emupac.c | 121 +++++++++++++++
.../compiler-rt/lib/builtins/BUILD.gn | 2 +
.../compiler-rt/lib/builtins/sources.gni | 1 +
.../compiler-rt/test/builtins/BUILD.gn | 1 +
9 files changed, 290 insertions(+), 5 deletions(-)
create mode 100644 compiler-rt/lib/builtins/aarch64/emupac.cpp
create mode 100644 compiler-rt/test/builtins/Unit/aarch64/emupac.c
diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
index 9a0426ff29470..fb2aee8e42ee2 100644
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake
+++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
@@ -162,7 +162,9 @@ endmacro()
# OBJECT_LIBS <object libraries to use as sources>
# PARENT_TARGET <convenience parent target>
# ADDITIONAL_HEADERS <header files>
-# EXTENSIONS <boolean>)
+# EXTENSIONS <boolean>
+# C_STANDARD <version>
+# CXX_STANDARD <version>)
function(add_compiler_rt_runtime name type)
if(NOT type MATCHES "^(OBJECT|STATIC|SHARED|MODULE)$")
message(FATAL_ERROR
@@ -171,7 +173,7 @@ function(add_compiler_rt_runtime name type)
endif()
cmake_parse_arguments(LIB
""
- "PARENT_TARGET"
+ "PARENT_TARGET;C_STANDARD;CXX_STANDARD"
"OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;DEPS;LINK_LIBS;OBJECT_LIBS;ADDITIONAL_HEADERS;EXTENSIONS"
${ARGN})
set(libnames)
@@ -360,6 +362,12 @@ function(add_compiler_rt_runtime name type)
set_target_link_flags(${libname} ${extra_link_flags_${libname}})
set_property(TARGET ${libname} APPEND PROPERTY
COMPILE_DEFINITIONS ${LIB_DEFS})
+ if(LIB_C_STANDARD)
+ set_property(TARGET ${libname} PROPERTY C_STANDARD ${LIB_C_STANDARD})
+ endif()
+ if(LIB_CXX_STANDARD)
+ set_property(TARGET ${libname} PROPERTY CXX_STANDARD ${LIB_CXX_STANDARD})
+ endif()
set_target_output_directories(${libname} ${output_dir_${libname}})
install(TARGETS ${libname}
ARCHIVE DESTINATION ${install_dir_${libname}}
diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake
index c62855835512d..b86bb1bca7cda 100644
--- a/compiler-rt/cmake/builtin-config-ix.cmake
+++ b/compiler-rt/cmake/builtin-config-ix.cmake
@@ -26,6 +26,7 @@ builtin_check_c_compiler_flag("-Xclang -mcode-object-version=none" COMPILER_RT_H
builtin_check_c_compiler_flag(-Wbuiltin-declaration-mismatch COMPILER_RT_HAS_WBUILTIN_DECLARATION_MISMATCH_FLAG)
builtin_check_c_compiler_flag(/Zl COMPILER_RT_HAS_ZL_FLAG)
builtin_check_c_compiler_flag(-fcf-protection=full COMPILER_RT_HAS_FCF_PROTECTION_FLAG)
+builtin_check_c_compiler_flag(-nostdinc++ COMPILER_RT_HAS_NOSTDINCXX_FLAG)
builtin_check_c_compiler_source(COMPILER_RT_HAS_ATOMIC_KEYWORD
"
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index 5e832315f3666..3ab92403d4168 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -6,7 +6,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
cmake_minimum_required(VERSION 3.20.0)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
- project(CompilerRTBuiltins C ASM)
+ project(CompilerRTBuiltins C CXX ASM)
set(COMPILER_RT_STANDALONE_BUILD TRUE)
set(COMPILER_RT_BUILTINS_STANDALONE_BUILD TRUE)
@@ -64,6 +64,8 @@ include(CMakePushCheckState)
option(COMPILER_RT_BUILTINS_HIDE_SYMBOLS
"Do not export any symbols from the static library." ON)
+include_directories(../../../third-party/siphash/include)
+
# TODO: Need to add a mechanism for logging errors when builtin source files are
# added to a sub-directory and not this CMakeLists file.
set(GENERIC_SOURCES
@@ -589,6 +591,7 @@ set(aarch64_SOURCES
${GENERIC_TF_SOURCES}
${GENERIC_SOURCES}
cpu_model/aarch64.c
+ aarch64/emupac.cpp
aarch64/fp_mode.c
)
@@ -836,7 +839,7 @@ else ()
append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full BUILTIN_CFLAGS)
endif()
- append_list_if(COMPILER_RT_HAS_STD_C11_FLAG -std=c11 BUILTIN_CFLAGS)
+ append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ BUILTIN_CFLAGS)
append_list_if(COMPILER_RT_HAS_WBUILTIN_DECLARATION_MISMATCH_FLAG -Werror=builtin-declaration-mismatch BUILTIN_CFLAGS)
# Don't embed directives for picking any specific CRT
@@ -958,6 +961,8 @@ else ()
SOURCES ${${arch}_SOURCES}
DEFS ${BUILTIN_DEFS}
CFLAGS ${BUILTIN_CFLAGS_${arch}}
+ C_STANDARD 11
+ CXX_STANDARD 17
PARENT_TARGET builtins)
cmake_pop_check_state()
endif ()
diff --git a/compiler-rt/lib/builtins/aarch64/emupac.cpp b/compiler-rt/lib/builtins/aarch64/emupac.cpp
new file mode 100644
index 0000000000000..62c551971bc90
--- /dev/null
+++ b/compiler-rt/lib/builtins/aarch64/emupac.cpp
@@ -0,0 +1,146 @@
+//===--- emupac.cpp - Emulated PAC implementation -------------------------===//
+//
+// 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 Emulated PAC using SipHash_1_3 as the IMPDEF hashing
+// scheme.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+
+#include "siphash/SipHash.h"
+
+// EmuPAC implements runtime emulation of PAC instructions. If the current
+// CPU supports PAC, EmuPAC uses real PAC instructions. Otherwise, it uses the
+// emulation, which is effectively an implementation of PAC with an IMPDEF
+// hashing scheme based on SipHash_1_3.
+//
+// The purpose of the emulation is to allow programs to be built to be portable
+// to machines without PAC support, with some performance loss and increased
+// probability of false positives (due to not being able to portably determine
+// the VA size), while being functionally almost equivalent to running on a
+// machine with PAC support. One example of a use case is if PAC is used in
+// production as a security mitigation, but the testing environment is
+// heterogeneous (i.e. some machines lack PAC support). In this case we would
+// like the testing machines to be able to detect issues resulting
+// from the use of PAC instructions that would affect production by running
+// tests. This can be achieved by building test binaries with EmuPAC and
+// production binaries with real PAC.
+//
+// EmuPAC should not be used in production and is only intended for testing use
+// cases. This is not only because of the performance costs, which will exist
+// even on PAC-supporting machines because of the function call overhead for
+// each sign/auth operation, but because it provides weaker security compared to
+// real PAC: the key is constant and public, which means that we do not mix a
+// global secret.
+//
+// The emulation assumes that the VA size is at most 48 bits. The architecture
+// as of ARMv8.2, which was the last architecture version in which PAC was not
+// mandatory, permitted VA size up to 52 bits via ARMv8.2-LVA, but we are
+// unaware of an ARMv8.2 CPU that implemented ARMv8.2-LVA.
+
+const uint64_t max_va_size = 48;
+const uint64_t pac_mask = ((1ULL << 55) - 1) & ~((1ULL << max_va_size) - 1);
+const uint64_t ttbr1_mask = 1ULL << 55;
+
+// Determine whether PAC is supported without accessing memory. This utilizes
+// the XPACLRI instruction which will copy bit 55 of x30 into at least bit 54 if
+// PAC is supported and acts as a NOP if PAC is not supported.
+static bool pac_supported() {
+ register uintptr_t x30 __asm__("x30") = 1ULL << 55;
+ __asm__ __volatile__("xpaclri" : "+r"(x30));
+ return x30 & (1ULL << 54);
+}
+
+// This asm snippet is used to force the creation of a frame record when
+// calling the EmuPAC functions. This is important because the EmuPAC functions
+// may crash if an auth failure is detected and may be unwound past using a
+// frame pointer based unwinder.
+#ifdef __GCC_HAVE_DWARF2_CFI_ASM
+#define CFI_INST(inst) inst
+#else
+#define CFI_INST(inst)
+#endif
+
+#ifdef __APPLE__
+#define ASM_SYMBOL(symbol) "_" #symbol
+#else
+#define ASM_SYMBOL(symbol) #symbol
+#endif
+
+// clang-format off
+#define FRAME_POINTER_WRAP(sym) \
+ CFI_INST(".cfi_startproc\n") \
+ "stp x29, x30, [sp, #-16]!\n" \
+ CFI_INST(".cfi_def_cfa_offset 16\n") \
+ "mov x29, sp\n" \
+ CFI_INST(".cfi_def_cfa w29, 16\n") \
+ CFI_INST(".cfi_offset w30, -8\n") \
+ CFI_INST(".cfi_offset w29, -16\n") \
+ "bl " ASM_SYMBOL(sym) "\n" \
+ CFI_INST(".cfi_def_cfa wsp, 16\n") \
+ "ldp x29, x30, [sp], #16\n" \
+ CFI_INST(".cfi_def_cfa_offset 0\n") \
+ CFI_INST(".cfi_restore w30\n") \
+ CFI_INST(".cfi_restore w29\n") \
+ "ret\n" \
+ CFI_INST(".cfi_endproc\n")
+// clang-format on
+
+// Emulated DA key value.
+static const uint8_t emu_da_key[16] = {0xb5, 0xd4, 0xc9, 0xeb, 0x79, 0x10,
+ 0x4a, 0x79, 0x6f, 0xec, 0x8b, 0x1b,
+ 0x42, 0x87, 0x81, 0xd4};
+
+extern "C" [[gnu::flatten]] uint64_t
+__emupac_pacda_impl(uint64_t ptr, uint64_t disc) {
+ if (pac_supported()) {
+ __asm__ __volatile__(".arch_extension pauth\npacda %0, %1"
+ : "+r"(ptr)
+ : "r"(disc));
+ return ptr;
+ }
+ if (ptr & ttbr1_mask) {
+ if ((ptr & pac_mask) != pac_mask) {
+ return ptr | pac_mask;
+ }
+ } else {
+ if (ptr & pac_mask) {
+ return ptr & ~pac_mask;
+ }
+ }
+ uint64_t hash;
+ siphash<1, 3>(reinterpret_cast<uint8_t *>(&ptr), 8, emu_da_key,
+ *reinterpret_cast<uint8_t(*)[8]>(&hash));
+ return (ptr & ~pac_mask) | (hash & pac_mask);
+}
+
+__asm__(".globl __emupac_pacda\n"
+ "__emupac_pacda:\n" FRAME_POINTER_WRAP(__emupac_pacda_impl));
+
+extern "C" [[gnu::flatten]] uint64_t
+__emupac_autda_impl(uint64_t ptr, uint64_t disc) {
+ if (pac_supported()) {
+ __asm__ __volatile__(".arch_extension pauth\nautda %0, %1"
+ : "+r"(ptr)
+ : "r"(disc));
+ return ptr;
+ }
+ uint64_t ptr_without_pac =
+ (ptr & ttbr1_mask) ? (ptr | pac_mask) : (ptr & ~pac_mask);
+ uint64_t hash;
+ siphash<1, 3>(reinterpret_cast<uint8_t *>(&ptr_without_pac), 8, emu_da_key,
+ *reinterpret_cast<uint8_t(*)[8]>(&hash));
+ if (((ptr & ~pac_mask) | (hash & pac_mask)) != ptr) {
+ __builtin_trap();
+ }
+ return ptr_without_pac;
+}
+
+__asm__(".globl __emupac_autda\n"
+ "__emupac_autda:\n" FRAME_POINTER_WRAP(__emupac_autda_impl));
diff --git a/compiler-rt/lib/builtins/int_types.h b/compiler-rt/lib/builtins/int_types.h
index 48862f3642175..7c7f8cb64aa9a 100644
--- a/compiler-rt/lib/builtins/int_types.h
+++ b/compiler-rt/lib/builtins/int_types.h
@@ -223,7 +223,7 @@ typedef union {
#define CRT_HAS_TF_MODE
#endif
-#if __STDC_VERSION__ >= 199901L
+#if __STDC_VERSION__ >= 199901L && !defined(_MSC_VER)
typedef float _Complex Fcomplex;
typedef double _Complex Dcomplex;
typedef long double _Complex Lcomplex;
diff --git a/compiler-rt/test/builtins/Unit/aarch64/emupac.c b/compiler-rt/test/builtins/Unit/aarch64/emupac.c
new file mode 100644
index 0000000000000..2140944b0eec5
--- /dev/null
+++ b/compiler-rt/test/builtins/Unit/aarch64/emupac.c
@@ -0,0 +1,121 @@
+// REQUIRES: librt_has_emupac
+// RUN: %clang_builtins %s %librt -o %t
+// RUN: %run %t 1
+// RUN: %run %t 2
+// RUN: %expect_crash %run %t 3
+// RUN: %expect_crash %run %t 4
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+uint64_t __emupac_pacda(uint64_t ptr, uint64_t disc);
+uint64_t __emupac_autda(uint64_t ptr, uint64_t disc);
+
+static bool pac_supported() {
+ register uintptr_t x30 __asm__("x30") = 1ULL << 55;
+ __asm__ __volatile__("xpaclri" : "+r"(x30));
+ return x30 & (1ULL << 54);
+}
+
+static bool fpac_supported(uint64_t ap) {
+ // The meaning of values larger than 6 is reserved as of July 2025; in theory
+ // larger values could mean that FEAT_FPAC is not implemented.
+ return ap == 4 || ap == 5 || ap == 6;
+}
+
+// The crash tests would fail to crash (causing the test to fail) if:
+// - The operating system did not enable the DA key, or
+// - The CPU supports FEAT_PAuth but not FEAT_FPAC.
+// Therefore, they call this function, which will crash the test process if one
+// of these cases is detected so that %expect_crash detects the crash and causes
+// the test to pass.
+//
+// We detect the former case by attempting to sign a pointer. If the signed
+// pointer is equal to the unsigned pointer, DA is likely disabled, so we crash.
+//
+// We detect the latter case by reading ID_AA64ISAR1_EL1 and ID_AA64ISAR2_EL1.
+// It is expected that the operating system will either trap and emulate reading
+// the system registers (as Linux does) or crash the process. In the
+// trap/emulate case we check the APA, API and APA3 fields for FEAT_FPAC support
+// and crash if it is not available. In the crash case we will crash when
+// reading the register leading to a passing test. This means that operating
+// systems with the crashing behavior do not support the crash tests.
+static void crash_if_crash_tests_unsupported() {
+ if (!pac_supported())
+ return;
+
+ uint64_t ptr = 0;
+ __asm__ __volatile__(".arch_extension pauth\npacda %0, %1"
+ : "+r"(ptr)
+ : "r"(0ul));
+ if (ptr == 0)
+ __builtin_trap();
+
+ uint64_t aa64isar1;
+ __asm__ __volatile__("mrs %0, id_aa64isar1_el1" : "=r"(aa64isar1));
+ uint64_t apa = (aa64isar1 >> 4) & 0xf;
+ uint64_t api = (aa64isar1 >> 8) & 0xf;
+ if (fpac_supported(apa) || fpac_supported(api))
+ return;
+
+ uint64_t aa64isar2;
+ __asm__ __volatile__("mrs %0, id_aa64isar2_el1" : "=r"(aa64isar2));
+ uint64_t apa3 = (aa64isar2 >> 12) & 0xf;
+ if (fpac_supported(apa3))
+ return;
+
+ __builtin_trap();
+}
+
+int main(int argc, char **argv) {
+ char stack_object1;
+ uint64_t ptr1 = (uint64_t)&stack_object1;
+
+ char stack_object2;
+ uint64_t ptr2 = (uint64_t)&stack_object2;
+
+ switch (atoi(argv[1])) {
+ case 1: {
+ // Normal case: test that a pointer authenticated with the same
+ // discriminator is equal to the original pointer.
+ uint64_t signed_ptr = __emupac_pacda(ptr1, ptr2);
+ uint64_t authed_ptr = __emupac_autda(signed_ptr, ptr2);
+ if (authed_ptr != ptr1) {
+ printf("0x%lx != 0x%lx\n", authed_ptr, ptr1);
+ return 1;
+ }
+ break;
+ }
+ case 2: {
+ // Test that negative addresses (addresses controlled by TTBR1,
+ // conventionally kernel addresses) can be signed and authenticated.
+ uint64_t unsigned_ptr = -1ULL;
+ uint64_t signed_ptr = __emupac_pacda(unsigned_ptr, ptr2);
+ uint64_t authed_ptr = __emupac_autda(signed_ptr, ptr2);
+ if (authed_ptr != unsigned_ptr) {
+ printf("0x%lx != 0x%lx\n", authed_ptr, unsigned_ptr);
+ return 1;
+ }
+ break;
+ }
+ case 3: {
+ crash_if_crash_tests_unsupported();
+ // Test that a corrupted signature crashes the program.
+ uint64_t signed_ptr = __emupac_pacda(ptr1, ptr2);
+ __emupac_autda(signed_ptr + (1ULL << 48), ptr2);
+ break;
+ }
+ case 4: {
+ crash_if_crash_tests_unsupported();
+ // Test that signing a pointer with signature bits already set produces a pointer
+ // that would fail auth.
+ uint64_t signed_ptr = __emupac_pacda(ptr1 + (1ULL << 48), ptr2);
+ __emupac_autda(signed_ptr, ptr2);
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn
index 44f5fdc20837c..2e7aa45f38e3e 100644
--- a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn
@@ -78,12 +78,14 @@ static_library("builtins") {
cflags += [ "-fomit-frame-pointer" ]
}
cflags_c = [ "-std=c11" ]
+ cflags_cc = [ "-nostdinc++" ]
}
defines = builtins_defines
sources = builtins_sources
deps = lse_targets
+ include_dirs = [ "//third-party/siphash/include" ]
}
# Currently unused but necessary to make sync_source_lists_from_cmake.py happy.
diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni
index ba151075c0f9d..bba2a4e891aa6 100644
--- a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni
+++ b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni
@@ -429,6 +429,7 @@ if (current_cpu == "arm") {
if (current_cpu == "arm64") {
builtins_sources -= [ "fp_mode.c" ]
builtins_sources += [
+ "aarch64/emupac.cpp",
"aarch64/fp_mode.c",
"cpu_model/aarch64.c",
]
diff --git a/llvm/utils/gn/secondary/compiler-rt/test/builtins/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/test/builtins/BUILD.gn
index 87848075a804e..97e4fdf61ec2d 100644
--- a/llvm/utils/gn/secondary/compiler-rt/test/builtins/BUILD.gn
+++ b/llvm/utils/gn/secondary/compiler-rt/test/builtins/BUILD.gn
@@ -46,6 +46,7 @@ if (current_toolchain != host_toolchain) {
"//compiler-rt/include($host_toolchain)",
"//compiler-rt/lib/builtins",
"//compiler-rt/test:lit_common_configured",
+ "//llvm/utils/not($host_toolchain)",
]
}
}
>From 60a471f0fea3ae0a53aa787f6273695b852d7fd6 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <pcc at google.com>
Date: Thu, 10 Jul 2025 18:07:14 -0700
Subject: [PATCH 2/3] Format
Created using spr 1.3.6-beta.1
---
compiler-rt/lib/builtins/aarch64/emupac.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/compiler-rt/lib/builtins/aarch64/emupac.cpp b/compiler-rt/lib/builtins/aarch64/emupac.cpp
index 62c551971bc90..eb7de9ff6e102 100644
--- a/compiler-rt/lib/builtins/aarch64/emupac.cpp
+++ b/compiler-rt/lib/builtins/aarch64/emupac.cpp
@@ -97,8 +97,8 @@ static const uint8_t emu_da_key[16] = {0xb5, 0xd4, 0xc9, 0xeb, 0x79, 0x10,
0x4a, 0x79, 0x6f, 0xec, 0x8b, 0x1b,
0x42, 0x87, 0x81, 0xd4};
-extern "C" [[gnu::flatten]] uint64_t
-__emupac_pacda_impl(uint64_t ptr, uint64_t disc) {
+extern "C" [[gnu::flatten]] uint64_t __emupac_pacda_impl(uint64_t ptr,
+ uint64_t disc) {
if (pac_supported()) {
__asm__ __volatile__(".arch_extension pauth\npacda %0, %1"
: "+r"(ptr)
@@ -116,15 +116,15 @@ __emupac_pacda_impl(uint64_t ptr, uint64_t disc) {
}
uint64_t hash;
siphash<1, 3>(reinterpret_cast<uint8_t *>(&ptr), 8, emu_da_key,
- *reinterpret_cast<uint8_t(*)[8]>(&hash));
+ *reinterpret_cast<uint8_t (*)[8]>(&hash));
return (ptr & ~pac_mask) | (hash & pac_mask);
}
__asm__(".globl __emupac_pacda\n"
"__emupac_pacda:\n" FRAME_POINTER_WRAP(__emupac_pacda_impl));
-extern "C" [[gnu::flatten]] uint64_t
-__emupac_autda_impl(uint64_t ptr, uint64_t disc) {
+extern "C" [[gnu::flatten]] uint64_t __emupac_autda_impl(uint64_t ptr,
+ uint64_t disc) {
if (pac_supported()) {
__asm__ __volatile__(".arch_extension pauth\nautda %0, %1"
: "+r"(ptr)
@@ -135,7 +135,7 @@ __emupac_autda_impl(uint64_t ptr, uint64_t disc) {
(ptr & ttbr1_mask) ? (ptr | pac_mask) : (ptr & ~pac_mask);
uint64_t hash;
siphash<1, 3>(reinterpret_cast<uint8_t *>(&ptr_without_pac), 8, emu_da_key,
- *reinterpret_cast<uint8_t(*)[8]>(&hash));
+ *reinterpret_cast<uint8_t (*)[8]>(&hash));
if (((ptr & ~pac_mask) | (hash & pac_mask)) != ptr) {
__builtin_trap();
}
>From 5478ef8f69c94ccb657640823b651aba5f42ec32 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <pcc at google.com>
Date: Fri, 11 Jul 2025 13:54:52 -0700
Subject: [PATCH 3/3] Address review comments
Created using spr 1.3.6-beta.1
---
compiler-rt/lib/builtins/aarch64/emupac.cpp | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/builtins/aarch64/emupac.cpp b/compiler-rt/lib/builtins/aarch64/emupac.cpp
index eb7de9ff6e102..7eaea7deb61a6 100644
--- a/compiler-rt/lib/builtins/aarch64/emupac.cpp
+++ b/compiler-rt/lib/builtins/aarch64/emupac.cpp
@@ -120,8 +120,13 @@ extern "C" [[gnu::flatten]] uint64_t __emupac_pacda_impl(uint64_t ptr,
return (ptr & ~pac_mask) | (hash & pac_mask);
}
-__asm__(".globl __emupac_pacda\n"
- "__emupac_pacda:\n" FRAME_POINTER_WRAP(__emupac_pacda_impl));
+// clang-format off
+__asm__(
+ ".globl " ASM_SYMBOL(__emupac_pacda) "\n"
+ ASM_SYMBOL(__emupac_pacda) ":\n"
+ FRAME_POINTER_WRAP(__emupac_pacda_impl)
+);
+// clang-format on
extern "C" [[gnu::flatten]] uint64_t __emupac_autda_impl(uint64_t ptr,
uint64_t disc) {
@@ -142,5 +147,10 @@ extern "C" [[gnu::flatten]] uint64_t __emupac_autda_impl(uint64_t ptr,
return ptr_without_pac;
}
-__asm__(".globl __emupac_autda\n"
- "__emupac_autda:\n" FRAME_POINTER_WRAP(__emupac_autda_impl));
+// clang-format off
+__asm__(
+ ".globl " ASM_SYMBOL(__emupac_autda) "\n"
+ ASM_SYMBOL(__emupac_autda) ":\n"
+ FRAME_POINTER_WRAP(__emupac_autda_impl)
+);
+// clang-format on
More information about the llvm-commits
mailing list