xref: /openbmc/u-boot/lib/libavb/avb_util.h (revision 4ac5df4b)
1*897a1d94STom Rini /* SPDX-License-Identifier: MIT */
2d8f9d2afSIgor Opaniuk /*
3d8f9d2afSIgor Opaniuk  * Copyright (C) 2016 The Android Open Source Project
4d8f9d2afSIgor Opaniuk  */
5d8f9d2afSIgor Opaniuk 
6d8f9d2afSIgor Opaniuk #if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
7d8f9d2afSIgor Opaniuk #error "Never include this file directly, include libavb.h instead."
8d8f9d2afSIgor Opaniuk #endif
9d8f9d2afSIgor Opaniuk 
10d8f9d2afSIgor Opaniuk #ifndef AVB_UTIL_H_
11d8f9d2afSIgor Opaniuk #define AVB_UTIL_H_
12d8f9d2afSIgor Opaniuk 
13d8f9d2afSIgor Opaniuk #include "avb_sysdeps.h"
14d8f9d2afSIgor Opaniuk 
15d8f9d2afSIgor Opaniuk #ifdef __cplusplus
16d8f9d2afSIgor Opaniuk extern "C" {
17d8f9d2afSIgor Opaniuk #endif
18d8f9d2afSIgor Opaniuk 
19d8f9d2afSIgor Opaniuk #define AVB_STRINGIFY(x) #x
20d8f9d2afSIgor Opaniuk #define AVB_TO_STRING(x) AVB_STRINGIFY(x)
21d8f9d2afSIgor Opaniuk 
22d8f9d2afSIgor Opaniuk #ifdef AVB_ENABLE_DEBUG
23d8f9d2afSIgor Opaniuk /* Aborts the program if |expr| is false.
24d8f9d2afSIgor Opaniuk  *
25d8f9d2afSIgor Opaniuk  * This has no effect unless AVB_ENABLE_DEBUG is defined.
26d8f9d2afSIgor Opaniuk  */
27d8f9d2afSIgor Opaniuk #define avb_assert(expr)                     \
28d8f9d2afSIgor Opaniuk   do {                                       \
29d8f9d2afSIgor Opaniuk     if (!(expr)) {                           \
30d8f9d2afSIgor Opaniuk       avb_fatal("assert fail: " #expr "\n"); \
31d8f9d2afSIgor Opaniuk     }                                        \
32d8f9d2afSIgor Opaniuk   } while (0)
33d8f9d2afSIgor Opaniuk #else
34d8f9d2afSIgor Opaniuk #define avb_assert(expr)
35d8f9d2afSIgor Opaniuk #endif
36d8f9d2afSIgor Opaniuk 
37d8f9d2afSIgor Opaniuk /* Aborts the program if reached.
38d8f9d2afSIgor Opaniuk  *
39d8f9d2afSIgor Opaniuk  * This has no effect unless AVB_ENABLE_DEBUG is defined.
40d8f9d2afSIgor Opaniuk  */
41d8f9d2afSIgor Opaniuk #ifdef AVB_ENABLE_DEBUG
42d8f9d2afSIgor Opaniuk #define avb_assert_not_reached()         \
43d8f9d2afSIgor Opaniuk   do {                                   \
44d8f9d2afSIgor Opaniuk     avb_fatal("assert_not_reached()\n"); \
45d8f9d2afSIgor Opaniuk   } while (0)
46d8f9d2afSIgor Opaniuk #else
47d8f9d2afSIgor Opaniuk #define avb_assert_not_reached()
48d8f9d2afSIgor Opaniuk #endif
49d8f9d2afSIgor Opaniuk 
50d8f9d2afSIgor Opaniuk /* Aborts the program if |addr| is not word-aligned.
51d8f9d2afSIgor Opaniuk  *
52d8f9d2afSIgor Opaniuk  * This has no effect unless AVB_ENABLE_DEBUG is defined.
53d8f9d2afSIgor Opaniuk  */
54d8f9d2afSIgor Opaniuk #define avb_assert_aligned(addr) \
55d8f9d2afSIgor Opaniuk   avb_assert((((uintptr_t)addr) & (AVB_ALIGNMENT_SIZE - 1)) == 0)
56d8f9d2afSIgor Opaniuk 
57d8f9d2afSIgor Opaniuk #ifdef AVB_ENABLE_DEBUG
58d8f9d2afSIgor Opaniuk /* Print functions, used for diagnostics.
59d8f9d2afSIgor Opaniuk  *
60d8f9d2afSIgor Opaniuk  * These have no effect unless AVB_ENABLE_DEBUG is defined.
61d8f9d2afSIgor Opaniuk  */
62d8f9d2afSIgor Opaniuk #define avb_debug(message)              \
63d8f9d2afSIgor Opaniuk   do {                                  \
64d8f9d2afSIgor Opaniuk     avb_printv(avb_basename(__FILE__),  \
65d8f9d2afSIgor Opaniuk                ":",                     \
66d8f9d2afSIgor Opaniuk                AVB_TO_STRING(__LINE__), \
67d8f9d2afSIgor Opaniuk                ": DEBUG: ",             \
68d8f9d2afSIgor Opaniuk                message,                 \
69d8f9d2afSIgor Opaniuk                NULL);                   \
70d8f9d2afSIgor Opaniuk   } while (0)
71d8f9d2afSIgor Opaniuk #define avb_debugv(message, ...)        \
72d8f9d2afSIgor Opaniuk   do {                                  \
73d8f9d2afSIgor Opaniuk     avb_printv(avb_basename(__FILE__),  \
74d8f9d2afSIgor Opaniuk                ":",                     \
75d8f9d2afSIgor Opaniuk                AVB_TO_STRING(__LINE__), \
76d8f9d2afSIgor Opaniuk                ": DEBUG: ",             \
77d8f9d2afSIgor Opaniuk                message,                 \
78d8f9d2afSIgor Opaniuk                ##__VA_ARGS__);          \
79d8f9d2afSIgor Opaniuk   } while (0)
80d8f9d2afSIgor Opaniuk #else
81d8f9d2afSIgor Opaniuk #define avb_debug(message)
82d8f9d2afSIgor Opaniuk #define avb_debugv(message, ...)
83d8f9d2afSIgor Opaniuk #endif
84d8f9d2afSIgor Opaniuk 
85d8f9d2afSIgor Opaniuk /* Prints out a message. This is typically used if a runtime-error
86d8f9d2afSIgor Opaniuk  * occurs.
87d8f9d2afSIgor Opaniuk  */
88d8f9d2afSIgor Opaniuk #define avb_error(message)              \
89d8f9d2afSIgor Opaniuk   do {                                  \
90d8f9d2afSIgor Opaniuk     avb_printv(avb_basename(__FILE__),  \
91d8f9d2afSIgor Opaniuk                ":",                     \
92d8f9d2afSIgor Opaniuk                AVB_TO_STRING(__LINE__), \
93d8f9d2afSIgor Opaniuk                ": ERROR: ",             \
94d8f9d2afSIgor Opaniuk                message,                 \
95d8f9d2afSIgor Opaniuk                NULL);                   \
96d8f9d2afSIgor Opaniuk   } while (0)
97d8f9d2afSIgor Opaniuk #define avb_errorv(message, ...)        \
98d8f9d2afSIgor Opaniuk   do {                                  \
99d8f9d2afSIgor Opaniuk     avb_printv(avb_basename(__FILE__),  \
100d8f9d2afSIgor Opaniuk                ":",                     \
101d8f9d2afSIgor Opaniuk                AVB_TO_STRING(__LINE__), \
102d8f9d2afSIgor Opaniuk                ": ERROR: ",             \
103d8f9d2afSIgor Opaniuk                message,                 \
104d8f9d2afSIgor Opaniuk                ##__VA_ARGS__);          \
105d8f9d2afSIgor Opaniuk   } while (0)
106d8f9d2afSIgor Opaniuk 
107d8f9d2afSIgor Opaniuk /* Prints out a message and calls avb_abort().
108d8f9d2afSIgor Opaniuk  */
109d8f9d2afSIgor Opaniuk #define avb_fatal(message)              \
110d8f9d2afSIgor Opaniuk   do {                                  \
111d8f9d2afSIgor Opaniuk     avb_printv(avb_basename(__FILE__),  \
112d8f9d2afSIgor Opaniuk                ":",                     \
113d8f9d2afSIgor Opaniuk                AVB_TO_STRING(__LINE__), \
114d8f9d2afSIgor Opaniuk                ": FATAL: ",             \
115d8f9d2afSIgor Opaniuk                message,                 \
116d8f9d2afSIgor Opaniuk                NULL);                   \
117d8f9d2afSIgor Opaniuk     avb_abort();                        \
118d8f9d2afSIgor Opaniuk   } while (0)
119d8f9d2afSIgor Opaniuk #define avb_fatalv(message, ...)        \
120d8f9d2afSIgor Opaniuk   do {                                  \
121d8f9d2afSIgor Opaniuk     avb_printv(avb_basename(__FILE__),  \
122d8f9d2afSIgor Opaniuk                ":",                     \
123d8f9d2afSIgor Opaniuk                AVB_TO_STRING(__LINE__), \
124d8f9d2afSIgor Opaniuk                ": FATAL: ",             \
125d8f9d2afSIgor Opaniuk                message,                 \
126d8f9d2afSIgor Opaniuk                ##__VA_ARGS__);          \
127d8f9d2afSIgor Opaniuk     avb_abort();                        \
128d8f9d2afSIgor Opaniuk   } while (0)
129d8f9d2afSIgor Opaniuk 
130d8f9d2afSIgor Opaniuk /* Converts a 32-bit unsigned integer from big-endian to host byte order. */
131d8f9d2afSIgor Opaniuk uint32_t avb_be32toh(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
132d8f9d2afSIgor Opaniuk 
133d8f9d2afSIgor Opaniuk /* Converts a 64-bit unsigned integer from big-endian to host byte order. */
134d8f9d2afSIgor Opaniuk uint64_t avb_be64toh(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
135d8f9d2afSIgor Opaniuk 
136d8f9d2afSIgor Opaniuk /* Converts a 32-bit unsigned integer from host to big-endian byte order. */
137d8f9d2afSIgor Opaniuk uint32_t avb_htobe32(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
138d8f9d2afSIgor Opaniuk 
139d8f9d2afSIgor Opaniuk /* Converts a 64-bit unsigned integer from host to big-endian byte order. */
140d8f9d2afSIgor Opaniuk uint64_t avb_htobe64(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
141d8f9d2afSIgor Opaniuk 
142d8f9d2afSIgor Opaniuk /* Compare |n| bytes starting at |s1| with |s2| and return 0 if they
143d8f9d2afSIgor Opaniuk  * match, 1 if they don't.  Returns 0 if |n|==0, since no bytes
144d8f9d2afSIgor Opaniuk  * mismatched.
145d8f9d2afSIgor Opaniuk  *
146d8f9d2afSIgor Opaniuk  * Time taken to perform the comparison is only dependent on |n| and
147d8f9d2afSIgor Opaniuk  * not on the relationship of the match between |s1| and |s2|.
148d8f9d2afSIgor Opaniuk  *
149d8f9d2afSIgor Opaniuk  * Note that unlike avb_memcmp(), this only indicates inequality, not
150d8f9d2afSIgor Opaniuk  * whether |s1| is less than or greater than |s2|.
151d8f9d2afSIgor Opaniuk  */
152d8f9d2afSIgor Opaniuk int avb_safe_memcmp(const void* s1,
153d8f9d2afSIgor Opaniuk                     const void* s2,
154d8f9d2afSIgor Opaniuk                     size_t n) AVB_ATTR_WARN_UNUSED_RESULT;
155d8f9d2afSIgor Opaniuk 
156d8f9d2afSIgor Opaniuk /* Adds |value_to_add| to |value| with overflow protection.
157d8f9d2afSIgor Opaniuk  *
158d8f9d2afSIgor Opaniuk  * Returns false if the addition overflows, true otherwise. In either
159d8f9d2afSIgor Opaniuk  * case, |value| is always modified.
160d8f9d2afSIgor Opaniuk  */
161d8f9d2afSIgor Opaniuk bool avb_safe_add_to(uint64_t* value,
162d8f9d2afSIgor Opaniuk                      uint64_t value_to_add) AVB_ATTR_WARN_UNUSED_RESULT;
163d8f9d2afSIgor Opaniuk 
164d8f9d2afSIgor Opaniuk /* Adds |a| and |b| with overflow protection, returning the value in
165d8f9d2afSIgor Opaniuk  * |out_result|.
166d8f9d2afSIgor Opaniuk  *
167d8f9d2afSIgor Opaniuk  * It's permissible to pass NULL for |out_result| if you just want to
168d8f9d2afSIgor Opaniuk  * check that the addition would not overflow.
169d8f9d2afSIgor Opaniuk  *
170d8f9d2afSIgor Opaniuk  * Returns false if the addition overflows, true otherwise.
171d8f9d2afSIgor Opaniuk  */
172d8f9d2afSIgor Opaniuk bool avb_safe_add(uint64_t* out_result,
173d8f9d2afSIgor Opaniuk                   uint64_t a,
174d8f9d2afSIgor Opaniuk                   uint64_t b) AVB_ATTR_WARN_UNUSED_RESULT;
175d8f9d2afSIgor Opaniuk 
176d8f9d2afSIgor Opaniuk /* Checks if |num_bytes| data at |data| is a valid UTF-8
177d8f9d2afSIgor Opaniuk  * string. Returns true if valid UTF-8, false otherwise.
178d8f9d2afSIgor Opaniuk  */
179d8f9d2afSIgor Opaniuk bool avb_validate_utf8(const uint8_t* data,
180d8f9d2afSIgor Opaniuk                        size_t num_bytes) AVB_ATTR_WARN_UNUSED_RESULT;
181d8f9d2afSIgor Opaniuk 
182d8f9d2afSIgor Opaniuk /* Concatenates |str1| (of |str1_len| bytes) and |str2| (of |str2_len|
183d8f9d2afSIgor Opaniuk  * bytes) and puts the result in |buf| which holds |buf_size|
184d8f9d2afSIgor Opaniuk  * bytes. The result is also guaranteed to be NUL terminated. Fail if
185d8f9d2afSIgor Opaniuk  * there is not enough room in |buf| for the resulting string plus
186d8f9d2afSIgor Opaniuk  * terminating NUL byte.
187d8f9d2afSIgor Opaniuk  *
188d8f9d2afSIgor Opaniuk  * Returns true if the operation succeeds, false otherwise.
189d8f9d2afSIgor Opaniuk  */
190d8f9d2afSIgor Opaniuk bool avb_str_concat(char* buf,
191d8f9d2afSIgor Opaniuk                     size_t buf_size,
192d8f9d2afSIgor Opaniuk                     const char* str1,
193d8f9d2afSIgor Opaniuk                     size_t str1_len,
194d8f9d2afSIgor Opaniuk                     const char* str2,
195d8f9d2afSIgor Opaniuk                     size_t str2_len);
196d8f9d2afSIgor Opaniuk 
197d8f9d2afSIgor Opaniuk /* Like avb_malloc_() but prints a error using avb_error() if memory
198d8f9d2afSIgor Opaniuk  * allocation fails.
199d8f9d2afSIgor Opaniuk  */
200d8f9d2afSIgor Opaniuk void* avb_malloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
201d8f9d2afSIgor Opaniuk 
202d8f9d2afSIgor Opaniuk /* Like avb_malloc() but sets the memory with zeroes. */
203d8f9d2afSIgor Opaniuk void* avb_calloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
204d8f9d2afSIgor Opaniuk 
205d8f9d2afSIgor Opaniuk /* Duplicates a NUL-terminated string. Returns NULL on OOM. */
206d8f9d2afSIgor Opaniuk char* avb_strdup(const char* str) AVB_ATTR_WARN_UNUSED_RESULT;
207d8f9d2afSIgor Opaniuk 
208d8f9d2afSIgor Opaniuk /* Duplicates a NULL-terminated array of NUL-terminated strings by
209d8f9d2afSIgor Opaniuk  * concatenating them. The returned string will be
210d8f9d2afSIgor Opaniuk  * NUL-terminated. Returns NULL on OOM.
211d8f9d2afSIgor Opaniuk  */
212d8f9d2afSIgor Opaniuk char* avb_strdupv(const char* str,
213d8f9d2afSIgor Opaniuk                   ...) AVB_ATTR_WARN_UNUSED_RESULT AVB_ATTR_SENTINEL;
214d8f9d2afSIgor Opaniuk 
215d8f9d2afSIgor Opaniuk /* Finds the first occurrence of |needle| in the string |haystack|
216d8f9d2afSIgor Opaniuk  * where both strings are NUL-terminated strings. The terminating NUL
217d8f9d2afSIgor Opaniuk  * bytes are not compared.
218d8f9d2afSIgor Opaniuk  *
219d8f9d2afSIgor Opaniuk  * Returns NULL if not found, otherwise points into |haystack| for the
220d8f9d2afSIgor Opaniuk  * first occurrence of |needle|.
221d8f9d2afSIgor Opaniuk  */
222d8f9d2afSIgor Opaniuk const char* avb_strstr(const char* haystack,
223d8f9d2afSIgor Opaniuk                        const char* needle) AVB_ATTR_WARN_UNUSED_RESULT;
224d8f9d2afSIgor Opaniuk 
225d8f9d2afSIgor Opaniuk /* Finds the first occurrence of |str| in the NULL-terminated string
226d8f9d2afSIgor Opaniuk  * array |strings|. Each element in |strings| must be
227d8f9d2afSIgor Opaniuk  * NUL-terminated. The string given by |str| need not be
228d8f9d2afSIgor Opaniuk  * NUL-terminated but its size must be given in |str_size|.
229d8f9d2afSIgor Opaniuk  *
230d8f9d2afSIgor Opaniuk  * Returns NULL if not found, otherwise points into |strings| for the
231d8f9d2afSIgor Opaniuk  * first occurrence of |str|.
232d8f9d2afSIgor Opaniuk  */
233d8f9d2afSIgor Opaniuk const char* avb_strv_find_str(const char* const* strings,
234d8f9d2afSIgor Opaniuk                               const char* str,
235d8f9d2afSIgor Opaniuk                               size_t str_size);
236d8f9d2afSIgor Opaniuk 
237d8f9d2afSIgor Opaniuk /* Replaces all occurrences of |search| with |replace| in |str|.
238d8f9d2afSIgor Opaniuk  *
239d8f9d2afSIgor Opaniuk  * Returns a newly allocated string or NULL if out of memory.
240d8f9d2afSIgor Opaniuk  */
241d8f9d2afSIgor Opaniuk char* avb_replace(const char* str,
242d8f9d2afSIgor Opaniuk                   const char* search,
243d8f9d2afSIgor Opaniuk                   const char* replace) AVB_ATTR_WARN_UNUSED_RESULT;
244d8f9d2afSIgor Opaniuk 
245d8f9d2afSIgor Opaniuk /* Calculates the CRC-32 for data in |buf| of size |buf_size|. */
246d8f9d2afSIgor Opaniuk uint32_t avb_crc32(const uint8_t* buf, size_t buf_size);
247d8f9d2afSIgor Opaniuk 
248d8f9d2afSIgor Opaniuk /* Returns the basename of |str|. This is defined as the last path
249d8f9d2afSIgor Opaniuk  * component, assuming the normal POSIX separator '/'. If there are no
250d8f9d2afSIgor Opaniuk  * separators, returns |str|.
251d8f9d2afSIgor Opaniuk  */
252d8f9d2afSIgor Opaniuk const char* avb_basename(const char* str);
253d8f9d2afSIgor Opaniuk 
254d8f9d2afSIgor Opaniuk /* Converts any ascii lowercase characters in |str| to uppercase in-place.
255d8f9d2afSIgor Opaniuk  * |str| must be NUL-terminated and valid UTF-8.
256d8f9d2afSIgor Opaniuk  */
257d8f9d2afSIgor Opaniuk void avb_uppercase(char* str);
258d8f9d2afSIgor Opaniuk 
259d8f9d2afSIgor Opaniuk /* Converts |data_len| bytes of |data| to hex and returns the result. Returns
260d8f9d2afSIgor Opaniuk  * NULL on OOM. Caller must free the returned string with avb_free.
261d8f9d2afSIgor Opaniuk  */
262d8f9d2afSIgor Opaniuk char* avb_bin2hex(const uint8_t* data, size_t data_len);
263d8f9d2afSIgor Opaniuk 
264d8f9d2afSIgor Opaniuk #ifdef __cplusplus
265d8f9d2afSIgor Opaniuk }
266d8f9d2afSIgor Opaniuk #endif
267d8f9d2afSIgor Opaniuk 
268d8f9d2afSIgor Opaniuk #endif /* AVB_UTIL_H_ */
269