Blame dutil.h

Packit Service 154b7f
#ifndef _DUTIL_H_
Packit Service 154b7f
#define _DUTIL_H_ 1
Packit Service 154b7f
/*
Packit Service 154b7f
  SPDX-License-Identifier: GPL-2.0-only
Packit Service 154b7f
Packit Service 154b7f
 * Copyright (C) 2007..2009 Arnaldo Carvalho de Melo <acme@redhat.com>
Packit Service 154b7f
 *
Packit Service 154b7f
 * Some functions came from the Linux Kernel sources, copyrighted by a
Packit Service 154b7f
 * cast of dozens, please see the Linux Kernel git history for details.
Packit Service 154b7f
 */
Packit Service 154b7f
Packit Service 154b7f
#include <stdbool.h>
Packit Service 154b7f
#include <stddef.h>
Packit Service 154b7f
#include <string.h>
Packit Service 154b7f
#include <elf.h>
Packit Service 154b7f
#include <gelf.h>
Packit Service 154b7f
#include <asm/bitsperlong.h>
Packit Service 154b7f
#include "rbtree.h"
Packit Service 154b7f
Packit Service 154b7f
#define BITS_PER_LONG __BITS_PER_LONG
Packit Service 154b7f
Packit Service 154b7f
#ifndef __unused
Packit Service 154b7f
#define __unused __attribute__ ((unused))
Packit Service 154b7f
#endif
Packit Service 154b7f
Packit Service 154b7f
#ifndef __pure
Packit Service 154b7f
#define __pure __attribute__ ((pure))
Packit Service 154b7f
#endif
Packit Service 154b7f
Packit Service 154b7f
#define roundup(x,y) ((((x) + ((y) - 1)) / (y)) * (y))
Packit Service 154b7f
Packit Service 154b7f
static inline __attribute__((const)) bool is_power_of_2(unsigned long n)
Packit Service 154b7f
{
Packit Service 154b7f
        return (n != 0 && ((n & (n - 1)) == 0));
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
/**
Packit Service 154b7f
 * fls - find last (most-significant) bit set
Packit Service 154b7f
 * @x: the word to search
Packit Service 154b7f
 *
Packit Service 154b7f
 * This is defined the same way as ffs.
Packit Service 154b7f
 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
Packit Service 154b7f
 */
Packit Service 154b7f
static __always_inline int fls(int x)
Packit Service 154b7f
{
Packit Service 154b7f
	return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
/**
Packit Service 154b7f
 * fls64 - find last set bit in a 64-bit word
Packit Service 154b7f
 * @x: the word to search
Packit Service 154b7f
 *
Packit Service 154b7f
 * This is defined in a similar way as the libc and compiler builtin
Packit Service 154b7f
 * ffsll, but returns the position of the most significant set bit.
Packit Service 154b7f
 *
Packit Service 154b7f
 * fls64(value) returns 0 if value is 0 or the position of the last
Packit Service 154b7f
 * set bit if value is nonzero. The last (most significant) bit is
Packit Service 154b7f
 * at position 64.
Packit Service 154b7f
 */
Packit Service 154b7f
#if BITS_PER_LONG == 32
Packit Service 154b7f
static __always_inline int fls64(uint64_t x)
Packit Service 154b7f
{
Packit Service 154b7f
	uint32_t h = x >> 32;
Packit Service 154b7f
	if (h)
Packit Service 154b7f
		return fls(h) + 32;
Packit Service 154b7f
	return fls(x);
Packit Service 154b7f
}
Packit Service 154b7f
#elif BITS_PER_LONG == 64
Packit Service 154b7f
/**
Packit Service 154b7f
 * __fls - find last (most-significant) set bit in a long word
Packit Service 154b7f
 * @word: the word to search
Packit Service 154b7f
 *
Packit Service 154b7f
 * Undefined if no set bit exists, so code should check against 0 first.
Packit Service 154b7f
 */
Packit Service 154b7f
static __always_inline unsigned long __fls(unsigned long word)
Packit Service 154b7f
{
Packit Service 154b7f
	int num = BITS_PER_LONG - 1;
Packit Service 154b7f
Packit Service 154b7f
#if BITS_PER_LONG == 64
Packit Service 154b7f
	if (!(word & (~0ul << 32))) {
Packit Service 154b7f
		num -= 32;
Packit Service 154b7f
		word <<= 32;
Packit Service 154b7f
	}
Packit Service 154b7f
#endif
Packit Service 154b7f
	if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
Packit Service 154b7f
		num -= 16;
Packit Service 154b7f
		word <<= 16;
Packit Service 154b7f
	}
Packit Service 154b7f
	if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
Packit Service 154b7f
		num -= 8;
Packit Service 154b7f
		word <<= 8;
Packit Service 154b7f
	}
Packit Service 154b7f
	if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
Packit Service 154b7f
		num -= 4;
Packit Service 154b7f
		word <<= 4;
Packit Service 154b7f
	}
Packit Service 154b7f
	if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
Packit Service 154b7f
		num -= 2;
Packit Service 154b7f
		word <<= 2;
Packit Service 154b7f
	}
Packit Service 154b7f
	if (!(word & (~0ul << (BITS_PER_LONG-1))))
Packit Service 154b7f
		num -= 1;
Packit Service 154b7f
	return num;
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
static __always_inline int fls64(uint64_t x)
Packit Service 154b7f
{
Packit Service 154b7f
	if (x == 0)
Packit Service 154b7f
		return 0;
Packit Service 154b7f
	return __fls(x) + 1;
Packit Service 154b7f
}
Packit Service 154b7f
#else
Packit Service 154b7f
#error BITS_PER_LONG not 32 or 64
Packit Service 154b7f
#endif
Packit Service 154b7f
Packit Service 154b7f
static inline unsigned fls_long(unsigned long l)
Packit Service 154b7f
{
Packit Service 154b7f
	if (sizeof(l) == 4)
Packit Service 154b7f
		return fls(l);
Packit Service 154b7f
	return fls64(l);
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
/*
Packit Service 154b7f
 * round up to nearest power of two
Packit Service 154b7f
 */
Packit Service 154b7f
static inline __attribute__((const))
Packit Service 154b7f
unsigned long __roundup_pow_of_two(unsigned long n)
Packit Service 154b7f
{
Packit Service 154b7f
	return 1UL << fls_long(n - 1);
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
/*
Packit Service 154b7f
 * non-constant log of base 2 calculators
Packit Service 154b7f
 * - the arch may override these in asm/bitops.h if they can be implemented
Packit Service 154b7f
 *   more efficiently than using fls() and fls64()
Packit Service 154b7f
 * - the arch is not required to handle n==0 if implementing the fallback
Packit Service 154b7f
 */
Packit Service 154b7f
static inline __attribute__((const))
Packit Service 154b7f
int __ilog2_u32(uint32_t n)
Packit Service 154b7f
{
Packit Service 154b7f
	return fls(n) - 1;
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
static inline __attribute__((const))
Packit Service 154b7f
int __ilog2_u64(uint64_t n)
Packit Service 154b7f
{
Packit Service 154b7f
	return fls64(n) - 1;
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
/*
Packit Service 154b7f
 * deal with unrepresentable constant logarithms
Packit Service 154b7f
 */
Packit Service 154b7f
extern __attribute__((const))
Packit Service 154b7f
int ____ilog2_NaN(void);
Packit Service 154b7f
Packit Service 154b7f
/**
Packit Service 154b7f
 * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
Packit Service 154b7f
 * @n - parameter
Packit Service 154b7f
 *
Packit Service 154b7f
 * constant-capable log of base 2 calculation
Packit Service 154b7f
 * - this can be used to initialise global variables from constant data, hence
Packit Service 154b7f
 *   the massive ternary operator construction
Packit Service 154b7f
 *
Packit Service 154b7f
 * selects the appropriately-sized optimised version depending on sizeof(n)
Packit Service 154b7f
 */
Packit Service 154b7f
#define ilog2(n)				\
Packit Service 154b7f
(						\
Packit Service 154b7f
	__builtin_constant_p(n) ? (		\
Packit Service 154b7f
		(n) < 1 ? ____ilog2_NaN() :	\
Packit Service 154b7f
		(n) & (1ULL << 63) ? 63 :	\
Packit Service 154b7f
		(n) & (1ULL << 62) ? 62 :	\
Packit Service 154b7f
		(n) & (1ULL << 61) ? 61 :	\
Packit Service 154b7f
		(n) & (1ULL << 60) ? 60 :	\
Packit Service 154b7f
		(n) & (1ULL << 59) ? 59 :	\
Packit Service 154b7f
		(n) & (1ULL << 58) ? 58 :	\
Packit Service 154b7f
		(n) & (1ULL << 57) ? 57 :	\
Packit Service 154b7f
		(n) & (1ULL << 56) ? 56 :	\
Packit Service 154b7f
		(n) & (1ULL << 55) ? 55 :	\
Packit Service 154b7f
		(n) & (1ULL << 54) ? 54 :	\
Packit Service 154b7f
		(n) & (1ULL << 53) ? 53 :	\
Packit Service 154b7f
		(n) & (1ULL << 52) ? 52 :	\
Packit Service 154b7f
		(n) & (1ULL << 51) ? 51 :	\
Packit Service 154b7f
		(n) & (1ULL << 50) ? 50 :	\
Packit Service 154b7f
		(n) & (1ULL << 49) ? 49 :	\
Packit Service 154b7f
		(n) & (1ULL << 48) ? 48 :	\
Packit Service 154b7f
		(n) & (1ULL << 47) ? 47 :	\
Packit Service 154b7f
		(n) & (1ULL << 46) ? 46 :	\
Packit Service 154b7f
		(n) & (1ULL << 45) ? 45 :	\
Packit Service 154b7f
		(n) & (1ULL << 44) ? 44 :	\
Packit Service 154b7f
		(n) & (1ULL << 43) ? 43 :	\
Packit Service 154b7f
		(n) & (1ULL << 42) ? 42 :	\
Packit Service 154b7f
		(n) & (1ULL << 41) ? 41 :	\
Packit Service 154b7f
		(n) & (1ULL << 40) ? 40 :	\
Packit Service 154b7f
		(n) & (1ULL << 39) ? 39 :	\
Packit Service 154b7f
		(n) & (1ULL << 38) ? 38 :	\
Packit Service 154b7f
		(n) & (1ULL << 37) ? 37 :	\
Packit Service 154b7f
		(n) & (1ULL << 36) ? 36 :	\
Packit Service 154b7f
		(n) & (1ULL << 35) ? 35 :	\
Packit Service 154b7f
		(n) & (1ULL << 34) ? 34 :	\
Packit Service 154b7f
		(n) & (1ULL << 33) ? 33 :	\
Packit Service 154b7f
		(n) & (1ULL << 32) ? 32 :	\
Packit Service 154b7f
		(n) & (1ULL << 31) ? 31 :	\
Packit Service 154b7f
		(n) & (1ULL << 30) ? 30 :	\
Packit Service 154b7f
		(n) & (1ULL << 29) ? 29 :	\
Packit Service 154b7f
		(n) & (1ULL << 28) ? 28 :	\
Packit Service 154b7f
		(n) & (1ULL << 27) ? 27 :	\
Packit Service 154b7f
		(n) & (1ULL << 26) ? 26 :	\
Packit Service 154b7f
		(n) & (1ULL << 25) ? 25 :	\
Packit Service 154b7f
		(n) & (1ULL << 24) ? 24 :	\
Packit Service 154b7f
		(n) & (1ULL << 23) ? 23 :	\
Packit Service 154b7f
		(n) & (1ULL << 22) ? 22 :	\
Packit Service 154b7f
		(n) & (1ULL << 21) ? 21 :	\
Packit Service 154b7f
		(n) & (1ULL << 20) ? 20 :	\
Packit Service 154b7f
		(n) & (1ULL << 19) ? 19 :	\
Packit Service 154b7f
		(n) & (1ULL << 18) ? 18 :	\
Packit Service 154b7f
		(n) & (1ULL << 17) ? 17 :	\
Packit Service 154b7f
		(n) & (1ULL << 16) ? 16 :	\
Packit Service 154b7f
		(n) & (1ULL << 15) ? 15 :	\
Packit Service 154b7f
		(n) & (1ULL << 14) ? 14 :	\
Packit Service 154b7f
		(n) & (1ULL << 13) ? 13 :	\
Packit Service 154b7f
		(n) & (1ULL << 12) ? 12 :	\
Packit Service 154b7f
		(n) & (1ULL << 11) ? 11 :	\
Packit Service 154b7f
		(n) & (1ULL << 10) ? 10 :	\
Packit Service 154b7f
		(n) & (1ULL <<  9) ?  9 :	\
Packit Service 154b7f
		(n) & (1ULL <<  8) ?  8 :	\
Packit Service 154b7f
		(n) & (1ULL <<  7) ?  7 :	\
Packit Service 154b7f
		(n) & (1ULL <<  6) ?  6 :	\
Packit Service 154b7f
		(n) & (1ULL <<  5) ?  5 :	\
Packit Service 154b7f
		(n) & (1ULL <<  4) ?  4 :	\
Packit Service 154b7f
		(n) & (1ULL <<  3) ?  3 :	\
Packit Service 154b7f
		(n) & (1ULL <<  2) ?  2 :	\
Packit Service 154b7f
		(n) & (1ULL <<  1) ?  1 :	\
Packit Service 154b7f
		(n) & (1ULL <<  0) ?  0 :	\
Packit Service 154b7f
		____ilog2_NaN()			\
Packit Service 154b7f
				   ) :		\
Packit Service 154b7f
	(sizeof(n) <= 4) ?			\
Packit Service 154b7f
	__ilog2_u32(n) :			\
Packit Service 154b7f
	__ilog2_u64(n)				\
Packit Service 154b7f
 )
Packit Service 154b7f
Packit Service 154b7f
/**
Packit Service 154b7f
 * roundup_pow_of_two - round the given value up to nearest power of two
Packit Service 154b7f
 * @n - parameter
Packit Service 154b7f
 *
Packit Service 154b7f
 * round the given value up to the nearest power of two
Packit Service 154b7f
 * - the result is undefined when n == 0
Packit Service 154b7f
 * - this can be used to initialise global variables from constant data
Packit Service 154b7f
 */
Packit Service 154b7f
#define roundup_pow_of_two(n)			\
Packit Service 154b7f
(						\
Packit Service 154b7f
	__builtin_constant_p(n) ? (		\
Packit Service 154b7f
		(n == 1) ? 1 :			\
Packit Service 154b7f
		(1UL << (ilog2((n) - 1) + 1))	\
Packit Service 154b7f
				   ) :		\
Packit Service 154b7f
	__roundup_pow_of_two(n)			\
Packit Service 154b7f
 )
Packit Service 154b7f
Packit Service 154b7f
/* We need define two variables, argp_program_version_hook and
Packit Service 154b7f
   argp_program_bug_address, in all programs.  argp.h declares these
Packit Service 154b7f
   variables as non-const (which is correct in general).  But we can
Packit Service 154b7f
   do better, it is not going to change.  So we want to move them into
Packit Service 154b7f
   the .rodata section.  Define macros to do the trick.  */
Packit Service 154b7f
#define ARGP_PROGRAM_VERSION_HOOK_DEF \
Packit Service 154b7f
	void (*const apvh) (FILE *, struct argp_state *) \
Packit Service 154b7f
	__asm ("argp_program_version_hook")
Packit Service 154b7f
#define ARGP_PROGRAM_BUG_ADDRESS_DEF \
Packit Service 154b7f
	const char *const apba__ __asm ("argp_program_bug_address")
Packit Service 154b7f
Packit Service 154b7f
struct str_node {
Packit Service 154b7f
	struct rb_node rb_node;
Packit Service 154b7f
	const char       *s;
Packit Service 154b7f
};
Packit Service 154b7f
Packit Service 154b7f
struct strlist {
Packit Service 154b7f
	struct rb_root entries;
Packit Service 154b7f
	bool dupstr;
Packit Service 154b7f
};
Packit Service 154b7f
Packit Service 154b7f
struct strlist *strlist__new(bool dupstr);
Packit Service 154b7f
void strlist__delete(struct strlist *slist);
Packit Service 154b7f
Packit Service 154b7f
void strlist__remove(struct strlist *slist, struct str_node *sn);
Packit Service 154b7f
int strlist__load(struct strlist *slist, const char *filename);
Packit Service 154b7f
int strlist__add(struct strlist *slist, const char *str);
Packit Service 154b7f
Packit Service 154b7f
bool strlist__has_entry(struct strlist *slist, const char *entry);
Packit Service 154b7f
Packit Service 154b7f
static inline bool strlist__empty(const struct strlist *slist)
Packit Service 154b7f
{
Packit Service 154b7f
	return rb_first(&slist->entries) == NULL;
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
/**
Packit Service 154b7f
 * strstarts - does @str start with @prefix?
Packit Service 154b7f
 * @str: string to examine
Packit Service 154b7f
 * @prefix: prefix to look for.
Packit Service 154b7f
 */
Packit Service 154b7f
static inline bool strstarts(const char *str, const char *prefix)
Packit Service 154b7f
{
Packit Service 154b7f
	return strncmp(str, prefix, strlen(prefix)) == 0;
Packit Service 154b7f
}
Packit Service 154b7f
Packit Service 154b7f
void *zalloc(const size_t size);
Packit Service 154b7f
Packit Service 154b7f
Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
Packit Service 154b7f
			     GElf_Shdr *shp, const char *name, size_t *index);
Packit Service 154b7f
Packit Service 154b7f
#ifndef SHT_GNU_ATTRIBUTES
Packit Service 154b7f
/* Just a way to check if we're using an old elfutils version */
Packit Service 154b7f
static inline int elf_getshdrstrndx(Elf *elf, size_t *dst)
Packit Service 154b7f
{
Packit Service 154b7f
	return elf_getshstrndx(elf, dst);
Packit Service 154b7f
}
Packit Service 154b7f
#endif
Packit Service 154b7f
Packit Service 154b7f
#endif /* _DUTIL_H_ */