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