https://github.com/Il-Capitano updated https://github.com/llvm/llvm-project/pull/125688
From a25845dcb484514c83022a21ee924e31a39882f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.ha...@arm.com> Date: Tue, 4 Feb 2025 14:51:55 +0100 Subject: [PATCH 1/2] [Clang][AArch64] Add support for SHF_AARCH64_PURECODE ELF section flag (2/3) Add support for the new SHF_AARCH64_PURECODE ELF section flag: https://github.com/ARM-software/abi-aa/pull/304 The general implementation follows the existing one for ARM targets. Simlarly to ARM targets, generating object files with the `SHF_AARCH64_PURECODE` flag set is enabled by the `-mexecute-only`/`-mpure-code` driver flag. --- clang/include/clang/Driver/Options.td | 4 ++-- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 11 +++++++++ clang/test/CodeGen/aarch64-execute-only.c | 24 ++++++++++++++++++++ clang/test/Driver/aarch64-execute-only.c | 6 +++++ clang/test/Driver/fsanitize.c | 8 ++++++- 5 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-execute-only.c create mode 100644 clang/test/Driver/aarch64-execute-only.c diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5ad187926e710..0c8c4e5e0fae4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4692,9 +4692,9 @@ def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_Group>, HelpText<"Restore the default behaviour of not generating long calls">; } // let Flags = [TargetSpecific] def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>, - HelpText<"Disallow generation of data access to code sections (ARM only)">; + HelpText<"Disallow generation of data access to code sections (AArch64/ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>, - HelpText<"Allow generation of data access to code sections (ARM only)">; + HelpText<"Allow generation of data access to code sections (AArch64/ARM only)">; let Flags = [TargetSpecific] in { def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft,cp15,tpidrurw,tpidruro,tpidrprw,el0,el1,el2,el3,tpidr_el0,tpidr_el1,tpidr_el2,tpidr_el3,tpidrro_el0">, HelpText<"Thread pointer access method. " diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 1e2ac4e501baf..1248fea50f9de 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -332,6 +332,17 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, } else if (Triple.isOSOpenBSD()) Features.push_back("+strict-align"); + // Generate execute-only output (no data access to code sections). + // This only makes sense for the compiler, not for the assembler. + if (!ForAS) { + if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, + options::OPT_mno_execute_only)) { + if (A->getOption().matches(options::OPT_mexecute_only)) { + Features.push_back("+execute-only"); + } + } + } + if (Args.hasArg(options::OPT_ffixed_x1)) Features.push_back("+reserve-x1"); diff --git a/clang/test/CodeGen/aarch64-execute-only.c b/clang/test/CodeGen/aarch64-execute-only.c new file mode 100644 index 0000000000000..d885e954166f6 --- /dev/null +++ b/clang/test/CodeGen/aarch64-execute-only.c @@ -0,0 +1,24 @@ +// RUN: %clang -target aarch64 -### %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY + +// RUN: %clang -target aarch64 -### -mexecute-only %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY + +// RUN: %clang -target aarch64 -### -mexecute-only -mno-execute-only %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY + + +// -mpure-code flag for GCC compatibility +// RUN: %clang -target aarch64 -### %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY + +// RUN: %clang -target aarch64 -### -mpure-code %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-EXECUTE-ONLY + +// RUN: %clang -target aarch64 -### -mpure-code -mno-pure-code %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-EXECUTE-ONLY + +// CHECK-NO-EXECUTE-ONLY-NOT: "+execute-only" +// CHECK-EXECUTE-ONLY: "+execute-only" + +void a() {} diff --git a/clang/test/Driver/aarch64-execute-only.c b/clang/test/Driver/aarch64-execute-only.c new file mode 100644 index 0000000000000..67c6d4a5eb066 --- /dev/null +++ b/clang/test/Driver/aarch64-execute-only.c @@ -0,0 +1,6 @@ +// RUN: %clang --sysroot=%S/Inputs -c -fdriver-only -Werror --target=aarch64-unknown-linux-gnu \ +// RUN: -mexecute-only %s 2>&1 | count 0 + +// RUN: %clang -### --target=aarch64-unknown-linux-gnu -x assembler -mexecute-only %s -c -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-EXECUTE-ONLY-ASM +// CHECK-NO-EXECUTE-ONLY-ASM: warning: argument unused during compilation: '-mexecute-only' diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index 429dc51b3356d..cb3b75cbd27a7 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -1052,7 +1052,6 @@ // RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-TARGET // RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=function -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-TARGET --check-prefix=CHECK-UBSAN-FUNCTION-TARGET // RUN: %clang --target=x86_64-sie-ps5 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-UNDEFINED -// CHECK-UBSAN-UNDEFINED: "-fsanitize={{((alignment|array-bounds|bool|builtin|enum|float-cast-overflow|integer-divide-by-zero|nonnull-attribute|null|pointer-overflow|return|returns-nonnull-attribute|shift-base|shift-exponent|signed-integer-overflow|unreachable|vla-bound),?){17}"}} // RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-MEXECUTE-ONLY // RUN: not %clang --target=armv6t2-eabi -mpure-code -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-MPURE-CODE @@ -1060,12 +1059,19 @@ // RUN: not %clang --target=armv6t2-eabi -mpure-code -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-MPURE-CODE // RUN: %clang --target=armv6t2-eabi -mexecute-only -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-UNDEFINED-VPTR +// RUN: not %clang --target=aarch64 -mexecute-only -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-MEXECUTE-ONLY +// RUN: not %clang --target=aarch64 -mpure-code -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-MPURE-CODE +// RUN: not %clang --target=aarch64 -mexecute-only -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-MEXECUTE-ONLY +// RUN: not %clang --target=aarch64 -mpure-code -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-MPURE-CODE +// RUN: %clang --target=aarch64 -mexecute-only -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-UNDEFINED + // CHECK-UBSAN-KCFI-TARGET-DAG: error: unsupported option '-fsanitize=kcfi' for target 'x86_64-sie-ps5' // CHECK-UBSAN-KCFI-MEXECUTE-ONLY-DAG: error: invalid argument '-fsanitize=kcfi' not allowed with '-mexecute-only' // CHECK-UBSAN-KCFI-MPURE-CODE-DAG: error: invalid argument '-fsanitize=kcfi' not allowed with '-mpure-code' // CHECK-UBSAN-FUNCTION-TARGET-DAG: error: unsupported option '-fsanitize=function' for target 'x86_64-sie-ps5' // CHECK-UBSAN-FUNCTION-MEXECUTE-ONLY-DAG: error: invalid argument '-fsanitize=function' not allowed with '-mexecute-only' // CHECK-UBSAN-FUNCTION-MPURE-CODE-DAG: error: invalid argument '-fsanitize=function' not allowed with '-mpure-code' +// CHECK-UBSAN-UNDEFINED: "-fsanitize={{((alignment|array-bounds|bool|builtin|enum|float-cast-overflow|integer-divide-by-zero|nonnull-attribute|null|pointer-overflow|return|returns-nonnull-attribute|shift-base|shift-exponent|signed-integer-overflow|unreachable|vla-bound),?){17}"}} // CHECK-UBSAN-UNDEFINED-VPTR: "-fsanitize={{((alignment|array-bounds|bool|builtin|enum|float-cast-overflow|integer-divide-by-zero|nonnull-attribute|null|pointer-overflow|return|returns-nonnull-attribute|shift-base|shift-exponent|signed-integer-overflow|unreachable|vla-bound|vptr),?){18}"}} // * Test BareMetal toolchain sanitizer support * From 3fb9937a2587eac98f5e83848d08a182cc7d2750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.ha...@arm.com> Date: Tue, 18 Feb 2025 10:19:58 +0100 Subject: [PATCH 2/2] Fix unused argument diagnostic emission for baremetal targets --- clang/lib/Driver/ToolChain.cpp | 4 +++- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 6 ++++-- clang/lib/Driver/ToolChains/Arch/AArch64.h | 2 +- clang/test/Driver/aarch64-execute-only.c | 3 +++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 56bc500da66b9..f116679fbe49b 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -210,7 +210,9 @@ static void getAArch64MultilibFlags(const Driver &D, const llvm::opt::ArgList &Args, Multilib::flags_list &Result) { std::vector<StringRef> Features; - tools::aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, false); + tools::aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, + /*ForAS=*/false, + /*ForMultilib=*/true); const auto UnifiedFeatures = tools::unifyTargetFeatures(Features); llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(), UnifiedFeatures.end()); diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 1248fea50f9de..6e70effe9e325 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -196,7 +196,7 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, std::vector<StringRef> &Features, - bool ForAS) { + bool ForAS, bool ForMultilib) { Arg *A; bool success = true; llvm::StringRef WaMArch; @@ -334,7 +334,9 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, // Generate execute-only output (no data access to code sections). // This only makes sense for the compiler, not for the assembler. - if (!ForAS) { + // It's not needed for multilib selection and may hide an unused + // argument diagnostic if the code is always run. + if (!ForAS && !ForMultilib) { if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) { if (A->getOption().matches(options::OPT_mexecute_only)) { diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.h b/clang/lib/Driver/ToolChains/Arch/AArch64.h index 6d071167bd392..2057272867a17 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.h +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.h @@ -23,7 +23,7 @@ namespace aarch64 { void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector<llvm::StringRef> &Features, - bool ForAS); + bool ForAS, bool ForMultilib = false); std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, llvm::opt::Arg *&A); diff --git a/clang/test/Driver/aarch64-execute-only.c b/clang/test/Driver/aarch64-execute-only.c index 67c6d4a5eb066..e7d0949f09d13 100644 --- a/clang/test/Driver/aarch64-execute-only.c +++ b/clang/test/Driver/aarch64-execute-only.c @@ -3,4 +3,7 @@ // RUN: %clang -### --target=aarch64-unknown-linux-gnu -x assembler -mexecute-only %s -c -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-NO-EXECUTE-ONLY-ASM +// RUN: %clang -### --multi-lib-config=%S/Inputs/multilib/empty.yaml --sysroot= \ +// RUN: --target=aarch64-none-elf -x assembler -mexecute-only %s -c -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-EXECUTE-ONLY-ASM // CHECK-NO-EXECUTE-ONLY-ASM: warning: argument unused during compilation: '-mexecute-only' _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits