Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ set(ZEPHYR_CURRENT_LINKER_PASS 0)
set(ZEPHYR_CURRENT_LINKER_CMD linker_zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS}.cmd)
set(ZEPHYR_LINK_STAGE_EXECUTABLE zephyr_pre${ZEPHYR_CURRENT_LINKER_PASS})

# Make kconfig variables available to the linker script generator
zephyr_linker_include_generated(KCONFIG ${CMAKE_CURRENT_BINARY_DIR}/.config)

# The linker generator also needs sections.h to be able to access e.g. _APP_SMEM_SECTION_NAME
# for linkerscripts that do not support c-preprocessing.
zephyr_linker_include_generated(HEADER ${ZEPHYR_BASE}/include/zephyr/linker/sections.h)

zephyr_linker_include_var(VAR CMAKE_VERBOSE_MAKEFILE VALUE ${CMAKE_VERBOSE_MAKEFILE})

# ZEPHYR_PREBUILT_EXECUTABLE is used outside of this file, therefore keep the
# existing variable to allow slowly cleanup of linking stage handling.
# Three stage linking active: pre0 -> pre1 -> final, this will correspond to `pre1`
Expand Down Expand Up @@ -935,6 +944,8 @@ add_custom_target(${DEVICE_API_LD_TARGET}
${DEVICE_API_LINKER_SECTIONS_CMAKE}
)

zephyr_linker_include_generated(CMAKE ${DEVICE_API_LINKER_SECTIONS_CMAKE})

# Add a pseudo-target that is up-to-date when all generated headers
# are up-to-date.

Expand Down Expand Up @@ -1136,14 +1147,20 @@ if(NOT EXISTS ${LINKER_SCRIPT})
endif()

if(CONFIG_USERSPACE)
set(APP_SMEM_ALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.ld")
set(APP_SMEM_UNALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.ld")
if(CONFIG_CMAKE_LINKER_GENERATOR)
set(APP_SMEM_LD_EXT "cmake")
else()
set(APP_SMEM_LD_EXT "ld")
endif()

set(APP_SMEM_ALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_aligned.${APP_SMEM_LD_EXT}")
set(APP_SMEM_UNALIGNED_LD "${PROJECT_BINARY_DIR}/include/generated/app_smem_unaligned.${APP_SMEM_LD_EXT}")

if(CONFIG_LINKER_USE_PINNED_SECTION)
set(APP_SMEM_PINNED_ALIGNED_LD
"${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_aligned.ld")
"${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_aligned.${APP_SMEM_LD_EXT}")
set(APP_SMEM_PINNED_UNALIGNED_LD
"${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_unaligned.ld")
"${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned_unaligned.${APP_SMEM_LD_EXT}")

if(NOT CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT)
# The libc partition may hold symbols that are required during boot process,
Expand Down Expand Up @@ -1208,9 +1225,11 @@ if(CONFIG_USERSPACE)

set(APP_SMEM_UNALIGNED_LIB app_smem_unaligned_output_obj_renamed_lib)
list(APPEND LINKER_PASS_${ZEPHYR_CURRENT_LINKER_PASS}_DEFINE "LINKER_APP_SMEM_UNALIGNED")
endif()

if (CONFIG_USERSPACE)
foreach(dep ${APP_SMEM_UNALIGNED_LD} ${APP_SMEM_PINNED_UNALIGNED_LD})
zephyr_linker_include_generated(CMAKE ${dep} PASS LINKER_APP_SMEM_UNALIGNED)
endforeach()

add_custom_command(
OUTPUT ${APP_SMEM_ALIGNED_LD} ${APP_SMEM_PINNED_ALIGNED_LD}
COMMAND ${PYTHON_EXECUTABLE}
Expand All @@ -1230,6 +1249,9 @@ if (CONFIG_USERSPACE)
COMMAND_EXPAND_LISTS
COMMENT "Generating app_smem_aligned linker section"
)
foreach(dep ${APP_SMEM_ALIGNED_LD} ${APP_SMEM_PINNED_ALIGNED_LD})
zephyr_linker_include_generated(CMAKE ${dep} PASS NOT LINKER_APP_SMEM_UNALIGNED)
endforeach()
endif()

if(CONFIG_USERSPACE)
Expand Down Expand Up @@ -1337,6 +1359,13 @@ if(CONFIG_USERSPACE)
DEPENDS
${KOBJECT_LINKER_HEADER_DATA}
)

