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