Skip to content

Commit 577ce96

Browse files
committed
[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
1 parent bca39f4 commit 577ce96

15 files changed

+73
-10
lines changed

compiler-rt/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@ option(COMPILER_RT_USE_BUILTINS_LIBRARY
307307

308308
option(COMPILER_RT_USE_ATOMIC_LIBRARY "Use compiler-rt atomic instead of libatomic" OFF)
309309

310+
option(COMPILER_RT_EXECUTE_ONLY_CODE "Compile compiler-rt as execute-only" OFF)
311+
if (COMPILER_RT_EXECUTE_ONLY_CODE AND NOT LLVM_RUNTIMES_BUILD)
312+
message(SEND_ERROR "COMPILER_RT_EXECUTE_ONLY_CODE is only supported "
313+
"for runtimes build of compiler-rt.")
314+
endif()
315+
310316
include(config-ix)
311317

312318
#================================
@@ -603,6 +609,20 @@ string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}
603609
list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag})
604610
list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag})
605611

612+
# Add flags for execute-only code generation.
613+
# We need to add to both COMPILER_RT_COMMON_CFLAGS and CMAKE_<LANG>_FLAGS.
614+
if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
615+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only COMPILER_RT_COMMON_CFLAGS)
616+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_COMMON_CFLAGS)
617+
append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
618+
append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS)
619+
elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG)
620+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code COMPILER_RT_COMMON_CFLAGS)
621+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_COMMON_CFLAGS)
622+
append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
623+
append_string_if(COMPILER_RT_EXECUTE_ONLY_CODE -DCOMPILER_RT_EXECUTE_ONLY_CODE CMAKE_ASM_FLAGS)
624+
endif()
625+
606626
# TODO: There's a lot of duplication across lib/*/tests/CMakeLists.txt files,
607627
# move some of the common flags to COMPILER_RT_UNITTEST_CFLAGS.
608628

compiler-rt/cmake/builtin-config-ix.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ builtin_check_c_compiler_flag("-Xclang -mcode-object-version=none" COMPILER_RT_H
2626
builtin_check_c_compiler_flag(-Wbuiltin-declaration-mismatch COMPILER_RT_HAS_WBUILTIN_DECLARATION_MISMATCH_FLAG)
2727
builtin_check_c_compiler_flag(/Zl COMPILER_RT_HAS_ZL_FLAG)
2828
builtin_check_c_compiler_flag(-fcf-protection=full COMPILER_RT_HAS_FCF_PROTECTION_FLAG)
29+
builtin_check_c_compiler_flag(-mexecute-only COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
30+
builtin_check_c_compiler_flag(-mpure-code COMPILER_RT_HAS_MPURE_CODE_FLAG)
2931

3032
builtin_check_c_compiler_source(COMPILER_RT_HAS_ATOMIC_KEYWORD
3133
"

compiler-rt/cmake/config-ix.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG)
115115
check_cxx_compiler_flag("-Werror -mcrc" COMPILER_RT_HAS_MCRC_FLAG)
116116
check_cxx_compiler_flag(-fno-partial-inlining COMPILER_RT_HAS_FNO_PARTIAL_INLINING_FLAG)
117117
check_cxx_compiler_flag("-Werror -ftrivial-auto-var-init=pattern" COMPILER_RT_HAS_TRIVIAL_AUTO_INIT)
118+
check_cxx_compiler_flag(-mexecute-only COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
119+
check_cxx_compiler_flag(-mpure-code COMPILER_RT_HAS_MPURE_CODE_FLAG)
118120

119121
if(NOT WIN32 AND NOT CYGWIN)
120122
# MinGW warns if -fvisibility-inlines-hidden is used.

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,7 @@ else ()
885885
cmake_push_check_state()
886886
# TODO: we should probably make most of the checks in builtin-config depend on the target flags.
887887
set(BUILTIN_CFLAGS_${arch} ${BUILTIN_CFLAGS})
888+
set(BUILTIN_DEFS_${arch} ${BUILTIN_DEFS})
888889
# CMAKE_REQUIRED_FLAGS must be a space separated string
889890
# Join BUILTIN_CFLAGS_${arch} and TARGET_${arch}_CFLAGS as a
890891
# space-separated string.
@@ -922,6 +923,13 @@ else ()
922923
if(COMPILER_RT_HAS_${arch}_BFLOAT16)
923924
list(APPEND ${arch}_SOURCES ${BF16_SOURCES})
924925
endif()
926+
if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
927+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only BUILTIN_CFLAGS_${arch})
928+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch})
929+
elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG)
930+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code BUILTIN_CFLAGS_${arch})
931+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch})
932+
endif()
925933

926934
# Remove a generic C builtin when an arch-specific builtin is specified.
927935
filter_builtin_sources(${arch}_SOURCES ${arch})
@@ -943,7 +951,7 @@ else ()
943951
ARCHS ${arch}
944952
DEPS ${deps_${arch}}
945953
SOURCES ${${arch}_SOURCES}
946-
DEFS ${BUILTIN_DEFS}
954+
DEFS ${BUILTIN_DEFS_${arch}}
947955
CFLAGS ${BUILTIN_CFLAGS_${arch}}
948956
PARENT_TARGET builtins)
949957
cmake_pop_check_state()
@@ -1015,6 +1023,11 @@ if (COMPILER_RT_BUILD_CRT)
10151023
if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG)
10161024
append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS)
10171025
endif()
1026+
if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
1027+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only CRT_CFLAGS)
1028+
elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG)
1029+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code CRT_CFLAGS)
1030+
endif()
10181031

