linker generated list: explicit alignment on data definitions

The alignment fix on struct device definitions should be done to all
such linker list tricks. Let's abstract the declaration plus alignment
with a macro and apply it to all concerned cases.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
Nicolas Pitre 2019-05-25 22:53:37 -04:00 committed by Andrew Boie
parent 7daa5451cf
commit 8bb1f2a947
4 changed files with 39 additions and 21 deletions

View file

@ -107,9 +107,8 @@ extern "C" {
.name = drv_name, .init = (init_fn), \
.config_info = (cfg_info) \
}; \
static struct device _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)), \
aligned(__alignof(struct device)))) = { \
static Z_DECL_ALIGN(struct device) _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
.config = &_CONCAT(__config_, dev_name), \
.driver_api = api, \
.driver_data = data \
@ -165,9 +164,8 @@ extern "C" {
.pm = &_CONCAT(__pm_, dev_name), \
.config_info = (cfg_info) \
}; \
static struct device _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)), \
aligned(__alignof(struct device)))) = { \
static Z_DECL_ALIGN(struct device) _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
.config = &_CONCAT(__config_, dev_name), \
.driver_api = api, \
.driver_data = data, \

View file

@ -187,7 +187,7 @@ struct _k_object_assignment {
static void * const _CONCAT(_object_list_, name_)[] = \
{ __VA_ARGS__, NULL }; \
static __used __in_section_unique(object_access) \
const struct _k_object_assignment \
const Z_DECL_ALIGN(struct _k_object_assignment) \
_CONCAT(_object_access_, name_) = \
{ (&_k_thread_obj_ ## name_), \
(_CONCAT(_object_list_, name_)) }
@ -969,7 +969,7 @@ struct _static_thread_data {
prio, options, delay) \
K_THREAD_STACK_DEFINE(_k_thread_stack_##name, stack_size); \
struct k_thread _k_thread_obj_##name; \
struct _static_thread_data _k_thread_data_##name __aligned(4) \
Z_DECL_ALIGN(struct _static_thread_data) _k_thread_data_##name \
__in_section(_static_thread_data, static, name) = \
_THREAD_INITIALIZER(&_k_thread_obj_##name, \
_k_thread_stack_##name, stack_size, \
@ -1468,7 +1468,7 @@ typedef void (*k_timer_stop_t)(struct k_timer *timer);
* @param stop_fn Function to invoke if the timer is stopped while running.
*/
#define K_TIMER_DEFINE(name, expiry_fn, stop_fn) \
struct k_timer name \
Z_DECL_ALIGN(struct k_timer) name \
__in_section(_k_timer, static, name) = \
Z_TIMER_INITIALIZER(name, expiry_fn, stop_fn)
@ -2050,7 +2050,7 @@ static inline void *z_impl_k_queue_peek_tail(struct k_queue *queue)
* @param name Name of the queue.
*/
#define K_QUEUE_DEFINE(name) \
struct k_queue name \
Z_DECL_ALIGN(struct k_queue) name \
__in_section(_k_queue, static, name) = \
_K_QUEUE_INITIALIZER(name)
@ -2266,7 +2266,7 @@ struct k_fifo {
* @req K-FIFO-002
*/
#define K_FIFO_DEFINE(name) \
struct k_fifo name \
Z_DECL_ALIGN(struct k_fifo) name \
__in_section(_k_queue, static, name) = \
Z_FIFO_INITIALIZER(name)
@ -2378,7 +2378,7 @@ struct k_lifo {
* @req K-LIFO-002
*/
#define K_LIFO_DEFINE(name) \
struct k_lifo name \
Z_DECL_ALIGN(struct k_lifo) name \
__in_section(_k_queue, static, name) = \
_K_LIFO_INITIALIZER(name)
@ -2514,7 +2514,7 @@ __syscall int k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout);
#define K_STACK_DEFINE(name, stack_num_entries) \
u32_t __noinit \
_k_stack_buf_##name[stack_num_entries]; \
struct k_stack name \
Z_DECL_ALIGN(struct k_stack) name \
__in_section(_k_stack, static, name) = \
_K_STACK_INITIALIZER(name, _k_stack_buf_##name, \
stack_num_entries)
@ -2949,7 +2949,7 @@ struct k_mutex {
* @req K-MUTEX-001
*/
#define K_MUTEX_DEFINE(name) \
struct k_mutex name \
Z_DECL_ALIGN(struct k_mutex) name \
__in_section(_k_mutex, static, name) = \
_K_MUTEX_INITIALIZER(name)
@ -3150,7 +3150,7 @@ static inline unsigned int z_impl_k_sem_count_get(struct k_sem *sem)
* @req K-SEM-002
*/
#define K_SEM_DEFINE(name, initial_count, count_limit) \
struct k_sem name \
Z_DECL_ALIGN(struct k_sem) name \
__in_section(_k_sem, static, name) = \
Z_SEM_INITIALIZER(name, initial_count, count_limit); \
BUILD_ASSERT(((count_limit) != 0) && \
@ -3240,7 +3240,7 @@ struct k_msgq_attrs {
#define K_MSGQ_DEFINE(q_name, q_msg_size, q_max_msgs, q_align) \
static char __noinit __aligned(q_align) \
_k_fifo_buf_##q_name[(q_max_msgs) * (q_msg_size)]; \
struct k_msgq q_name \
Z_DECL_ALIGN(struct k_msgq) q_name \
__in_section(_k_msgq, static, q_name) = \
_K_MSGQ_INITIALIZER(q_name, _k_fifo_buf_##q_name, \
q_msg_size, q_max_msgs)
@ -3504,7 +3504,7 @@ struct k_mbox {
* @req K-MBOX-001
*/
#define K_MBOX_DEFINE(name) \
struct k_mbox name \
Z_DECL_ALIGN(struct k_mbox) name \
__in_section(_k_mbox, static, name) = \
_K_MBOX_INITIALIZER(name) \
@ -3707,7 +3707,7 @@ struct k_pipe {
#define K_PIPE_DEFINE(name, pipe_buffer_size, pipe_align) \
static unsigned char __noinit __aligned(pipe_align) \
_k_pipe_buf_##name[pipe_buffer_size]; \
struct k_pipe name \
Z_DECL_ALIGN(struct k_pipe) name \
__in_section(_k_pipe, static, name) = \
_K_PIPE_INITIALIZER(name, _k_pipe_buf_##name, pipe_buffer_size)
@ -3888,7 +3888,7 @@ struct k_mem_slab {
#define K_MEM_SLAB_DEFINE(name, slab_block_size, slab_num_blocks, slab_align) \
char __noinit __aligned(slab_align) \
_k_mem_slab_buf_##name[(slab_num_blocks) * (slab_block_size)]; \
struct k_mem_slab name \
Z_DECL_ALIGN(struct k_mem_slab) name \
__in_section(_k_mem_slab, static, name) = \
_K_MEM_SLAB_INITIALIZER(name, _k_mem_slab_buf_##name, \
slab_block_size, slab_num_blocks)
@ -4025,7 +4025,8 @@ struct k_mem_pool {
char __aligned(align) _mpool_buf_##name[_ALIGN4(maxsz * nmax) \
+ _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \
struct sys_mem_pool_lvl _mpool_lvls_##name[Z_MPOOL_LVLS(maxsz, minsz)]; \
struct k_mem_pool name __in_section(_k_mem_pool, static, name) = { \
Z_DECL_ALIGN(struct k_mem_pool) name \
__in_section(_k_mem_pool, static, name) = { \
.base = { \
.buf = _mpool_buf_##name, \
.max_sz = maxsz, \

View file

@ -144,4 +144,23 @@
#define BUILD_ASSERT_MSG(EXPR, MSG) BUILD_ASSERT(EXPR)
#endif
/*
* This is meant to be used in conjonction with __in_section() and similar
* where scattered structure instances are concatened together by the linker
* and walked by the code at run time just like a contiguous array of such
* structures.
*
* Assemblers and linkers may insert alignment padding by default whose
* size is larger than the natural alignment for those structures when
* gathering various section segments together, messing up the array walk.
* To prevent this, we need to provide an explicit alignment not to rely
* on the default that might just work by luck.
*
* Alignment statements in linker scripts are not sufficient as
* the assembler may add padding by itself to each segment when switching
* between sections within the same file even if it merges many such segments
* into a single section in the end.
*/
#define Z_DECL_ALIGN(type) __aligned(__alignof(type)) type
#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_COMMON_H_ */

View file

@ -14,7 +14,7 @@ struct bt_settings_handler {
};
#define BT_SETTINGS_DEFINE(_name, _set, _commit, _export) \
const struct bt_settings_handler _name __aligned(4) \
const Z_DECL_ALIGN(struct bt_settings_handler) _name \
__in_section(_bt_settings, static, _name) = { \
.name = STRINGIFY(_name), \
.set = _set, \