Ensure k_args fields are properly aligned and packed

The size of the k_args strcture must be equivalent to ...
    CMD_PKT_SIZE_IN_WORDS * sizeof(uint32_t)

This is complicated by the fact that not only do different compilers treat the
size of 'bool' and 'enum' types differently, they may also pad structures
differently.  Both of these differences have direct impacts on the k_args
structure.  To work around this, the k_args fields 'alloc' and 'Comm' are
forcibly aligned to a 4-byte boundary, while the rest of the k_args structure
is packed.

Change-Id: I722f1a585e5e34a7a7218ed0b214b54fac6d39f7
Signed-off-by: Peter Mitsis <peter.mitsis@windriver.com>
This commit is contained in:
Peter Mitsis 2015-06-01 16:52:13 -04:00 committed by Anas Nashif
parent 53bee67642
commit ad71ba6fa1
2 changed files with 16 additions and 5 deletions

View File

@ -60,12 +60,12 @@ that have an ISR component should use their own command packet set.
/*
* generate build error by defining a negative-size array if the hard-coded
* command packet size is smaller than the actual size; otherwise, define
* command packet size differs from the actual size; otherwise, define
* a zero-element array that gets thrown away by linker
*/
uint32_t _k_test_cmd_pkt_size
[0 - ((CMD_PKT_SIZE_IN_WORDS * sizeof(uint32_t)) < sizeof(struct k_args))];
[0 - ((CMD_PKT_SIZE_IN_WORDS * sizeof(uint32_t)) != sizeof(struct k_args))];
/*******************************************************************************
*

View File

@ -448,12 +448,23 @@ union k_args_args {
struct k_chack ChAck;
};
/*
* The size of the k_args structure must be equivalent to ...
* CMD_PKT_SIZE_IN_WORDS * sizeof(uint32_t)
* To this end the entire structure is packed. This ensures that the compiler
* aligns 'Args' to a 4-byte boundary. If left unpacked, then some compilers
* may provide an extra 4 bytes of padding to align it to an 8-byte boundary,
* thereby violating the previously stated equivalence.
*/
struct k_args {
struct k_args *Forw;
struct k_args **Head;
kpriority_t Prio;
bool alloc; /* true if allocated via GETARGS(); else false */
K_COMM Comm;
/* 'alloc' is true if k_args is allocated via GETARGS() */
bool alloc __aligned(4);
K_COMM Comm __aligned(4);
K_CREF Ctxt;
union {
int32_t ticks;
@ -461,7 +472,7 @@ struct k_args {
int rcode;
} Time;
K_ARGS_ARGS Args;
};
} __packed;
/* ---------------------------------------------------------------------- */
/* KERNEL OBJECT STRUCTURES */