Initial import of libdpf.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ryan Henry 2026-09-24 14:08:32 -06:00
commit e4e666f459
4563 changed files with 1690372 additions and 0 deletions

View file

@ -0,0 +1,53 @@
# Endianness Detection and Swapping
This header provides a convenient way to detect endianness, and
perform swapping. It provides 6 important functions:
```c
psnip_uint16_t psnip_endian_le16(psnip_uint16_t v);
psnip_uint32_t psnip_endian_le32(psnip_uint32_t v);
psnip_uint64_t psnip_endian_le64(psnip_uint64_t v);
psnip_uint16_t psnip_endian_be16(psnip_uint16_t v);
psnip_uint32_t psnip_endian_be32(psnip_uint32_t v);
psnip_uint64_t psnip_endian_be64(psnip_uint64_t v);
```
These are usually implemented as macros, the prototypes above are
purely for documentation.
These functions will swap byte ordering to or from the provided type
**if necessary**. For example, `psnip_endian_le32` is used to convert
a 32-bit unsigned integer to/from little-endian. If the machine is
little-endian nothing will be done, but if it is big-endian then a
swap will be performed. It's a bit like `hton`/`ntoh`, except instead
of host to/from network order, it's host to/from whatever order you
want.
If you wish to ignore the result of compile-time detection attempts,
you may define `PSNIP_ENDIAN_FORCE_RT` prior to including this header
to force run-time detection.
If you're only interested in detection you can just ignore the
swapping functions mentioned above. If endianness could be determined
at compile-time (i.e., through preprocessor macros),
`PSNIP_ENDIAN_ORDER` will be defined to either `PSNIP_ENDIAN_LITTLE`
or `PSNIP_ENDIAN_BIG`.
If you need (or prefer) to fall back on run-time detection,
`PSNIP_ENDIAN_ORDER_RT` will evaluate to the same values
(`PSNIP_ENDIAN_LITTLE` or `PSNIP_ENDIAN_BIG`). Note that the
"run-time" detection will likely be optimized away by the compiler.
## Dependencies
To maximize portability you should #include the exact-int module
before including endian.h, but if you don't want to add the extra
file to your project you can omit it and this module will simply rely
on <stdint.h>. As an alternative you may define `psnip_uint16_t`,
`psnip_uint32_t`, and `psnip_uint64_t` to appropriate values yourself
before including endian.h.
This module requires the builtin portable-snippet module. If you do
not include builtin.h before endian.h, endian.h will automatically
include "../builtin/builtin.h". If you include builtin.h manually you
are free to use whatever directory structure you like.

View file

