1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-11 05:17:44 +03:00

macro: Move ALIGN_TO to macro-fundamental.h and introduce CONST_ALIGN_TO

This commit is contained in:
Jan Janssen 2021-10-06 10:21:42 +02:00
parent 53f69d671c
commit a36a0d1540
6 changed files with 43 additions and 27 deletions

View File

@ -145,24 +145,6 @@
#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p)))
#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p)))
static inline size_t ALIGN_TO(size_t l, size_t ali) {
/* Check that alignment is exponent of 2 */
#if SIZE_MAX == UINT_MAX
assert(__builtin_popcount(ali) == 1);
#elif SIZE_MAX == ULONG_MAX
assert(__builtin_popcountl(ali) == 1);
#elif SIZE_MAX == ULLONG_MAX
assert(__builtin_popcountll(ali) == 1);
#else
#error "Unexpected size_t"
#endif
if (l > SIZE_MAX - (ali - 1))
return SIZE_MAX; /* indicate overflow */
return ((l + ali - 1) & ~(ali - 1));
}
#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali)))
/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */

View File

@ -24,13 +24,6 @@
#define UINT64_MAX ((UINT64) -1)
#endif
static inline UINTN ALIGN_TO(UINTN l, UINTN ali) {
if (l > UINTN_MAX - (ali - 1)) /* Overflow? */
return UINTN_MAX;
return ((l + (ali - 1)) & ~(ali - 1));
}
EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b);
UINT64 ticks_read(void);

View File

@ -9,7 +9,7 @@
union GptHeaderBuffer {
EFI_PARTITION_TABLE_HEADER gpt_header;
uint8_t space[((sizeof(EFI_PARTITION_TABLE_HEADER) + 511) / 512) * 512];
uint8_t space[CONST_ALIGN_TO(sizeof(EFI_PARTITION_TABLE_HEADER), 512)];
};
static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node) {

View File

@ -5,6 +5,7 @@
#include <assert.h>
#endif
#include <limits.h>
#include "type.h"
#define _align_(x) __attribute__((__aligned__(x)))
@ -273,3 +274,34 @@
free(memory); \
(typeof(memory)) NULL; \
})
static inline size_t ALIGN_TO(size_t l, size_t ali) {
/* sd-boot uses UINTN for size_t, let's make sure SIZE_MAX is correct. */
assert_cc(SIZE_MAX == ~(size_t)0);
/* Check that alignment is exponent of 2 */
#if SIZE_MAX == UINT_MAX
assert(__builtin_popcount(ali) == 1);
#elif SIZE_MAX == ULONG_MAX
assert(__builtin_popcountl(ali) == 1);
#elif SIZE_MAX == ULLONG_MAX
assert(__builtin_popcountll(ali) == 1);
#else
#error "Unexpected size_t"
#endif
if (l > SIZE_MAX - (ali - 1))
return SIZE_MAX; /* indicate overflow */
return ((l + ali - 1) & ~(ali - 1));
}
/* Same as ALIGN_TO but callable in constant contexts. */
#define CONST_ALIGN_TO(l, ali) \
__builtin_choose_expr( \
__builtin_constant_p(l) && \
__builtin_constant_p(ali) && \
__builtin_popcountll(ali) == 1 && /* is power of 2? */ \
(l <= SIZE_MAX - (ali - 1)), /* overflow? */ \
((l) + (ali) - 1) & ~((ali) - 1), \
VOID_0)

View File

@ -395,7 +395,7 @@ static int64_t write_catalog(
header = (CatalogHeader) {
.signature = CATALOG_SIGNATURE,
.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)),
.header_size = htole64(CONST_ALIGN_TO(sizeof(CatalogHeader), 8)),
.catalog_item_size = htole64(sizeof(CatalogItem)),
.n_items = htole64(n),
};

View File

@ -325,6 +325,15 @@ static void test_align_to(void) {
assert_se(ALIGN_TO(SIZE_MAX-2, 4) == SIZE_MAX); /* overflow */
assert_se(ALIGN_TO(SIZE_MAX-1, 4) == SIZE_MAX); /* overflow */
assert_se(ALIGN_TO(SIZE_MAX, 4) == SIZE_MAX); /* overflow */
assert_cc(CONST_ALIGN_TO(96, 512) == 512);
assert_cc(CONST_ALIGN_TO(511, 512) == 512);
assert_cc(CONST_ALIGN_TO(512, 512) == 512);
assert_cc(CONST_ALIGN_TO(513, 512) == 1024);
assert_cc(CONST_ALIGN_TO(sizeof(int), 64) == 64);
assert_cc(__builtin_types_compatible_p(typeof(CONST_ALIGN_TO(4, 3)), void));
assert_cc(__builtin_types_compatible_p(typeof(CONST_ALIGN_TO(SIZE_MAX, 512)), void));
}
int main(int argc, char *argv[]) {