diff --git a/CMakeLists.txt b/CMakeLists.txt index eeca1dc26a234..c811f0cdf5bc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -410,6 +410,10 @@ zephyr_link_libraries_ifndef(CONFIG_LINKER_USE_RELAX PROPERTY no_relax) zephyr_link_libraries_ifdef(CONFIG_LINKER_USE_RELAX PROPERTY relax) +zephyr_link_libraries_ifndef(CONFIG_LINKER_ERROR_RWX_SEGMENTS PROPERTY no_error_rwx_segments) + +zephyr_link_libraries_ifdef(CONFIG_LINKER_ERROR_RWX_SEGMENTS PROPERTY error_rwx_segments) + # Sort the common symbols and each input section by alignment # in descending order to minimize padding between these symbols. zephyr_link_libraries_ifdef(CONFIG_LINKER_SORT_BY_ALIGNMENT PROPERTY sort_alignment) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 99295612b68ff..61cf29f1d756b 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -324,6 +324,14 @@ config LINKER_USE_RELAX Disabling it can reduce performance, as the linker is no longer able to substiture long / in-effective jump calls to shorter / more effective instructions. +config LINKER_ERROR_RWX_SEGMENTS + bool "Error on RWX output segments" + help + This option configures the linker to generate an error for output + segments that are marked both executable and writable. Use to + ensure that segments with code are only shared with read-only + data and not read-write data. + endmenu # "Linker Sections" config LINKER_ITERABLE_SUBALIGN diff --git a/cmake/linker/ld/linker_flags.cmake b/cmake/linker/ld/linker_flags.cmake index 885a1844cc5d6..c408325d5a25f 100644 --- a/cmake/linker/ld/linker_flags.cmake +++ b/cmake/linker/ld/linker_flags.cmake @@ -49,6 +49,12 @@ check_set_linker_property(TARGET linker PROPERTY sort_alignment ${LINKERFLAGPREFIX},--sort-section=alignment ) +check_set_linker_property(TARGET linker PROPERTY no_error_rwx_segments + ${LINKERFLAGPREFIX},--no-warn-rwx-segments ${LINKERFLAGPREFIX},--no-error-rwx-segments) + +check_set_linker_property(TARGET linker PROPERTY error_rwx_segments + ${LINKERFLAGPREFIX},--warn-rwx-segments ${LINKERFLAGPREFIX},--error-rwx-segments) + # Some linker flags might not be purely ld specific, but a combination of # linker and compiler, such as: # --coverage for clang diff --git a/cmake/linker/linker_flags_template.cmake b/cmake/linker/linker_flags_template.cmake index 8b0b948b028eb..cc7d00c2eed97 100644 --- a/cmake/linker/linker_flags_template.cmake +++ b/cmake/linker/linker_flags_template.cmake @@ -50,6 +50,12 @@ set_property(TARGET linker PROPERTY no_relax) # Linker flag for enabling relaxation of address optimization for jump calls. set_property(TARGET linker PROPERTY relax) +# Linker flag for enabling errors about RWX segments +set_property(TARGET linker PROPERTY error_rwx_segments) + +# Linker flag for disabling errors about RWX segments +set_property(TARGET linker PROPERTY no_error_rwx_segments) + # Linker flag for defining specs. Defined only by gcc, when gcc is used as # front-end for ld. set_compiler_property(PROPERTY specs) diff --git a/cmake/linker/lld/linker_flags.cmake b/cmake/linker/lld/linker_flags.cmake index 6997f865d28d4..5cea6422f1d60 100644 --- a/cmake/linker/lld/linker_flags.cmake +++ b/cmake/linker/lld/linker_flags.cmake @@ -17,6 +17,12 @@ set_property(TARGET linker PROPERTY lto_arguments) check_set_linker_property(TARGET linker PROPERTY sort_alignment ${LINKERFLAGPREFIX},--sort-section=alignment) +check_set_linker_property(TARGET linker PROPERTY no_error_rwx_segments + ${LINKERFLAGPREFIX},--no-warn-rwx-segments ${LINKERFLAGPREFIX},--no-error-rwx-segments) + +check_set_linker_property(TARGET linker PROPERTY error_rwx_segments + ${LINKERFLAGPREFIX},--warn-rwx-segments ${LINKERFLAGPREFIX},--error-rwx-segments) + if(CONFIG_RISCV_GP) check_set_linker_property(TARGET linker PROPERTY relax ${LINKERFLAGPREFIX},--relax-gp) endif()