Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10393
-gerrit
commit 8038999a29f6740d0bd1d67fd0757594897cdb20 Author: Julius Werner jwerner@chromium.org Date: Fri May 22 18:09:48 2015 -0700
Make common macros double-evaluation-safe
Our MIN(), MAX() and ALIGN*() macros are currently vulnerable to double-evaluation (e.g. x = ALIGN_UP(y, big_func_with_side_effects(y)); doesn't do what you'd think it should). GCC (and mostly GCC-compatible compilers like clang) long had the statement expression and typeof() extensions to deal with problems like this. We should use them.
BRANCH=None BUG=None TEST=None
Change-Id: I4cc368a2f9966139c988257afc013151cd90c7ab Signed-off-by: Patrick Georgi pgeorgi@chromium.org Original-Commit-Id: 985abba1a9b8fa659a9f40e224f81266d7e542bb Original-Change-Id: I2519d552b67096c9277c5206964f83dda97c8d01 Original-Signed-off-by: Julius Werner jwerner@chromium.org Original-Reviewed-on: https://chromium-review.googlesource.com/273009 Original-Reviewed-by: Patrick Georgi pgeorgi@chromium.org --- payloads/libpayload/include/libpayload.h | 12 ++++++++++-- payloads/libpayload/include/stdlib.h | 6 +++++- src/include/stdlib.h | 18 +++++++++++++++--- 3 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index 781a41d..198f4f2 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -62,8 +62,16 @@ #include <lar.h> #endif
-#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ({ \ + typeof(a) _a = a; \ + typeof(b) _b = b; \ + _a < _b ? _a : _b; \ +}) +#define MAX(a, b) ({ \ + typeof(a) _a = a; \ + typeof(b) _b = b; \ + _a > _b ? _a : _b; \ +}) #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static inline u32 div_round_up(u32 n, u32 d) { return n + d - 1 / d; } diff --git a/payloads/libpayload/include/stdlib.h b/payloads/libpayload/include/stdlib.h index 08c7d06..71610c1 100644 --- a/payloads/libpayload/include/stdlib.h +++ b/payloads/libpayload/include/stdlib.h @@ -35,8 +35,12 @@ #include <stddef.h> #include <string.h>
+#define __ALIGN_MASK(x, mask) ({ \ + typeof(mask) _mask = mask; \ + ((x) + _mask) & ~_mask; \ +}) + #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1UL) -#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) #define ALIGN_UP(x,a) ALIGN((x),(a)) #define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) #define IS_ALIGNED(x,a) (((x) & ((typeof(x))(a)-1UL)) == 0) diff --git a/src/include/stdlib.h b/src/include/stdlib.h index 35e8b32..37ed6ef 100644 --- a/src/include/stdlib.h +++ b/src/include/stdlib.h @@ -5,14 +5,26 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#define __ALIGN_MASK(x, mask) ({ \ + typeof(mask) _mask = mask; \ + ((x) + _mask) & ~_mask; \ +}) + #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1UL) -#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) #define ALIGN_UP(x,a) ALIGN((x),(a)) #define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) #define IS_ALIGNED(x,a) (((x) & ((typeof(x))(a)-1UL)) == 0)
-#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ({ \ + typeof(a) _a = a; \ + typeof(b) _b = b; \ + _a < _b ? _a : _b; \ +}) +#define MAX(a, b) ({ \ + typeof(a) _a = a; \ + typeof(b) _b = b; \ + _a > _b ? _a : _b; \ +}) #define ABS(a) (((a) < 0) ? (-(a)) : (a)) #define CEIL_DIV(a, b) (((a) + (b) - 1) / (b)) #define IS_POWER_OF_2(x) (((x) & ((x) - 1)) == 0)