Skip to content
Permalink
Browse files

cmake: Add function for adding snippets to the linker file

Allows snippets to be placed in different locations:
 - The noinit, rwdata and rodata output sections
 - Two different locations for placing custom output sections,
   one location for RAM and another for all other sections.

Signed-off-by: Øyvind Rønningstad <oyvind.ronningstad@nordicsemi.no>
  • Loading branch information...
oyvindronningstad authored and nashif committed Mar 6, 2019
1 parent f888f9a commit f2a1572ac2f1845e819fe1756565c10f76d63579
@@ -118,6 +118,9 @@ add_custom_target(
# Equivalent to rm -rf build/*
)

# Dummy add to generate files.
zephyr_linker_sources(SECTIONS)

# The BOARD can be set by 3 sources. Through environment variables,
# through the cmake CLI, and through CMakeLists.txt.
#
@@ -745,6 +745,101 @@ function(zephyr_check_compiler_flag lang option check)
endif()
endfunction()

# zephyr_linker_sources(<location> <files>)
#
# <files> is one or more .ld formatted files whose contents will be
# copied/included verbatim into the given <location> in the global linker.ld.
# Preprocessor directives work inside <files>. Relative paths are resolved
# relative to the calling file, like zephyr_sources().
# <location> is one of
# NOINIT Inside the noinit output section.
# RWDATA Inside the data output section.
# RODATA Inside the rodata output section.
# RAM_SECTIONS Inside the RAMABLE_REGION GROUP.
# SECTIONS Near the end of the file. Don't use this when linking into
# RAMABLE_REGION, use RAM_SECTIONS instead.
#
# Use NOINIT, RWDATA, and RODATA unless they don't work for your use case.
#
# When placing into NOINIT, RWDATA, or RODATA, the contents of the files will be
# placed inside an output section, so assume the section definition is already
# present, e.g.:
# _mysection_start = .;
# KEEP(*(.mysection));
# _mysection_end = .;
# _mysection_size = ABSOLUTE(_mysection_end - _mysection_start);
#
# When placing into SECTIONS or RAM_SECTIONS, the files must instead define
# their own output sections to acheive the same thing:
# SECTION_PROLOGUE(.mysection,,)
# {
# _mysection_start = .;
# KEEP(*(.mysection))
# _mysection_end = .;
# } GROUP_LINK_IN(ROMABLE_REGION)
# _mysection_size = _mysection_end - _mysection_start;
#
# Note about the above examples: If the first example was used with RODATA, and
# the second with SECTIONS, the two examples do the same thing from a user
# perspective.
#
# Friendly reminder: Beware of the different ways the location counter ('.')
# behaves inside vs. outside section definitions.
function(zephyr_linker_sources location)
# Set up the paths to the destination files. These files are #included inside
# the global linker.ld.
set(snippet_base "${__build_dir}/include/generated")
set(sections_path "${snippet_base}/snippets-sections.ld")
set(ram_sections_path "${snippet_base}/snippets-ram-sections.ld")
set(noinit_path "${snippet_base}/snippets-noinit.ld")
set(rwdata_path "${snippet_base}/snippets-rwdata.ld")
set(rodata_path "${snippet_base}/snippets-rodata.ld")

# Clear destination files if this is the first time the function is called.
get_property(cleared GLOBAL PROPERTY snippet_files_cleared)
if (NOT DEFINED cleared)
file(WRITE ${sections_path} "")
file(WRITE ${ram_sections_path} "")
file(WRITE ${noinit_path} "")
file(WRITE ${rwdata_path} "")
file(WRITE ${rodata_path} "")
set_property(GLOBAL PROPERTY snippet_files_cleared true)
endif()

# Choose destination file, based on the <location> argument.
if ("${location}" STREQUAL "SECTIONS")
set(snippet_path "${sections_path}")
elseif("${location}" STREQUAL "RAM_SECTIONS")
set(snippet_path "${ram_sections_path}")
elseif("${location}" STREQUAL "NOINIT")
set(snippet_path "${noinit_path}")
elseif("${location}" STREQUAL "RWDATA")
set(snippet_path "${rwdata_path}")
elseif("${location}" STREQUAL "RODATA")
set(snippet_path "${rodata_path}")
else()
message(fatal_error "Must choose valid location for linker snippet.")
endif()

foreach(file IN ITEMS ${ARGN})
# Resolve path.
if(IS_ABSOLUTE ${file})
set(path ${file})
else()
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${file})
endif()

if(IS_DIRECTORY ${path})
message(FATAL_ERROR "zephyr_linker_sources() was called on a directory")
endif()

# Append the file contents to the relevant destination file.
file(READ ${path} snippet)
file(APPEND ${snippet_path} "\n/* From ${path}: */\n" "${snippet}\n")
endforeach()
endfunction(zephyr_linker_sources)


