You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.8 KiB
107 lines
3.8 KiB
8 months ago
|
From 925a5adafed2d17c4f2c50460d4e571ca509f54e Mon Sep 17 00:00:00 2001
|
||
|
From: Lennart Poettering <lennart@poettering.net>
|
||
|
Date: Wed, 7 Dec 2022 18:31:27 +0100
|
||
|
Subject: [PATCH] macro: add generic IS_ALIGNED32() anf friends
|
||
|
|
||
|
Let's generalize (and invert) the UNALIGNED32_P() macro from the sha256
|
||
|
code, and let's add a test for it.
|
||
|
|
||
|
(cherry picked from commit 4f07388360a3513b9fc8d2773568b8def941f4a4)
|
||
|
|
||
|
Related: RHEL-16952
|
||
|
---
|
||
|
src/fundamental/macro-fundamental.h | 9 +++++
|
||
|
src/test/test-macro.c | 53 +++++++++++++++++++++++++++++
|
||
|
2 files changed, 62 insertions(+)
|
||
|
|
||
|
diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h
|
||
|
index e0665d9dcb..dd0de328cb 100644
|
||
|
--- a/src/fundamental/macro-fundamental.h
|
||
|
+++ b/src/fundamental/macro-fundamental.h
|
||
|
@@ -334,14 +334,23 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
|
||
|
return ((l + ali - 1) & ~(ali - 1));
|
||
|
}
|
||
|
|
||
|
+#define ALIGN2(l) ALIGN_TO(l, 2)
|
||
|
#define ALIGN4(l) ALIGN_TO(l, 4)
|
||
|
#define ALIGN8(l) ALIGN_TO(l, 8)
|
||
|
+#define ALIGN2_PTR(p) ((void*) ALIGN2((uintptr_t) p))
|
||
|
+#define ALIGN4_PTR(p) ((void*) ALIGN4((uintptr_t) p))
|
||
|
+#define ALIGN8_PTR(p) ((void*) ALIGN8((uintptr_t) p))
|
||
|
#ifndef SD_BOOT
|
||
|
/* libefi also provides ALIGN, and we do not use them in sd-boot explicitly. */
|
||
|
#define ALIGN(l) ALIGN_TO(l, sizeof(void*))
|
||
|
#define ALIGN_PTR(p) ((void*) ALIGN((uintptr_t) (p)))
|
||
|
#endif
|
||
|
|
||
|
+/* Checks if the specified pointer is aligned as appropriate for the specific type */
|
||
|
+#define IS_ALIGNED16(p) (((uintptr_t) p) % __alignof__(uint16_t) == 0)
|
||
|
+#define IS_ALIGNED32(p) (((uintptr_t) p) % __alignof__(uint32_t) == 0)
|
||
|
+#define IS_ALIGNED64(p) (((uintptr_t) p) % __alignof__(uint64_t) == 0)
|
||
|
+
|
||
|
/* Same as ALIGN_TO but callable in constant contexts. */
|
||
|
#define CONST_ALIGN_TO(l, ali) \
|
||
|
__builtin_choose_expr( \
|
||
|
diff --git a/src/test/test-macro.c b/src/test/test-macro.c
|
||
|
index bb79ea0dbe..a1618c3105 100644
|
||
|
--- a/src/test/test-macro.c
|
||
|
+++ b/src/test/test-macro.c
|
||
|
@@ -755,4 +755,57 @@ TEST(FOREACH_ARRAY) {
|
||
|
assert_se(n == 0);
|
||
|
}
|
||
|
|
||
|
+TEST(ALIGNED) {
|
||
|
+ assert_se(IS_ALIGNED16(NULL));
|
||
|
+ assert_se(IS_ALIGNED32(NULL));
|
||
|
+ assert_se(IS_ALIGNED64(NULL));
|
||
|
+
|
||
|
+ uint64_t u64;
|
||
|
+ uint32_t u32;
|
||
|
+ uint16_t u16;
|
||
|
+
|
||
|
+ assert_se(IS_ALIGNED16(&u16));
|
||
|
+ assert_se(IS_ALIGNED16(&u32));
|
||
|
+ assert_se(IS_ALIGNED16(&u64));
|
||
|
+ assert_se(IS_ALIGNED32(&u32));
|
||
|
+ assert_se(IS_ALIGNED32(&u64));
|
||
|
+ assert_se(IS_ALIGNED64(&u64));
|
||
|
+
|
||
|
+ _align_(32) uint8_t ua256;
|
||
|
+ _align_(8) uint8_t ua64;
|
||
|
+ _align_(4) uint8_t ua32;
|
||
|
+ _align_(2) uint8_t ua16;
|
||
|
+
|
||
|
+ assert_se(IS_ALIGNED16(&ua256));
|
||
|
+ assert_se(IS_ALIGNED32(&ua256));
|
||
|
+ assert_se(IS_ALIGNED64(&ua256));
|
||
|
+
|
||
|
+ assert_se(IS_ALIGNED16(&ua64));
|
||
|
+ assert_se(IS_ALIGNED32(&ua64));
|
||
|
+ assert_se(IS_ALIGNED64(&ua64));
|
||
|
+
|
||
|
+ assert_se(IS_ALIGNED16(&ua32));
|
||
|
+ assert_se(IS_ALIGNED32(&ua32));
|
||
|
+
|
||
|
+ assert_se(IS_ALIGNED16(&ua16));
|
||
|
+
|
||
|
+#ifdef __x86_64__
|
||
|
+ /* Conditionalized on x86-64, since there we know for sure that all three types are aligned to
|
||
|
+ * their size. Too lazy to figure it out for other archs */
|
||
|
+ void *p = UINT_TO_PTR(1); /* definitely not aligned */
|
||
|
+ assert_se(!IS_ALIGNED16(p));
|
||
|
+ assert_se(!IS_ALIGNED32(p));
|
||
|
+ assert_se(!IS_ALIGNED64(p));
|
||
|
+
|
||
|
+ assert_se(IS_ALIGNED16(ALIGN2_PTR(p)));
|
||
|
+ assert_se(IS_ALIGNED32(ALIGN4_PTR(p)));
|
||
|
+ assert_se(IS_ALIGNED64(ALIGN8_PTR(p)));
|
||
|
+
|
||
|
+ p = UINT_TO_PTR(-1); /* also definitely not aligned */
|
||
|
+ assert_se(!IS_ALIGNED16(p));
|
||
|
+ assert_se(!IS_ALIGNED32(p));
|
||
|
+ assert_se(!IS_ALIGNED64(p));
|
||
|
+#endif
|
||
|
+}
|
||
|
+
|
||
|
DEFINE_TEST_MAIN(LOG_INFO);
|