Blame SOURCES/0036-util.h-implement-add-mul-sub-for-more-integer-types.patch

d5c737
From 73635c7e096eb36b52c1e874f9b76856c6a41228 Mon Sep 17 00:00:00 2001
d5c737
From: Peter Jones <pjones@redhat.com>
d5c737
Date: Mon, 17 Jun 2019 16:37:29 -0400
d5c737
Subject: [PATCH 36/63] util.h: implement add()/mul()/sub() for more integer
d5c737
 types.
d5c737
d5c737
This adds the following:
d5c737
uint_add()
d5c737
uint_mul()
d5c737
uint_sub()
d5c737
long_sub()
d5c737
ulong_sub()
d5c737
d5c737
Additionally it renames ulong_mult() to ulong_mul() and long_mult() to
d5c737
long_mul().
d5c737
d5c737
As before, all of these are available without caring about the types,
d5c737
as if declared:
d5c737
d5c737
bool add(TYPE addend, TYPE addend, TYPE *sum);
d5c737
bool mul(TYPE factor, TYPE factor, TYPE *product);
d5c737
bool sub(TYPE minuend, TYPE subtractahend, TYPE *difference);
d5c737
d5c737
If overflow would occur, the pointer target for the result is not
d5c737
changed and the function returns true, otherwise it returns false.
d5c737
d5c737
Signed-off-by: Peter Jones <pjones@redhat.com>
d5c737
---
d5c737
 src/efivar.h   |   1 +
d5c737
 src/safemath.h | 208 +++++++++++++++++++++++++++++++++++++++++++++++++
d5c737
 src/util.h     |  96 -----------------------
d5c737
 3 files changed, 209 insertions(+), 96 deletions(-)
d5c737
 create mode 100644 src/safemath.h
d5c737
d5c737
diff --git a/src/efivar.h b/src/efivar.h
d5c737
index 3d4b429631e..646863d14c5 100644
d5c737
--- a/src/efivar.h
d5c737
+++ b/src/efivar.h
d5c737
@@ -23,6 +23,7 @@
d5c737
 #include <efivar/efivar.h>
d5c737
 
d5c737
 #include "util.h"
d5c737
+#include "safemath.h"
d5c737
 #include "efivar_endian.h"
d5c737
 #include "lib.h"
d5c737
 #include "guid.h"