10191032
foreach(arch ${BUILTIN_SUPPORTED_ARCH})
10201033
add_compiler_rt_runtime(clang_rt.crtbegin

compiler-rt/lib/builtins/assembly.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,17 @@
7171

7272
#endif
7373

74+
#if defined(__aarch64__) && defined(__ELF__) && \
75+
defined(COMPILER_RT_EXECUTE_ONLY_CODE)
76+
#define TEXT_SECTION \
77+
.section .text,"axy",@progbits,unique,0
78+
#else
79+
#define TEXT_SECTION \
80+
.text
81+
#endif
82+
7483
#if defined(__arm__) || defined(__aarch64__) || defined(__arm64ec__)
7584
#define FUNC_ALIGN \
76-
.text SEPARATOR \
7785
.balign 16 SEPARATOR
7886
#else
7987
#define FUNC_ALIGN
@@ -230,6 +238,7 @@
230238
#endif
231239

232240
#define DEFINE_COMPILERRT_FUNCTION(name) \
241+
TEXT_SECTION SEPARATOR \
233242
DEFINE_CODE_STATE \
234243
FILE_LEVEL_DIRECTIVE SEPARATOR \
235244
.globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
@@ -239,6 +248,7 @@
239248
FUNC_SYMBOL(SYMBOL_NAME(name)):
240249

241250
#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \
251+
TEXT_SECTION SEPARATOR \
242252
DEFINE_CODE_STATE \
243253
FILE_LEVEL_DIRECTIVE SEPARATOR \
244254
.globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
@@ -248,6 +258,7 @@
248258
FUNC_SYMBOL(SYMBOL_NAME(name)):
249259

250260
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
261+
TEXT_SECTION SEPARATOR \
251262
DEFINE_CODE_STATE \
252263
FILE_LEVEL_DIRECTIVE SEPARATOR \
253264
.globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
@@ -257,6 +268,7 @@
257268
FUNC_SYMBOL(SYMBOL_NAME(name)):
258269

259270
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
271+
TEXT_SECTION SEPARATOR \
260272
DEFINE_CODE_STATE \
261273
.globl FUNC_SYMBOL(name) SEPARATOR \
262274
SYMBOL_IS_FUNC(name) SEPARATOR \
@@ -265,6 +277,7 @@
265277
FUNC_SYMBOL(name):
266278

267279
#define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \
280+
TEXT_SECTION SEPARATOR \
268281
DEFINE_CODE_STATE \
269282
FUNC_ALIGN \
270283
.globl FUNC_SYMBOL(name) SEPARATOR \

compiler-rt/lib/fuzzer/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ if(OS_NAME MATCHES "Android|Linux|Fuchsia" AND
163163
CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON
164164
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
165165
-DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
166+
-DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE}
166167
-DLIBCXX_ABI_NAMESPACE=__Fuzzer
167-
-DLIBCXX_ENABLE_EXCEPTIONS=OFF)
168+
-DLIBCXX_ENABLE_EXCEPTIONS=OFF
169+
-DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE})
168170
target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
169171
add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-install-cmake326-workaround)
170172
target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)

compiler-rt/lib/hwasan/hwasan_setjmp_aarch64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
// stack pointer when compiling a C function.
2929
// Hence we have to write this function in assembly.
3030

31-
.section .text
31+
TEXT_SECTION
3232
.file "hwasan_setjmp_aarch64.S"
3333

3434
.global ASM_WRAPPER_NAME(setjmp)

compiler-rt/lib/hwasan/hwasan_tag_mismatch_aarch64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
// clobbering the x17 register in error reports, and that the program will have
7171
// a runtime dependency on the __hwasan_tag_mismatch_v2 symbol therefore it will
7272
// fail to start up given an older (i.e. incompatible) runtime.
73-
.section .text
73+
TEXT_SECTION
7474
.file "hwasan_tag_mismatch_aarch64.S"
7575
.global __hwasan_tag_mismatch
7676
.type __hwasan_tag_mismatch, %function

compiler-rt/lib/msan/tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS AND
139139
add_custom_libcxx(libcxx_msan_${arch} ${LIBCXX_PREFIX}
140140
DEPS ${MSAN_RUNTIME_LIBRARIES}
141141
CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS}
142+
CMAKE_ARGS -DLIBCXX_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE}
143+
-DLIBCXXABI_EXECUTE_ONLY_CODE=${COMPILER_RT_EXECUTE_ONLY_CODE}
142144
USE_TOOLCHAIN)
143145
set(MSAN_LIBCXX_DIR ${LIBCXX_PREFIX}/lib/)
144146

compiler-rt/lib/orc/elfnix_tls.aarch64.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515

1616
#define REGISTER_SAVE_SPACE_SIZE 32 * 24
1717

18+
#if defined(COMPILER_RT_EXECUTE_ONLY_CODE)
19+
.section .text,"axy",@progbits,unique,0
20+
#else
1821
.text
22+
#endif
1923

2024
// returns address of TLV in x0, all other registers preserved
2125
// TODO: add fast-path for repeat access

0 commit comments

Comments
 (0)