@ -0,0 +1,200 @@
/* Endianness detection and swapping (v3)
* Portable Snippets - https://github.com/nemequ/portable-snippets
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* https://creativecommons.org/publicdomain/zero/1.0/
*/
#if !defined(PSNIP_ENDIAN_H)
#define PSNIP_ENDIAN_H
/* For maximum portability include the exact-int module from
portable snippets. */
#if \
!defined(psnip_uint64_t) || \
!defined(psnip_uint32_t) || \
!defined(psnip_uint16_t)
# include <stdint.h>
# if !defined(psnip_uint64_t)
# define psnip_uint64_t uint64_t
# endif
# if !defined(psnip_uint32_t)
# define psnip_uint32_t uint32_t
# endif
# if !defined(psnip_uint16_t)
# define psnip_uint16_t uint16_t
# endif
#endif
#if !defined(PSNIP_BUILTIN_H)
# include "../builtin/builtin.h"
#endif
#if !defined(PSNIP_ENDIAN_STATIC_INLINE)
# if defined(__GNUC__)
# define PSNIP_ENDIAN__COMPILER_ATTRIBUTES __attribute__((__unused__))
# else
# define PSNIP_ENDIAN__COMPILER_ATTRIBUTES
# endif
# if defined(HEDLEY_INLINE)
# define PSNIP_ENDIAN__INLINE HEDLEY_INLINE
# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define PSNIP_ENDIAN__INLINE inline
# elif defined(__GNUC_STDC_INLINE__)
# define PSNIP_ENDIAN__INLINE __inline__
# elif defined(_MSC_VER) && _MSC_VER >= 1200
# define PSNIP_ENDIAN__INLINE __inline
# else
# define PSNIP_ENDIAN__INLINE
# endif
# define PSNIP_ENDIAN__FUNCTION PSNIP_ENDIAN__COMPILER_ATTRIBUTES static PSNIP_ENDIAN__INLINE
#endif
#if !defined(PSNIP_ENDIAN_LITTLE)
# define PSNIP_ENDIAN_LITTLE 1234
#endif
#if !defined(PSNIP_ENDIAN_BIG)
# define PSNIP_ENDIAN_BIG 4321
#endif
#if !defined(PSNIP_ENDIAN_PDP)
# define PSNIP_ENDIAN_PDP 3412
#endif
/* Detection
*
* Detecting endianness can be a bit tricky. There isn't really a
* good standard way of determining endianness, and it's actually
* possible to mix endianness within a single program. This is
* currently pretty rare, though.
*
* We try to define PSNIP_ENDIAN_ORDER to PSNIP_ENDIAN_LITTLE,
* PSNIP_ENDIAN_BIG, or PSNIP_ENDIAN_PDP. Additionally, you can use
* the PSNIP_RT_BYTE_ORDER to check the runtime byte order, which is a
* bit more reliable (though it may introduce some runtime overhead).
*
* In the event we are unable to determine endianness at compile-time,
* PSNIP_ENDIAN_ORDER is left undefined and you will be forced to rely
* on PSNIP_RT_BYTE_ORDER. */
#if !defined(PSNIP_ENDIAN_FORCE_RT)
#if !defined(PSNIP_ENDIAN_ORDER)
/* GCC (and compilers masquerading as GCC) define __BYTE_ORDER__. */
# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
# elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_BIG
# elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_PDP_ENDIAN__)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_PDP
/* TI defines _BIG_ENDIAN or _LITTLE_ENDIAN */
# elif defined(_BIG_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_BIG
# elif defined(_LITTLE_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
/* We know the endianness of some common architectures. Common
* architectures not listed (ARM, POWER, MIPS, etc.) here are
* bi-endian. */
# elif defined(__amd64) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
# elif defined(__s390x__) || defined(__zarch__)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_BIG
/* Looks like we'll have to rely on the platform. If we're missing a
* platform, please let us know. */
# elif defined(_WIN32)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
# elif defined(sun) || defined(__sun) /* Solaris */
# include <sys/byteorder.h>
# if defined(_LITTLE_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
# elif defined(_BIG_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_BIG
# endif
# elif defined(__APPLE__)
# include <libkern/OSByteOrder.h>
# if defined(__LITTLE_ENDIAN__)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
# elif defined(__BIG_ENDIAN__)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_BIG
# endif
# elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(BSD)
# include <machine/endian.h>
# if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
# elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_BIG
# elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __PDP_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_PDP
# endif
# elif defined(__linux__) || defined(__linux) || defined(__gnu_linux__)
# include <endian.h>
# if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_LITTLE
# elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_BIG
# elif defined(__BYTE_ORDER) && defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN)
# define PSNIP_ENDIAN_ORDER PSNIP_ENDIAN_PDP
# endif
# endif
#endif
/* PDP endian not yet supported. Patches welcome. */
#if defined(PSNIP_ENDIAN_ORDER) && (PSNIP_ENDIAN_ORDER == PSNIP_ENDIAN_PDP)
# error PDP endian is not supported.
#endif
#endif /* !defined(PSNIP_ENDIAN_FORCE_RT) */
static const union {
unsigned long long value;
unsigned char bytes[4];
} psnip_endian_rt_data = {
1
};
#define PSNIP_ENDIAN_ORDER_RT_IS_LE (psnip_endian_rt_data.bytes[0] == 1)
#define PSNIP_ENDIAN_ORDER_RT_IS_BE (psnip_endian_rt_data.bytes[sizeof(unsigned long long) - 1] == 1)
#define PSNIP_ENDIAN_ORDER_RT (PSNIP_ENDIAN_ORDER_RT_IS_LE ? PSNIP_ENDIAN_LITTLE : PSNIP_ENDIAN_BIG)
#if defined(PSNIP_ENDIAN_FORCE_RT) || !defined(PSNIP_ENDIAN_ORDER)
#define PSNIP_ENDIAN__DEFINE_LE_FUNC(siz) \
PSNIP_ENDIAN__FUNCTION \
psnip_uint##siz##_t psnip_endian_le##siz(psnip_uint##siz##_t v) { \
return PSNIP_ENDIAN_ORDER_RT_IS_LE ? v : psnip_builtin_bswap##siz(v); \
}
#define PSNIP_ENDIAN__DEFINE_BE_FUNC(siz) \
PSNIP_ENDIAN__FUNCTION \
psnip_uint##siz##_t psnip_endian_be##siz(psnip_uint##siz##_t v) { \
return PSNIP_ENDIAN_ORDER_RT_IS_BE ? v : psnip_builtin_bswap##siz(v); \
}
PSNIP_ENDIAN__DEFINE_LE_FUNC(16)
PSNIP_ENDIAN__DEFINE_LE_FUNC(32)
PSNIP_ENDIAN__DEFINE_LE_FUNC(64)
PSNIP_ENDIAN__DEFINE_BE_FUNC(16)
PSNIP_ENDIAN__DEFINE_BE_FUNC(32)
PSNIP_ENDIAN__DEFINE_BE_FUNC(64)
#elif PSNIP_ENDIAN_ORDER == PSNIP_ENDIAN_LITTLE
# define psnip_endian_le16(v) ((psnip_uint16_t) (v))
# define psnip_endian_le32(v) ((psnip_uint32_t) (v))
# define psnip_endian_le64(v) ((psnip_uint64_t) (v))
# define psnip_endian_be16(v) psnip_builtin_bswap16((psnip_uint16_t) (v))
# define psnip_endian_be32(v) psnip_builtin_bswap32((psnip_uint32_t) (v))
# define psnip_endian_be64(v) psnip_builtin_bswap64((psnip_uint64_t) (v))
#elif PSNIP_ENDIAN_ORDER == PSNIP_ENDIAN_BIG
# define psnip_endian_le16(v) psnip_builtin_bswap16((psnip_uint16_t) (v))
# define psnip_endian_le32(v) psnip_builtin_bswap32((psnip_uint32_t) (v))
# define psnip_endian_le64(v) psnip_builtin_bswap64((psnip_uint64_t) (v))
# define psnip_endian_be16(v) ((psnip_uint16_t) (v))
# define psnip_endian_be32(v) ((psnip_uint32_t) (v))
# define psnip_endian_be64(v) ((psnip_uint64_t) (v))
#else
# error Unknown endianness.
#endif
#endif /* !defined(PSNIP_ENDIAN_H) */