~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 26dc6b045ac7cf6362246d4fbffd1443d2e7386c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/* SPDX-License-Identifier: MIT */
/*
 * Copyright (C) 2016 The Android Open Source Project
 */

#if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
#error "Never include this file directly, include libavb.h instead."
#endif

#ifndef AVB_UTIL_H_
#define AVB_UTIL_H_

#include "avb_sysdeps.h"

#ifdef __cplusplus
extern "C" {
#endif

#define AVB_STRINGIFY(x) #x
#define AVB_TO_STRING(x) AVB_STRINGIFY(x)

#ifdef AVB_ENABLE_DEBUG
/* Aborts the program if |expr| is false.
 *
 * This has no effect unless AVB_ENABLE_DEBUG is defined.
 */
#define avb_assert(expr)                     \
  do {                                       \
    if (!(expr)) {                           \
      avb_fatal("assert fail: " #expr "\n"); \
    }                                        \
  } while (0)
#else
#define avb_assert(expr)
#endif

/* Aborts the program if reached.
 *
 * This has no effect unless AVB_ENABLE_DEBUG is defined.
 */
#ifdef AVB_ENABLE_DEBUG
#define avb_assert_not_reached()         \
  do {                                   \
    avb_fatal("assert_not_reached()\n"); \
  } while (0)
#else
#define avb_assert_not_reached()
#endif

/* Aborts the program if |addr| is not word-aligned.
 *
 * This has no effect unless AVB_ENABLE_DEBUG is defined.
 */
#define avb_assert_aligned(addr) \
  avb_assert((((uintptr_t)addr) & (AVB_ALIGNMENT_SIZE - 1)) == 0)

#ifdef AVB_ENABLE_DEBUG
/* Print functions, used for diagnostics.
 *
 * These have no effect unless AVB_ENABLE_DEBUG is defined.
 */
#define avb_debug(message)              \
  do {                                  \
    avb_printv(avb_basename(__FILE__),  \
               ":",                     \
               AVB_TO_STRING(__LINE__), \
               ": DEBUG: ",             \
               message,                 \
               NULL);                   \
  } while (0)
#define avb_debugv(message, ...)        \
  do {                                  \
    avb_printv(avb_basename(__FILE__),  \
               ":",                     \
               AVB_TO_STRING(__LINE__), \
               ": DEBUG: ",             \
               message,                 \
               ##__VA_ARGS__);          \
  } while (0)
#else
#define avb_debug(message)
#define avb_debugv(message, ...)
#endif

/* Prints out a message. This is typically used if a runtime-error
 * occurs.
 */
#define avb_error(message)              \
  do {                                  \
    avb_printv(avb_basename(__FILE__),  \
               ":",                     \
               AVB_TO_STRING(__LINE__), \
               ": ERROR: ",             \
               message,                 \
               NULL);                   \
  } while (0)
#define avb_errorv(message, ...)        \
  do {                                  \
    avb_printv(avb_basename(__FILE__),  \
               ":",                     \
               AVB_TO_STRING(__LINE__), \
               ": ERROR: ",             \
               message,                 \
               ##__VA_ARGS__);          \
  } while (0)

/* Prints out a message and calls avb_abort().
 */
#define avb_fatal(message)              \
  do {                                  \
    avb_printv(avb_basename(__FILE__),  \
               ":",                     \
               AVB_TO_STRING(__LINE__), \
               ": FATAL: ",             \
               message,                 \
               NULL);                   \
    avb_abort();                        \
  } while (0)
#define avb_fatalv(message, ...)        \
  do {                                  \
    avb_printv(avb_basename(__FILE__),  \
               ":",                     \
               AVB_TO_STRING(__LINE__), \
               ": FATAL: ",             \
               message,                 \
               ##__VA_ARGS__);          \
    avb_abort();                        \
  } while (0)

/* Converts a 32-bit unsigned integer from big-endian to host byte order. */
uint32_t avb_be32toh(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;

/* Converts a 64-bit unsigned integer from big-endian to host byte order. */
uint64_t avb_be64toh(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;

/* Converts a 32-bit unsigned integer from host to big-endian byte order. */
uint32_t avb_htobe32(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;

/* Converts a 64-bit unsigned integer from host to big-endian byte order. */
uint64_t avb_htobe64(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;

/* Compare |n| bytes starting at |s1| with |s2| and return 0 if they
 * match, 1 if they don't.  Returns 0 if |n|==0, since no bytes
 * mismatched.
 *
 * Time taken to perform the comparison is only dependent on |n| and
 * not on the relationship of the match between |s1| and |s2|.
 *
 * Note that unlike avb_memcmp(), this only indicates inequality, not
 * whether |s1| is less than or greater than |s2|.
 */
int avb_safe_memcmp(const void* s1,
                    const void* s2,
                    size_t n) AVB_ATTR_WARN_UNUSED_RESULT;

/* Adds |value_to_add| to |value| with overflow protection.
 *
 * Returns false if the addition overflows, true otherwise. In either
 * case, |value| is always modified.
 */
bool avb_safe_add_to(uint64_t* value,
                     uint64_t value_to_add) AVB_ATTR_WARN_UNUSED_RESULT;

/* Adds |a| and |b| with overflow protection, returning the value in
 * |out_result|.
 *
 * It's permissible to pass NULL for |out_result| if you just want to
 * check that the addition would not overflow.
 *
 * Returns false if the addition overflows, true otherwise.
 */
bool avb_safe_add(uint64_t* out_result,
                  uint64_t a,
                  uint64_t b) AVB_ATTR_WARN_UNUSED_RESULT;

/* Checks if |num_bytes| data at |data| is a valid UTF-8
 * string. Returns true if valid UTF-8, false otherwise.
 */
bool avb_validate_utf8(const uint8_t* data,
                       size_t num_bytes) AVB_ATTR_WARN_UNUSED_RESULT;

/* Concatenates |str1| (of |str1_len| bytes) and |str2| (of |str2_len|
 * bytes) and puts the result in |buf| which holds |buf_size|
 * bytes. The result is also guaranteed to be NUL terminated. Fail if
 * there is not enough room in |buf| for the resulting string plus
 * terminating NUL byte.
 *
 * Returns true if the operation succeeds, false otherwise.
 */
bool avb_str_concat(char* buf,
                    size_t buf_size,
                    const char* str1,
                    size_t str1_len,
                    const char* str2,
                    size_t str2_len);

/* Like avb_malloc_() but prints a error using avb_error() if memory
 * allocation fails.
 */
void* avb_malloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;

/* Like avb_malloc() but sets the memory with zeroes. */
void* avb_calloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;

/* Duplicates a NUL-terminated string. Returns NULL on OOM. */
char* avb_strdup(const char* str) AVB_ATTR_WARN_UNUSED_RESULT;

/* Duplicates a NULL-terminated array of NUL-terminated strings by
 * concatenating them. The returned string will be
 * NUL-terminated. Returns NULL on OOM.
 */
char* avb_strdupv(const char* str,
                  ...) AVB_ATTR_WARN_UNUSED_RESULT AVB_ATTR_SENTINEL;

/* Finds the first occurrence of |needle| in the string |haystack|
 * where both strings are NUL-terminated strings. The terminating NUL
 * bytes are not compared.
 *
 * Returns NULL if not found, otherwise points into |haystack| for the
 * first occurrence of |needle|.
 */
const char* avb_strstr(const char* haystack,
                       const char* needle) AVB_ATTR_WARN_UNUSED_RESULT;

/* Finds the first occurrence of |str| in the NULL-terminated string
 * array |strings|. Each element in |strings| must be
 * NUL-terminated. The string given by |str| need not be
 * NUL-terminated but its size must be given in |str_size|.
 *
 * Returns NULL if not found, otherwise points into |strings| for the
 * first occurrence of |str|.
 */
const char* avb_strv_find_str(const char* const* strings,
                              const char* str,
                              size_t str_size);

/* Replaces all occurrences of |search| with |replace| in |str|.
 *
 * Returns a newly allocated string or NULL if out of memory.
 */
char* avb_replace(const char* str,
                  const char* search,
                  const char* replace) AVB_ATTR_WARN_UNUSED_RESULT;

/* Calculates the CRC-32 for data in |buf| of size |buf_size|. */
uint32_t avb_crc32(const uint8_t* buf, size_t buf_size);

/* Returns the basename of |str|. This is defined as the last path
 * component, assuming the normal POSIX separator '/'. If there are no
 * separators, returns |str|.
 */
const char* avb_basename(const char* str);

/* Converts any ascii lowercase characters in |str| to uppercase in-place.
 * |str| must be NUL-terminated and valid UTF-8.
 */
void avb_uppercase(char* str);

/* Converts |data_len| bytes of |data| to hex and returns the result. Returns
 * NULL on OOM. Caller must free the returned string with avb_free.
 */
char* avb_bin2hex(const uint8_t* data, size_t data_len);

#ifdef __cplusplus
}
#endif

#endif /* AVB_UTIL_H_ */