#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) */
#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);
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) {
#include <assert.h>
#endif
+#include <limits.h>
#include "type.h"
#define _align_(x) __attribute__((__aligned__(x)))
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)
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),
};
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[]) {