OpenAMP Library  86
Loading...
Searching...
No Matches
utilities.h
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2024, STMicroelectronics
5 *
6 */
7
8#include <stdbool.h>
9#include <stdint.h>
10#include <string.h>
11
36size_t safe_strcpy(char *dst, size_t d_size, const char *src, size_t s_size);
37
38/*
39 * Convert an arithmetic operand to uint64_t, rejecting negative values and
40 * values which cannot be represented. This also makes the builtin and
41 * fallback implementations below apply the same input rules.
42 */
43#if defined(__has_builtin)
44#if __has_builtin(__builtin_add_overflow) && \
45 __has_builtin(__builtin_sub_overflow) && \
46 __has_builtin(__builtin_mul_overflow)
47#define OPENAMP_HAVE_BUILTIN_OVERFLOW 1
48#endif
49#endif
50
51#if !defined(OPENAMP_HAVE_BUILTIN_OVERFLOW) && defined(__GNUC__) && \
52 (__GNUC__ >= 5)
53#define OPENAMP_HAVE_BUILTIN_OVERFLOW 1
54#endif
55
56#if defined(OPENAMP_HAVE_BUILTIN_OVERFLOW)
57#define OPENAMP_TO_U64_SAFE(value, out) (__extension__({ \
58 __typeof__(value) __openamp_value = (value); \
59 __builtin_add_overflow(__openamp_value, 0, (out)); \
60}))
61#else
62#define OPENAMP_TO_U64_SAFE(value, out) (__extension__({ \
63 __typeof__(value) __openamp_value = (value); \
64 int __openamp_overflow = 1; \
65 if (__openamp_value == 0 || __openamp_value > 0) { \
66 *(out) = (uint64_t)__openamp_value; \
67 __openamp_overflow = 0; \
68 } \
69 __openamp_overflow; \
70}))
71#endif
72
73#if defined(OPENAMP_HAVE_BUILTIN_OVERFLOW)
74#define OPENAMP_ADD_U64_SAFE(a, b, out) \
75 __builtin_add_overflow((a), (b), (out))
76#define OPENAMP_SUB_U64_SAFE(a, b, out) \
77 __builtin_sub_overflow((a), (b), (out))
78#define OPENAMP_MUL_U64_SAFE(a, b, out) \
79 __builtin_mul_overflow((a), (b), (out))
80#else
81#define OPENAMP_ADD_U64_SAFE(a, b, out) (__extension__({ \
82 __typeof__(out) __openamp_out = (out); \
83 __typeof__(a) __openamp_a = (a); \
84 __typeof__(b) __openamp_b = (b); \
85 uint64_t __openamp_umax = (uint64_t)(__typeof__(*__openamp_out)) \
86 ~(__typeof__(*__openamp_out))0; \
87 int __openamp_overflow = __openamp_a > __openamp_umax || \
88 __openamp_b > __openamp_umax - __openamp_a; \
89 if (!__openamp_overflow) \
90 *__openamp_out = (__typeof__(*__openamp_out)) \
91 (__openamp_a + __openamp_b); \
92 __openamp_overflow; \
93}))
94#define OPENAMP_SUB_U64_SAFE(a, b, out) (__extension__({ \
95 __typeof__(out) __openamp_out = (out); \
96 __typeof__(a) __openamp_a = (a); \
97 __typeof__(b) __openamp_b = (b); \
98 uint64_t __openamp_umax = (uint64_t)(__typeof__(*__openamp_out)) \
99 ~(__typeof__(*__openamp_out))0; \
100 int __openamp_overflow = __openamp_a > __openamp_umax || \
101 __openamp_b > __openamp_umax || __openamp_a < __openamp_b; \
102 if (!__openamp_overflow) \
103 *__openamp_out = (__typeof__(*__openamp_out)) \
104 (__openamp_a - __openamp_b); \
105 __openamp_overflow; \
106}))
107#define OPENAMP_MUL_U64_SAFE(a, b, out) (__extension__({ \
108 __typeof__(out) __openamp_out = (out); \
109 __typeof__(a) __openamp_a = (a); \
110 __typeof__(b) __openamp_b = (b); \
111 uint64_t __openamp_umax = (uint64_t)(__typeof__(*__openamp_out)) \
112 ~(__typeof__(*__openamp_out))0; \
113 int __openamp_overflow = __openamp_a != 0 && \
114 __openamp_b > __openamp_umax / __openamp_a; \
115 if (!__openamp_overflow) \
116 *__openamp_out = (__typeof__(*__openamp_out)) \
117 (__openamp_a * __openamp_b); \
118 __openamp_overflow; \
119}))
120#endif
121
129#define OPENAMP_ADD_SAFE(a, b, out) (__extension__({ \
130 __typeof__(out) __openamp_out = (out); \
131 uint64_t __openamp_a; \
132 uint64_t __openamp_b; \
133 int __openamp_overflow = !__openamp_out || \
134 OPENAMP_TO_U64_SAFE((a), &__openamp_a) || \
135 OPENAMP_TO_U64_SAFE((b), &__openamp_b); \
136 if (!__openamp_overflow) \
137 __openamp_overflow = OPENAMP_ADD_U64_SAFE( \
138 __openamp_a, __openamp_b, __openamp_out); \
139 __openamp_overflow; \
140}))
141
149#define OPENAMP_SUB_SAFE(a, b, out) (__extension__({ \
150 __typeof__(out) __openamp_out = (out); \
151 uint64_t __openamp_a; \
152 uint64_t __openamp_b; \
153 int __openamp_overflow = !__openamp_out || \
154 OPENAMP_TO_U64_SAFE((a), &__openamp_a) || \
155 OPENAMP_TO_U64_SAFE((b), &__openamp_b); \
156 if (!__openamp_overflow) \
157 __openamp_overflow = OPENAMP_SUB_U64_SAFE( \
158 __openamp_a, __openamp_b, __openamp_out); \
159 __openamp_overflow; \
160}))
161
169#define OPENAMP_MUL_SAFE(a, b, out) (__extension__({ \
170 __typeof__(out) __openamp_out = (out); \
171 uint64_t __openamp_a; \
172 uint64_t __openamp_b; \
173 int __openamp_overflow = !__openamp_out || \
174 OPENAMP_TO_U64_SAFE((a), &__openamp_a) || \
175 OPENAMP_TO_U64_SAFE((b), &__openamp_b); \
176 if (!__openamp_overflow) \
177 __openamp_overflow = OPENAMP_MUL_U64_SAFE( \
178 __openamp_a, __openamp_b, __openamp_out); \
179 __openamp_overflow; \
180}))
181
196#define OPENAMP_RANGE_CONTAINS(base, base_len, offset, len, contained) \
197 (__extension__({ \
198 __typeof__(contained) __openamp_contained = (contained); \
199 __typeof__(base) __openamp_base = (base); \
200 __typeof__(base_len) __openamp_base_len = (base_len); \
201 __typeof__(offset) __openamp_offset = (offset); \
202 __typeof__(len) __openamp_len = (len); \
203 size_t __openamp_base_end; \
204 size_t __openamp_end; \
205 int __openamp_range_overflow = !__openamp_contained || \
206 OPENAMP_ADD_SAFE(__openamp_base, __openamp_base_len, \
207 &__openamp_base_end) || \
208 OPENAMP_ADD_SAFE(__openamp_offset, __openamp_len, \
209 &__openamp_end); \
210 if (!__openamp_range_overflow) \
211 *__openamp_contained = __openamp_base <= __openamp_offset && \
212 __openamp_base_end >= __openamp_end; \
213 __openamp_range_overflow; \
214 }))
size_t safe_strcpy(char *dst, size_t d_size, const char *src, size_t s_size)
Definition utilities.c:12