[RFC PATCH mtd-utils 019/110] ubifs-utils: Add compiler attributes implementations

From: Zhihao Cheng
Date: Fri Jun 07 2024 - 00:30:04 EST


Add compiler attributes implementations, such as __packed, __unused,
__const, etc., which could be used in linux kernel libs. Besides, change
some existing attributes into linux kernel style.

This is a preparation for replacing implementation of UBIFS utils with
linux kernel libs.

Signed-off-by: Zhihao Cheng <chengzhihao1@xxxxxxxxxx>
---
ubifs-utils/Makemodule.am | 1 +
ubifs-utils/common/compiler_attributes.h | 79 ++++++++++++++++++++++++++++++++
ubifs-utils/common/fscrypt.h | 6 ++-
ubifs-utils/common/sign.c | 4 +-
4 files changed, 86 insertions(+), 4 deletions(-)
create mode 100644 ubifs-utils/common/compiler_attributes.h

diff --git a/ubifs-utils/Makemodule.am b/ubifs-utils/Makemodule.am
index 90cc7005..d58570fe 100644
--- a/ubifs-utils/Makemodule.am
+++ b/ubifs-utils/Makemodule.am
@@ -1,4 +1,5 @@
common_SOURCES = \
+ ubifs-utils/common/compiler_attributes.h \
ubifs-utils/common/defs.h \
ubifs-utils/common/crc16.h \
ubifs-utils/common/crc16.c \
diff --git a/ubifs-utils/common/compiler_attributes.h b/ubifs-utils/common/compiler_attributes.h
new file mode 100644
index 00000000..bb65d3a9
--- /dev/null
+++ b/ubifs-utils/common/compiler_attributes.h
@@ -0,0 +1,79 @@
+#ifndef __COMPILER_ATTRIBUTES_H__
+#define __COMPILER_ATTRIBUTES_H__
+
+#if __has_attribute(__fallthrough__)
+#define fallthrough __attribute__((__fallthrough__))
+#else
+#define fallthrough do {} while (0)
+#endif
+
+#define __packed __attribute__((__packed__))
+#define __unused __attribute__((__unused__))
+#define __const __attribute__((__const__))
+#define __must_check __attribute__((__warn_unused_result__))
+#ifndef __force
+#define __force
+#endif
+
+/*
+ * Optional: only supported since clang >= 14.0
+ *
+ * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-error-function-attribute
+ */
+#if __has_attribute(__error__)
+# define __compiletime_error(msg) __attribute__((__error__(msg)))
+#else
+# define __compiletime_error(msg)
+#endif
+
+#ifndef __compiletime_error
+# define __compiletime_error(message)
+#endif
+
+#ifdef __OPTIMIZE__
+# define __compiletime_assert(condition, msg, prefix, suffix) \
+ do { \
+ extern void prefix ## suffix(void) __compiletime_error(msg); \
+ if (!(condition)) \
+ prefix ## suffix(); \
+ } while (0)
+#else
+# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
+#endif
+
+#define _compiletime_assert(condition, msg, prefix, suffix) \
+ __compiletime_assert(condition, msg, prefix, suffix)
+
+/**
+ * compiletime_assert - break build and emit msg if condition is false
+ * @condition: a compile-time constant condition to check
+ * @msg: a message to emit if condition is false
+ *
+ * In tradition of POSIX assert, this macro will break the build if the
+ * supplied condition is *false*, emitting the supplied error message if the
+ * compiler has support to do so.
+ */
+#define compiletime_assert(condition, msg) \
+ _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
+
+/**
+ * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
+ * error message.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * See BUILD_BUG_ON for description.
+ */
+#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
+
+/**
+ * BUILD_BUG_ON - break compile if a condition is true.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * If you have some code which relies on certain constants being equal, or
+ * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
+ * detect if someone changes it.
+ */
+#define BUILD_BUG_ON(condition) \
+ BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
+
+#endif
diff --git a/ubifs-utils/common/fscrypt.h b/ubifs-utils/common/fscrypt.h
index 908a5041..b8a599de 100644
--- a/ubifs-utils/common/fscrypt.h
+++ b/ubifs-utils/common/fscrypt.h
@@ -25,6 +25,8 @@
#include <openssl/rand.h>
#endif
#include <assert.h>
+
+#include "compiler_attributes.h"
#include "ubifs.h"
#include "crypto.h"

@@ -79,7 +81,7 @@ struct fscrypt_context {
__u8 flags;
__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
-} __attribute__((packed));
+} __packed;

/**
* For encrypted symlinks, the ciphertext length is stored at the beginning
@@ -88,7 +90,7 @@ struct fscrypt_context {
struct fscrypt_symlink_data {
__le16 len;
char encrypted_path[1];
-} __attribute__((packed));
+} __packed;


#ifndef FS_MAX_KEY_SIZE
diff --git a/ubifs-utils/common/sign.c b/ubifs-utils/common/sign.c
index 9c53e671..7530503a 100644
--- a/ubifs-utils/common/sign.c
+++ b/ubifs-utils/common/sign.c
@@ -28,6 +28,7 @@
#include <openssl/conf.h>
#include <err.h>

+#include "compiler_attributes.h"
#include "sign.h"
#include "defs.h"
#include "ubifs.h"
@@ -116,8 +117,7 @@ static void drain_openssl_errors(void)

static const char *key_pass;

-static int pem_pw_cb(char *buf, int len, __attribute__((unused)) int w,
- __attribute__((unused)) void *v)
+static int pem_pw_cb(char *buf, int len, __unused int w, __unused void *v)
{
int pwlen;

--
2.13.6