llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Daniil Kovalev (kovdan01) <details> <summary>Changes</summary> Compiler-synthesized functions such as `__llvm_gcov_writeout`, `__llvm_gcov_reset` and `__llvm_gcov_init` were previously never receiving the AArch64 hardening function attributes (ptrauth-returns, ptrauth-auth-traps, ptrauth-indirect-gotos and aarch64-jump-table-hardening) since the attributes were only emitted by Clang and gated by `PointerAuthOptions` structure's corresponding fields. See `setPointerAuthFnAttributes` and `initPointerAuthFnAttributes` member functions of `TargetCodeGenInfo`. This patch resolves this in the same manner as #<!-- -->83153 does for several other attributes. Particularly, Clang now emits corresponding 4 module flags (conditionally on whether the related feature is enabled) with Max behavior, and LLVM's `Function::createWithDefaultAttr` derives the matching function attributes from them. Max behavior with conditional emission is safe because none of these features affect ABI, so promoting an absent flag on module merge cannot break compatibility. --- Full diff: https://github.com/llvm/llvm-project/pull/211013.diff 4 Files Affected: - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+21) - (added) clang/test/CodeGen/AArch64/ptrauth-function-attributes-synthetic.c (+41) - (modified) llvm/lib/IR/Function.cpp (+4) - (added) llvm/test/Instrumentation/AddressSanitizer/ptrauth-module-flags-aarch64.ll (+14) ``````````diff diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 5f5fc4401bb4e..52b110ccbac68 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1540,6 +1540,27 @@ void CodeGenModule::Release() { "sign-return-address-with-bkey", 2); } if (T.isAArch64()) { + // Emit the following 4 module flags so LLVM can derive corresponding + // function attributes for synthetically generated functions (e.g. + // __llvm_gcov_writeout). It is safe to only emit the flags conditionally + // and set the Max behavior because of two reasons: + // 1) all 4 hardening features gated behind the attributes do not break ABI + // compatibility, so we do not need to error on flag mismatch (thus, + // conditional emission); + // 2) promoting an absent flag to a present flag enables the corresponding + // hardening feature for newly emitted functions which does not affect + // correctness and is guaranteed to have sufficient target features for + // it, since the module we are merging with already has the flag set. + if (LangOpts.PointerAuthReturns) + getModule().addModuleFlag(llvm::Module::Max, "ptrauth-returns", 1); + if (LangOpts.PointerAuthAuthTraps) + getModule().addModuleFlag(llvm::Module::Max, "ptrauth-auth-traps", 1); + if (LangOpts.PointerAuthIndirectGotos) + getModule().addModuleFlag(llvm::Module::Max, "ptrauth-indirect-gotos", 1); + if (LangOpts.AArch64JumpTableHardening) + getModule().addModuleFlag(llvm::Module::Max, + "aarch64-jump-table-hardening", 1); + if (getTriple().isOSBinFormatELF()) { getModule().addModuleFlag(llvm::Module::Error, "ptrauth-elf-got", LangOpts.PointerAuthELFGOT); diff --git a/clang/test/CodeGen/AArch64/ptrauth-function-attributes-synthetic.c b/clang/test/CodeGen/AArch64/ptrauth-function-attributes-synthetic.c new file mode 100644 index 0000000000000..6e6d6542db0d6 --- /dev/null +++ b/clang/test/CodeGen/AArch64/ptrauth-function-attributes-synthetic.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -coverage-data-file=/dev/null -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,OFF +// RUN: %clang_cc1 -triple arm64e-apple-ios -coverage-data-file=/dev/null -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,OFF +// RUN: %clang_cc1 -triple aarch64-linux-gnu -coverage-data-file=/dev/null -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,OFF + +// RUN: %clang_cc1 -triple arm64-apple-ios -coverage-data-file=/dev/null -fptrauth-returns -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,RETS +// RUN: %clang_cc1 -triple aarch64-linux-gnu -coverage-data-file=/dev/null -fptrauth-returns -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,RETS + +// RUN: %clang_cc1 -triple arm64-apple-ios -coverage-data-file=/dev/null -fptrauth-auth-traps -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,TRAPS +// RUN: %clang_cc1 -triple aarch64-linux-gnu -coverage-data-file=/dev/null -fptrauth-auth-traps -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,TRAPS + +// RUN: %clang_cc1 -triple arm64-apple-ios -coverage-data-file=/dev/null -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS +// RUN: %clang_cc1 -triple aarch64-linux-gnu -coverage-data-file=/dev/null -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS + +// RUN: %clang_cc1 -triple arm64e-apple-ios -coverage-data-file=/dev/null -faarch64-jump-table-hardening -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,JMPTBL +// RUN: %clang_cc1 -triple aarch64-linux-gnu -coverage-data-file=/dev/null -faarch64-jump-table-hardening -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,JMPTBL + +// ALL: define internal void @__llvm_gcov_writeout() unnamed_addr #[[#T:]] { +// ALL: define internal void @__llvm_gcov_reset() unnamed_addr #[[#T]] { +// ALL: define internal void @__llvm_gcov_init() unnamed_addr #[[#T]] { + +// RETS: attributes #[[#T]] = {{{.*}} "ptrauth-returns" {{.*}}} +// RETS: !llvm.module.flags = !{{{.*}}!3{{.*}}} +// RETS: !3 = !{i32 7, !"ptrauth-returns", i32 1} + +// TRAPS: attributes #[[#T]] = {{{.*}} "ptrauth-auth-traps" {{.*}}} +// TRAPS: !llvm.module.flags = !{{{.*}}!3{{.*}}} +// TRAPS: !3 = !{i32 7, !"ptrauth-auth-traps", i32 1} + +// GOTOS: attributes #[[#T]] = {{{.*}} "ptrauth-indirect-gotos" {{.*}}} +// GOTOS: !llvm.module.flags = !{{{.*}}!3{{.*}}} +// GOTOS: !3 = !{i32 7, !"ptrauth-indirect-gotos", i32 1} + +// JMPTBL: attributes #[[#T]] = {{{.*}} "aarch64-jump-table-hardening" {{.*}}} +// JMPTBL: !llvm.module.flags = !{{{.*}}!3{{.*}}} +// JMPTBL: !3 = !{i32 7, !"aarch64-jump-table-hardening", i32 1} + +// OFF-NOT: attributes {{.*}} "ptrauth- +// OFF-NOT: !"ptrauth-returns" +// OFF-NOT: !"ptrauth-auth-traps" +// OFF-NOT: !"ptrauth-indirect-gotos" +// OFF-NOT: !"aarch64-jump-table-hardening" diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 03e91bc8e2aa4..7c2a151dbefda 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -432,6 +432,10 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty, AddAttributeIfSet("branch-target-enforcement"); AddAttributeIfSet("branch-protection-pauth-lr"); AddAttributeIfSet("guarded-control-stack"); + AddAttributeIfSet("ptrauth-returns"); + AddAttributeIfSet("ptrauth-auth-traps"); + AddAttributeIfSet("ptrauth-indirect-gotos"); + AddAttributeIfSet("aarch64-jump-table-hardening"); F->addFnAttrs(B); return F; diff --git a/llvm/test/Instrumentation/AddressSanitizer/ptrauth-module-flags-aarch64.ll b/llvm/test/Instrumentation/AddressSanitizer/ptrauth-module-flags-aarch64.ll new file mode 100644 index 0000000000000..0e63ebd978d62 --- /dev/null +++ b/llvm/test/Instrumentation/AddressSanitizer/ptrauth-module-flags-aarch64.ll @@ -0,0 +1,14 @@ +; RUN: opt < %s -passes=asan -S | FileCheck %s +; REQUIRES: aarch64-registered-target + +target triple = "aarch64-unknown-linux-gnu" + +!llvm.module.flags = !{!0, !1, !2, !3} + +!0 = !{i32 7, !"ptrauth-returns", i32 1} +!1 = !{i32 7, !"ptrauth-auth-traps", i32 1} +!2 = !{i32 7, !"ptrauth-indirect-gotos", i32 1} +!3 = !{i32 7, !"aarch64-jump-table-hardening", i32 1} + +; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]] +; CHECK: attributes #[[#ATTR]] = { nounwind "aarch64-jump-table-hardening" "ptrauth-auth-traps" "ptrauth-indirect-gotos" "ptrauth-returns" } `````````` </details> https://github.com/llvm/llvm-project/pull/211013 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
