Rizin
unix-like reverse engineering framework and cli tools
rz_types_overflow.h
Go to the documentation of this file.
1 #ifndef RZ_TYPES_OVERFLOW_H
2 #define RZ_TYPES_OVERFLOW_H
3 
4 #include <rz_types.h>
5 
6 // TODO: Use CLANG/GCC builtins if available: __builtin_mul_overflow
7 
8 // ADD
9 // if ((x > 0) && (a > INT_MAX - x)) /* `a + x` would overflow */;
10 // if ((x < 0) && (a < INT_MIN - x)) /* `a + x` would underflow */;
11 #define SZT_ADD_OVFCHK(x, y) ((SIZE_MAX - (x)) < (y))
12 #define SSZT_ADD_OVFCHK(a, x) ((((x) > 0) && ((a) > SSIZE_MAX - (x))) || (((x) < 0) && (a) < SSIZE_MIN - (x)))
13 #define UT64_ADD_OVFCHK(x, y) ((UT64_MAX - (x)) < (y))
14 #define ST64_ADD_OVFCHK(a, x) ((((x) > 0) && ((a) > ST64_MAX - (x))) || (((x) < 0) && (a) < ST64_MIN - (x)))
15 #define UT32_ADD_OVFCHK(x, y) ((UT32_MAX - (x)) < (y))
16 #define ST32_ADD_OVFCHK(a, x) ((((x) > 0) && ((a) > ST32_MAX - (x))) || (((x) < 0) && (a) < ST32_MIN - (x)))
17 #define UT16_ADD_OVFCHK(x, y) ((UT16_MAX - (x)) < (y))
18 #define ST16_ADD_OVFCHK(a, b) ((((b) > 0) && ((a) > ST16_MAX - (b))) || (((b) < 0) && ((a) < ST16_MIN - (b))))
19 #define UT8_ADD_OVFCHK(x, y) ((UT8_MAX - (x)) < (y))
20 #define ST8_ADD_OVFCHK(a, x) ((((x) > 0) && ((a) > ST8_MAX - (x))) || ((x) < 0 && (a) < ST8_MIN - (x)))
21 
22 // SUB
23 // if ((x < 0) && (a > INT_MAX + x)) /* `a - x` would overflow */;
24 // if ((x > 0) && (a < INT_MIN + x)) /* `a - x` would underflow */;
25 #define SZT_SUB_OVFCHK(a, b) SZT_ADD_OVFCHK(a, -(b))
26 #define SSZT_SUB_OVFCHK(a, b) SSZT_ADD_OVFCHK(a, -(b))
27 #define UT64_SUB_OVFCHK(a, b) UT64_ADD_OVFCHK(a, -(b))
28 #define ST64_SUB_OVFCHK(a, b) ST64_ADD_OVFCHK(a, -(b))
29 #define UT32_SUB_OVFCHK(a, b) UT32_ADD_OVFCHK(a, -(b))
30 #define ST32_SUB_OVFCHK(a, b) ST32_ADD_OVFCHK(a, -(b))
31 #define UT16_SUB_OVFCHK(a, b) UT16_ADD_OVFCHK(a, -(b))
32 #define ST16_SUB_OVFCHK(a, b) ST16_ADD_OVFCHK(a, -(b))
33 #define UT8_SUB_OVFCHK(a, b) UT8_ADD_OVFCHK(a, -(b))
34 #define ST8_SUB_OVFCHK(a, b) ST8_ADD_OVFCHK(a, -(b))
35 
36 // MUL
37 #define UNSIGNED_MUL_OVERFLOW_CHECK(overflow_name, type_base, type_min, type_max) \
38  static inline bool overflow_name(type_base a, type_base b) { \
39  return (a > 0 && b > 0 && a > type_max / b); \
40  }
41 
42 #define SIGNED_MUL_OVERFLOW_CHECK(overflow_name, type_base, type_min, type_max) \
43  static inline bool overflow_name(type_base a, type_base b) { \
44  if (a > 0) { \
45  if (b > 0) { \
46  return a > type_max / b; \
47  } \
48  return b < type_min / a; \
49  } \
50  if (b > 0) { \
51  return a < type_min / b; \
52  } \
53  return a && b < type_max / a; \
54  }
55 
56 #define SIGNED_DIV_OVERFLOW_CHECK(overflow_name, type_base, type_mid, type_max) \
57  static inline bool overflow_name(type_base a, type_base b) { \
58  return (!b || (a == type_mid && b == type_max)); \
59  }
60 #define UNSIGNED_DIV_OVERFLOW_CHECK(overflow_name, type_base, type_min, type_max) \
61  static inline bool overflow_name(type_base a, type_base b) { \
62  (void)a; \
63  return !b; \
64  }
65 
74 // TODO: Windows doesn't have ssize_t, and we don't need this check yet
75 // SIGNED_MUL_OVERFLOW_CHECK(SSZT_MUL_OVFCHK, ssize_t, SSZT_MIN, SSZT_MAX)
80 UNSIGNED_MUL_OVERFLOW_CHECK(SZT_MUL_OVFCHK, size_t, SZT_MIN, SZT_MAX)
85 
86 #endif
uint16_t ut16
uint32_t ut32
uint8_t ut8
Definition: lh5801.h:11
#define ST16_MAX
#define UT64_GT0
Definition: rz_types_base.h:87
#define UT8_MIN
#define st8
Definition: rz_types_base.h:16
#define UT32_GT0
Definition: rz_types_base.h:95
#define ST8_MIN
#define UT8_GT0
#define ST64_MIN
Definition: rz_types_base.h:85
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99
#define ST32_MAX
Definition: rz_types_base.h:97
#define UT64_MAX
Definition: rz_types_base.h:86
#define UT8_MAX
#define UT64_MIN
Definition: rz_types_base.h:89
#define UT16_MIN
Definition: rz_types_base.h:94
#define UT32_MIN
Definition: rz_types_base.h:93
#define UT16_GT0
#define SZT_MAX
#define ST32_MIN
Definition: rz_types_base.h:98
#define st16
Definition: rz_types_base.h:14
#define SZT_MIN
#define st32
Definition: rz_types_base.h:12
#define UT16_MAX
#define ST8_MAX
#define ST64_MAX
Definition: rz_types_base.h:84
#define ST16_MIN
#define UNSIGNED_MUL_OVERFLOW_CHECK(overflow_name, type_base, type_min, type_max)
#define SIGNED_DIV_OVERFLOW_CHECK(overflow_name, type_base, type_mid, type_max)
#define UNSIGNED_DIV_OVERFLOW_CHECK(overflow_name, type_base, type_min, type_max)
#define SIGNED_MUL_OVERFLOW_CHECK(overflow_name, type_base, type_min, type_max)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()