mirror of
https://github.com/apache/nuttx.git
synced 2026-08-27 04:10:40 +00:00
include/nuttx: Add link-time iterable sections infrastructure
Add generic support for link-time registration of struct instances, modeled after the Zephyr STRUCT_SECTION_* mechanism: - include/nuttx/iterable_sections.h: STRUCT_SECTION_ITERABLE/DECLARE/ FOREACH/GET/COUNT macros placing instances in name-sorted linker sections delimited by _<type>_list_start/_end symbols (attributes through the nuttx/compiler.h macros; FOREACH takes a caller-declared iterator, like list_for_every_entry). - include/nuttx/linker/iterable_sections.ld: ITERABLE_SECTION() macro emitting the KEEP + SORT_BY_NAME collection statements (linker scripts in ARCHSCRIPT are CPP-preprocessed). - include/nuttx/linker/common-rom.ld / common-ram.ld: central aggregators meant to be included by board linker scripts (inside .text and .data respectively); subsystems register their sections here guarded by their Kconfig options, so the fragments expand to nothing on configurations that do not use them. - CONFIG_ITERABLE_SECTIONS_LINKER_INSERT + include/nuttx/linker/ common-insert.ld (added before the board script by tools/Config.mk and by the top-level CMakeLists.txt): optional zero-touch mode that supplements the board script through GNU ld INSERT AFTER, collecting the subsystems' ITERABLE_SECTION blocks in one output section; the common-rom.ld/common-ram.ld fragments expand to nothing in that mode. See the option help for the constraints. - Documentation/components/iterable_sections.rst. First user: the Zephyr zbus message bus port (apps/system/zbus in nuttx-apps); its board integration comes in a companion PR. Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
This commit is contained in:
parent
71610ddac0
commit
7cd511fed2
10 changed files with 531 additions and 0 deletions
|
|
@ -674,6 +674,13 @@ process_all_directory_romfs()
|
|||
# Get linker script to use
|
||||
get_property(ldscript GLOBAL PROPERTY LD_SCRIPT)
|
||||
|
||||
# Iterable sections "zero-touch" mode: the central INSERT fragment must come
|
||||
# BEFORE the board script on the linker command line (GNU ld requirement for
|
||||
# INSERT AFTER), see include/nuttx/linker/common-insert.ld.
|
||||
if(CONFIG_ITERABLE_SECTIONS_LINKER_INSERT)
|
||||
list(PREPEND ldscript ${NUTTX_DIR}/include/nuttx/linker/common-insert.ld)
|
||||
endif()
|
||||
|
||||
# Pre-compile linker script(s)
|
||||
if(NOT CONFIG_ARCH_SIM)
|
||||
set(ldscript_tmp_list)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ case, you can head to the :doc:`reference <../reference/index>`.
|
|||
|
||||
binfmt.rst
|
||||
concurrency/index.rst
|
||||
iterable_sections.rst
|
||||
drivers/index.rst
|
||||
nxflat.rst
|
||||
nxgraphics/index.rst
|
||||
|
|
|
|||
172
Documentation/components/iterable_sections.rst
Normal file
172
Documentation/components/iterable_sections.rst
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
=================
|
||||
Iterable Sections
|
||||
=================
|
||||
|
||||
Iterable sections provide **link-time registration** of ``struct``
|
||||
instances: an instance defined with :c:macro:`STRUCT_SECTION_ITERABLE` in
|
||||
any compilation unit is placed in a dedicated linker input section. The
|
||||
linker collects all instances into a contiguous, name-sorted array
|
||||
delimited by ``_<type>_list_start``/``_<type>_list_end`` symbols, which
|
||||
the code can then iterate like a plain C array -- no runtime registration
|
||||
calls, no central list to maintain.
|
||||
|
||||
This is the same mechanism used by the Zephyr RTOS ``STRUCT_SECTION_*``
|
||||
macros. The first user of this infrastructure is the zbus message bus
|
||||
port (``apps/system/zbus``, from nuttx-apps).
|
||||
|
||||
C API
|
||||
=====
|
||||
|
||||
The macros are provided by ``include/nuttx/iterable_sections.h``:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <nuttx/iterable_sections.h>
|
||||
|
||||
struct my_entry
|
||||
{
|
||||
const char *name;
|
||||
int value;
|
||||
};
|
||||
|
||||
/* In any .c file (const places the instance in ROM): */
|
||||
|
||||
const STRUCT_SECTION_ITERABLE(my_entry, entry_foo) =
|
||||
{
|
||||
.name = "foo",
|
||||
.value = 42,
|
||||
};
|
||||
|
||||
/* In the file that iterates: declare the section boundaries once, at
|
||||
* file scope, then loop with a caller-declared pointer.
|
||||
*/
|
||||
|
||||
STRUCT_SECTION_DECLARE(my_entry);
|
||||
|
||||
void print_entries(void)
|
||||
{
|
||||
FAR struct my_entry *entry;
|
||||
|
||||
STRUCT_SECTION_FOREACH(my_entry, entry)
|
||||
{
|
||||
printf("%s = %d\n", entry->name, entry->value);
|
||||
}
|
||||
}
|
||||
|
||||
Available macros:
|
||||
|
||||
* ``STRUCT_SECTION_ITERABLE(type, varname)`` -- define an instance inside
|
||||
the iterable section ``._<type>.static.<varname>``. The variable name
|
||||
is part of the input section name, so the linker's ``SORT_BY_NAME()``
|
||||
defines the iteration order (instances may encode ordering in their
|
||||
names).
|
||||
* ``STRUCT_SECTION_DECLARE(type)`` -- declare the boundary symbols (file
|
||||
scope), required before iterating.
|
||||
* ``STRUCT_SECTION_FOREACH(type, iterator)`` -- for-loop over all
|
||||
instances; ``iterator`` is a pointer declared by the caller, as with
|
||||
``list_for_every_entry()``.
|
||||
* ``STRUCT_SECTION_GET(type, i, dst)`` -- random access by index.
|
||||
* ``STRUCT_SECTION_COUNT(type, dst)`` -- number of instances.
|
||||
* ``STRUCT_SECTION_START/END/START_EXTERN/END_EXTERN`` -- direct access
|
||||
to the boundary symbols.
|
||||
|
||||
Linker integration
|
||||
==================
|
||||
|
||||
The collection step needs linker script support. Two mechanisms are
|
||||
available; both rely on the fact that the linker scripts listed in
|
||||
``ARCHSCRIPT`` are preprocessed with CPP (arm, arm64, risc-v, xtensa,
|
||||
x86_64 and tricore), so ``#include`` and ``#ifdef CONFIG_*`` work inside
|
||||
them.
|
||||
|
||||
Board script include (first-class mechanism)
|
||||
--------------------------------------------
|
||||
|
||||
The board linker script includes the central fragments, which expand to
|
||||
nothing unless a subsystem using iterable sections is enabled:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
.text :
|
||||
{
|
||||
...
|
||||
*(.gnu.linkonce.r.*)
|
||||
#include <nuttx/linker/common-rom.ld>
|
||||
_etext = ABSOLUTE(.);
|
||||
} > flash
|
||||
|
||||
.data :
|
||||
{
|
||||
_sdata = ABSOLUTE(.);
|
||||
...
|
||||
#include <nuttx/linker/common-ram.ld>
|
||||
. = ALIGN(4);
|
||||
_edata = ABSOLUTE(.);
|
||||
} > sram AT > flash
|
||||
|
||||
* ``common-rom.ld`` collects the read-only (``const``) iterable sections
|
||||
and must be included inside the read-only output section (typically
|
||||
``.text``, before ``_etext``).
|
||||
* ``common-ram.ld`` collects mutable *initialized* iterable sections and
|
||||
must be included inside ``.data`` (between ``_sdata`` and ``_edata``)
|
||||
so the startup FLASH-to-RAM copy initializes the entries.
|
||||
* Subsystems add their sections to these central files, guarded by their
|
||||
Kconfig option (see ``include/nuttx/linker/common-rom.ld`` for the zbus
|
||||
example).
|
||||
|
||||
Supplementary INSERT script (zero-touch mode)
|
||||
---------------------------------------------
|
||||
|
||||
With ``CONFIG_ITERABLE_SECTIONS_LINKER_INSERT`` the central script
|
||||
``include/nuttx/linker/common-insert.ld`` is added before the board
|
||||
script by the build system (``tools/Config.mk`` for Make, the top-level
|
||||
``CMakeLists.txt`` for CMake) and supplements it through the GNU ld
|
||||
``INSERT AFTER`` command, so **no board script modification is needed**.
|
||||
The file defines one output section, ``.iterable_sections``, inserted
|
||||
after ``.text``; subsystems add their ``ITERABLE_SECTION()`` blocks
|
||||
inside it, guarded by their Kconfig option, exactly as in
|
||||
``common-rom.ld`` (which expands to nothing in this mode).
|
||||
|
||||
This mode has constraints, discovered the hard way and worth knowing
|
||||
before choosing it:
|
||||
|
||||
* GNU ld only (``INSERT`` is not supported by the macOS ld64).
|
||||
* The INSERT script must come *before* the board script on the linker
|
||||
command line. Adding it via ``ARCHSCRIPT`` from ``tools/Config.mk``
|
||||
guarantees that, because ``Config.mk`` is included by the board
|
||||
``Make.defs`` before it appends its own script. (The reversed order
|
||||
fails with ``.text not found for insert``.)
|
||||
* GNU ld assigns an INSERTed output section to a ``MEMORY`` region by
|
||||
*attribute matching in declaration order*, not by inheriting the anchor
|
||||
section's region. The ROM/flash region must therefore be the first
|
||||
region compatible with read-only sections. Boards declaring a generic
|
||||
``rwx`` region at a lower address first (e.g. an ITCM at ``0x0``) are
|
||||
incompatible with this mode and must use the board script include.
|
||||
* Giving the inserted section an explicit address is **not** a fix: a
|
||||
section with an explicit address does not consume the memory region,
|
||||
so the next region-allocated section overlaps it.
|
||||
|
||||
Alignment rules
|
||||
===============
|
||||
|
||||
Instances are aligned to the natural alignment of their type
|
||||
(``STRUCT_SECTION_ITERABLE`` adds ``__aligned__(__alignof__(type))``), and
|
||||
``sizeof`` is always a multiple of ``alignof``, so the collected section
|
||||
can be indexed as a plain array with no padding between entries from
|
||||
different compilation units. The fragments additionally align the list
|
||||
boundaries to 4 bytes.
|
||||
|
||||
Adding a new iterable type
|
||||
==========================
|
||||
|
||||
1. Define the instances with ``STRUCT_SECTION_ITERABLE(mytype, name)``.
|
||||
2. Add ``ITERABLE_SECTION(mytype)`` to
|
||||
``include/nuttx/linker/common-rom.ld`` (const) or ``common-ram.ld``
|
||||
(mutable initialized), guarded by the subsystem Kconfig option.
|
||||
3. Iterate with ``STRUCT_SECTION_FOREACH(mytype, it)`` after
|
||||
``STRUCT_SECTION_DECLARE(mytype);`` at file scope.
|
||||
|
||||
Caveat on generated linker scripts: the preprocessed ``.ld.tmp`` files
|
||||
only depend on the board script and ``.config``; after editing the
|
||||
central fragments during development, remove the ``.tmp`` files (or run
|
||||
``make clean``) to force regeneration.
|
||||
24
Kconfig
24
Kconfig
|
|
@ -2957,6 +2957,30 @@ config DEBUG_LINK_MAP
|
|||
and debugging magic section games, and for seeing which
|
||||
pieces of code get eliminated with DEBUG_OPT_UNUSED_SECTIONS.
|
||||
|
||||
config ITERABLE_SECTIONS_LINKER_INSERT
|
||||
bool "Collect iterable sections through a supplementary INSERT linker script"
|
||||
default n
|
||||
depends on ARCH_TOOLCHAIN_GNU
|
||||
---help---
|
||||
Zero-touch mode for link-time iterable sections
|
||||
(include/nuttx/iterable_sections.h): instead of the board linker
|
||||
script including <nuttx/linker/common-rom.ld>, the supplementary
|
||||
script <nuttx/linker/common-insert.ld> is added before the board
|
||||
script (Make and CMake builds) and supplements it with GNU ld
|
||||
"INSERT AFTER .text"; subsystems add their ITERABLE_SECTION blocks
|
||||
to that central file.
|
||||
|
||||
Leave disabled for boards whose linker script already includes
|
||||
the common fragments.
|
||||
|
||||
Constraints: requires GNU ld, a board script with an output
|
||||
section named ".text", and a MEMORY layout where the ROM/flash
|
||||
region is the first region compatible with read-only sections
|
||||
(GNU ld assigns INSERTed sections to a region by attribute
|
||||
matching, in declaration order). Boards declaring a generic
|
||||
rwx region at a lower address first (e.g. ITCM at 0x0) must use
|
||||
the common-rom.ld include instead.
|
||||
|
||||
config CCACHE
|
||||
bool "Use ccache"
|
||||
default n
|
||||
|
|
|
|||
121
include/nuttx/iterable_sections.h
Normal file
121
include/nuttx/iterable_sections.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/iterable_sections.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Iterable sections: link-time registration of struct instances.
|
||||
*
|
||||
* A struct instance defined with STRUCT_SECTION_ITERABLE() in any
|
||||
* compilation unit is placed in a dedicated input section named
|
||||
* "._<struct_type>.static.<varname>". The board linker script collects
|
||||
* these input sections (sorted by name) into a contiguous array delimited
|
||||
* by the _<struct_type>_list_start/_<struct_type>_list_end symbols by
|
||||
* including <nuttx/linker/common-rom.ld> (const data, inside the .text or
|
||||
* .rodata output section) and <nuttx/linker/common-ram.ld> (mutable
|
||||
* initialized data, inside the .data output section, so that the startup
|
||||
* FLASH-to-RAM copy initializes it).
|
||||
*
|
||||
* The collection is only available on architectures whose linker scripts
|
||||
* are preprocessed with CPP (arm, arm64, risc-v, xtensa, x86_64, tricore)
|
||||
* and on boards whose scripts include the common-*.ld fragments.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_ITERABLE_SECTIONS_H
|
||||
#define __INCLUDE_NUTTX_ITERABLE_SECTIONS_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Define a struct instance inside an iterable section. A "const"
|
||||
* qualifier may be prepended at the point of use to place the instance in
|
||||
* ROM. Each instance is aligned to the natural alignment of its type so
|
||||
* that the collected section can be indexed as a plain C array. The
|
||||
* variable name is part of the input section name so that the linker's
|
||||
* SORT_BY_NAME() defines the iteration order (instances may encode
|
||||
* ordering in their names).
|
||||
*/
|
||||
|
||||
#define STRUCT_SECTION_ITERABLE(struct_type, varname) \
|
||||
struct struct_type varname \
|
||||
used_data \
|
||||
aligned_data(__alignof__(struct struct_type)) \
|
||||
locate_data("._" #struct_type ".static." #varname)
|
||||
|
||||
/* Start/end symbols provided by the linker script fragments */
|
||||
|
||||
#define STRUCT_SECTION_START(struct_type) _##struct_type##_list_start
|
||||
#define STRUCT_SECTION_END(struct_type) _##struct_type##_list_end
|
||||
|
||||
#define STRUCT_SECTION_START_EXTERN(struct_type) \
|
||||
extern struct struct_type STRUCT_SECTION_START(struct_type)[]
|
||||
#define STRUCT_SECTION_END_EXTERN(struct_type) \
|
||||
extern struct struct_type STRUCT_SECTION_END(struct_type)[]
|
||||
|
||||
/* Declare both boundary symbols of an iterable section. Place it at file
|
||||
* scope (followed by a semicolon) in every file that iterates with
|
||||
* STRUCT_SECTION_FOREACH.
|
||||
*/
|
||||
|
||||
#define STRUCT_SECTION_DECLARE(struct_type) \
|
||||
STRUCT_SECTION_START_EXTERN(struct_type); \
|
||||
STRUCT_SECTION_END_EXTERN(struct_type)
|
||||
|
||||
/* Iterate over every instance of an iterable section. "iterator" is a
|
||||
* pointer variable (FAR struct struct_type *) declared by the caller, as
|
||||
* with list_for_every_entry(); the boundary symbols must be in scope
|
||||
* (STRUCT_SECTION_DECLARE).
|
||||
*/
|
||||
|
||||
#define STRUCT_SECTION_FOREACH(struct_type, iterator) \
|
||||
for ((iterator) = STRUCT_SECTION_START(struct_type); \
|
||||
(iterator) < STRUCT_SECTION_END(struct_type); \
|
||||
(iterator)++)
|
||||
|
||||
/* Get the i-th element of an iterable section (no bounds checking) */
|
||||
|
||||
#define STRUCT_SECTION_GET(struct_type, i, dst) \
|
||||
do \
|
||||
{ \
|
||||
STRUCT_SECTION_START_EXTERN(struct_type); \
|
||||
*(dst) = &STRUCT_SECTION_START(struct_type)[i]; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Number of elements in an iterable section */
|
||||
|
||||
#define STRUCT_SECTION_COUNT(struct_type, dst) \
|
||||
do \
|
||||
{ \
|
||||
STRUCT_SECTION_START_EXTERN(struct_type); \
|
||||
STRUCT_SECTION_END_EXTERN(struct_type); \
|
||||
*(dst) = STRUCT_SECTION_END(struct_type) - \
|
||||
STRUCT_SECTION_START(struct_type); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_ITERABLE_SECTIONS_H */
|
||||
59
include/nuttx/linker/common-insert.ld
Normal file
59
include/nuttx/linker/common-insert.ld
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/linker/common-insert.ld
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Supplementary linker script for the iterable sections "zero-touch" mode
|
||||
* (CONFIG_ITERABLE_SECTIONS_LINKER_INSERT): added before the board linker
|
||||
* script by the build system, it supplements -- does not replace -- that
|
||||
* script through the GNU ld INSERT command, so boards need no edit. The
|
||||
* read-only iterable sections are collected in one output section placed
|
||||
* right after .text.
|
||||
*
|
||||
* Subsystem blocks are added inside the output section below, each
|
||||
* guarded by its Kconfig option (same layout as common-rom.ld):
|
||||
*
|
||||
* #ifdef CONFIG_MYSUBSYS
|
||||
* ITERABLE_SECTION(mysubsys_entry)
|
||||
* #endif
|
||||
*
|
||||
* Constraints of this mode:
|
||||
* - GNU ld only (INSERT is not supported by the macOS ld64), and this
|
||||
* script must come BEFORE the board script on the command line (the
|
||||
* build system guarantees that ordering).
|
||||
* - The board script must define an output section named ".text".
|
||||
* - The ROM/flash region must be the first MEMORY region compatible
|
||||
* with read-only sections: GNU ld assigns the INSERTed section to a
|
||||
* region by attribute matching in declaration order, so a board that
|
||||
* declares a generic rwx region at a lower address first (e.g. ITCM
|
||||
* at 0x0) would pull these sections into the wrong region. Such
|
||||
* boards must use the <nuttx/linker/common-rom.ld> include instead.
|
||||
*/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/linker/iterable_sections.ld>
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.iterable_sections : SUBALIGN(4)
|
||||
{
|
||||
}
|
||||
}
|
||||
INSERT AFTER .text;
|
||||
43
include/nuttx/linker/common-ram.ld
Normal file
43
include/nuttx/linker/common-ram.ld
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/linker/common-ram.ld
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Mutable (initialized) iterable sections. Boards opt in by adding,
|
||||
* INSIDE their .data output section (between _sdata and _edata, so the
|
||||
* startup FLASH-to-RAM copy initializes the entries):
|
||||
*
|
||||
* #include <nuttx/linker/common-ram.ld>
|
||||
*
|
||||
* Every block below is guarded by its subsystem's Kconfig option, so this
|
||||
* file expands to nothing on configurations that do not use iterable
|
||||
* sections (zero binary impact).
|
||||
*/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/linker/iterable_sections.ld>
|
||||
|
||||
#ifndef CONFIG_ITERABLE_SECTIONS_LINKER_INSERT
|
||||
|
||||
/* Extension point for subsystems that need initialized RAM iterable
|
||||
* sections; blocks are added below, each guarded by its Kconfig option.
|
||||
*/
|
||||
|
||||
#endif /* !CONFIG_ITERABLE_SECTIONS_LINKER_INSERT */
|
||||
47
include/nuttx/linker/common-rom.ld
Normal file
47
include/nuttx/linker/common-rom.ld
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/linker/common-rom.ld
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Read-only iterable sections. Boards opt in by adding, INSIDE their
|
||||
* read-only output section (typically .text, before _etext):
|
||||
*
|
||||
* #include <nuttx/linker/common-rom.ld>
|
||||
*
|
||||
* Every block below is guarded by its subsystem's Kconfig option, so this
|
||||
* file expands to nothing on configurations that do not use iterable
|
||||
* sections (zero binary impact). In the INSERT mode
|
||||
* (CONFIG_ITERABLE_SECTIONS_LINKER_INSERT) the sections are collected by
|
||||
* common-insert.ld instead, so this file expands to nothing as well.
|
||||
*/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/linker/iterable_sections.ld>
|
||||
|
||||
#ifndef CONFIG_ITERABLE_SECTIONS_LINKER_INSERT
|
||||
|
||||
/* Subsystem blocks are added below, each guarded by its Kconfig option:
|
||||
*
|
||||
* #ifdef CONFIG_MYSUBSYS
|
||||
* ITERABLE_SECTION(mysubsys_entry)
|
||||
* #endif
|
||||
*/
|
||||
|
||||
#endif /* !CONFIG_ITERABLE_SECTIONS_LINKER_INSERT */
|
||||
43
include/nuttx/linker/iterable_sections.ld
Normal file
43
include/nuttx/linker/iterable_sections.ld
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/linker/iterable_sections.ld
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* CPP macro emitting the linker statements that collect one iterable
|
||||
* section (see include/nuttx/iterable_sections.h). This file is meant to
|
||||
* be included from linker scripts that are preprocessed with CPP (the
|
||||
* ARCHSCRIPT .tmp rule).
|
||||
*
|
||||
* The macro must be expanded INSIDE an output section (e.g. .text or
|
||||
* .data). KEEP() protects the entries from --gc-sections and
|
||||
* SORT_BY_NAME() defines the iteration order.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_LINKER_ITERABLE_SECTIONS_LD
|
||||
#define __INCLUDE_NUTTX_LINKER_ITERABLE_SECTIONS_LD
|
||||
|
||||
#define ITERABLE_SECTION(name) \
|
||||
. = ALIGN(4); \
|
||||
_##name##_list_start = .; \
|
||||
KEEP(*(SORT_BY_NAME(._##name.static.*))); \
|
||||
_##name##_list_end = .; \
|
||||
. = ALIGN(4);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_LINKER_ITERABLE_SECTIONS_LD */
|
||||
|
|
@ -861,3 +861,17 @@ LOWERMAP = A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R
|
|||
|
||||
UPPER_CASE = $(call ULMAP,$(UPPERMAP),$(1))
|
||||
LOWER_CASE = $(call ULMAP,$(LOWERMAP),$(1))
|
||||
|
||||
# Iterable sections "zero-touch" mode: supplement the board linker script
|
||||
# with the central INSERT fragment (include/nuttx/linker/common-insert.ld,
|
||||
# which collects the per-subsystem iterable sections) instead of requiring
|
||||
# the board script to include common-rom.ld.
|
||||
#
|
||||
# The fragment is added through ARCHSCRIPT (not EXTRALINKCMDS) because GNU
|
||||
# ld requires the INSERT script to come BEFORE the script that defines the
|
||||
# target section on the command line; this file is included by the board
|
||||
# Make.defs before it appends its own script, so the fragment lands first.
|
||||
|
||||
ifeq ($(CONFIG_ITERABLE_SECTIONS_LINKER_INSERT),y)
|
||||
ARCHSCRIPT += $(TOPDIR)$(DELIM)include$(DELIM)nuttx$(DELIM)linker$(DELIM)common-insert.ld
|
||||
endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue