blob: b2b18ef6de20dfeeae7a1058287d1c1d3579bb12 [file] [log] [blame]
Eric Biggers431c67b2018-06-27 15:01:06 -07001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Utility functions and macros for the 'fsverity' program
4 *
Eric Biggers8387ad32018-08-21 12:37:56 -07005 * Copyright (C) 2018 Google LLC
Eric Biggers431c67b2018-06-27 15:01:06 -07006 */
7#ifndef UTIL_H
8#define UTIL_H
9
10#include <inttypes.h>
11#include <stdbool.h>
12#include <stddef.h>
13
14typedef uint8_t u8;
15typedef uint16_t u16;
16typedef uint32_t u32;
17typedef uint64_t u64;
18
19#ifdef __CHECKER__
20# define __force __attribute__((force))
21#else
22# define __force
23#endif
24
25#define __printf(fmt_idx, vargs_idx) \
26 __attribute__((format(printf, fmt_idx, vargs_idx)))
27
28#define __noreturn __attribute__((noreturn))
29#define __cold __attribute__((cold))
30
31#define min(a, b) ({ \
32 __typeof__(a) _a = (a); \
33 __typeof__(b) _b = (b); \
34 _a < _b ? _a : _b; \
35})
36#define max(a, b) ({ \
37 __typeof__(a) _a = (a); \
38 __typeof__(b) _b = (b); \
39 _a > _b ? _a : _b; \
40})
41
42#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
43
44#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
45
46/*
47 * Round 'v' up to the next 'alignment'-byte aligned boundary.
48 * 'alignment' must be a power of 2.
49 */
50#define ALIGN(v, alignment) (((v) + ((alignment) - 1)) & ~((alignment) - 1))
51
52static inline bool is_power_of_2(unsigned long n)
53{
54 return n != 0 && ((n & (n - 1)) == 0);
55}
56
57static inline int ilog2(unsigned long n)
58{
59 return (8 * sizeof(n) - 1) - __builtin_clzl(n);
60}
61
62/* ========== Endianness conversion ========== */
63
64#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
65# define cpu_to_le16(v) ((__force __le16)(u16)(v))
66# define le16_to_cpu(v) ((__force u16)(__le16)(v))
67# define cpu_to_le32(v) ((__force __le32)(u32)(v))
68# define le32_to_cpu(v) ((__force u32)(__le32)(v))
69# define cpu_to_le64(v) ((__force __le64)(u64)(v))
70# define le64_to_cpu(v) ((__force u64)(__le64)(v))
71# define cpu_to_be16(v) ((__force __be16)__builtin_bswap16(v))
72# define be16_to_cpu(v) (__builtin_bswap16((__force u16)(v)))
73# define cpu_to_be32(v) ((__force __be32)__builtin_bswap32(v))
74# define be32_to_cpu(v) (__builtin_bswap32((__force u32)(v)))
75# define cpu_to_be64(v) ((__force __be64)__builtin_bswap64(v))
76# define be64_to_cpu(v) (__builtin_bswap64((__force u64)(v)))
77#else
78# define cpu_to_le16(v) ((__force __le16)__builtin_bswap16(v))
79# define le16_to_cpu(v) (__builtin_bswap16((__force u16)(v)))
80# define cpu_to_le32(v) ((__force __le32)__builtin_bswap32(v))
81# define le32_to_cpu(v) (__builtin_bswap32((__force u32)(v)))
82# define cpu_to_le64(v) ((__force __le64)__builtin_bswap64(v))
83# define le64_to_cpu(v) (__builtin_bswap64((__force u64)(v)))
84# define cpu_to_be16(v) ((__force __be16)(u16)(v))
85# define be16_to_cpu(v) ((__force u16)(__be16)(v))
86# define cpu_to_be32(v) ((__force __be32)(u32)(v))
87# define be32_to_cpu(v) ((__force u32)(__be32)(v))
88# define cpu_to_be64(v) ((__force __be64)(u64)(v))
89# define be64_to_cpu(v) ((__force u64)(__be64)(v))
90#endif
91
92/* ========== Memory allocation ========== */
93
94void *xmalloc(size_t size);
95void *xzalloc(size_t size);
96void *xmemdup(const void *mem, size_t size);
97char *xstrdup(const char *s);
98__printf(1, 2) char *xasprintf(const char *format, ...);
99
100/* ========== Error messages and assertions ========== */
101
102__printf(1, 2) __cold void error_msg(const char *format, ...);
103__printf(1, 2) __cold void error_msg_errno(const char *format, ...);
104__printf(1, 2) __cold __noreturn void fatal_error(const char *format, ...);
105__cold __noreturn void assertion_failed(const char *expr,
106 const char *file, int line);
107
108#define ASSERT(e) ({ if (!(e)) assertion_failed(#e, __FILE__, __LINE__); })
109
110/* ========== File utilities ========== */
111
112struct filedes {
113 int fd;
114 bool autodelete; /* unlink when closed? */
115 char *name; /* filename, for logging or error messages */
116 u64 pos; /* lseek() position */
117};
118
119bool open_file(struct filedes *file, const char *filename, int flags, int mode);
120bool open_tempfile(struct filedes *file);
121bool get_file_size(struct filedes *file, u64 *size_ret);
122bool filedes_seek(struct filedes *file, u64 pos, int whence);
123bool full_read(struct filedes *file, void *buf, size_t count);
124bool full_pread(struct filedes *file, void *buf, size_t count, u64 offset);
125bool full_write(struct filedes *file, const void *buf, size_t count);
126bool full_pwrite(struct filedes *file, const void *buf, size_t count,
127 u64 offset);
128bool copy_file_data(struct filedes *src, struct filedes *dst, u64 length);
129bool write_zeroes(struct filedes *file, u64 length);
130bool filedes_close(struct filedes *file);
131
132/* ========== String utilities ========== */
133
134bool hex2bin(const char *hex, u8 *bin, size_t bin_len);
135void bin2hex(const u8 *bin, size_t bin_len, char *hex);
136
137struct string_list {
138 char **strings;
139 size_t length;
140 size_t capacity;
141};
142
143#define STRING_LIST_INITIALIZER { .strings = NULL, .length = 0, .capacity = 0 }
144#define STRING_LIST(_list) struct string_list _list = STRING_LIST_INITIALIZER
145
146void string_list_append(struct string_list *list, char *string);
147void string_list_destroy(struct string_list *list);
148
149#endif /* UTIL_H */