Skip to content

Commit 6d41758

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 97d4e96 commit 6d41758

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
@@ -309,6 +309,12 @@ option(COMPILER_RT_USE_BUILTINS_LIBRARY
309309

310310
option(COMPILER_RT_USE_ATOMIC_LIBRARY "Use compiler-rt atomic instead of libatomic" OFF)
311311

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

314320
#================================
@@ -605,6 +611,20 @@ string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}
605611
list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag})
606612
list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag})
607613

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

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ builtin_check_c_compiler_flag(-Wbuiltin-declaration-mismatch COMPILER_RT_HAS_WBU
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)
2929
builtin_check_c_compiler_flag(-nostdinc++ COMPILER_RT_HAS_NOSTDINCXX_FLAG)
30+
builtin_check_c_compiler_flag(-mexecute-only COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
31+
builtin_check_c_compiler_flag(-mpure-code COMPILER_RT_HAS_MPURE_CODE_FLAG)
3032

3133
builtin_check_c_compiler_source(COMPILER_RT_HAS_ATOMIC_KEYWORD
3234
"

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
@@ -913,6 +913,7 @@ else ()
913913
cmake_push_check_state()
914914
# TODO: we should probably make most of the checks in builtin-config depend on the target flags.
915915
set(BUILTIN_CFLAGS_${arch} ${BUILTIN_CFLAGS})
916+
set(BUILTIN_DEFS_${arch} ${BUILTIN_DEFS})
916917
# CMAKE_REQUIRED_FLAGS must be a space separated string
917918
# Join BUILTIN_CFLAGS_${arch} and TARGET_${arch}_CFLAGS as a
918919
# space-separated string.
@@ -950,6 +951,13 @@ else ()
950951
if(COMPILER_RT_HAS_${arch}_BFLOAT16)
951952
list(APPEND ${arch}_SOURCES ${BF16_SOURCES})
952953
endif()
954+
if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
955+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only BUILTIN_CFLAGS_${arch})
956+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch})
957+
elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG)
958+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code BUILTIN_CFLAGS_${arch})
959+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE COMPILER_RT_EXECUTE_ONLY_CODE BUILTIN_DEFS_${arch})
960+
endif()
953961

954962
# Remove a generic C builtin when an arch-specific builtin is specified.
955963
filter_builtin_sources(${arch}_SOURCES ${arch})
@@ -971,7 +979,7 @@ else ()
971979
ARCHS ${arch}
972980
DEPS ${deps_${arch}}
973981
SOURCES ${${arch}_SOURCES}
974-
DEFS ${BUILTIN_DEFS}
982+
DEFS ${BUILTIN_DEFS_${arch}}
975983
CFLAGS ${BUILTIN_CFLAGS_${arch}}
976984
C_STANDARD 11
977985
CXX_STANDARD 17
@@ -1045,6 +1053,11 @@ if (COMPILER_RT_BUILD_CRT)
10451053
if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG)
10461054
append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS)
10471055
endif()
1056+
if (COMPILER_RT_HAS_MEXECUTE_ONLY_FLAG)
1057+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mexecute-only CRT_CFLAGS)
1058+
elseif (COMPILER_RT_HAS_MPURE_CODE_FLAG)
1059+
append_list_if(COMPILER_RT_EXECUTE_ONLY_CODE -mpure-code CRT_CFLAGS)
1060+
endif()
10481061

10491062
foreach(arch ${BUILTIN_SUPPORTED_ARCH})
10501063
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
@@ -255,6 +263,7 @@
255263
#endif
256264

257265
#define DEFINE_COMPILERRT_FUNCTION(name) \
266+
TEXT_SECTION SEPARATOR \
258267
DEFINE_CODE_STATE \
259268
FILE_LEVEL_DIRECTIVE SEPARATOR \
260269
.globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
@@ -264,6 +273,7 @@
264273
FUNC_SYMBOL(SYMBOL_NAME(name)):
265274

266275
#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \
276+
TEXT_SECTION SEPARATOR \
267277
DEFINE_CODE_STATE \
268278
FILE_LEVEL_DIRECTIVE SEPARATOR \
269279
.globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
@@ -273,6 +283,7 @@
273283
FUNC_SYMBOL(SYMBOL_NAME(name)):
274284

275285
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
286+
TEXT_SECTION SEPARATOR \
276287
DEFINE_CODE_STATE \
277288
FILE_LEVEL_DIRECTIVE SEPARATOR \
278289
.globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
@@ -282,6 +293,7 @@
282293
FUNC_SYMBOL(SYMBOL_NAME(name)):
283294

284295
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
296+
TEXT_SECTION SEPARATOR \
285297
DEFINE_CODE_STATE \
286298
.globl FUNC_SYMBOL(name) SEPARATOR \
287299
SYMBOL_IS_FUNC(name) SEPARATOR \
@@ -290,6 +302,7 @@
290302
FUNC_SYMBOL(name):
291303

292304
#define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \
305+
TEXT_SECTION SEPARATOR \
293306
DEFINE_CODE_STATE \
294307
FUNC_ALIGN \
295308
.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)