1# SPDX-License-Identifier: Apache-2.0
2
3set_property(TARGET linker PROPERTY devices_start_symbol "Image$$device$$Base")
4
5find_program(CMAKE_LINKER ${CROSS_COMPILE}armlink PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
6
7add_custom_target(armlink)
8
9macro(toolchain_ld_base)
10endmacro()
11
12function(toolchain_ld_force_undefined_symbols)
13  foreach(symbol ${ARGN})
14    zephyr_link_libraries(--undefined=${symbol})
15  endforeach()
16endfunction()
17
18macro(toolchain_ld_baremetal)
19endmacro()
20
21macro(configure_linker_script linker_script_gen linker_pass_define)
22  set(STEERING_FILE)
23  set(STEERING_C)
24  set(STEERING_FILE_ARG)
25  set(STEERING_C_ARG)
26  set(linker_pass_define_list ${linker_pass_define})
27
28  if("LINKER_ZEPHYR_FINAL" IN_LIST linker_pass_define_list)
29    set(STEERING_FILE ${CMAKE_CURRENT_BINARY_DIR}/armlink_symbol_steering.steer)
30    set(STEERING_C ${CMAKE_CURRENT_BINARY_DIR}/armlink_symbol_steering.c)
31    set(STEERING_FILE_ARG "-DSTEERING_FILE=${STEERING_FILE}")
32    set(STEERING_C_ARG "-DSTEERING_C=${STEERING_C}")
33  endif()
34
35  add_custom_command(
36    OUTPUT ${linker_script_gen}
37           ${STEERING_FILE}
38           ${STEERING_C}
39    COMMAND ${CMAKE_COMMAND}
40      -DPASS="${linker_pass_define}"
41      -DMEMORY_REGIONS="$<TARGET_PROPERTY:linker,MEMORY_REGIONS>"
42      -DGROUPS="$<TARGET_PROPERTY:linker,GROUPS>"
43      -DSECTIONS="$<TARGET_PROPERTY:linker,SECTIONS>"
44      -DSECTION_SETTINGS="$<TARGET_PROPERTY:linker,SECTION_SETTINGS>"
45      -DSYMBOLS="$<TARGET_PROPERTY:linker,SYMBOLS>"
46      ${STEERING_FILE_ARG}
47      ${STEERING_C_ARG}
48      -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
49      -P ${ZEPHYR_BASE}/cmake/linker/armlink/scatter_script.cmake
50  )
51
52  if("LINKER_ZEPHYR_FINAL" IN_LIST linker_pass_define_list)
53    add_library(armlink_steering OBJECT ${STEERING_C})
54    target_link_libraries(armlink_steering PRIVATE zephyr_interface)
55  endif()
56endmacro()
57
58function(toolchain_ld_link_elf)
59  cmake_parse_arguments(
60    TOOLCHAIN_LD_LINK_ELF                                     # prefix of output variables
61    ""                                                        # list of names of the boolean arguments
62    "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT"                     # list of names of scalar arguments
63    "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments
64    ${ARGN}                                                   # input args to parse
65  )
66
67  foreach(lib ${ZEPHYR_LIBS_PROPERTY})
68    if(NOT ${lib} STREQUAL arch__arm__core__cortex_m)
69      list(APPEND ZEPHYR_LIBS_OBJECTS $<TARGET_OBJECTS:${lib}>)
70      list(APPEND ZEPHYR_LIBS_OBJECTS $<TARGET_PROPERTY:${lib},LINK_LIBRARIES>)
71    endif()
72  endforeach()
73
74  target_link_libraries(
75    ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF}
76    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT}
77    --scatter=${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT}
78    ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT}
79    $<TARGET_OBJECTS:arch__arm__core__cortex_m>
80    --map --list=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP}
81    ${ZEPHYR_LIBS_OBJECTS}
82    kernel
83    $<TARGET_OBJECTS:${OFFSETS_LIB}>
84    --library_type=microlib
85    --entry=$<TARGET_PROPERTY:linker,ENTRY>
86    "--keep=\"*.o(.init_*)\""
87    "--keep=\"*.o(.device_*)\""
88    $<TARGET_OBJECTS:armlink_steering>
89    --edit=${CMAKE_CURRENT_BINARY_DIR}/armlink_symbol_steering.steer
90    # Resolving symbols using generated steering files will emit the warnings 6331 and 6332.
91    # Steering files are used because we want to be able to use `__device_end` instead of `Image$$device$$Limit`.
92    # Thus silence those two warnings.
93    --diag_suppress=6331,6332
94    # The scatter file is generated, and thus sometimes input sections are specified
95    # even though there will be no such sections found in the libraries linked.
96    --diag_suppress=6314
97    # We use empty execution sections in order to define custom symbols, such as
98    # __kernel_ram_x symbols, but nothing will go in those section, so silence
99    # the warning. Note, marking the section EMPTY causes armlink to reserve the
100    # address which in some cases leads to overlapping section errors.
101    --diag_suppress=6312
102    # Use of '.gnu.linkonce' sections. Those are used by ld, and # supported by armlink, albeit
103    # deprecated there. For current ARMClang support phase, we accept this warning, but we should
104    # look into changing to COMDAT groups.
105    --diag_suppress=6092
106    # Wildcard matching of keep sections, Those are needed for gnu ld, and thus we inherit the same
107    # keep flags and apply them to armlink. Consider adjusting keep flags per linker in future.
108    --diag_suppress=6319
109    # Match pattern for an unused section that is being removed.
110    --diag_suppress=6329
111    ${TOOLCHAIN_LIBS_OBJECTS}
112
113    ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES}
114  )
115endfunction(toolchain_ld_link_elf)
116
117include(${ZEPHYR_BASE}/cmake/linker/ld/target_cpp.cmake)
118include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake)
119include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake)
120