Home | History | Annotate | Download | only in fsverity-utils
      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