# Helper function for CONFIG_CODE_DATA_RELOCATION
# Call this function with 2 arguments file and then memory location
function(zephyr_code_relocate file location)
@@ -1018,6 +1113,12 @@ function(zephyr_library_link_libraries_ifdef feature_toggle item)
endif()
endfunction()

function(zephyr_linker_sources_ifdef feature_toggle)
if(${${feature_toggle}})
zephyr_linker_sources(${ARGN})
endif()
endfunction()

macro(list_append_ifdef feature_toggle list)
if(${${feature_toggle}})
list(APPEND ${list} ${ARGN})
@@ -115,6 +115,10 @@ SECTIONS {
*(".rodata.*")
*(.gnu.linkonce.r.*)

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#ifdef CONFIG_SOC_RODATA_LD
#include <soc-rodata.ld>
#endif
@@ -139,6 +143,11 @@ SECTIONS {

#include <app_data_alignment.ld>

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>

#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN
#define SMEM_PARTITION_ALIGN MPU_ALIGN
@@ -181,6 +190,10 @@ SECTIONS {
*(".noinit.*")
*(".kernel_noinit.*")

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>
#ifdef CONFIG_SOC_NOINIT_LD
#include <soc-noinit.ld>
#endif
@@ -195,6 +208,10 @@ SECTIONS {
*(".data.*")
*(".kernel.*")

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_SOC_RWDATA_LD
#include <soc-rwdata.ld>
#endif
@@ -228,6 +245,10 @@ SECTIONS {
/* Located in project source directory */
#include <custom-sections.ld>
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>

#ifdef CONFIG_GEN_ISR_TABLES
#include <linker/intlist.ld>
@@ -235,6 +235,10 @@ SECTIONS
*(".rodata.*")
*(.gnu.linkonce.r.*)

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#ifdef CONFIG_SOC_RODATA_LD
#include <soc-rodata.ld>
#endif
@@ -385,6 +389,11 @@ SECTIONS
_ramfunc_rom_start = LOADADDR(.ramfunc);
#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>

#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN
@@ -427,6 +436,10 @@ SECTIONS
*(".noinit.*")
*(".kernel_noinit.*")

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>
#ifdef CONFIG_SOC_NOINIT_LD
#include <soc-noinit.ld>
#endif
@@ -440,6 +453,10 @@ SECTIONS
*(".data.*")
*(".kernel.*")

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_SOC_RWDATA_LD
#include <soc-rwdata.ld>
#endif
@@ -516,6 +533,11 @@ SECTIONS
#include <custom-sections.ld>
#endif

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>

#ifdef CONFIG_GEN_ISR_TABLES
#include <linker/intlist.ld>
#endif
@@ -147,6 +147,10 @@ SECTIONS
*(".rodata.*")
*(.gnu.linkonce.r.*)

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#ifdef CONFIG_SOC_RODATA_LD
#include <soc-rodata.ld>
#endif
@@ -195,6 +199,10 @@ SECTIONS
*(.data)
*(".data.*")

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_SOC_RWDATA_LD
#include <soc-rwdata.ld>
#endif
@@ -224,6 +232,11 @@ SECTIONS
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>

} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

__data_ram_end = .;
@@ -260,6 +273,10 @@ SECTIONS
#ifdef CONFIG_SOC_NOINIT_LD
#include <soc-noinit.ld>
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>

} GROUP_LINK_IN(RAMABLE_REGION)

@@ -273,6 +290,10 @@ SECTIONS
/* Located in project source directory */
#include <custom-sections.ld>
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>

#ifdef CONFIG_GEN_ISR_TABLES
#include <linker/intlist.ld>
@@ -110,6 +110,10 @@ SECTIONS
*(".rodata.*")
*(.gnu.linkonce.r.*)

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#ifdef CONFIG_SOC_RODATA_LD
#include <soc-rodata.ld>
#endif
@@ -135,6 +139,10 @@ SECTIONS
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_SOC_RWDATA_LD
#include <soc-rwdata.ld>
#endif
@@ -143,6 +151,10 @@ SECTIONS

#include <linker/common-ram.ld>

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>
__data_ram_end = .;

SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
@@ -174,6 +186,10 @@ SECTIONS
*(.noinit)
*(".noinit.*")

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>
#ifdef CONFIG_SOC_NOINIT_LD
#include <soc-noinit.ld>
#endif
@@ -183,6 +199,11 @@ SECTIONS
_image_ram_end = .;
_end = .; /* end of image */

/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>

#ifdef CONFIG_GEN_ISR_TABLES
#include <linker/intlist.ld>
#endif

0 comments on commit f2a1572

Please sign in to comment.
You can’t perform that action at this time.