d5c737
diff --git a/src/safemath.h b/src/safemath.h
d5c737
new file mode 100644
d5c737
index 00000000000..08dfef7ec0b
d5c737
--- /dev/null
d5c737
+++ b/src/safemath.h
d5c737
@@ -0,0 +1,208 @@
d5c737
+/*
d5c737
+ * safemath.h
d5c737
+ * Copyright 2016-2019 Peter Jones <pjones@redhat.com>
d5c737
+ *
d5c737
+ * This library is free software; you can redistribute it and/or
d5c737
+ * modify it under the terms of the GNU Lesser General Public License as
d5c737
+ * published by the Free Software Foundation; either version 2.1 of the
d5c737
+ * License, or (at your option) any later version.
d5c737
+ *
d5c737
+ * This library is distributed in the hope that it will be useful,
d5c737
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
d5c737
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
d5c737
+ * Lesser General Public License for more details.
d5c737
+ *
d5c737
+ * You should have received a copy of the GNU Lesser General Public
d5c737
+ * License along with this library; if not, see
d5c737
+ * <http://www.gnu.org/licenses/>.
d5c737
+ *
d5c737
+ */
d5c737
+
d5c737
+#ifndef SAFEMATH_H_
d5c737
+#define SAFEMATH_H_
d5c737
+
d5c737
+/*
d5c737
+ * I'm not actually sure when these appear, but they're present in the
d5c737
+ * version in front of me.
d5c737
+ */
d5c737
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
d5c737
+#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
d5c737
+#define int_add(a, b, c) __builtin_add_overflow(a, b, c)
d5c737
+#define uint_add(a, b, c) __builtin_add_overflow(a, b, c)
d5c737
+#define long_add(a, b, c) __builtin_add_overflow(a, b, c)
d5c737
+#define ulong_add(a, b, c) __builtin_add_overflow(a, b, c)
d5c737
+
d5c737
+#define int_mul(a, b, c) __builtin_mul_overflow(a, b, c)
d5c737
+#define uint_mul(a, b, c) __builtin_mul_overflow(a, b, c)
d5c737
+#define long_mul(a, b, c) __builtin_mul_overflow(a, b, c)
d5c737
+#define ulong_mul(a, b, c) __builtin_mul_overflow(a, b, c)
d5c737
+
d5c737
+#define int_sub(a, b, c) __builtin_sub_overflow(a, b, c)
d5c737
+#define uint_sub(a, b, c) __builtin_sub_overflow(a, b, c)
d5c737
+#define long_sub(a, b, c) __builtin_sub_overflow(a, b, c)
d5c737
+#define ulong_sub(a, b, c) __builtin_sub_overflow(a, b, c)
d5c737
+#endif
d5c737
+#endif
d5c737
+
d5c737
+#ifndef int_add
d5c737
+#define int_add(a, b, c) ({					\
d5c737
+		const int _limit = INT_MAX;			\
d5c737
+		long int _ret = _limit - (a);			\
d5c737
+		_ret = _ret > (b);				\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) + (b));			\
d5c737
+		(bool)_ret;					\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef uint_add
d5c737
+#define uint_add(a, b, c) ({					\
d5c737
+		const unsigned int _limit = UINT_MAX;		\
d5c737
+		unsigned int _ret = _limit - (a);		\
d5c737
+		_ret = _ret > (b);				\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) + (b));			\
d5c737
+		(bool)_ret;					\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef long_add
d5c737
+#define long_add(a, b, c) ({					\
d5c737
+		const long _limit = LONG_MAX;			\
d5c737
+		long _ret = _limit - (a);			\
d5c737
+		_ret = _ret > (b);				\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) + (b));			\
d5c737
+		(bool)_ret;					\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef ulong_add
d5c737
+#define ulong_add(a, b, c) ({					\
d5c737
+		const unsigned long _limit = ULONG_MAX;		\
d5c737
+		unsigned long _ret = _limit - (a);		\
d5c737
+		_ret = _ret > (b);				\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) + (b));			\
d5c737
+		(bool)_ret;					\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef int_mul
d5c737
+#define int_mul(a, b, c) ({						\
d5c737
+		int _ret;						\
d5c737
+		_ret = __builtin_popcount(a) + __builtin_popcount(b);	\
d5c737
+		_ret = _ret < ((sizeof(a) + sizeof(b)) << 4);		\
d5c737
+		if (!_ret)						\
d5c737
+			*(c) = ((a) * (b));				\
d5c737
+		(bool)_ret;						\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef uint_mul
d5c737
+#define uint_mul(a, b, c) int_mul(a, b, c)
d5c737
+#endif
d5c737
+
d5c737
+#ifndef long_mul
d5c737
+#define long_mul(a, b, c) int_mul(a, b, c)
d5c737
+#endif
d5c737
+
d5c737
+#ifndef ulong_mul
d5c737
+#define ulong_mul(a, b, c) int_mul(a, b, c)
d5c737
+#endif
d5c737
+
d5c737
+#ifndef int_sub
d5c737
+#define int_sub(a, b, c) ({					\
d5c737
+		const long _min_limit = INT_MIN;		\
d5c737
+		const long _max_limit = INT_MAX;		\
d5c737
+		int _ret;					\
d5c737
+		_ret = _min_limit + (b);			\
d5c737
+		_ret = !(_ret < (a));				\
d5c737
+		if (!_ret) {					\
d5c737
+			_ret = _max_limit - (a);		\
d5c737
+			_ret = _ret > (b);			\
d5c737
+		}						\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) - (b));			\
d5c737
+		(bool)_ret;					\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef uint_sub
d5c737
+#define uint_sub(a, b, c) ({					\
d5c737
+		const unsigned int _limit = UINT_MAX;		\
d5c737
+		unsigned int _ret = _limit - (a);		\
d5c737
+		_ret = _ret > (b);				\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) - (b));			\
d5c737
+		(bool)_ret;					\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef long_sub
d5c737
+#define long_sub(a, b, c) ({					\
d5c737
+		const long _min_limit = LONG_MIN;		\
d5c737
+		const long _max_limit = LONG_MAX;		\
d5c737
+		int _ret;					\
d5c737
+		_ret = _min_limit + (b);			\
d5c737
+		_ret = !(_ret < (a));				\
d5c737
+		if (!_ret) {					\
d5c737
+			_ret = _max_limit - (a);		\
d5c737
+			_ret = _ret > (b);			\
d5c737
+		}						\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) - (b));			\
d5c737
+		(bool)_ret;					\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#ifndef ulong_sub
d5c737
+#define ulong_sub(a, b, c) ({					\
d5c737
+		const unsigned long _limit = ULONG_MAX;		\
d5c737
+		unsigned long _ret = _limit - (a);		\
d5c737
+		_ret = _ret > (b);				\
d5c737
+		if (!_ret)					\
d5c737
+			*(c) = ((a) - (b));			\
d5c737
+		_ret;						\
d5c737
+	})
d5c737
+#endif
d5c737
+
d5c737
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
d5c737
+#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
d5c737
+#define add(a, b, c) _Generic((c),					\
d5c737
+			      int *: int_add(a, b, c),			\
d5c737
+			      unsigned int *: uint_add(a, b, c),	\
d5c737
+			      long *: long_add(a, b, c),		\
d5c737
+			      unsigned long *: ulong_add(a, b, c))
d5c737
+#define sub(a, b, c) _Generic((c),					\
d5c737
+			      int *: int_sub(a, b, c),			\
d5c737
+			      unsigned int *: uint_sub(a, b, c),	\
d5c737
+			      long *: long_sub(a, b, c),		\
d5c737
+			      unsigned long *: ulong_sub(a, b, c))
d5c737
+#define mul(a, b, c) _Generic((c),					\
d5c737
+			      int *: int_sub(a, b, c),			\
d5c737
+			      unsigned int *: uint_mul(a, b, c),	\
d5c737
+			      long *: long_mul(a, b, c),		\
d5c737
+			      unsigned long *: ulong_mul(a, b, c))
d5c737
+#endif
d5c737
+#endif
d5c737
+
d5c737
+#ifndef add
d5c737
+#define add(a, b, c) ({						\
d5c737
+		(*(c)) = ((a) + (b));				\
d5c737
+		})
d5c737
+#endif
d5c737
+#ifndef mul
d5c737
+#define mul(a, b, c) ({						\
d5c737
+		(*(c)) = ((a) * (b));				\
d5c737
+		})
d5c737
+#endif
d5c737
+#ifndef sub
d5c737
+#define sub(a, b, c) ({						\
d5c737
+		(*(c)) = ((a) - (b));				\
d5c737
+		})
d5c737
+#endif
d5c737
+
d5c737
+
d5c737
+#endif /* !SAFEMATH_H_ */
d5c737
+// vim:fenc=utf-8:tw=75:noet
d5c737
diff --git a/src/util.h b/src/util.h
d5c737
index 712abea2d42..3f68d812700 100644
d5c737
--- a/src/util.h
d5c737
+++ b/src/util.h
d5c737
@@ -61,102 +61,6 @@
d5c737
 #define unlikely(x) (__branch_check__(x, 0, __builtin_constant_p(x)))
