1# SPDX-License-Identifier: Apache-2.0
2set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start")
3
4find_program(CMAKE_LINKER ${CROSS_COMPILE}lldac PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
5
6# the prefix to transfer linker options from compiler
7set_ifndef(LINKERFLAGPREFIX -Wl)
8
9# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
10# NOTE: ${linker_script_gen} will be produced at build-time; not at configure-time
11macro(configure_linker_script linker_script_gen linker_pass_define)
12  set(extra_dependencies ${ARGN})
13  set(template_script_defines ${linker_pass_define})
14  list(TRANSFORM template_script_defines PREPEND "-D")
15
16  # Different generators deal with depfiles differently.
17  if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
18    # Note that the IMPLICIT_DEPENDS option is currently supported only
19    # for Makefile generators and will be ignored by other generators.
20    set(linker_script_dep IMPLICIT_DEPENDS C ${LINKER_SCRIPT})
21  elseif(CMAKE_GENERATOR STREQUAL "Ninja")
22    # Using DEPFILE with other generators than Ninja is an error.
23    set(linker_script_dep DEPFILE ${PROJECT_BINARY_DIR}/${linker_script_gen}.dep)
24  else()
25    # TODO: How would the linker script dependencies work for non-linker
26    # script generators.
27    message(STATUS "Warning; this generator is not well supported. The
28                    Linker script may not be regenerated when it should.")
29    set(linker_script_dep "")
30  endif()
31
32  zephyr_get_include_directories_for_lang(C current_includes)
33
34# the command to generate linker file from template
35  add_custom_command(
36    OUTPUT ${linker_script_gen}
37    DEPENDS
38    ${LINKER_SCRIPT}
39    ${AUTOCONF_H}
40    ${extra_dependencies}
41    # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
42    ${linker_script_dep}
43    COMMAND ${CMAKE_C_COMPILER}
44    -x c
45    ${NOSYSDEF_CFLAG}
46    -Hnocopyr
47    -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen}
48    -D_LINKER
49    -D_ASMLANGUAGE
50    -D__MWDT_LINKER_CMD__
51    -imacros ${AUTOCONF_H}
52    ${current_includes}
53    ${template_script_defines}
54    ${LINKER_SCRIPT}
55    -E
56    -o ${linker_script_gen}
57    VERBATIM
58    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
59    COMMAND_EXPAND_LISTS
60)
61endmacro()
62
63# Force symbols to be entered in the output file as undefined symbols
64function(toolchain_ld_force_undefined_symbols)
65  foreach(symbol ${ARGN})
66    zephyr_link_libraries(${LINKERFLAGPREFIX},-u${symbol})
67  endforeach()
68endfunction()
69
70# Link a target to given libraries with toolchain-specific argument order
71#
72# Usage:
73#   toolchain_ld_link_elf(
74#     TARGET_ELF             <target_elf>
75#     OUTPUT_MAP             <output_map_file_of_target>
76#     LIBRARIES_PRE_SCRIPT   [libraries_pre_script]
77#     LINKER_SCRIPT          <linker_script>
78#     LIBRARIES_POST_SCRIPT  [libraries_post_script]
79#     DEPENDENCIES           [dependencies]
80#   )
81function(toolchain_ld_link_elf)
82  cmake_parse_arguments(
83    TOOLCHAIN_LD_LINK_ELF                                     # prefix of output variables
84    ""                                                        # list of names of the boolean arguments
85    "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT"                     # list of names of scalar arguments
86    "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
87    ${ARGN}                                                   # input args to parse
88  )
89
90  target_link_libraries(
91    ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
92    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
93    ${LINKERFLAGPREFIX},-T${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
94    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
95    ${LINKERFLAGPREFIX},--gc-sections
96    ${LINKERFLAGPREFIX},--entry=__start
97    ${LINKERFLAGPREFIX},--Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
98    ${LINKERFLAGPREFIX},--whole-archive
99    ${WHOLE_ARCHIVE_LIBS}
100    ${LINKERFLAGPREFIX},--no-whole-archive
101    ${NO_WHOLE_ARCHIVE_LIBS}
102    $<TARGET_OBJECTS:${OFFSETS_LIB}>
103    ${LIB_INCLUDE_DIR}
104    -L${PROJECT_BINARY_DIR}
105    ${TOOLCHAIN_LIBS}
106
107    ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
108  )
109endfunction(toolchain_ld_link_elf)
110
111# linker options of temporary linkage for code generation
112macro(toolchain_ld_baremetal)
113endmacro()
114
115# base linker options
116macro(toolchain_ld_base)
117endmacro()
118
119# generate linker script snippets from configure files
120macro(toolchain_ld_configure_files)
121  configure_file(
122       $ENV{ZEPHYR_BASE}/include/zephyr/arch/common/app_data_alignment.ld
123       ${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld)
124
125  configure_file(
126       $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem.ld
127       ${PROJECT_BINARY_DIR}/include/generated/app_smem.ld)
128
129  configure_file(
130       $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_aligned.ld
131       ${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld)
132
133  configure_file(
134       $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_unaligned.ld
135       ${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld)
136endmacro()
137
138# link C++ libraries
139macro(toolchain_ld_cpp)
140endmacro()
141
142# use linker for relocation
143macro(toolchain_ld_relocation)
144  set(MEM_RELOCATION_LD   "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld")
145  set(MEM_RELOCATION_SRAM_DATA_LD
146       "${PROJECT_BINARY_DIR}/include/generated/linker_sram_data_relocate.ld")
147  set(MEM_RELOCATION_SRAM_BSS_LD
148       "${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld")
149  set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c")
150
151  add_custom_command(
152    OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD}
153    COMMAND
154    ${PYTHON_EXECUTABLE}
155    ${ZEPHYR_BASE}/scripts/build/gen_relocate_app.py
156    $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
157    -d ${APPLICATION_BINARY_DIR}
158    -i \"$<TARGET_PROPERTY:code_data_relocation_target,INTERFACE_SOURCES>\"
159    -o ${MEM_RELOCATION_LD}
160    -s ${MEM_RELOCATION_SRAM_DATA_LD}
161    -b ${MEM_RELOCATION_SRAM_BSS_LD}
162    -c ${MEM_RELOCATION_CODE}
163    DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY}
164    )
165
166  add_library(code_relocation_source_lib  STATIC ${MEM_RELOCATION_CODE})
167  target_include_directories(code_relocation_source_lib PRIVATE
168	${ZEPHYR_BASE}/kernel/include ${ARCH_DIR}/${ARCH}/include)
169  target_link_libraries(code_relocation_source_lib zephyr_interface)
170endmacro()
171