From 577ce965795a1326d5e946b1d87673cf8c69f1be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= Date: Mon, 19 May 2025 12:34:46 +0200 Subject: [PATCH 1/6] [compiler-rt] Add CMake option to enable execute-only code generation on AArch64 For a full toolchain supporting execute-only code generation the runtime libraries also need to be pre-compiled with it enabled. For compiler-rt this can now be enabled with the `COMPILER_RT_EXECUTE_ONLY_CODE` CMake option during build configuration. The build option can only be enabled for a runtimes build of compiler-rt, because a recent version of Clang is needed to correctly compile assembly files with execute-only code support. Related RFC: https://discourse.llvm.org/t/rfc-execute-only-code-support-for-runtime-libraries-on-aarch64/86180 --- compiler-rt/CMakeLists.txt | 20 +++++++++++++++++++ compiler-rt/cmake/builtin-config-ix.cmake | 2 ++ compiler-rt/cmake/config-ix.cmake | 2 ++ compiler-rt/lib/builtins/CMakeLists.txt | 15 +++++++++++++- compiler-rt/lib/builtins/assembly.h | 15 +++++++++++++- compiler-rt/lib/fuzzer/CMakeLists.txt | 4 +++- .../lib/hwasan/hwasan_setjmp_aarch64.S | 2 +- .../lib/hwasan/hwasan_tag_mismatch_aarch64.S | 2 +- compiler-rt/lib/msan/tests/CMakeLists.txt | 2 ++ compiler-rt/lib/orc/elfnix_tls.aarch64.S | 4 ++++ compiler-rt/lib/orc/sysv_reenter.arm64.S | 4 ++++ ...er_common_interceptors_vfork_aarch64.inc.S | 1 + compiler-rt/lib/tsan/CMakeLists.txt | 2 ++ compiler-rt/lib/tsan/rtl/tsan_rtl_aarch64.S | 6 ++---- .../lib/xray/xray_trampoline_AArch64.S | 2 +- 15 files changed, 73 insertions(+), 10 deletions(-) diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 9f8e8334d75ba..0e91e419fa373 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -307,6 +307,12 @@ option(COMPILER_RT_USE_BUILTINS_LIBRARY option(COMPILER_RT_USE_ATOMIC_LIBRARY "Use compiler-rt atomic instead of libatomic" OFF) +option(COMPILER_RT_EXECUTE_ONLY_CODE "Compile compiler-rt as execute-only" OFF) +if (COMPILER_RT_EXECUTE_ONLY_CODE AND NOT LLVM_RUNTIMES_BUILD) + message(SEND_ERROR "COMPILER_RT_EXECUTE_ONLY_CODE is only supported " + "for runtimes build of compiler-rt.") +endif() + include(config-ix) #================================ @@ -603,6 +609,20 @@ string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag}) list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag}) +# Add flags for execute-only code generation. +# We need to add to both COMPILER_RT_COMMON_CFLAGS and CMAKE__FLAGS. +if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only COMPILER_RT_COMMON_CFLAGS) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_COMMON_CFLAGS) + append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS) +elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code COMPILER_RT_COMMON_CFLAGS) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_COMMON_CFLAGS) + append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS) +endif() + # TODO: There's a lot of duplication across lib/*/tests/CMakeLists.txt files, # move some of the common flags to COMPILER_RT_UNITTEST_CFLAGS. diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake index 8c9c84ad64bc0..82fde12d85bf0 100644 --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -26,6 +26,8 @@ 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(-mexecute-only COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) +builtin_check_c_compiler_flag(-mpure-code COMPILER_RT_HAS_MPURE_CODE_FLAG) builtin_check_c_compiler_source(COMPILER_RT_HAS_ATOMIC_KEYWORD " diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index e3310b1ff0e2c..e44eeb0ab1c20 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -115,6 +115,8 @@ check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG) check_cxx_compiler_flag("-Werror -mcrc" COMPILER_RT_HAS_MCRC_FLAG) check_cxx_compiler_flag(-fno-partial-inlining COMPILER_RT_HAS_FNO_PARTIAL_INLINING_FLAG) check_cxx_compiler_flag("-Werror -ftrivial-auto-var-init=pattern" COMPILER_RT_HAS_TRIVIAL_AUTO_INIT) +check_cxx_compiler_flag(-mexecute-only COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) +check_cxx_compiler_flag(-mpure-code COMPILER_RT_HAS_MPURE_CODE_FLAG) if(NOT WIN32 AND NOT CYGWIN) # MinGW warns if -fvisibility-inlines-hidden is used. diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index d9b7800a95565..3842c089c1fbf 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -885,6 +885,7 @@ else () cmake_push_check_state() # TODO: we should probably make most of the checks in builtin-config depend on the target flags. set(BUILTIN_CFLAGS_${arch} ${BUILTIN_CFLAGS}) + set(BUILTIN_DEFS_${arch} ${BUILTIN_DEFS}) # CMAKE_REQUIRED_FLAGS must be a space separated string # Join BUILTIN_CFLAGS_${arch} and TARGET_${arch}_CFLAGS as a # space-separated string. @@ -922,6 +923,13 @@ else () if(COMPILER_RT_HAS_${arch}_BFLOAT16) list(APPEND ${arch}_SOURCES ${BF16_SOURCES}) endif() + if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only BUILTIN_CFLAGS_${arch}) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch}) + elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code BUILTIN_CFLAGS_${arch}) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch}) + endif() # Remove a generic C builtin when an arch-specific builtin is specified. filter_builtin_sources(${arch}_SOURCES ${arch}) @@ -943,7 +951,7 @@ else () ARCHS ${arch} DEPS ${deps_${arch}} SOURCES ${${arch}_SOURCES} - DEFS ${BUILTIN_DEFS} + DEFS ${BUILTIN_DEFS_${arch}} CFLAGS ${BUILTIN_CFLAGS_${arch}} PARENT_TARGET builtins) cmake_pop_check_state() @@ -1015,6 +1023,11 @@ if (COMPILER_RT_BUILD_CRT) if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG) append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS) endif() + if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only CRT_CFLAGS) + elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG) + append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code CRT_CFLAGS) + endif() foreach(arch ${BUILTIN_SUPPORTED_ARCH}) add_compiler_rt_runtime(clang_rt.crtbegin diff --git a/compiler-rt/lib/builtins/assembly.h b/compiler-rt/lib/builtins/assembly.h index 385dc190369d9..2e4195d0ba6a8 100644 --- a/compiler-rt/lib/builtins/assembly.h +++ b/compiler-rt/lib/builtins/assembly.h @@ -71,9 +71,17 @@ #endif +#if defined(__aarch64__) && defined(__ELF__) && \ + defined(COMPILER_RT_EXECUTE_ONLY_CODE) +#define TEXT_SECTION \ + .section .text,"axy",@progbits,unique,0 +#else +#define TEXT_SECTION \ + .text +#endif + #if defined(__arm__) || defined(__aarch64__) || defined(__arm64ec__) #define FUNC_ALIGN \ - .text SEPARATOR \ .balign 16 SEPARATOR #else #define FUNC_ALIGN @@ -230,6 +238,7 @@ #endif #define DEFINE_COMPILERRT_FUNCTION(name) \ + TEXT_SECTION SEPARATOR \ DEFINE_CODE_STATE \ FILE_LEVEL_DIRECTIVE SEPARATOR \ .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ @@ -239,6 +248,7 @@ FUNC_SYMBOL(SYMBOL_NAME(name)): #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ + TEXT_SECTION SEPARATOR \ DEFINE_CODE_STATE \ FILE_LEVEL_DIRECTIVE SEPARATOR \ .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ @@ -248,6 +258,7 @@ FUNC_SYMBOL(SYMBOL_NAME(name)): #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ + TEXT_SECTION SEPARATOR \ DEFINE_CODE_STATE \ FILE_LEVEL_DIRECTIVE SEPARATOR \ .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ @@ -257,6 +268,7 @@ FUNC_SYMBOL(SYMBOL_NAME(name)): #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ + TEXT_SECTION SEPARATOR \ DEFINE_CODE_STATE \ .globl FUNC_SYMBOL(name) SEPARATOR \ SYMBOL_IS_FUNC(name) SEPARATOR \ @@ -265,6 +277,7 @@ FUNC_SYMBOL(name): #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \ + TEXT_SECTION SEPARATOR \ DEFINE_CODE_STATE \ FUNC_ALIGN \ .globl FUNC_SYMBOL(name) SEPARATOR \ diff --git a/compiler-rt/lib/fuzzer/CMakeLists.txt b/compiler-rt/lib/fuzzer/CMakeLists.txt index 6db24610df1f0..adfba850861ac 100644 --- a/compiler-rt/lib/fuzzer/CMakeLists.txt +++ b/compiler-rt/lib/fuzzer/CMakeLists.txt @@ -163,8 +163,10 @@ if(OS_NAME MATCHES "Android|Linux|Fuchsia" AND CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF + -DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} -DLIBCXX_ABI_NAMESPACE=__Fuzzer - -DLIBCXX_ENABLE_EXCEPTIONS=OFF) + -DLIBCXX_ENABLE_EXCEPTIONS=OFF + -DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE}) target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-install-cmake326-workaround) target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) diff --git a/compiler-rt/lib/hwasan/hwasan_setjmp_aarch64.S b/compiler-rt/lib/hwasan/hwasan_setjmp_aarch64.S index 0c0abb6de861f..75ee6bc50baa8 100644 --- a/compiler-rt/lib/hwasan/hwasan_setjmp_aarch64.S +++ b/compiler-rt/lib/hwasan/hwasan_setjmp_aarch64.S @@ -28,7 +28,7 @@ // stack pointer when compiling a C function. // Hence we have to write this function in assembly. -.section .text +TEXT_SECTION .file "hwasan_setjmp_aarch64.S" .global ASM_WRAPPER_NAME(setjmp) diff --git a/compiler-rt/lib/hwasan/hwasan_tag_mismatch_aarch64.S b/compiler-rt/lib/hwasan/hwasan_tag_mismatch_aarch64.S index fd060c51cd8e2..d38767f9378fa 100644 --- a/compiler-rt/lib/hwasan/hwasan_tag_mismatch_aarch64.S +++ b/compiler-rt/lib/hwasan/hwasan_tag_mismatch_aarch64.S @@ -70,7 +70,7 @@ // clobbering the x17 register in error reports, and that the program will have // a runtime dependency on the __hwasan_tag_mismatch_v2 symbol therefore it will // fail to start up given an older (i.e. incompatible) runtime. -.section .text +TEXT_SECTION .file "hwasan_tag_mismatch_aarch64.S" .global __hwasan_tag_mismatch .type __hwasan_tag_mismatch, %function diff --git a/compiler-rt/lib/msan/tests/CMakeLists.txt b/compiler-rt/lib/msan/tests/CMakeLists.txt index a8500225337e6..53f570cfff27f 100644 --- a/compiler-rt/lib/msan/tests/CMakeLists.txt +++ b/compiler-rt/lib/msan/tests/CMakeLists.txt @@ -139,6 +139,8 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND add_custom_libcxx(libcxx_msan_${arch} ${LIBCXX_PREFIX} DEPS ${MSAN_RUNTIME_LIBRARIES} CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS} + CMAKE_ARGS -DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} + -DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} USE_TOOLCHAIN) set(MSAN_LIBCXX_DIR ${LIBCXX_PREFIX}/lib/) diff --git a/compiler-rt/lib/orc/elfnix_tls.aarch64.S b/compiler-rt/lib/orc/elfnix_tls.aarch64.S index 8dcdd535be8ae..22bd5b560c852 100644 --- a/compiler-rt/lib/orc/elfnix_tls.aarch64.S +++ b/compiler-rt/lib/orc/elfnix_tls.aarch64.S @@ -15,7 +15,11 @@ #define REGISTER_SAVE_SPACE_SIZE 32 * 24 +#if defined(COMPILER_RT_EXECUTE_ONLY_CODE) + .section .text,"axy",@progbits,unique,0 +#else .text +#endif // returns address of TLV in x0, all other registers preserved // TODO: add fast-path for repeat access diff --git a/compiler-rt/lib/orc/sysv_reenter.arm64.S b/compiler-rt/lib/orc/sysv_reenter.arm64.S index 74941c459d6ac..87a857c56ac61 100644 --- a/compiler-rt/lib/orc/sysv_reenter.arm64.S +++ b/compiler-rt/lib/orc/sysv_reenter.arm64.S @@ -13,7 +13,11 @@ // The content of this file is arm64-only #if defined(__arm64__) || defined(__aarch64__) +#if defined(__ELF__) && defined(COMPILER_RT_EXECUTE_ONLY_CODE) + .section .text,"axy",@progbits,unique,0 +#else .text +#endif // Saves GPRs, calls __orc_rt_resolve .globl __orc_rt_sysv_reenter diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S index cdfa6f1d7f53b..99d0aae0d2faa 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S @@ -5,6 +5,7 @@ ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) +TEXT_SECTION .comm _ZN14__interception10real_vforkE,8,8 .globl ASM_WRAPPER_NAME(vfork) ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt index 7928116879c09..686543e15fa6c 100644 --- a/compiler-rt/lib/tsan/CMakeLists.txt +++ b/compiler-rt/lib/tsan/CMakeLists.txt @@ -30,6 +30,8 @@ if(COMPILER_RT_LIBCXX_PATH AND add_custom_libcxx(libcxx_tsan_${arch} ${LIBCXX_PREFIX} DEPS ${TSAN_RUNTIME_LIBRARIES} CFLAGS ${TARGET_CFLAGS} -fsanitize=thread + CMAKE_ARGS -DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} + -DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} USE_TOOLCHAIN) list(APPEND libcxx_tsan_deps libcxx_tsan_${arch}-install-cmake326-workaround) endforeach() diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_aarch64.S b/compiler-rt/lib/tsan/rtl/tsan_rtl_aarch64.S index 7d920bee4a2db..93ad0d663c7a8 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_aarch64.S +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_aarch64.S @@ -4,10 +4,8 @@ #include "sanitizer_common/sanitizer_asm.h" #include "builtins/assembly.h" -#if !defined(__APPLE__) -.section .text -#else -.section __TEXT,__text +TEXT_SECTION +#if defined(__APPLE__) .align 3 #endif diff --git a/compiler-rt/lib/xray/xray_trampoline_AArch64.S b/compiler-rt/lib/xray/xray_trampoline_AArch64.S index 2586def04cbb1..5d951f3821a50 100644 --- a/compiler-rt/lib/xray/xray_trampoline_AArch64.S +++ b/compiler-rt/lib/xray/xray_trampoline_AArch64.S @@ -37,7 +37,7 @@ #endif .endm -.text +TEXT_SECTION .p2align 2 .global ASM_SYMBOL(__xray_FunctionEntry) ASM_HIDDEN(__xray_FunctionEntry) From 16605d8ee2ecb32bf0372fd47fe9c4aa2b8b0e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= Date: Tue, 20 May 2025 10:20:53 +0200 Subject: [PATCH 2/6] Add comment describing why 'unique,0' is needed --- compiler-rt/lib/builtins/assembly.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler-rt/lib/builtins/assembly.h b/compiler-rt/lib/builtins/assembly.h index 2e4195d0ba6a8..7f3af0141ae12 100644 --- a/compiler-rt/lib/builtins/assembly.h +++ b/compiler-rt/lib/builtins/assembly.h @@ -73,6 +73,13 @@ #if defined(__aarch64__) && defined(__ELF__) && \ defined(COMPILER_RT_EXECUTE_ONLY_CODE) +// The assembler always creates an implicit '.text' section with default flags +// (SHF_ALLOC | SHF_EXECINSTR), which is incompatible with the execute-only +// '.text' section we want to create here because of the missing +// SHF_AARCH64_PURECODE section flag. To solve this, we use 'unique,0' to +// differentiate the two sections. The output will therefore have two separate +// sections named '.text', where code will be placed into the execute-only +// '.text' section, and the implicitly-created one will be empty. #define TEXT_SECTION \ .section .text,"axy",@progbits,unique,0 #else From 591d0e8109f8a1abc465a084b832a050d62ab080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= Date: Wed, 21 May 2025 09:59:12 +0200 Subject: [PATCH 3/6] Use TEXT_SECTION macro in orc --- compiler-rt/lib/orc/elfnix_tls.aarch64.S | 8 +++----- compiler-rt/lib/orc/sysv_reenter.arm64.S | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/compiler-rt/lib/orc/elfnix_tls.aarch64.S b/compiler-rt/lib/orc/elfnix_tls.aarch64.S index 22bd5b560c852..25d97e6593dc0 100644 --- a/compiler-rt/lib/orc/elfnix_tls.aarch64.S +++ b/compiler-rt/lib/orc/elfnix_tls.aarch64.S @@ -13,13 +13,11 @@ // The content of this file is aarch64-only #if defined(__arm64__) || defined(__aarch64__) +#include "builtins/assembly.h" + #define REGISTER_SAVE_SPACE_SIZE 32 * 24 -#if defined(COMPILER_RT_EXECUTE_ONLY_CODE) - .section .text,"axy",@progbits,unique,0 -#else - .text -#endif + TEXT_SECTION // returns address of TLV in x0, all other registers preserved // TODO: add fast-path for repeat access diff --git a/compiler-rt/lib/orc/sysv_reenter.arm64.S b/compiler-rt/lib/orc/sysv_reenter.arm64.S index 87a857c56ac61..61e58e50c97c7 100644 --- a/compiler-rt/lib/orc/sysv_reenter.arm64.S +++ b/compiler-rt/lib/orc/sysv_reenter.arm64.S @@ -13,11 +13,9 @@ // The content of this file is arm64-only #if defined(__arm64__) || defined(__aarch64__) -#if defined(__ELF__) && defined(COMPILER_RT_EXECUTE_ONLY_CODE) - .section .text,"axy",@progbits,unique,0 -#else - .text -#endif +#include "builtins/assembly.h" + + TEXT_SECTION // Saves GPRs, calls __orc_rt_resolve .globl __orc_rt_sysv_reenter From 44a3a2d3ca082699b5114399563aef138185bc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= Date: Wed, 11 Jun 2025 11:06:13 +0200 Subject: [PATCH 4/6] Simplify CMake configuration based on RFC feedback --- compiler-rt/CMakeLists.txt | 21 +++++---------------- compiler-rt/cmake/builtin-config-ix.cmake | 2 -- compiler-rt/cmake/config-ix.cmake | 2 -- compiler-rt/lib/builtins/CMakeLists.txt | 15 +-------------- compiler-rt/lib/fuzzer/CMakeLists.txt | 5 ++--- compiler-rt/lib/msan/tests/CMakeLists.txt | 3 +-- compiler-rt/lib/tsan/CMakeLists.txt | 3 +-- 7 files changed, 10 insertions(+), 41 deletions(-) diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 0e91e419fa373..ee617fec50c70 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -307,9 +307,8 @@ option(COMPILER_RT_USE_BUILTINS_LIBRARY option(COMPILER_RT_USE_ATOMIC_LIBRARY "Use compiler-rt atomic instead of libatomic" OFF) -option(COMPILER_RT_EXECUTE_ONLY_CODE "Compile compiler-rt as execute-only" OFF) -if (COMPILER_RT_EXECUTE_ONLY_CODE AND NOT LLVM_RUNTIMES_BUILD) - message(SEND_ERROR "COMPILER_RT_EXECUTE_ONLY_CODE is only supported " +if (LLVM_EXECUTE_ONLY_CODE AND NOT LLVM_RUNTIMES_BUILD) + message(SEND_ERROR "LLVM_EXECUTE_ONLY_CODE is only supported " "for runtimes build of compiler-rt.") endif() @@ -609,19 +608,9 @@ string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag}) list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag}) -# Add flags for execute-only code generation. -# We need to add to both COMPILER_RT_COMMON_CFLAGS and CMAKE__FLAGS. -if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only COMPILER_RT_COMMON_CFLAGS) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_COMMON_CFLAGS) - append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS) -elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code COMPILER_RT_COMMON_CFLAGS) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_COMMON_CFLAGS) - append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS) -endif() +# Add assembler flags for execute-only code generation. C and C++ flags should have already +# been added to CMAKE_C_FLAGS and CMAKE_CXX_FLAGS. +append_string_if(LLVM_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS) # TODO: There's a lot of duplication across lib/*/tests/CMakeLists.txt files, # move some of the common flags to COMPILER_RT_UNITTEST_CFLAGS. diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake index 82fde12d85bf0..8c9c84ad64bc0 100644 --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -26,8 +26,6 @@ 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(-mexecute-only COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) -builtin_check_c_compiler_flag(-mpure-code COMPILER_RT_HAS_MPURE_CODE_FLAG) builtin_check_c_compiler_source(COMPILER_RT_HAS_ATOMIC_KEYWORD " diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index e44eeb0ab1c20..e3310b1ff0e2c 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -115,8 +115,6 @@ check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG) check_cxx_compiler_flag("-Werror -mcrc" COMPILER_RT_HAS_MCRC_FLAG) check_cxx_compiler_flag(-fno-partial-inlining COMPILER_RT_HAS_FNO_PARTIAL_INLINING_FLAG) check_cxx_compiler_flag("-Werror -ftrivial-auto-var-init=pattern" COMPILER_RT_HAS_TRIVIAL_AUTO_INIT) -check_cxx_compiler_flag(-mexecute-only COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) -check_cxx_compiler_flag(-mpure-code COMPILER_RT_HAS_MPURE_CODE_FLAG) if(NOT WIN32 AND NOT CYGWIN) # MinGW warns if -fvisibility-inlines-hidden is used. diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 3842c089c1fbf..d9b7800a95565 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -885,7 +885,6 @@ else () cmake_push_check_state() # TODO: we should probably make most of the checks in builtin-config depend on the target flags. set(BUILTIN_CFLAGS_${arch} ${BUILTIN_CFLAGS}) - set(BUILTIN_DEFS_${arch} ${BUILTIN_DEFS}) # CMAKE_REQUIRED_FLAGS must be a space separated string # Join BUILTIN_CFLAGS_${arch} and TARGET_${arch}_CFLAGS as a # space-separated string. @@ -923,13 +922,6 @@ else () if(COMPILER_RT_HAS_${arch}_BFLOAT16) list(APPEND ${arch}_SOURCES ${BF16_SOURCES}) endif() - if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only BUILTIN_CFLAGS_${arch}) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch}) - elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code BUILTIN_CFLAGS_${arch}) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch}) - endif() # Remove a generic C builtin when an arch-specific builtin is specified. filter_builtin_sources(${arch}_SOURCES ${arch}) @@ -951,7 +943,7 @@ else () ARCHS ${arch} DEPS ${deps_${arch}} SOURCES ${${arch}_SOURCES} - DEFS ${BUILTIN_DEFS_${arch}} + DEFS ${BUILTIN_DEFS} CFLAGS ${BUILTIN_CFLAGS_${arch}} PARENT_TARGET builtins) cmake_pop_check_state() @@ -1023,11 +1015,6 @@ if (COMPILER_RT_BUILD_CRT) if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG) append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS) endif() - if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only CRT_CFLAGS) - elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG) - append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code CRT_CFLAGS) - endif() foreach(arch ${BUILTIN_SUPPORTED_ARCH}) add_compiler_rt_runtime(clang_rt.crtbegin diff --git a/compiler-rt/lib/fuzzer/CMakeLists.txt b/compiler-rt/lib/fuzzer/CMakeLists.txt index adfba850861ac..73077d1bd5d59 100644 --- a/compiler-rt/lib/fuzzer/CMakeLists.txt +++ b/compiler-rt/lib/fuzzer/CMakeLists.txt @@ -162,11 +162,10 @@ if(OS_NAME MATCHES "Android|Linux|Fuchsia" AND CFLAGS ${TARGET_CFLAGS} CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DLLVM_EXECUTE_ONLY_CODE=${LLVM_EXECUTE_ONLY_CODE} -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF - -DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} -DLIBCXX_ABI_NAMESPACE=__Fuzzer - -DLIBCXX_ENABLE_EXCEPTIONS=OFF - -DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE}) + -DLIBCXX_ENABLE_EXCEPTIONS=OFF) target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-install-cmake326-workaround) target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1) diff --git a/compiler-rt/lib/msan/tests/CMakeLists.txt b/compiler-rt/lib/msan/tests/CMakeLists.txt index 53f570cfff27f..bf953e66c52e3 100644 --- a/compiler-rt/lib/msan/tests/CMakeLists.txt +++ b/compiler-rt/lib/msan/tests/CMakeLists.txt @@ -139,8 +139,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND add_custom_libcxx(libcxx_msan_${arch} ${LIBCXX_PREFIX} DEPS ${MSAN_RUNTIME_LIBRARIES} CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS} - CMAKE_ARGS -DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} - -DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} + CMAKE_ARGS -DLLVM_EXECUTE_ONLY_CODE=${LLVM_EXECUTE_ONLY_CODE} USE_TOOLCHAIN) set(MSAN_LIBCXX_DIR ${LIBCXX_PREFIX}/lib/) diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt index 686543e15fa6c..caacb286ab728 100644 --- a/compiler-rt/lib/tsan/CMakeLists.txt +++ b/compiler-rt/lib/tsan/CMakeLists.txt @@ -30,8 +30,7 @@ if(COMPILER_RT_LIBCXX_PATH AND add_custom_libcxx(libcxx_tsan_${arch} ${LIBCXX_PREFIX} DEPS ${TSAN_RUNTIME_LIBRARIES} CFLAGS ${TARGET_CFLAGS} -fsanitize=thread - CMAKE_ARGS -DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} - -DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE} + CMAKE_ARGS -DLLVM_EXECUTE_ONLY_CODE=${LLVM_EXECUTE_ONLY_CODE} USE_TOOLCHAIN) list(APPEND libcxx_tsan_deps libcxx_tsan_${arch}-install-cmake326-workaround) endforeach() From d9b1c15e13c83e412224019cfd3dcd911772448a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= Date: Thu, 12 Jun 2025 10:03:35 +0200 Subject: [PATCH 5/6] Don't check if we're doing a runtimes build A non-runtimes build of compiler-rt is deprecated and should be removed in the next release entirely, so we don't have to check for it. --- compiler-rt/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index ee617fec50c70..557c2cf89758a 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -307,11 +307,6 @@ option(COMPILER_RT_USE_BUILTINS_LIBRARY option(COMPILER_RT_USE_ATOMIC_LIBRARY "Use compiler-rt atomic instead of libatomic" OFF) -if (LLVM_EXECUTE_ONLY_CODE AND NOT LLVM_RUNTIMES_BUILD) - message(SEND_ERROR "LLVM_EXECUTE_ONLY_CODE is only supported " - "for runtimes build of compiler-rt.") -endif() - include(config-ix) #================================ From f80014cf5e518517028962f241949edf8fb535db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= Date: Thu, 26 Jun 2025 14:30:41 +0200 Subject: [PATCH 6/6] Rename LLVM_EXECUTE_ONLY_CODE to RUNTIMES_EXECUTE_ONLY_CODE --- compiler-rt/CMakeLists.txt | 2 +- compiler-rt/lib/fuzzer/CMakeLists.txt | 2 +- compiler-rt/lib/msan/tests/CMakeLists.txt | 2 +- compiler-rt/lib/tsan/CMakeLists.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 557c2cf89758a..7a16acf54b532 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -605,7 +605,7 @@ list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag}) # Add assembler flags for execute-only code generation. C and C++ flags should have already # been added to CMAKE_C_FLAGS and CMAKE_CXX_FLAGS. -append_string_if(LLVM_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS) +append_string_if(RUNTIMES_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS) # TODO: There's a lot of duplication across lib/*/tests/CMakeLists.txt files, # move some of the common flags to COMPILER_RT_UNITTEST_CFLAGS. diff --git a/compiler-rt/lib/fuzzer/CMakeLists.txt b/compiler-rt/lib/fuzzer/CMakeLists.txt index 73077d1bd5d59..a57e2fe46245a 100644 --- a/compiler-rt/lib/fuzzer/CMakeLists.txt +++ b/compiler-rt/lib/fuzzer/CMakeLists.txt @@ -162,7 +162,7 @@ if(OS_NAME MATCHES "Android|Linux|Fuchsia" AND CFLAGS ${TARGET_CFLAGS} CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON - -DLLVM_EXECUTE_ONLY_CODE=${LLVM_EXECUTE_ONLY_CODE} + -DRUNTIMES_EXECUTE_ONLY_CODE=${RUNTIMES_EXECUTE_ONLY_CODE} -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF -DLIBCXX_ABI_NAMESPACE=__Fuzzer -DLIBCXX_ENABLE_EXCEPTIONS=OFF) diff --git a/compiler-rt/lib/msan/tests/CMakeLists.txt b/compiler-rt/lib/msan/tests/CMakeLists.txt index bf953e66c52e3..b4848a8d190dc 100644 --- a/compiler-rt/lib/msan/tests/CMakeLists.txt +++ b/compiler-rt/lib/msan/tests/CMakeLists.txt @@ -139,7 +139,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND add_custom_libcxx(libcxx_msan_${arch} ${LIBCXX_PREFIX} DEPS ${MSAN_RUNTIME_LIBRARIES} CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS} - CMAKE_ARGS -DLLVM_EXECUTE_ONLY_CODE=${LLVM_EXECUTE_ONLY_CODE} + CMAKE_ARGS -DRUNTIMES_EXECUTE_ONLY_CODE=${RUNTIMES_EXECUTE_ONLY_CODE} USE_TOOLCHAIN) set(MSAN_LIBCXX_DIR ${LIBCXX_PREFIX}/lib/) diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt index caacb286ab728..3319855521bd5 100644 --- a/compiler-rt/lib/tsan/CMakeLists.txt +++ b/compiler-rt/lib/tsan/CMakeLists.txt @@ -30,7 +30,7 @@ if(COMPILER_RT_LIBCXX_PATH AND add_custom_libcxx(libcxx_tsan_${arch} ${LIBCXX_PREFIX} DEPS ${TSAN_RUNTIME_LIBRARIES} CFLAGS ${TARGET_CFLAGS} -fsanitize=thread - CMAKE_ARGS -DLLVM_EXECUTE_ONLY_CODE=${LLVM_EXECUTE_ONLY_CODE} + CMAKE_ARGS -DRUNTIMES_EXECUTE_ONLY_CODE=${RUNTIMES_EXECUTE_ONLY_CODE} USE_TOOLCHAIN) list(APPEND libcxx_tsan_deps libcxx_tsan_${arch}-install-cmake326-workaround) endforeach()