diff --git a/CMakeLists.txt b/CMakeLists.txt index 196a87294ea..74052ded692 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,6 @@ set(OFFSETS_H_TARGET offsets_h) set(SYSCALL_LIST_H_TARGET syscall_list_h_target) set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target) set(KOBJ_TYPES_H_TARGET kobj_types_h_target) -set(PARSE_SYSCALLS_TARGET parse_syscalls_target) set(DEVICE_API_LD_TARGET device_api_ld_target) define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ") @@ -344,6 +343,18 @@ if (CONFIG_PICOLIBC AND NOT CONFIG_PICOLIBC_IO_FLOAT) zephyr_compile_options($<$:$>) endif() +if(CONFIG_UBSAN) + zephyr_compile_options($<$:$>) + zephyr_link_libraries($) + if(CONFIG_UBSAN_LIBRARY) + zephyr_compile_options($<$:$>) + zephyr_link_libraries($) + elseif(CONFIG_UBSAN_TRAP) + zephyr_compile_options($<$:$>) + zephyr_link_libraries($) + endif() +endif() + # @Intent: Set compiler specific flag for tentative definitions, no-common zephyr_compile_options($) @@ -822,7 +833,7 @@ add_custom_command( --file-list ${syscalls_file_list_output} $<$:--emit-all-syscalls> DEPENDS ${syscalls_subdirs_trigger} ${PARSE_SYSCALLS_HEADER_DEPENDS} - ${syscalls_file_list_output} ${syscalls_interface} + ${syscalls_file_list_output} syscalls_interface ) # Make sure Picolibc is built before the rest of the system; there's no explicit @@ -840,12 +851,6 @@ set_property(TARGET ${SYSCALL_LIST_H_TARGET} ${CMAKE_CURRENT_BINARY_DIR}/include/generated/zephyr/syscalls ) -add_custom_target(${PARSE_SYSCALLS_TARGET} - DEPENDS - ${syscalls_json} - ${struct_tags_json} - ) - # 64-bit systems do not require special handling of 64-bit system call # parameters or return values, indicate this to the system call boilerplate # generation script. @@ -888,30 +893,24 @@ add_custom_command( COMMAND ${LEGACY_SYSCALL_LIST_H_ARGS} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${PARSE_SYSCALLS_TARGET} + DEPENDS ${syscalls_json} ) -# This is passed into all calls to the gen_kobject_list.py script. -set(gen_kobject_list_include_args --include-subsystem-list ${struct_tags_json}) +include(${ZEPHYR_BASE}/cmake/kobj.cmake) set(DRV_VALIDATION ${PROJECT_BINARY_DIR}/include/generated/zephyr/driver-validation.h) -add_custom_command( - OUTPUT ${DRV_VALIDATION} - COMMAND - ${PYTHON_EXECUTABLE} - ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py - --validation-output ${DRV_VALIDATION} - ${gen_kobject_list_include_args} - $<$:--verbose> - DEPENDS - ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py - ${PARSE_SYSCALLS_TARGET} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +gen_kobject_list( + TARGET ${DRIVER_VALIDATION_H_TARGET} + OUTPUTS ${DRV_VALIDATION} + SCRIPT_ARGS --validation-output ${DRV_VALIDATION} + INCLUDES ${struct_tags_json} + DEPENDS ${struct_tags_json} ) -add_custom_target(${DRIVER_VALIDATION_H_TARGET} DEPENDS ${DRV_VALIDATION}) -include(${ZEPHYR_BASE}/cmake/kobj.cmake) -gen_kobj(KOBJ_INCLUDE_PATH) +gen_kobject_list_headers( + INCLUDES ${struct_tags_json} + DEPENDS ${struct_tags_json} + ) # Generate sections for kernel device subsystems set( @@ -1110,7 +1109,6 @@ if(CONFIG_USERSPACE) NO_COVERAGE_FLAGS "${compiler_flags_priv}" ) - set(GEN_KOBJ_LIST ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py) set(PROCESS_GPERF ${ZEPHYR_BASE}/scripts/build/process_gperf.py) endif() @@ -1264,23 +1262,13 @@ if(CONFIG_USERSPACE) set(KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE kobject_prebuilt_hash_preprocessed.c) set(KOBJECT_PREBUILT_HASH_OUTPUT_SRC kobject_prebuilt_hash.c) - add_custom_command( + gen_kobject_list_gperf( + TARGET kobj_prebuilt_hash_list OUTPUT ${KOBJECT_PREBUILT_HASH_LIST} - COMMAND - ${PYTHON_EXECUTABLE} - ${GEN_KOBJ_LIST} - --kernel $ - --gperf-output ${KOBJECT_PREBUILT_HASH_LIST} - ${gen_kobject_list_include_args} - $<$:--verbose> - DEPENDS - ${ZEPHYR_LINK_STAGE_EXECUTABLE} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + KERNEL_TARGET ${ZEPHYR_LINK_STAGE_EXECUTABLE} + INCLUDES ${struct_tags_json} + DEPENDS ${struct_tags_json} ) - add_custom_target( - kobj_prebuilt_hash_list - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_PREBUILT_HASH_LIST} - ) add_custom_command( OUTPUT ${KOBJECT_PREBUILT_HASH_OUTPUT_SRC_PRE} @@ -1471,23 +1459,13 @@ if(CONFIG_USERSPACE) # Use the script GEN_KOBJ_LIST to scan the kernel binary's # (${ZEPHYR_LINK_STAGE_EXECUTABLE}) DWARF information to produce a table of kernel # objects (KOBJECT_HASH_LIST) which we will then pass to gperf - add_custom_command( + gen_kobject_list_gperf( + TARGET kobj_hash_list OUTPUT ${KOBJECT_HASH_LIST} - COMMAND - ${PYTHON_EXECUTABLE} - ${GEN_KOBJ_LIST} - --kernel $ - --gperf-output ${KOBJECT_HASH_LIST} - ${gen_kobject_list_include_args} - $<$:--verbose> - DEPENDS - ${ZEPHYR_LINK_STAGE_EXECUTABLE} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + KERNEL_TARGET ${ZEPHYR_LINK_STAGE_EXECUTABLE} + INCLUDES ${struct_tags_json} + DEPENDS ${struct_tags_json} ) - add_custom_target( - kobj_hash_list - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${KOBJECT_HASH_LIST} - ) # Use gperf to generate C code (KOBJECT_HASH_OUTPUT_SRC_PRE) which implements a # perfect hashtable based on KOBJECT_HASH_LIST @@ -1750,13 +1728,8 @@ if(CONFIG_BUILD_OUTPUT_ADJUST_LMA) ) endif() -if(NOT CONFIG_CPP_EXCEPTIONS) - set(eh_frame_section ".eh_frame") -else() - set(eh_frame_section "") -endif() set(remove_sections_argument_list "") -foreach(section .comment COMMON ${eh_frame_section}) +foreach(section .comment COMMON) list(APPEND remove_sections_argument_list $${section}) endforeach() @@ -1837,6 +1810,28 @@ if(CONFIG_BUILD_OUTPUT_BIN AND CONFIG_BUILD_OUTPUT_UF2) set(BYPRODUCT_KERNEL_UF2_NAME "${PROJECT_BINARY_DIR}/${KERNEL_UF2_NAME}" CACHE FILEPATH "Kernel uf2 file" FORCE) endif() +if(CONFIG_BUILD_OUTPUT_MOT) + get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) + if(srec IN_LIST elfconvert_formats) + list(APPEND + post_build_commands + COMMAND $ + $ + ${GAP_FILL} + $srec + $${OUTPUT_FORMAT} + $${KERNEL_ELF_NAME} + $${KERNEL_MOT_NAME} + $ + ) + list(APPEND + post_build_byproducts + ${KERNEL_MOT_NAME} + ) + set(BYPRODUCT_KERNEL_MOT_NAME "${PROJECT_BINARY_DIR}/${KERNEL_MOT_NAME}" CACHE FILEPATH "Kernel mot file" FORCE) + endif() +endif() + set(KERNEL_META_PATH ${PROJECT_BINARY_DIR}/${KERNEL_META_NAME} CACHE INTERNAL "") if(CONFIG_BUILD_OUTPUT_META) list(APPEND @@ -2302,7 +2297,7 @@ if(CONFIG_LLEXT_EDK) ${SYSCALL_SPLIT_TIMEOUT_ARG} COMMAND ${CMAKE_COMMAND} -P ${ZEPHYR_BASE}/cmake/llext-edk.cmake - DEPENDS ${logical_target_for_zephyr_elf} build_info_yaml_saved + DEPENDS ${logical_target_for_zephyr_elf} ${syscalls_json} build_info_yaml_saved COMMAND_EXPAND_LISTS ) add_custom_target(llext-edk DEPENDS ${llext_edk_file}) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 23f7507b432..99295612b68 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -785,6 +785,12 @@ config BUILD_OUTPUT_UF2 Build a UF2 binary zephyr/zephyr.uf2 in the build directory. The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. +config BUILD_OUTPUT_MOT + bool "Build a binary in MOT format" + help + Build a MOT binary zephyr/zephyr.mot in the build directory. + The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. + if BUILD_OUTPUT_UF2 config BUILD_OUTPUT_UF2_FAMILY_ID diff --git a/arch/Kconfig b/arch/Kconfig index f17c29ec6e3..8e9b7040b11 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -328,6 +328,7 @@ config PRIVILEGED_STACK_SIZE config KOBJECT_TEXT_AREA int "Size of kobject text area" + default 1024 if UBSAN default 512 if COVERAGE_GCOV default 512 if NO_OPTIMIZATIONS default 512 if STACK_CANARIES && RISCV diff --git a/arch/arm64/core/Kconfig b/arch/arm64/core/Kconfig index 35a480a24fd..21327f62c1b 100644 --- a/arch/arm64/core/Kconfig +++ b/arch/arm64/core/Kconfig @@ -126,6 +126,7 @@ config PRIVILEGED_STACK_SIZE default 4096 config KOBJECT_TEXT_AREA + default 1024 if UBSAN default 512 if TEST config WAIT_AT_RESET_VECTOR diff --git a/cmake/bintools/gnu/target_bintools.cmake b/cmake/bintools/gnu/target_bintools.cmake index 6bbe8f8a3cf..2abe7d321ab 100644 --- a/cmake/bintools/gnu/target_bintools.cmake +++ b/cmake/bintools/gnu/target_bintools.cmake @@ -27,8 +27,8 @@ set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_OBJCOPY}) # List of format the tool supports for converting, for example, -# GNU tools uses objectcopy, which supports the following: ihex, srec, binary -set_property(TARGET bintools PROPERTY elfconvert_formats ihex srec binary) +# GNU tools uses objectcopy, which supports the following: ihex, srec, binary, mot +set_property(TARGET bintools PROPERTY elfconvert_formats ihex srec binary mot) set_property(TARGET bintools PROPERTY elfconvert_flag "") set_property(TARGET bintools PROPERTY elfconvert_flag_final "") diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index 48afd244ac7..53b42823717 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -197,6 +197,10 @@ if(NOT CONFIG_NO_OPTIMIZATIONS) set_compiler_property(PROPERTY security_fortify_run_time _FORTIFY_SOURCE=2) endif() +check_set_compiler_property(PROPERTY sanitizer_undefined -fsanitize=undefined) +check_set_compiler_property(PROPERTY sanitizer_undefined_trap -fsanitize-undefined-trap-on-error) +check_set_compiler_property(PROPERTY sanitizer_undefined_library) + # gcc flag for a hosted (no-freestanding) application check_set_compiler_property(APPEND PROPERTY hosted -fno-freestanding) diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index d1f0d17da6e..8b2f17aff95 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -60,6 +60,10 @@ function(runners_yaml_append_config) get_runners_prop(uf2_file uf2 "${KERNEL_UF2_NAME}") runners_yaml_append(" uf2_file: ${uf2}") endif() + if(CONFIG_BUILD_OUTPUT_MOT) + get_runners_prop(mot_file mot "${KERNEL_MOT_NAME}") + runners_yaml_append(" mot_file: ${mot}") + endif() zephyr_get(OPENOCD) zephyr_get(OPENOCD_DEFAULT_PATH) diff --git a/cmake/kobj.cmake b/cmake/kobj.cmake index 22fa36ae44a..e8c55adc1e2 100644 --- a/cmake/kobj.cmake +++ b/cmake/kobj.cmake @@ -1,6 +1,62 @@ # SPDX-License-Identifier: Apache-2.0 -function(gen_kobj gen_dir_out) +set(GEN_KOBJECT_LIST ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py) + +# Invokes gen_kobject_list.py with the given SCRIPT_ARGS, creating a TARGET that depends on the +# script's OUTPUTS +function(gen_kobject_list) + cmake_parse_arguments(PARSE_ARGV 0 arg + "" + "TARGET" + "OUTPUTS;SCRIPT_ARGS;INCLUDES;DEPENDS" + ) + foreach(include ${arg_INCLUDES}) + list(APPEND arg_SCRIPT_ARGS --include-subsystem-list ${include}) + endforeach() + add_custom_command( + OUTPUT ${arg_OUTPUTS} + COMMAND + ${PYTHON_EXECUTABLE} + ${GEN_KOBJECT_LIST} + ${arg_SCRIPT_ARGS} + $<$:--verbose> + DEPENDS + ${arg_DEPENDS} + ${GEN_KOBJECT_LIST} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + add_custom_target(${arg_TARGET} DEPENDS ${arg_OUTPUTS}) +endfunction() + +# Generates a gperf header file named OUTPUT using the symbols found in the KERNEL_TARGET's output +# binary. INCLUDES is a list of JSON files defining kernel subsystems and sockets. +function(gen_kobject_list_gperf) + cmake_parse_arguments(PARSE_ARGV 0 arg + "" + "TARGET;OUTPUT;KERNEL_TARGET" + "INCLUDES;DEPENDS" + ) + gen_kobject_list( + TARGET ${arg_TARGET} + OUTPUTS ${arg_OUTPUT} + SCRIPT_ARGS + --kernel $ + --gperf-output ${arg_OUTPUT} + INCLUDES ${arg_INCLUDES} + DEPENDS + ${arg_DEPENDS} + ${arg_KERNEL_TARGET} + ) +endfunction() + +# Generates header files describing the kernel subsystems defined by the JSON files in INCLUDES. The +# variable named by GEN_DIR_OUT_VAR is set to the directory containing the header files. +function(gen_kobject_list_headers) + cmake_parse_arguments(PARSE_ARGV 0 arg + "" + "GEN_DIR_OUT_VAR" + "INCLUDES;DEPENDS" + ) if (PROJECT_BINARY_DIR) set(gen_dir ${PROJECT_BINARY_DIR}/include/generated/zephyr) else () @@ -13,24 +69,21 @@ function(gen_kobj gen_dir_out) file(MAKE_DIRECTORY ${gen_dir}) - add_custom_command( - OUTPUT ${KOBJ_TYPES} ${KOBJ_OTYPE} ${KOBJ_SIZE} - COMMAND - ${PYTHON_EXECUTABLE} - ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py - --kobj-types-output ${KOBJ_TYPES} - --kobj-otype-output ${KOBJ_OTYPE} - --kobj-size-output ${KOBJ_SIZE} - ${gen_kobject_list_include_args} - $<$:--verbose> + gen_kobject_list( + TARGET ${KOBJ_TYPES_H_TARGET} + OUTPUTS ${KOBJ_TYPES} ${KOBJ_OTYPE} ${KOBJ_SIZE} + SCRIPT_ARGS + --kobj-types-output ${KOBJ_TYPES} + --kobj-otype-output ${KOBJ_OTYPE} + --kobj-size-output ${KOBJ_SIZE} + INCLUDES ${arg_INCLUDES} DEPENDS - ${ZEPHYR_BASE}/scripts/build/gen_kobject_list.py - ${PARSE_SYSCALLS_TARGET} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - add_custom_target(${KOBJ_TYPES_H_TARGET} DEPENDS ${KOBJ_TYPES} ${KOBJ_OTYPE}) - - cmake_path(GET gen_dir PARENT_PATH gen_dir) - set(${gen_dir_out} ${gen_dir} PARENT_SCOPE) + ${arg_DEPENDS} + ${arg_KERNEL_TARGET} + ) + if(arg_GEN_DIR_OUT_VAR) + cmake_path(GET gen_dir PARENT_PATH gen_dir) + set(${arg_GEN_DIR_OUT_VAR} ${gen_dir} PARENT_SCOPE) + endif() endfunction () diff --git a/cmake/linker/ld/linker_flags.cmake b/cmake/linker/ld/linker_flags.cmake index 0e0e8b6b0a1..885a1844cc5 100644 --- a/cmake/linker/ld/linker_flags.cmake +++ b/cmake/linker/ld/linker_flags.cmake @@ -24,6 +24,10 @@ check_set_linker_property(TARGET linker PROPERTY orphan_error check_set_linker_property(TARGET linker PROPERTY memusage "${LINKERFLAGPREFIX},--print-memory-usage") +check_set_linker_property(TARGET linker PROPERTY sanitizer_undefined -fsanitize=undefined) +check_set_linker_property(TARGET linker PROPERTY sanitizer_undefined_trap -fsanitize-undefined-trap-on-error) +check_set_linker_property(TARGET linker PROPERTY sanitizer_undefined_library) + # -no-pie is not supported until binutils 2.37. # If -no-pie is passed to old binutils <= 2.36, it is parsed # as separate arguments -n and -o, which results in output file diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index 6bbd564c9e8..5c8fa184b20 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -78,6 +78,7 @@ add_custom_target(code_data_relocation_target) # bin_file "zephyr.bin" file for flashing # hex_file "zephyr.hex" file for flashing # elf_file "zephyr.elf" file for flashing or debugging +# mot_file "zephyr.mot" file for flashing # yaml_contents generated contents of runners.yaml # # Note: there are quotes around "zephyr.bin" etc. because the actual @@ -170,6 +171,7 @@ set(KERNEL_EXE_NAME ${KERNEL_NAME}.exe) set(KERNEL_STAT_NAME ${KERNEL_NAME}.stat) set(KERNEL_STRIP_NAME ${KERNEL_NAME}.strip) set(KERNEL_META_NAME ${KERNEL_NAME}.meta) +set(KERNEL_MOT_NAME ${KERNEL_NAME}.mot) set(KERNEL_SYMBOLS_NAME ${KERNEL_NAME}.symbols) # Enable dynamic library support when required by LLEXT. diff --git a/cmake/modules/unittest.cmake b/cmake/modules/unittest.cmake index 4c80283aa0e..97b0d099f6e 100644 --- a/cmake/modules/unittest.cmake +++ b/cmake/modules/unittest.cmake @@ -55,7 +55,7 @@ target_link_libraries(testbinary PRIVATE test_interface) set(KOBJ_TYPES_H_TARGET kobj_types_h_target) include(${ZEPHYR_BASE}/cmake/kobj.cmake) add_dependencies(test_interface ${KOBJ_TYPES_H_TARGET}) -gen_kobj(KOBJ_GEN_DIR) +gen_kobject_list_headers(GEN_DIR_OUT_VAR KOBJ_GEN_DIR) # Generates empty header files to build set(INCL_GENERATED_DIR ${APPLICATION_BINARY_DIR}/zephyr/include/generated/zephyr) diff --git a/include/zephyr/arch/x86/ia32/linker.ld b/include/zephyr/arch/x86/ia32/linker.ld index 02360d98202..298e8e4f56e 100644 --- a/include/zephyr/arch/x86/ia32/linker.ld +++ b/include/zephyr/arch/x86/ia32/linker.ld @@ -557,12 +557,6 @@ SECTIONS #include /DISCARD/ : { *(.note.GNU-stack) } -/* - * eh_frame section won't be removed even with "--gc-sections" by LLVM lld. - */ -#if !defined(CONFIG_CPP_EXCEPTIONS) - /DISCARD/ : { *(.eh_frame) } -#endif /* * The sections below are still treated as warnings diff --git a/include/zephyr/arch/x86/intel64/linker.ld b/include/zephyr/arch/x86/intel64/linker.ld index 9506b301486..d220d8ccac4 100644 --- a/include/zephyr/arch/x86/intel64/linker.ld +++ b/include/zephyr/arch/x86/intel64/linker.ld @@ -223,12 +223,6 @@ SECTIONS *(.rel.*) *(.rela.*) } -/* - * eh_frame section won't be removed even with "--gc-sections" by LLVM lld. - */ -#if !defined(CONFIG_CPP_EXCEPTIONS) - /DISCARD/ : { *(.eh_frame) } -#endif /* * The sections below are still treated as warnings diff --git a/include/zephyr/linker/cplusplus-rom.ld b/include/zephyr/linker/cplusplus-rom.ld index 0d815d4e69b..89f35c309a5 100644 --- a/include/zephyr/linker/cplusplus-rom.ld +++ b/include/zephyr/linker/cplusplus-rom.ld @@ -28,3 +28,7 @@ #endif /* CONFIG_CPP_EXCEPTIONS */ #endif /* CONFIG_CPP */ + +#if !defined(CONFIG_CPP_EXCEPTIONS) + /DISCARD/ : { *(.eh_frame) } +#endif diff --git a/subsys/debug/Kconfig b/subsys/debug/Kconfig index 6ee215c16f5..4fc64deccf5 100644 --- a/subsys/debug/Kconfig +++ b/subsys/debug/Kconfig @@ -67,12 +67,35 @@ config ASAN_NOP_DLCLOSE config UBSAN bool "Build with undefined behavior sanitizer" - depends on ARCH_POSIX help - Builds Zephyr with Undefined Behavior Sanitizer enabled. - This is currently only supported by boards based on the posix - architecture, and requires a recent-ish compiler with the - ``-fsanitize=undefined`` command line option. + Builds Zephyr with Undefined Behavior Sanitizer enabled. This + requires a recent-ish compiler with the ``-fsanitize=undefined`` + command line option. + +choice UBSAN_MODE + prompt "Undefined behavior sanitizer mode" + depends on UBSAN + default UBSAN_LIBRARY + +config UBSAN_LIBRARY + bool "Call ubsan routines" + depends on ARCH_POSIX || PICOLIBC + help + Call ubsan library routines when undefined behavior is detected + at runtime. This provides information about the faulting + condition along with the source filename, line number, types and + values involved. This is currently only supported by boards + based on the posix architecture or when building with picolibc. + +config UBSAN_TRAP + bool "Call __builtin_trap" + help + When undefined behavior is detected, invoke __builtin_trap to + cause an exception to be raised. This can be used on any target, + but the lack of information makes figuring out the triggering + code difficult. + +endchoice config MSAN bool "Build with memory sanitizer"