d5c737
 #endif
d5c737
 
d5c737
-/*
d5c737
- * I'm not actually sure when these appear, but they're present in the
d5c737
- * version in front of me.
d5c737
- */
d5c737
-#if defined(__GNUC__) && defined(__GNUC_MINOR__)
d5c737
-#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
d5c737
-#define int_add(a, b, c) __builtin_add_overflow(a, b, c)
d5c737
-#define long_add(a, b, c) __builtin_add_overflow(a, b, c)
d5c737
-#define long_mult(a, b, c) __builtin_mul_overflow(a, b, c)
d5c737
-#define ulong_add(a, b, c) __builtin_add_overflow(a, b, c)
d5c737
-#define ulong_mult(a, b, c) __builtin_mul_overflow(a, b, c)
d5c737
-#endif
d5c737
-#endif
d5c737
-#ifndef int_add
d5c737
-#define int_add(a, b, c) ({					\
d5c737
-		const int _limit = INT_MAX;			\
d5c737
-		int _ret;					\
d5c737
-		_ret = _limit - ((unsigned long long)a) >	\
d5c737
-			  ((unsigned long long)b);		\
d5c737
-		if (!_ret)					\
d5c737
-			*(c) = ((a) + (b));			\
d5c737
-		_ret;						\
d5c737
-	})
d5c737
-#endif
d5c737
-#ifndef long_add
d5c737
-#define long_add(a, b, c) ({					\
d5c737
-		const long _limit = LONG_MAX;			\
d5c737
-		int _ret;					\
d5c737
-		_ret = _limit - ((unsigned long long)a) >	\
d5c737
-			   ((unsigned long long)b);		\
d5c737
-		if (!_ret)					\
d5c737
-			*(c) = ((a) + (b));			\
d5c737
-		_ret;						\
d5c737
-	})
d5c737
-#endif
d5c737
-#ifndef long_mult
d5c737
-#define long_mult(a, b, c) ({					\
d5c737
-		const long _limit = LONG_MAX;			\
d5c737
-		int _ret = 1;					\
d5c737
-		if ((a) == 0 || (b) == 0)			\
d5c737
-			_ret = 0;				\
d5c737
-		else						\
d5c737
-			_ret = _limit / (a) < (b);		\
d5c737
-		if (!_ret)					\
d5c737
-			*(c) = ((a) * (b));			\
d5c737
-		_ret;						\
d5c737
-	})
d5c737
-#endif
d5c737
-#ifndef ulong_add
d5c737
-#define ulong_add(a, b, c) ({					\
d5c737
-		const unsigned long _limit = ULONG_MAX;		\
d5c737
-		int _ret;					\
d5c737
-		_ret = _limit - ((unsigned long long)a) >	\
d5c737
-			    ((unsigned long long)b);		\
d5c737
-		if (!_ret)					\
d5c737
-			*(c) = ((a) + (b));			\
d5c737
-		_ret;						\
d5c737
-	})
d5c737
-#endif
d5c737
-#ifndef ulong_mult
d5c737
-#define ulong_mult(a, b, c) ({					\
d5c737
-		const unsigned long _limit = ULONG_MAX;		\
d5c737
-		int _ret = 1;					\
d5c737
-		if ((a) == 0 || (b) == 0)			\
d5c737
-			_ret = 0;				\
d5c737
-		else						\
d5c737
-			_ret = _limit / (a) < (b);		\
d5c737
-		if (!_ret)					\
d5c737
-			*(c) = ((a) * (b));			\
d5c737
-		_ret;						\
d5c737
-	})
d5c737
-#endif
d5c737
-
d5c737
-#if defined(__GNUC__) && defined(__GNUC_MINOR__)
d5c737
-#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
d5c737
-#define add(a, b, c) _Generic((c),				\
d5c737
-			      int *: int_add(a,b,c),		\
d5c737
-			      long *: long_add(a,b,c),		\
d5c737
-			      unsigned long *: ulong_add(a,b,c))
d5c737
-#define mult(a, b, c) _Generic((c),				\
d5c737
-			      long *: long_mult(a,b,c),		\
d5c737
-			      unsigned long *: ulong_mult(a,b,c))
d5c737
-#endif
d5c737
-#endif
d5c737
-
d5c737
-#ifndef add
d5c737
-#define add(a, b, c) ({						\
d5c737
-		(*(c)) = ((a) + (b));				\
d5c737
-		})
d5c737
-#endif
d5c737
-#ifndef mult
d5c737
-#define mult(a, b, c) ({					\
d5c737
-		(*(c)) = ((a) * (b));				\
d5c737
-		})
d5c737
-#endif
d5c737
-
d5c737
 static inline int UNUSED
d5c737
 read_file(int fd, uint8_t **result, size_t *bufsize)
d5c737
 {
d5c737
-- 
d5c737
2.26.2
d5c737