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  get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES)
34
35# the command to generate linker file from template
36  add_custom_command(
37    OUTPUT ${linker_script_gen}
38    DEPENDS
39    ${LINKER_SCRIPT}
40    ${AUTOCONF_H}
41    ${extra_dependencies}
42    # NB: 'linker_script_dep' will use a keyword that ends 'DEPENDS'
43    ${linker_script_dep}
44    COMMAND ${CMAKE_C_COMPILER}
45    -x c
46    ${NOSYSDEF_CFLAG}
47    -Hnocopyr
48    -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen}
49    -D_LINKER
50    -D_ASMLANGUAGE
51    -imacros ${AUTOCONF_H}
52    ${current_includes}
53    ${current_defines}
54    ${template_script_defines}
55    ${LINKER_SCRIPT}
56    -E
57    -o ${linker_script_gen}
58    VERBATIM
59    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
60    COMMAND_EXPAND_LISTS
61)
62endmacro()
63
64# Force symbols to be entered in the output file as undefined symbols
65function(toolchain_ld_force_undefined_symbols)
66  foreach(symbol ${ARGN})
67    zephyr_link_libraries(${LINKERFLAGPREFIX}-u${symbol})
68  endforeach()
69endfunction()
70
71# Link a target to given libraries with toolchain-specific argument order
72#
73# Usage:
74#   toolchain_ld_link_elf(
75#     TARGET_ELF             <target_elf>
76#     OUTPUT_MAP             <output_map_file_of_target>
77#     LIBRARIES_PRE_SCRIPT   [libraries_pre_script]
78#     LINKER_SCRIPT          <linker_script>
79#     LIBRARIES_POST_SCRIPT  [libraries_post_script]
80#     DEPENDENCIES           [dependencies]
81#   )
82function(toolchain_ld_link_elf)
83  cmake_parse_arguments(
84    TOOLCHAIN_LD_LINK_ELF                                     # prefix of output variables
85    ""                                                        # list of names of the boolean arguments
86    "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT"                     # list of names of scalar arguments
87    "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
88    ${ARGN}                                                   # input args to parse
89  )
90
91  target_link_libraries(
92    ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
93    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
94    ${LINKERFLAGPREFIX}-T${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
95    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
96    ${LINKERFLAGPREFIX}--gc-sections
97    ${LINKERFLAGPREFIX}--entry=__start
98    ${LINKERFLAGPREFIX}--Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
99    ${LINKERFLAGPREFIX}--whole-archive
100    ${ZEPHYR_LIBS_PROPERTY}
101    ${LINKERFLAGPREFIX}--no-whole-archive
102    kernel
103    $<TARGET_OBJECTS:${OFFSETS_LIB}>
104    ${LIB_INCLUDE_DIR}
105    -L${PROJECT_BINARY_DIR}
106    ${TOOLCHAIN_LIBS}
107
108    ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
109  )
110endfunction(toolchain_ld_link_elf)
111
112# linker options of temporary linkage for code generation
113macro(toolchain_ld_baremetal)
114  zephyr_ld_options(
115    -Hlld
116    -Hnosdata
117    -Xtimer0 # to suppress the warning message
118    -Hnoxcheck_obj
119    -Hnocplus
120    -Hhostlib=
121    -Hheap=0
122    -Hnoivt
123    -Hnocrt
124  )
125
126  # There are two options:
127  # - We have full MWDT libc support and we link MWDT libc - this is default
128  #   behavior and we don't need to do something for that.
129  # - We use minimal libc provided by Zephyr itself. In that case we must not
130  #   link MWDT libc, but we still need to link libmw
131  if(CONFIG_MINIMAL_LIBC)
132    zephyr_ld_options(
133      -Hnolib
134      -Hldopt=-lmw
135    )
136  endif()
137
138  # Funny thing is if this is set to =error, some architectures will
139  # skip this flag even though the compiler flag check passes
140  # (e.g. ARC and Xtensa). So warning should be the default for now.
141  #
142  # Skip this for native application as Zephyr only provides
143  # additions to the host toolchain linker script. The relocation
144  # sections (.rel*) requires us to override those provided
145  # by host toolchain. As we can't account for all possible
146  # combination of compiler and linker on all machines used
147  # for development, it is better to turn this off.
148  #
149  # CONFIG_LINKER_ORPHAN_SECTION_PLACE is to place the orphan sections
150  # without any warnings or errors, which is the default behavior.
151  # So there is no need to explicitly set a linker flag.
152  if(CONFIG_LINKER_ORPHAN_SECTION_WARN)
153    message(WARNING "MWDT toolchain does not support
154           CONFIG_LINKER_ORPHAN_SECTION_WARN")
155  elseif(CONFIG_LINKER_ORPHAN_SECTION_ERROR)
156    zephyr_ld_options(
157      ${LINKERFLAGPREFIX}--orphan-handling=error)
158  endif()
159endmacro()
160
161# base linker options
162macro(toolchain_ld_base)
163  if(NOT PROPERTY_LINKER_SCRIPT_DEFINES)
164    set_property(GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES -D__MWDT_LINKER_CMD__)
165  endif()
166
167  # Sort the common symbols and each input section by alignment
168  # in descending order to minimize padding between these symbols.
169  zephyr_ld_option_ifdef(
170    CONFIG_LINKER_SORT_BY_ALIGNMENT
171    ${LINKERFLAGPREFIX}--sort-section=alignment
172  )
173endmacro()
174
175# generate linker script snippets from configure files
176macro(toolchain_ld_configure_files)
177  configure_file(
178       $ENV{ZEPHYR_BASE}/include/zephyr/arch/common/app_data_alignment.ld
179       ${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld)
180
181  configure_file(
182       $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem.ld
183       ${PROJECT_BINARY_DIR}/include/generated/app_smem.ld)
184
185  configure_file(
186       $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_aligned.ld
187       ${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld)
188
189  configure_file(
190       $ENV{ZEPHYR_BASE}/include/zephyr/linker/app_smem_unaligned.ld
191       ${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld)
192endmacro()
193
194# link C++ libraries
195macro(toolchain_ld_cpp)
196  zephyr_link_libraries(
197    -Hcplus
198  )
199endmacro()
200
201# use linker for relocation
202macro(toolchain_ld_relocation)
203  set(MEM_RELOCATION_LD   "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld")
204  set(MEM_RELOCATION_SRAM_DATA_LD
205       "${PROJECT_BINARY_DIR}/include/generated/linker_sram_data_relocate.ld")
206  set(MEM_RELOCATION_SRAM_BSS_LD
207       "${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld")
208  set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c")
209
210  add_custom_command(
211    OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD}
212    COMMAND
213    ${PYTHON_EXECUTABLE}
214    ${ZEPHYR_BASE}/scripts/build/gen_relocate_app.py
215    $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
216    -d ${APPLICATION_BINARY_DIR}
217    -i \"$<TARGET_PROPERTY:code_data_relocation_target,COMPILE_DEFINITIONS>\"
218    -o ${MEM_RELOCATION_LD}
219    -s ${MEM_RELOCATION_SRAM_DATA_LD}
220    -b ${MEM_RELOCATION_SRAM_BSS_LD}
221    -c ${MEM_RELOCATION_CODE}
222    DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY}
223    )
224
225  add_library(code_relocation_source_lib  STATIC ${MEM_RELOCATION_CODE})
226  target_include_directories(code_relocation_source_lib PRIVATE
227	${ZEPHYR_BASE}/kernel/include ${ARCH_DIR}/${ARCH}/include)
228  target_link_libraries(code_relocation_source_lib zephyr_interface)
229endmacro()
230