The current gen_handles.py script uses linker defined symbols. As preparation for support of more linkers the gen_tables.py now takes the device start symbol as argument. For example, armlink and ld uses different symbols. With ld those can be named explicitly, but for armlink the linker decides the names. For ld, Zephyr defines: __device_start For armlink, the symbol is defined as: Image$$<section name>$$Base Therefore knowledge of the linker symbol to be used must be passed to gen_handles.py so that the correct symbol can be used for locating devices. To support this change, the creation of the asm, compiler, compiler-cpp, linker targets has been moved from target_toolchain_flags.cmake to target_toolchain.cmake. All linkers has been updated to support the use of the device_start_symbol on the linker target. List of linkers updated: - ld - lld - arcmwdt Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
230 lines
8.1 KiB
CMake
230 lines
8.1 KiB
CMake
# SPDX-License-Identifier: Apache-2.0
|
|
set_property(TARGET linker PROPERTY devices_start_symbol "__device_start")
|
|
|
|
find_program(CMAKE_LINKER ${CROSS_COMPILE}lldac PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
|
|
|
|
# the prefix to transfer linker options from compiler
|
|
set_ifndef(LINKERFLAGPREFIX -Wl,)
|
|
|
|
# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
|
|
# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time
|
|
macro(configure_linker_script linker_script_gen linker_pass_define)
|
|
set(extra_dependencies ${ARGN})
|
|
|
|
# Different generators deal with depfiles differently.
|
|
if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
|
|
# Note that the IMPLICIT_DEPENDS option is currently supported only
|
|
# for Makefile generators and will be ignored by other generators.
|
|
set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
|
|
elseif(CMAKE_GENERATOR STREQUAL "Ninja")
|
|
# Using DEPFILE with other generators than Ninja is an error.
|
|
set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
|
|
else()
|
|
# TODO: How would the linker script dependencies work for non-linker
|
|
# script generators.
|
|
message(STATUS "Warning; this generator is not well supported. The
|
|
Linker script may not be regenerated when it should.")
|
|
set(linker_script_dep "")
|
|
endif()
|
|
|
|
zephyr_get_include_directories_for_lang(C current_includes)
|
|
get_filename_component(base_name ${CMAKE_CURRENT_BINARY_DIR} NAME)
|
|
get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES)
|
|
|
|
# the command to generate linker file from template
|
|
add_custom_command(
|
|
OUTPUT ${linker_script_gen}
|
|
DEPENDS
|
|
${LINKER_SCRIPT}
|
|
${AUTOCONF_H}
|
|
${extra_dependencies}
|
|
# NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
|
|
${linker_script_dep}
|
|
COMMAND ${CMAKE_C_COMPILER}
|
|
-x c
|
|
${NOSYSDEF_CFLAG}
|
|
-Hnocopyr
|
|
-MD -MF ${linker_script_gen}.dep -MT ${base_name}/${linker_script_gen}
|
|
-D_LINKER
|
|
-D_ASMLANGUAGE
|
|
-imacros ${AUTOCONF_H}
|
|
${current_includes}
|
|
${current_defines}
|
|
${linker_pass_define}
|
|
${LINKER_SCRIPT}
|
|
-E
|
|
-o ${linker_script_gen}
|
|
VERBATIM
|
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
|
COMMAND_EXPAND_LISTS
|
|
)
|
|
endmacro()
|
|
|
|
# Force symbols to be entered in the output file as undefined symbols
|
|
function(toolchain_ld_force_undefined_symbols)
|
|
foreach(symbol ${ARGN})
|
|
zephyr_link_libraries(${LINKERFLAGPREFIX}-u${symbol})
|
|
endforeach()
|
|
endfunction()
|
|
|
|
# Link a target to given libraries with toolchain-specific argument order
|
|
#
|
|
# Usage:
|
|
# toolchain_ld_link_elf(
|
|
# TARGET_ELF <target_elf>
|
|
# OUTPUT_MAP <output_map_file_of_target>
|
|
# LIBRARIES_PRE_SCRIPT [libraries_pre_script]
|
|
# LINKER_SCRIPT <linker_script>
|
|
# LIBRARIES_POST_SCRIPT [libraries_post_script]
|
|
# DEPENDENCIES [dependencies]
|
|
# )
|
|
function(toolchain_ld_link_elf)
|
|
cmake_parse_arguments(
|
|
TOOLCHAIN_LD_LINK_ELF # prefix of output variables
|
|
"" # list of names of the boolean arguments
|
|
"TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments
|
|
"LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
|
|
${ARGN} # input args to parse
|
|
)
|
|
|
|
target_link_libraries(
|
|
${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
|
|
${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
|
|
${LINKERFLAGPREFIX}-T${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
|
|
${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
|
|
${LINKERFLAGPREFIX}--gc-sections
|
|
${LINKERFLAGPREFIX}--entry=__start
|
|
${LINKERFLAGPREFIX}--Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
|
|
${LINKERFLAGPREFIX}--whole-archive
|
|
${ZEPHYR_LIBS_PROPERTY}
|
|
${LINKERFLAGPREFIX}--no-whole-archive
|
|
kernel
|
|
$<TARGET_OBJECTS:${OFFSETS_LIB}>
|
|
${LIB_INCLUDE_DIR}
|
|
-L${PROJECT_BINARY_DIR}
|
|
${TOOLCHAIN_LIBS}
|
|
|
|
${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
|
|
)
|
|
endfunction(toolchain_ld_link_elf)
|
|
|
|
# linker options of temporary linkage for code generation
|
|
macro(toolchain_ld_baremetal)
|
|
zephyr_ld_options(
|
|
-Hlld
|
|
-Hnosdata
|
|
-Xtimer0 # to suppress the warning message
|
|
-Hnoxcheck_obj
|
|
-Hnocplus
|
|
-Hhostlib=
|
|
-Hheap=0
|
|
-Hnoivt
|
|
)
|
|
|
|
# We only use CPP initialization code from crt
|
|
if(NOT CONFIG_CPLUSPLUS)
|
|
zephyr_ld_options(-Hnocrt)
|
|
endif()
|
|
|
|
# There are two options:
|
|
# - We have full MWDT libc support and we link MWDT libc - this is default
|
|
# behavior and we don't need to do something for that.
|
|
# - We use minimal libc provided by Zephyr itself. In that case we must not
|
|
# link MWDT libc, but we still need to link libmw
|
|
if(CONFIG_MINIMAL_LIBC)
|
|
zephyr_ld_options(
|
|
-Hnolib
|
|
-Hldopt=-lmw
|
|
)
|
|
endif()
|
|
|
|
# Funny thing is if this is set to =error, some architectures will
|
|
# skip this flag even though the compiler flag check passes
|
|
# (e.g. ARC and Xtensa). So warning should be the default for now.
|
|
#
|
|
# Skip this for native application as Zephyr only provides
|
|
# additions to the host toolchain linker script. The relocation
|
|
# sections (.rel*) requires us to override those provided
|
|
# by host toolchain. As we can't account for all possible
|
|
# combination of compiler and linker on all machines used
|
|
# for development, it is better to turn this off.
|
|
#
|
|
# CONFIG_LINKER_ORPHAN_SECTION_PLACE is to place the orphan sections
|
|
# without any warnings or errors, which is the default behavior.
|
|
# So there is no need to explicitly set a linker flag.
|
|
if(CONFIG_LINKER_ORPHAN_SECTION_WARN)
|
|
message(WARNING "MWDT toolchain does not support
|
|
CONFIG_LINKER_ORPHAN_SECTION_WARN")
|
|
elseif(CONFIG_LINKER_ORPHAN_SECTION_ERROR)
|
|
zephyr_ld_options(
|
|
${LINKERFLAGPREFIX}--orphan-handling=error)
|
|
endif()
|
|
endmacro()
|
|
|
|
# base linker options
|
|
macro(toolchain_ld_base)
|
|
if(NOT PROPERTY_LINKER_SCRIPT_DEFINES)
|
|
set_property(GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES -D__MWDT_LINKER_CMD__)
|
|
endif()
|
|
|
|
# Sort the common symbols and each input section by alignment
|
|
# in descending order to minimize padding between these symbols.
|
|
zephyr_ld_option_ifdef(
|
|
CONFIG_LINKER_SORT_BY_ALIGNMENT
|
|
${LINKERFLAGPREFIX}--sort-section=alignment
|
|
)
|
|
endmacro()
|
|
|
|
# generate linker script snippts from configure files
|
|
macro(toolchain_ld_configure_files)
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/arch/common/app_data_alignment.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld)
|
|
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/linker/app_smem.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_smem.ld)
|
|
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/linker/app_smem_aligned.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld)
|
|
|
|
configure_file(
|
|
$ENV{ZEPHYR_BASE}/include/linker/app_smem_unaligned.ld
|
|
${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld)
|
|
endmacro()
|
|
|
|
# link C++ libraries
|
|
macro(toolchain_ld_cpp)
|
|
zephyr_link_libraries(
|
|
-Hcplus
|
|
)
|
|
endmacro()
|
|
|
|
# use linker for relocation
|
|
macro(toolchain_ld_relocation)
|
|
set(MEM_RELOCATION_LD "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld")
|
|
set(MEM_RELOCATION_SRAM_DATA_LD
|
|
"${PROJECT_BINARY_DIR}/include/generated/linker_sram_data_relocate.ld")
|
|
set(MEM_RELOCATION_SRAM_BSS_LD
|
|
"${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld")
|
|
set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c")
|
|
|
|
add_custom_command(
|
|
OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD}
|
|
COMMAND
|
|
${PYTHON_EXECUTABLE}
|
|
${ZEPHYR_BASE}/scripts/gen_relocate_app.py
|
|
$<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
|
|
-d ${APPLICATION_BINARY_DIR}
|
|
-i \"$<TARGET_PROPERTY:code_data_relocation_target,COMPILE_DEFINITIONS>\"
|
|
-o ${MEM_RELOCATION_LD}
|
|
-s ${MEM_RELOCATION_SRAM_DATA_LD}
|
|
-b ${MEM_RELOCATION_SRAM_BSS_LD}
|
|
-c ${MEM_RELOCATION_CODE}
|
|
DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY}
|
|
)
|
|
|
|
add_library(code_relocation_source_lib STATIC ${MEM_RELOCATION_CODE})
|
|
target_link_libraries(code_relocation_source_lib zephyr_interface)
|
|
endmacro()
|