From ad71ba6fa1f2ea7df31463dee9d5abefab9d0892 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 1 Jun 2015 16:52:13 -0400 Subject: [PATCH] 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 --- kernel/microkernel/cmdPkt.c | 4 ++-- kernel/microkernel/include/kernel_struct.h | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/kernel/microkernel/cmdPkt.c b/kernel/microkernel/cmdPkt.c index 247afc07ea5..61306f38106 100644 --- a/kernel/microkernel/cmdPkt.c +++ b/kernel/microkernel/cmdPkt.c @@ -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))]; /******************************************************************************* * diff --git a/kernel/microkernel/include/kernel_struct.h b/kernel/microkernel/include/kernel_struct.h index d702873a83e..f1c5d7d2cc1 100644 --- a/kernel/microkernel/include/kernel_struct.h +++ b/kernel/microkernel/include/kernel_struct.h @@ -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 */