linker: add iterable section macros

For iterable areas defined with Z_STRUCT_SECTION_ITERABLE(),
the corresponding output section in the linker script is just
boilerplate. Add macros to make these definitions simpler.

Unfortunately, we have a fair number of iterable sections not
defined with Z_STRUCT_SECTION_ITERABLE(), this patch does not
address this.

The output sections are all named <struct name>_area, update
sanitylib.py with this.

sys_sem with no userspace, and k_lifo/k_fifo are special cases
where different data types that are all equivalent need to be
put in the same iterable area. Add
Z_STRUCT_SECTION_ITERABLE_ALTERNATE() for this special case.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2020-05-23 14:38:39 -07:00 committed by Anas Nashif
commit 45979dafb4
7 changed files with 84 additions and 154 deletions

View file

@ -2773,7 +2773,7 @@ struct k_fifo {
* @param name Name of the FIFO queue. * @param name Name of the FIFO queue.
*/ */
#define K_FIFO_DEFINE(name) \ #define K_FIFO_DEFINE(name) \
Z_STRUCT_SECTION_ITERABLE(k_fifo, name) = \ Z_STRUCT_SECTION_ITERABLE_ALTERNATE(k_queue, k_fifo, name) = \
Z_FIFO_INITIALIZER(name) Z_FIFO_INITIALIZER(name)
/** @} */ /** @} */
@ -2879,7 +2879,7 @@ struct k_lifo {
* @param name Name of the fifo. * @param name Name of the fifo.
*/ */
#define K_LIFO_DEFINE(name) \ #define K_LIFO_DEFINE(name) \
Z_STRUCT_SECTION_ITERABLE(k_lifo, name) = \ Z_STRUCT_SECTION_ITERABLE_ALTERNATE(k_queue, k_lifo, name) = \
Z_LIFO_INITIALIZER(name) Z_LIFO_INITIALIZER(name)
/** @} */ /** @} */

View file

@ -68,12 +68,7 @@
__log_dynamic_end = .; __log_dynamic_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_static_thread_area,,SUBALIGN(4)) Z_ITERABLE_SECTION_RAM(_static_thread_data, 4)
{
__static_thread_data_list_start = .;
KEEP(*(SORT_BY_NAME(".__static_thread_data.static.*")))
__static_thread_data_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
#ifdef CONFIG_USERSPACE #ifdef CONFIG_USERSPACE
/* All kernel objects within are assumed to be either completely /* All kernel objects within are assumed to be either completely
@ -86,85 +81,17 @@
_static_kernel_objects_begin = .; _static_kernel_objects_begin = .;
#endif /* CONFIG_USERSPACE */ #endif /* CONFIG_USERSPACE */
SECTION_DATA_PROLOGUE(_k_timer_area,,SUBALIGN(4)) Z_ITERABLE_SECTION_RAM(k_timer, 4)
{ Z_ITERABLE_SECTION_RAM(k_mem_slab, 4)
_k_timer_list_start = .; Z_ITERABLE_SECTION_RAM(k_mem_pool, 4)
KEEP(*("._k_timer.static.*")) Z_ITERABLE_SECTION_RAM(k_heap, 4)
_k_timer_list_end = .; Z_ITERABLE_SECTION_RAM(k_mutex, 4)
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) Z_ITERABLE_SECTION_RAM(k_stack, 4)
Z_ITERABLE_SECTION_RAM(k_msgq, 4)
SECTION_DATA_PROLOGUE(_k_mem_slab_area,,SUBALIGN(4)) Z_ITERABLE_SECTION_RAM(k_mbox, 4)
{ Z_ITERABLE_SECTION_RAM(k_pipe, 4)
_k_mem_slab_list_start = .; Z_ITERABLE_SECTION_RAM(k_sem, 4)
KEEP(*("._k_mem_slab.static.*")) Z_ITERABLE_SECTION_RAM(k_queue, 4)
_k_mem_slab_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_mem_pool_area,,SUBALIGN(4))
{
_k_mem_pool_list_start = .;
KEEP(*("._k_mem_pool.static.*"))
_k_mem_pool_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_heap_area,,SUBALIGN(4))
{
_k_heap_list_start = .;
KEEP(*("._k_heap.static.*"))
_k_heap_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_sem_area,,SUBALIGN(4))
{
_k_sem_list_start = .;
KEEP(*("._k_sem.static.*"))
KEEP(*("._sys_sem.static.*"))
_k_sem_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_mutex_area,,SUBALIGN(4))
{
_k_mutex_list_start = .;
KEEP(*("._k_mutex.static.*"))
_k_mutex_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_queue_area,,SUBALIGN(4))
{
_k_queue_list_start = .;
KEEP(*("._k_queue.static.*"))
KEEP(*("._k_fifo.static.*"))
KEEP(*("._k_lifo.static.*"))
_k_queue_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_stack_area,,SUBALIGN(4))
{
_k_stack_list_start = .;
KEEP(*("._k_stack.static.*"))
_k_stack_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_msgq_area,,SUBALIGN(4))
{
_k_msgq_list_start = .;
KEEP(*("._k_msgq.static.*"))
_k_msgq_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_mbox_area,,SUBALIGN(4))
{
_k_mbox_list_start = .;
KEEP(*("._k_mbox.static.*"))
_k_mbox_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_k_pipe_area,,SUBALIGN(4))
{
_k_pipe_list_start = .;
KEEP(*("._k_pipe.static.*"))
_k_pipe_list_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(_net_buf_pool_area,,SUBALIGN(4)) SECTION_DATA_PROLOGUE(_net_buf_pool_area,,SUBALIGN(4))
{ {

View file

@ -76,12 +76,7 @@
/* Build-time assignment of permissions to kernel objects to /* Build-time assignment of permissions to kernel objects to
* threads declared with K_THREAD_DEFINE() * threads declared with K_THREAD_DEFINE()
*/ */
SECTION_PROLOGUE(object_access,,) Z_ITERABLE_SECTION_ROM(z_object_assignment, 4)
{
_z_object_assignment_list_start = .;
KEEP(*("._z_object_assignment.*"))
_z_object_assignment_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
#endif #endif
SECTION_PROLOGUE(app_shmem_regions,,) SECTION_PROLOGUE(app_shmem_regions,,)
@ -100,12 +95,7 @@
} GROUP_LINK_IN(ROMABLE_REGION) } GROUP_LINK_IN(ROMABLE_REGION)
#if defined(CONFIG_NET_SOCKETS) #if defined(CONFIG_NET_SOCKETS)
SECTION_PROLOGUE(net_socket_register,,) Z_ITERABLE_SECTION_ROM(net_socket_register, 4)
{
_net_socket_register_list_start = .;
KEEP(*(SORT_BY_NAME("._net_socket_register.*")))
_net_socket_register_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
#endif #endif
#if defined(CONFIG_NET_L2_PPP) #if defined(CONFIG_NET_L2_PPP)
@ -118,36 +108,16 @@
} GROUP_LINK_IN(ROMABLE_REGION) } GROUP_LINK_IN(ROMABLE_REGION)
#endif #endif
SECTION_DATA_PROLOGUE(_bt_channels_area,,SUBALIGN(4)) Z_ITERABLE_SECTION_ROM(bt_l2cap_fixed_chan, 4)
{
_bt_l2cap_fixed_chan_list_start = .;
KEEP(*(SORT_BY_NAME("._bt_l2cap_fixed_chan.static.*")))
_bt_l2cap_fixed_chan_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
#if defined(CONFIG_BT_BREDR) #if defined(CONFIG_BT_BREDR)
SECTION_DATA_PROLOGUE(_bt_br_channels_area,,SUBALIGN(4)) Z_ITERABLE_SECTION_ROM(bt_l2cap_br_fixed_chan, 4)
{
_bt_l2cap_br_fixed_chan_list_start = .;
KEEP(*(SORT_BY_NAME("._bt_l2cap_br_fixed_chan.static.*")))
_bt_l2cap_br_fixed_chan_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
#endif #endif
SECTION_DATA_PROLOGUE(_bt_services_area,,SUBALIGN(4)) Z_ITERABLE_SECTION_ROM(bt_gatt_service_static, 4)
{
_bt_gatt_service_static_list_start = .;
KEEP(*(SORT_BY_NAME("._bt_gatt_service_static.static.*")))
_bt_gatt_service_static_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
#if defined(CONFIG_SETTINGS) #if defined(CONFIG_SETTINGS)
SECTION_DATA_PROLOGUE(_settings_handlers_area,,SUBALIGN(4)) Z_ITERABLE_SECTION_ROM(settings_handler_static, 4)
{
_settings_handler_static_list_start = .;
KEEP(*(SORT_BY_NAME("._settings_handler_static.static.*")))
_settings_handler_static_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
#endif #endif
SECTION_DATA_PROLOGUE(log_const_sections,,) SECTION_DATA_PROLOGUE(log_const_sections,,)
@ -164,12 +134,7 @@
__log_backends_end = .; __log_backends_end = .;
} GROUP_LINK_IN(ROMABLE_REGION) } GROUP_LINK_IN(ROMABLE_REGION)
SECTION_DATA_PROLOGUE(shell_sections,,) Z_ITERABLE_SECTION_ROM(shell, 4)
{
_shell_list_start = .;
KEEP(*(SORT(._shell.static.*)));
_shell_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_DATA_PROLOGUE(shell_root_cmds_sections,,) SECTION_DATA_PROLOGUE(shell_root_cmds_sections,,)
{ {
@ -185,9 +150,4 @@
__font_entry_end = .; __font_entry_end = .;
} GROUP_LINK_IN(ROMABLE_REGION) } GROUP_LINK_IN(ROMABLE_REGION)
SECTION_DATA_PROLOGUE(tracing_backends_sections,,) Z_ITERABLE_SECTION_ROM(tracing_backend, 4)
{
_tracing_backend_list_start = .;
KEEP(*("._tracing_backend.*"));
_tracing_backend_list_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)

View file

@ -20,6 +20,7 @@
#define ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_ #define ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_
#include <toolchain.h> #include <toolchain.h>
#include <toolchain/common.h>
#include <linker/sections.h> #include <linker/sections.h>
#include <sys/util.h> #include <sys/util.h>
#include <offsets.h> #include <offsets.h>
@ -36,6 +37,35 @@
#endif #endif
#ifdef _LINKER #ifdef _LINKER
#define Z_LINK_ITERABLE(struct_type) \
_CONCAT(_##struct_type, _list_start) = .; \
KEEP(*(SORT_BY_NAME(._##struct_type##.static.*))); \
_CONCAT(_##struct_type, _list_end) = .
/* Define an output section which will set up an iterable area
* of equally-sized data structures. For use with Z_STRUCT_SECTION_ITERABLE.
* Input sections will be sorted by name, per ld's SORT_BY_NAME.
*
* This macro should be used for read-only data.
*/
#define Z_ITERABLE_SECTION_ROM(struct_type, subalign) \
SECTION_PROLOGUE(struct_type##_area,,SUBALIGN(subalign)) \
{ \
Z_LINK_ITERABLE(struct_type); \
} GROUP_LINK_IN(ROMABLE_REGION)
/* Define an output section which will set up an iterable area
* of equally-sized data structures. For use with Z_STRUCT_SECTION_ITERABLE.
* Input sections will be sorted by name, per ld's SORT_BY_NAME.
*
* This macro should be used for read-write data that is modified at runtime.
*/
#define Z_ITERABLE_SECTION_RAM(struct_type, subalign) \
SECTION_DATA_PROLOGUE(struct_type##_area,,SUBALIGN(subalign)) \
{ \
Z_LINK_ITERABLE(struct_type); \
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
/* /*
* generate a symbol to mark the start of the objects array for * generate a symbol to mark the start of the objects array for
* the specified object and level, then link all of those objects * the specified object and level, then link all of those objects

View file

@ -71,7 +71,7 @@ struct sys_sem {
* are identical and can be treated as a k_sem in the boot initialization code * are identical and can be treated as a k_sem in the boot initialization code
*/ */
#define SYS_SEM_DEFINE(_name, _initial_count, _count_limit) \ #define SYS_SEM_DEFINE(_name, _initial_count, _count_limit) \
Z_STRUCT_SECTION_ITERABLE(sys_sem, _name) = { \ Z_STRUCT_SECTION_ITERABLE_ALTERNATE(k_sem, sys_sem, _name) = { \
.kernel_sem = Z_SEM_INITIALIZER(_name.kernel_sem, \ .kernel_sem = Z_SEM_INITIALIZER(_name.kernel_sem, \
_initial_count, _count_limit) \ _initial_count, _count_limit) \
}; \ }; \

View file

@ -180,11 +180,22 @@
* Convenience helper combining __in_section() and Z_DECL_ALIGN(). * Convenience helper combining __in_section() and Z_DECL_ALIGN().
* The section name is the struct type prepended with an underscore. * The section name is the struct type prepended with an underscore.
* The subsection is "static" and the subsubsection is the variable name. * The subsection is "static" and the subsubsection is the variable name.
*
* In the linker script, create output sections for these using
* Z_ITERABLE_SECTION_ROM or Z_ITERABLE_SECTION_RAM.
*/ */
#define Z_STRUCT_SECTION_ITERABLE(struct_type, name) \ #define Z_STRUCT_SECTION_ITERABLE(struct_type, name) \
Z_DECL_ALIGN(struct struct_type) name \ Z_DECL_ALIGN(struct struct_type) name \
__in_section(_##struct_type, static, name) __used __in_section(_##struct_type, static, name) __used
/* Special variant of Z_STRUCT_SECTION_ITERABLE, for placing alternate
* data types within the iterable section of a specific data type. The
* data type sizes and semantics must be equivalent!
*/
#define Z_STRUCT_SECTION_ITERABLE_ALTERNATE(out_type, struct_type, name) \
Z_DECL_ALIGN(struct struct_type) name \
__in_section(_##out_type, static, name) __used
/* /*
* Itterator for structure instances gathered by Z_STRUCT_SECTION_ITERABLE(). * Itterator for structure instances gathered by Z_STRUCT_SECTION_ITERABLE().
* The linker must provide a _<struct_type>_list_start symbol and a * The linker must provide a _<struct_type>_list_start symbol and a

View file

@ -932,24 +932,24 @@ class SizeCalculator:
"initlevel", "initlevel",
"exceptions", "exceptions",
"initshell", "initshell",
"_static_thread_area", "_static_thread_data_area",
"_k_timer_area", "k_timer_area",
"_k_mem_slab_area", "k_mem_slab_area",
"_k_mem_pool_area", "k_mem_pool_area",
"sw_isr_table", "sw_isr_table",
"_k_sem_area", "k_sem_area",
"_k_mutex_area", "k_mutex_area",
"app_shmem_regions", "app_shmem_regions",
"_k_fifo_area", "_k_fifo_area",
"_k_lifo_area", "_k_lifo_area",
"_k_stack_area", "k_stack_area",
"_k_msgq_area", "k_msgq_area",
"_k_mbox_area", "k_mbox_area",
"_k_pipe_area", "k_pipe_area",
"net_if", "net_if",
"net_if_dev", "net_if_dev",
"net_l2_data", "net_l2_data",
"_k_queue_area", "k_queue_area",
"_net_buf_pool_area", "_net_buf_pool_area",
"app_datas", "app_datas",
"kobject_data", "kobject_data",
@ -980,19 +980,21 @@ class SizeCalculator:
"ctors", "ctors",
"init_array", "init_array",
"reset", "reset",
"object_access", "z_object_assignment_area",
"rodata", "rodata",
"devconfig", "devconfig",
"net_l2", "net_l2",
"vector", "vector",
"sw_isr_table", "sw_isr_table",
"_settings_handlers_area", "settings_handler_static_area",
"_bt_channels_area", "bt_l2cap_fixed_chan",
"_bt_br_channels_area", "bt_l2cap_br_fixec_chan",
"_bt_services_area", "bt_gatt_service_static",
"vectors", "vectors",
"net_socket_register", "net_socket_register_area",
"net_ppp_proto" "net_ppp_proto",
"shell_area",
"tracing_backend_area",
] ]
def __init__(self, filename, extra_sections): def __init__(self, filename, extra_sections):