summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2023-12-06 17:07:01 -0500
committerPeter Jones <pjones@redhat.com>2024-01-22 14:17:20 -0500
commit13abd9f51b285db7eb46bf375cae623bf1153404 (patch)
tree968a7aa0a95c36a919b2261b32327d758e063760
parentbe8ff7c2680fed067cdd76df0afc43138c24cc0d (diff)
downloadefi-boot-shim-13abd9f51b285db7eb46bf375cae623bf1153404.tar.gz
efi-boot-shim-13abd9f51b285db7eb46bf375cae623bf1153404.zip
pe-relocate: Avoid __builtin_add_overflow() on GCC < 5
GCC 4 doesn't have __builtin_add_overflow() and friends, so this results in a compiler error. On platforms using that version, do the arithmetic without it. Signed-off-by: Peter Jones <pjones@redhat.com>
-rw-r--r--include/compiler.h34
-rw-r--r--pe-relocate.c2
2 files changed, 35 insertions, 1 deletions
diff --git a/include/compiler.h b/include/compiler.h
index 545a72e5..8e8a658d 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -198,12 +198,46 @@
#error shim has no cache_invalidate() implementation for this compiler
#endif /* __GNUC__ */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define GNUC_PREREQ(maj, min) 0
+#endif
+
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define CLANG_PREREQ(maj, min) \
+ ((__clang_major__ > (maj)) || \
+ (__clang_major__ == (maj) && __clang_minor__ >= (min)))
+#else
+#define CLANG_PREREQ(maj, min) 0
+#endif
+
+#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8)
#define checked_add(addend0, addend1, sum) \
__builtin_add_overflow(addend0, addend1, sum)
#define checked_sub(minuend, subtrahend, difference) \
__builtin_sub_overflow(minuend, subtrahend, difference)
#define checked_mul(factor0, factor1, product) \
__builtin_mul_overflow(factor0, factor1, product)
+#else
+#define checked_add(a0, a1, s) \
+ ({ \
+ (*s) = ((a0) + (a1)); \
+ 0; \
+ })
+#define checked_sub(s0, s1, d) \
+ ({ \
+ (*d) = ((s0) - (s1)); \
+ 0; \
+ })
+#define checked_mul(f0, f1, p) \
+ ({ \
+ (*p) = ((f0) * (f1)); \
+ 0; \
+ })
+#endif
+
#define checked_div(dividend, divisor, quotient) \
({ \
bool _ret = True; \
diff --git a/pe-relocate.c b/pe-relocate.c
index d399cdf1..bde71729 100644
--- a/pe-relocate.c
+++ b/pe-relocate.c
@@ -20,7 +20,7 @@ ImageAddress (void *image, uint64_t size, uint64_t address)
/* Insure our math won't overflow */
img_addr = (uintptr_t)image;
- if (__builtin_add_overflow(img_addr, address, &img_addr))
+ if (checked_add(img_addr, address, &img_addr))
return NULL;
/* return the absolute pointer */