# gen_kobject_placeholders.py generates linker-kobject-prebuild-data.h,
# linker-kobject-prebuild-priv-stacks.h and linker-kobject-prebuild-rodata.h
foreach(ext "-data.h" "-priv-stacks.h" "-rodata.h")
string(REGEX REPLACE "-data.h$" ${ext} file ${KOBJECT_LINKER_HEADER_DATA})
zephyr_linker_include_generated(HEADER ${file} PASS LINKER_ZEPHYR_PREBUILT LINKER_ZEPHYR_FINAL)
endforeach()
endif()

if(CONFIG_USERSPACE OR CONFIG_DEVICE_DEPS)
Expand Down
14 changes: 3 additions & 11 deletions cmake/linker/armlink/target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,21 @@ macro(configure_linker_script linker_script_gen linker_pass_define)
set(STEERING_C_ARG "-DSTEERING_C=${STEERING_C}")
endif()

file(GENERATE OUTPUT ${cmake_linker_script_settings} CONTENT
"set(FORMAT \"$<TARGET_PROPERTY:linker,FORMAT>\" CACHE INTERNAL \"\")\n
set(ENTRY \"$<TARGET_PROPERTY:linker,ENTRY>\" CACHE INTERNAL \"\")\n
set(MEMORY_REGIONS \"$<TARGET_PROPERTY:linker,MEMORY_REGIONS>\" CACHE INTERNAL \"\")\n
set(GROUPS \"$<TARGET_PROPERTY:linker,GROUPS>\" CACHE INTERNAL \"\")\n
set(SECTIONS \"$<TARGET_PROPERTY:linker,SECTIONS>\" CACHE INTERNAL \"\")\n
set(SECTION_SETTINGS \"$<TARGET_PROPERTY:linker,SECTION_SETTINGS>\" CACHE INTERNAL \"\")\n
set(SYMBOLS \"$<TARGET_PROPERTY:linker,SYMBOLS>\" CACHE INTERNAL \"\")\n
"
)
zephyr_linker_generate_linker_settings_file(${cmake_linker_script_settings})

add_custom_command(
OUTPUT ${linker_script_gen}
${STEERING_FILE}
${STEERING_C}
COMMAND ${CMAKE_COMMAND}
-C ${DEVICE_API_LINKER_SECTIONS_CMAKE}
-C ${cmake_linker_script_settings}
-DPASS="${linker_pass_define}"
${STEERING_FILE_ARG}
${STEERING_C_ARG}
-DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
-P ${ZEPHYR_BASE}/cmake/linker/armlink/scatter_script.cmake
DEPENDS ${DEVICE_API_LD_TARGET}
${cmake_linker_script_settings}
)

if("LINKER_ZEPHYR_FINAL" IN_LIST linker_pass_define_list)
Expand Down
80 changes: 71 additions & 9 deletions cmake/linker/ld/ld_script.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ function(group_to_string)
cmake_parse_arguments(STRING "" "OBJECT;STRING" "" ${ARGN})

get_property(type GLOBAL PROPERTY ${STRING_OBJECT}_OBJ_TYPE)

# Output a comment for the section start
set(${STRING_STRING} "${${STRING_STRING}}\n /* ${type} : ${STRING_OBJECT} */")

if(${type} STREQUAL REGION)
get_property(empty GLOBAL PROPERTY ${STRING_OBJECT}_EMPTY)
if(empty)
Expand Down Expand Up @@ -168,6 +172,16 @@ function(group_to_string)
set(${STRING_STRING} ${${STRING_STRING}} PARENT_SCOPE)
endfunction()

# Helper to add size-checks and padding to handle MIN_SIZE and MAX_SIZE
macro(add_min_max_size TEMP min_size max_size symbol_start symbol_end)
if(DEFINED ${min_size})
set(${TEMP} "${${TEMP}}\n . = MAX(${${symbol_start}} + ${${min_size}}, .); /*MIN_SIZE*/")
endif()
if(DEFINED ${max_size})
set(${TEMP} "${${TEMP}}\n ASSERT( ${${symbol_end}} <= ( ${${symbol_start}} + ${${max_size}}), \"MAX_SIZE\");\n . = MIN( ., ${${symbol_start}} + ${${max_size}}); /*MAX_SIZE*/")
endif()
endmacro()

function(section_to_string)
cmake_parse_arguments(STRING "" "SECTION;STRING" "" ${ARGN})

Expand All @@ -185,6 +199,8 @@ function(section_to_string)
get_property(nosymbols GLOBAL PROPERTY ${STRING_SECTION}_NOSYMBOLS)
get_property(parent GLOBAL PROPERTY ${STRING_SECTION}_PARENT)
get_property(start_syms GLOBAL PROPERTY ${STRING_SECTION}_START_SYMBOLS)
get_property(sect_min_size GLOBAL PROPERTY ${STRING_SECTION}_MIN_SIZE)
get_property(sect_max_size GLOBAL PROPERTY ${STRING_SECTION}_MAX_SIZE)

string(REGEX REPLACE "^[\.]" "" name_clean "${name}")
string(REPLACE "." "_" name_clean "${name_clean}")
Expand Down Expand Up @@ -212,12 +228,24 @@ function(section_to_string)

set(TEMP "${name} ${address}${type} :${secalign}\n{")

# Symbol names for size_check
set(sect_symbol_start)
set(sect_symbol_end)

foreach(start_symbol ${start_syms})
set(TEMP "${TEMP}\n ${start_symbol} = .;")
set(sect_symbol_start "${start_symbol}")
endforeach()

if(NOT nosymbols)
set(TEMP "${TEMP}\n __${name_clean}_start = .;")
set(sect_symbol_start "__${name_clean}_start")
endif()

# Min and Max size may need symbols too, even if the user did not want them
if((DEFINED sect_min_size OR DEFINED sect_max_size)
AND NOT DEFINED sect_symbol_start)
set(sect_symbol_start "__${name_clean}_size_check_start")
endif()

if(NOT noinput)
Expand All @@ -236,8 +264,10 @@ function(section_to_string)
get_property(input GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_INPUT)
get_property(symbols GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_SYMBOLS)
get_property(offset GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_OFFSET)
get_property(min_size GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_MIN_SIZE)
get_property(max_size GLOBAL PROPERTY ${STRING_SECTION}_SETTING_${idx}_MAX_SIZE)

if(DEFINED SETTINGS_ALIGN)
if(DEFINED align)
set(TEMP "${TEMP}\n . = ALIGN(${align});")
endif()

Expand All @@ -250,6 +280,19 @@ function(section_to_string)
list(GET symbols 1 symbol_end)
endif()
endif()
# Min and Max size may need symbols too, even if the user did not want them
if(DEFINED min_size OR DEFINED max_size)
foreach(se "start" "end")
if(NOT DEFINED symbol_${se})
set(symbol_${se} "__${name_clean}_${idx}_size_check_${se}")
endif()
endforeach()
endif()

if(DEFINED offset AND NOT ("${offset}" STREQUAL "${current_offset}"))
set(TEMP "${TEMP}\n . = ${offset}; /* OFFSET */")
set(current_offset ${offset})
endif()

if(DEFINED symbol_start)
set(TEMP "${TEMP}\n ${symbol_start} = .;")
Expand All @@ -261,34 +304,53 @@ function(section_to_string)
set(current_offset ${offset})
endif()

if(keep AND sort)
set(TEMP "${TEMP}\n KEEP(*(${SORT_TYPE_${sort}}(${setting})));")
elseif(SETTINGS_SORT)
message(WARNING "Not tested")
set(TEMP "${TEMP}\n *(${SORT_TYPE_${sort}}(${setting}));")
elseif(keep)
set(TEMP "${TEMP}\n KEEP(*(${setting}));")
#setting may have file-pattern or not.
if(setting MATCHES "(.+)\\((.+)\\)")
set(file_pattern "${CMAKE_MATCH_1}")
set(section_pattern "${CMAKE_MATCH_2}")
else()
set(TEMP "${TEMP}\n *(${setting})")
set(file_pattern "*")
set(section_pattern "${setting}")
endif()

if(sort)
set(section_pattern "${SORT_TYPE_${sort}}(${section_pattern})")
endif()
set(pattern "${file_pattern}(${section_pattern})")
if(keep)
set(pattern "KEEP(${pattern})")
endif()
set(TEMP "${TEMP}\n ${pattern};")
endforeach()

if(DEFINED symbol_end)
set(TEMP "${TEMP}\n ${symbol_end} = .;")
endif()

add_min_max_size(TEMP min_size max_size symbol_start symbol_end)

set(symbol_start)
set(symbol_end)
endforeach()

if(NOT nosymbols)
set(TEMP "${TEMP}\n __${name_clean}_end = .;")
set(sect_symbol_end "__${name_clean}_end")
endif()

if(DEFINED extra_symbol_end)
set(TEMP "${TEMP}\n ${extra_symbol_end} = .;")
set(sect_symbol_end "${extra_symbol_end}")
endif()

# Min and Max size may need symbols too, even if the user did not want them
if((DEFINED sect_min_size OR DEFINED sect_max_size)
AND NOT DEFINED sect_symbol_end)
set(sect_symbol_end "__${name_clean}_size_check_end")
endif()

add_min_max_size(TEMP sect_min_size sect_max_size sect_symbol_start sect_symbol_end)

set(TEMP "${TEMP}\n}")

get_property(parent_type GLOBAL PROPERTY ${parent}_OBJ_TYPE)
Expand Down
19 changes: 7 additions & 12 deletions cmake/linker/ld/target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,20 @@ macro(configure_linker_script linker_script_gen linker_pass_define)
)

if(CONFIG_CMAKE_LINKER_GENERATOR)
file(GENERATE OUTPUT ${cmake_linker_script_settings} CONTENT
"set(FORMAT \"$<TARGET_PROPERTY:linker,FORMAT>\" CACHE INTERNAL \"\")\n
set(ENTRY \"$<TARGET_PROPERTY:linker,ENTRY>\" CACHE INTERNAL \"\")\n
set(MEMORY_REGIONS \"$<TARGET_PROPERTY:linker,MEMORY_REGIONS>\" CACHE INTERNAL \"\")\n
set(GROUPS \"$<TARGET_PROPERTY:linker,GROUPS>\" CACHE INTERNAL \"\")\n
set(SECTIONS \"$<TARGET_PROPERTY:linker,SECTIONS>\" CACHE INTERNAL \"\")\n
set(SECTION_SETTINGS \"$<TARGET_PROPERTY:linker,SECTION_SETTINGS>\" CACHE INTERNAL \"\")\n
set(SYMBOLS \"$<TARGET_PROPERTY:linker,SYMBOLS>\" CACHE INTERNAL \"\")\n
"
)

zephyr_linker_generate_linker_settings_file(${cmake_linker_script_settings})

add_custom_command(
OUTPUT ${linker_script_gen}
DEPENDS
${extra_dependencies}
${cmake_linker_script_settings}
${DEVICE_API_LD_TARGET}
COMMAND ${CMAKE_COMMAND}
-C ${DEVICE_API_LINKER_SECTIONS_CMAKE}
-C ${cmake_linker_script_settings}
-DPASS="${linker_pass_define}"
-DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen}
-P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake
DEPENDS ${DEVICE_API_LD_TARGET}
)
else()
set(template_script_defines ${linker_pass_define})
Expand Down
Loading
Loading