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