cmake: linker generator: group symbol from section

The root cause of #38591 was region symbols being placed before the
section description for data region.

Some region start symbols are placed before section description, other
region start symbols are placed inside the first section in the region
and thus identical to the sections own first symbol.

To support both schemes with the linker generator, a new
`SYMBOL SECTION` argument has been added to the zephyr_linker_group()
function.

The ld_script.cmake linker script generator has been updated to support
the new argument so that generated ld linker script has identical
behavior to the templated ld linker scripts.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
Torsten Rasmussen 2021-09-24 16:53:39 +02:00 committed by Christopher Friedt
commit 57ab0342d3
3 changed files with 31 additions and 5 deletions

View file

@ -3083,8 +3083,8 @@ function(zephyr_linker_dts_memory)
endfunction()
# Usage:
# zephyr_linker_group(NAME <name> [VMA <region|group>] [LMA <region|group>])
# zephyr_linker_group(NAME <name> GROUP <group>)
# zephyr_linker_group(NAME <name> [VMA <region|group>] [LMA <region|group>] [SYMBOL <SECTION>])
# zephyr_linker_group(NAME <name> GROUP <group> [SYMBOL <SECTION>])
#
# Zephyr linker group.
# This function specifies a group inside a memory region or another group.
@ -3108,6 +3108,8 @@ endfunction()
# If a group is used then the VMA region of that group will be used.
# LMA <region|group> : Memory region or group to be used for this group.
# GROUP <group> : Place the new group inside the existing group <group>
# SYMBOL <SECTION> : Specify that start symbol of the region should be identical
# to the start address of the first section in the group.
#
# Note: VMA and LMA are mutual exclusive with GROUP
#
@ -3153,7 +3155,8 @@ endfunction()
# | |
# +---------------------+
function(zephyr_linker_group)
set(single_args "NAME;GROUP;LMA;VMA")
set(single_args "NAME;GROUP;LMA;SYMBOL;VMA")
set(symbol_values SECTION)
cmake_parse_arguments(GROUP "" "${single_args}" "" ${ARGN})
if(GROUP_UNPARSED_ARGUMENTS)
@ -3168,6 +3171,12 @@ function(zephyr_linker_group)
)
endif()
if(DEFINED GROUP_SYMBOL)
if(NOT ${GROUP_SYMBOL} IN_LIST symbol_values)
message(FATAL_ERROR "zephyr_linker_group(SYMBOL ...) given unknown value")
endif()
endif()
set(GROUP)
zephyr_linker_arg_val_list(GROUP "${single_args}")

View file

@ -98,13 +98,19 @@ function(group_to_string)
set(${STRING_STRING} "${${STRING_STRING}}\n . = ${address};\n\n")
else()
get_property(name GLOBAL PROPERTY ${STRING_OBJECT}_NAME)
get_property(symbol GLOBAL PROPERTY ${STRING_OBJECT}_SYMBOL)
string(TOLOWER ${name} name)
set(${STRING_STRING} "${${STRING_STRING}}\n __${name}_start = .;\n")
get_objects(LIST sections OBJECT ${STRING_OBJECT} TYPE SECTION)
list(GET sections 0 section)
get_property(first_section_name GLOBAL PROPERTY ${section}_NAME)
if(DEFINED first_section_name AND "${symbol}" STREQUAL "SECTION")
set_property(GLOBAL APPEND PROPERTY ${section}_START_SYMBOLS __${name}_start)
else()
set(${STRING_STRING} "${${STRING_STRING}}\n __${name}_start = .;\n")
endif()
set(${STRING_STRING} "${${STRING_STRING}}\n __${name}_size = __${name}_end - __${name}_start;\n")
set(${STRING_STRING} "${${STRING_STRING}}\n __${name}_load_start = LOADADDR(${first_section_name});\n")
endif()
@ -178,6 +184,7 @@ function(section_to_string)
get_property(noinit GLOBAL PROPERTY ${STRING_SECTION}_NOINIT)
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)
string(REGEX REPLACE "^[\.]" "" name_clean "${name}")
string(REPLACE "." "_" name_clean "${name_clean}")
@ -204,6 +211,11 @@ function(section_to_string)
endif()
set(TEMP "${name} ${address}${type} :${secalign}\n{")
foreach(start_symbol ${start_syms})
set(TEMP "${TEMP}\n ${start_symbol} = .;")
endforeach()
if(NOT nosymbols)
set(TEMP "${TEMP}\n __${name_clean}_start = .;")
endif()
@ -273,6 +285,10 @@ function(section_to_string)
set(TEMP "${TEMP}\n __${name_clean}_end = .;")
endif()
if(DEFINED extra_symbol_end)
set(TEMP "${TEMP}\n ${extra_symbol_end} = .;")
endif()
set(TEMP "${TEMP}\n}")
get_property(parent_type GLOBAL PROPERTY ${parent}_OBJ_TYPE)

View file

@ -58,11 +58,12 @@ function(get_parent)
endfunction()
function(create_group)
cmake_parse_arguments(OBJECT "" "GROUP;LMA;NAME;OBJECT;VMA" "" ${ARGN})
cmake_parse_arguments(OBJECT "" "GROUP;LMA;NAME;OBJECT;SYMBOL;VMA" "" ${ARGN})
set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME} TRUE)
set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_OBJ_TYPE GROUP)
set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_NAME ${OBJECT_NAME})
set_property(GLOBAL PROPERTY GROUP_${OBJECT_NAME}_SYMBOL ${OBJECT_SYMBOL})
if(DEFINED OBJECT_GROUP)
find_object(OBJECT parent NAME ${OBJECT_GROUP})