mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-01-03 15:00:14 +01:00
dbus-mempool.c: ensure that all alignments are aligned to max_align_t
This is required e.g. for CHERI-enabled targets such as Arm Morello where aligning to sizeof(long) is not sufficient to load/store pointers (which need 16 byte alignment instead of 8 bytes). As we can't depend on C11 yet, this commit adds a max_align_t emulation to dbus-internals.h.
This commit is contained in:
parent
c4a8c2d920
commit
33dbeb5ebe
2 changed files with 41 additions and 6 deletions
|
|
@ -283,6 +283,21 @@ _dbus_assert_error_xor_bool (const DBusError *error,
|
|||
#define _DBUS_ALIGN_ADDRESS(this, boundary) \
|
||||
((void*)_DBUS_ALIGN_VALUE(this, boundary))
|
||||
|
||||
#define _DBUS_IS_ALIGNED(this, boundary) \
|
||||
((((size_t) (uintptr_t) (this)) & ((size_t) (boundary) - 1)) == 0)
|
||||
|
||||
/**
|
||||
* Aligning a pointer to _DBUS_ALIGNOF(dbus_max_align_t) guarantees that all
|
||||
* scalar types can be loaded/stored from/to such an address without incurring
|
||||
* an alignment fault (or a slow misaligned access).
|
||||
* This is based on C11 max_align_t, but falls back to DBusBasicValue for
|
||||
* older C standards.
|
||||
*/
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
||||
typedef max_align_t dbus_max_align_t;
|
||||
#else
|
||||
typedef DBusBasicValue dbus_max_align_t;
|
||||
#endif
|
||||
|
||||
DBUS_PRIVATE_EXPORT
|
||||
char* _dbus_strdup (const char *str);
|
||||
|
|
|
|||
|
|
@ -82,12 +82,24 @@ struct DBusMemBlock
|
|||
* when we free the mem pool.
|
||||
*/
|
||||
|
||||
/* this is a size_t so that "elements" is aligned */
|
||||
size_t used_so_far; /**< bytes of this block already allocated as elements. */
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
||||
/*
|
||||
* Ensure that elements is aligned correctly. For all supported pre-C11
|
||||
* targets, the size_t above should ensure that the elements array is
|
||||
* sufficiently aligned (this is checked in the static assert below).
|
||||
*/
|
||||
_Alignas (dbus_max_align_t)
|
||||
#endif
|
||||
unsigned char elements[]; /**< the block data, actually allocated to required size */
|
||||
};
|
||||
|
||||
_DBUS_STATIC_ASSERT (_DBUS_IS_ALIGNED (sizeof (struct DBusMemBlock),
|
||||
_DBUS_ALIGNOF (dbus_max_align_t)));
|
||||
_DBUS_STATIC_ASSERT (_DBUS_IS_ALIGNED (offsetof (struct DBusMemBlock,
|
||||
elements),
|
||||
_DBUS_ALIGNOF (dbus_max_align_t)));
|
||||
|
||||
/**
|
||||
* Internals fields of DBusMemPool
|
||||
*/
|
||||
|
|
@ -152,10 +164,11 @@ _dbus_mem_pool_new (int element_size,
|
|||
_dbus_assert (element_size >= (int) sizeof (void*));
|
||||
_dbus_assert (element_size >= (int) sizeof (DBusFreedElement));
|
||||
|
||||
/* align the element size to a pointer boundary so we won't get bus
|
||||
* errors under other architectures.
|
||||
/* align the element size to be suitable for the most-aligned type
|
||||
* that we care about (in practice usually a pointer).
|
||||
*/
|
||||
pool->element_size = _DBUS_ALIGN_VALUE (element_size, sizeof (void *));
|
||||
pool->element_size =
|
||||
_DBUS_ALIGN_VALUE (element_size, _DBUS_ALIGNOF (dbus_max_align_t));
|
||||
|
||||
pool->zero_elements = zero_elements != FALSE;
|
||||
|
||||
|
|
@ -239,6 +252,8 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
|
|||
|
||||
VALGRIND_MEMPOOL_ALLOC (pool, (void *) &block->elements[0],
|
||||
pool->element_size);
|
||||
_dbus_assert (_DBUS_IS_ALIGNED (&block->elements[0],
|
||||
_DBUS_ALIGNOF (dbus_max_align_t)));
|
||||
return (void*) &block->elements[0];
|
||||
}
|
||||
else
|
||||
|
|
@ -264,7 +279,8 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
|
|||
memset (element, '\0', pool->element_size);
|
||||
|
||||
pool->allocated_elements += 1;
|
||||
|
||||
_dbus_assert (
|
||||
_DBUS_IS_ALIGNED (element, _DBUS_ALIGNOF (dbus_max_align_t)));
|
||||
return element;
|
||||
}
|
||||
else
|
||||
|
|
@ -306,6 +322,8 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
|
|||
block = dbus_malloc0 (alloc_size);
|
||||
else
|
||||
block = dbus_malloc (alloc_size);
|
||||
_dbus_assert (
|
||||
_DBUS_IS_ALIGNED (block, _DBUS_ALIGNOF (dbus_max_align_t)));
|
||||
|
||||
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
|
||||
_dbus_set_fail_alloc_counter (saved_counter);
|
||||
|
|
@ -327,6 +345,8 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
|
|||
pool->allocated_elements += 1;
|
||||
|
||||
VALGRIND_MEMPOOL_ALLOC (pool, element, pool->element_size);
|
||||
_dbus_assert (
|
||||
_DBUS_IS_ALIGNED (element, _DBUS_ALIGNOF (dbus_max_align_t)));
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue