64-bit alignment in serialised data
The payload in a struct serdata_default is assumed to be at a 64-bit offset for conversion to/from a dds_{i,o}stream_t and getting padding calculations in the serialised representation correct. The definition did not guarantee this and got it wrong on a 32-bit release build. This commit computes the required padding at compile time and at verifies the assumption holds where it matters. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
2fe4a4ca35
commit
0dd2155f99
2 changed files with 42 additions and 13 deletions
|
@ -1614,6 +1614,8 @@ void dds_stream_extract_keyhash (dds_istream_t * __restrict is, dds_keyhash_t *
|
||||||
**
|
**
|
||||||
*******************************************************************************************/
|
*******************************************************************************************/
|
||||||
|
|
||||||
|
DDSRT_STATIC_ASSERT ((offsetof (struct ddsi_serdata_default, data) % 8) == 0);
|
||||||
|
|
||||||
void dds_istream_from_serdata_default (dds_istream_t * __restrict s, const struct ddsi_serdata_default * __restrict d)
|
void dds_istream_from_serdata_default (dds_istream_t * __restrict s, const struct ddsi_serdata_default * __restrict d)
|
||||||
{
|
{
|
||||||
s->m_buffer = (const unsigned char *) d;
|
s->m_buffer = (const unsigned char *) d;
|
||||||
|
|
|
@ -49,26 +49,52 @@ typedef struct dds_keyhash {
|
||||||
unsigned m_iskey : 1; /* m_hash is key value */
|
unsigned m_iskey : 1; /* m_hash is key value */
|
||||||
} dds_keyhash_t;
|
} dds_keyhash_t;
|
||||||
|
|
||||||
struct ddsi_serdata_default {
|
/* Debug builds may want to keep some additional state */
|
||||||
struct ddsi_serdata c;
|
|
||||||
uint32_t pos;
|
|
||||||
uint32_t size;
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
#define DDSI_SERDATA_DEFAULT_DEBUG_FIELDS \
|
||||||
bool fixed;
|
bool fixed;
|
||||||
|
#else
|
||||||
|
#define DDSI_SERDATA_DEFAULT_DEBUG_FIELDS
|
||||||
#endif
|
#endif
|
||||||
dds_keyhash_t keyhash;
|
|
||||||
|
|
||||||
struct serdatapool *pool;
|
/* There is an alignment requirement on the raw data (it must be at
|
||||||
struct ddsi_serdata_default *next; /* in pool->freelist */
|
offset mod 8 for the conversion to/from a dds_stream to work).
|
||||||
|
So we define two types: one without any additional padding, and
|
||||||
|
one where the appropriate amount of padding is inserted */
|
||||||
|
#define DDSI_SERDATA_DEFAULT_PREPAD \
|
||||||
|
struct ddsi_serdata c; \
|
||||||
|
uint32_t pos; \
|
||||||
|
uint32_t size; \
|
||||||
|
DDSI_SERDATA_DEFAULT_DEBUG_FIELDS \
|
||||||
|
dds_keyhash_t keyhash; \
|
||||||
|
struct serdatapool *pool; \
|
||||||
|
struct ddsi_serdata_default *next /* in pool->freelist */
|
||||||
|
#define DDSI_SERDATA_DEFAULT_POSTPAD \
|
||||||
|
struct CDRHeader hdr; \
|
||||||
|
char data[]
|
||||||
|
|
||||||
/* padding to ensure CDRHeader is at an offset 4 mod 8 from the
|
struct ddsi_serdata_default_unpadded {
|
||||||
start of the memory, so that data is 8-byte aligned provided
|
DDSI_SERDATA_DEFAULT_PREPAD;
|
||||||
serdata is 8-byte aligned */
|
DDSI_SERDATA_DEFAULT_POSTPAD;
|
||||||
char pad[8 - ((sizeof (struct ddsi_serdata) + 4) % 8)];
|
|
||||||
struct CDRHeader hdr;
|
|
||||||
char data[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define DDSI_SERDATA_DEFAULT_PAD(n) ((n) % 8)
|
||||||
|
#else
|
||||||
|
#define DDSI_SERDATA_DEFAULT_PAD(n) (n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ddsi_serdata_default {
|
||||||
|
DDSI_SERDATA_DEFAULT_PREPAD;
|
||||||
|
char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))];
|
||||||
|
DDSI_SERDATA_DEFAULT_POSTPAD;
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef DDSI_SERDATA_DEFAULT_PAD
|
||||||
|
#undef DDSI_SERDATA_DEFAULT_POSTPAD
|
||||||
|
#undef DDSI_SERDATA_DEFAULT_PREPAD
|
||||||
|
#undef DDSI_SERDATA_DEFAULT_FIXED_FIELD
|
||||||
|
|
||||||
struct dds_key_descriptor;
|
struct dds_key_descriptor;
|
||||||
struct dds_topic_descriptor;
|
struct dds_topic_descriptor;
|
||||||
|
|
||||||
|
@ -80,6 +106,7 @@ typedef bool (*dds_topic_intern_filter_fn) (const void * sample, void *ctx);
|
||||||
struct ddsi_sertopic_default {
|
struct ddsi_sertopic_default {
|
||||||
struct ddsi_sertopic c;
|
struct ddsi_sertopic c;
|
||||||
uint16_t native_encoding_identifier; /* (PL_)?CDR_(LE|BE) */
|
uint16_t native_encoding_identifier; /* (PL_)?CDR_(LE|BE) */
|
||||||
|
struct serdatapool *serpool;
|
||||||
|
|
||||||
struct dds_topic_descriptor * type;
|
struct dds_topic_descriptor * type;
|
||||||
unsigned nkeys;
|
unsigned nkeys;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue