diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/cc/compat_compiler.h | 197 | ||||
-rw-r--r-- | src/lib/cc/include.am | 4 | ||||
-rw-r--r-- | src/lib/cc/torint.h | 379 |
3 files changed, 580 insertions, 0 deletions
diff --git a/src/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h new file mode 100644 index 0000000000..a9a3266165 --- /dev/null +++ b/src/lib/cc/compat_compiler.h @@ -0,0 +1,197 @@ +/* Copyright (c) 2003-2004, Roger Dingledine + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef TOR_COMPAT_COMPILER_H +#define TOR_COMPAT_COMPILER_H + +#include "orconfig.h" + +#if defined(__has_feature) +# if __has_feature(address_sanitizer) +/* Some of the fancy glibc strcmp() macros include references to memory that + * clang rejects because it is off the end of a less-than-3. Clang hates this, + * even though those references never actually happen. */ +# undef strcmp +#endif /* __has_feature(address_sanitizer) */ +#endif /* defined(__has_feature) */ + +#ifndef NULL_REP_IS_ZERO_BYTES +#error "It seems your platform does not represent NULL as zero. We can't cope." +#endif + +#ifndef DOUBLE_0_REP_IS_ZERO_BYTES +#error "It seems your platform does not represent 0.0 as zeros. We can't cope." +#endif + +#if 'a'!=97 || 'z'!=122 || 'A'!=65 || ' '!=32 +#error "It seems that you encode characters in something other than ASCII." +#endif + +/* GCC can check printf and scanf types on arbitrary functions. */ +#ifdef __GNUC__ +#define CHECK_PRINTF(formatIdx, firstArg) \ + __attribute__ ((format(printf, formatIdx, firstArg))) +#else +#define CHECK_PRINTF(formatIdx, firstArg) +#endif /* defined(__GNUC__) */ +#ifdef __GNUC__ +#define CHECK_SCANF(formatIdx, firstArg) \ + __attribute__ ((format(scanf, formatIdx, firstArg))) +#else +#define CHECK_SCANF(formatIdx, firstArg) +#endif /* defined(__GNUC__) */ + +/* What GCC do we have? */ +#ifdef __GNUC__ +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +#define GCC_VERSION 0 +#endif + +/* Temporarily enable and disable warnings. */ +#ifdef __GNUC__ +# define PRAGMA_STRINGIFY_(s) #s +# define PRAGMA_JOIN_STRINGIFY_(a,b) PRAGMA_STRINGIFY_(a ## b) +/* Support for macro-generated pragmas (c99) */ +# define PRAGMA_(x) _Pragma (#x) +# ifdef __clang__ +# define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(clang diagnostic x) +# else +# define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(GCC diagnostic x) +# endif +# if defined(__clang__) || GCC_VERSION >= 406 +/* we have push/pop support */ +# define DISABLE_GCC_WARNING(warningopt) \ + PRAGMA_DIAGNOSTIC_(push) \ + PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) +# define ENABLE_GCC_WARNING(warningopt) \ + PRAGMA_DIAGNOSTIC_(pop) +#else /* !(defined(__clang__) || GCC_VERSION >= 406) */ +/* older version of gcc: no push/pop support. */ +# define DISABLE_GCC_WARNING(warningopt) \ + PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) +# define ENABLE_GCC_WARNING(warningopt) \ + PRAGMA_DIAGNOSTIC_(warning PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) +#endif /* defined(__clang__) || GCC_VERSION >= 406 */ +#else /* !(defined(__GNUC__)) */ +/* not gcc at all */ +# define DISABLE_GCC_WARNING(warning) +# define ENABLE_GCC_WARNING(warning) +#endif /* defined(__GNUC__) */ + +/* inline is __inline on windows. */ +#ifdef _WIN32 +#define inline __inline +#endif + +/* Try to get a reasonable __func__ substitute in place. */ +#if defined(_MSC_VER) + +#define __func__ __FUNCTION__ + +#else +/* For platforms where autoconf works, make sure __func__ is defined + * sanely. */ +#ifndef HAVE_MACRO__func__ +#ifdef HAVE_MACRO__FUNCTION__ +#define __func__ __FUNCTION__ +#elif HAVE_MACRO__FUNC__ +#define __func__ __FUNC__ +#else +#define __func__ "???" +#endif /* defined(HAVE_MACRO__FUNCTION__) || ... */ +#endif /* !defined(HAVE_MACRO__func__) */ +#endif /* defined(_MSC_VER) */ + +#define U64_TO_DBL(x) ((double) (x)) +#define DBL_TO_U64(x) ((uint64_t) (x)) + +#ifdef ENUM_VALS_ARE_SIGNED +#define ENUM_BF(t) unsigned +#else +/** Wrapper for having a bitfield of an enumerated type. Where possible, we + * just use the enumerated type (so the compiler can help us and notice + * problems), but if enumerated types are unsigned, we must use unsigned, + * so that the loss of precision doesn't make large values negative. */ +#define ENUM_BF(t) t +#endif /* defined(ENUM_VALS_ARE_SIGNED) */ + +/* GCC has several useful attributes. */ +#if defined(__GNUC__) && __GNUC__ >= 3 +#define ATTR_NORETURN __attribute__((noreturn)) +#define ATTR_CONST __attribute__((const)) +#define ATTR_MALLOC __attribute__((malloc)) +#define ATTR_NORETURN __attribute__((noreturn)) +#define ATTR_WUR __attribute__((warn_unused_result)) +/* Alas, nonnull is not at present a good idea for us. We'd like to get + * warnings when we pass NULL where we shouldn't (which nonnull does, albeit + * spottily), but we don't want to tell the compiler to make optimizations + * with the assumption that the argument can't be NULL (since this would make + * many of our checks go away, and make our code less robust against + * programming errors). Unfortunately, nonnull currently does both of these + * things, and there's no good way to split them up. + * + * #define ATTR_NONNULL(x) __attribute__((nonnull x)) */ +#define ATTR_NONNULL(x) +#define ATTR_UNUSED __attribute__ ((unused)) + +/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value + * of <b>exp</b> will probably be true. + * + * In other words, "if (PREDICT_LIKELY(foo))" is the same as "if (foo)", + * except that it tells the compiler that the branch will be taken most of the + * time. This can generate slightly better code with some CPUs. + */ +#define PREDICT_LIKELY(exp) __builtin_expect(!!(exp), 1) +/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value + * of <b>exp</b> will probably be false. + * + * In other words, "if (PREDICT_UNLIKELY(foo))" is the same as "if (foo)", + * except that it tells the compiler that the branch will usually not be + * taken. This can generate slightly better code with some CPUs. + */ +#define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0) +#else /* !(defined(__GNUC__) && __GNUC__ >= 3) */ +#define ATTR_NORETURN +#define ATTR_CONST +#define ATTR_MALLOC +#define ATTR_NORETURN +#define ATTR_NONNULL(x) +#define ATTR_UNUSED +#define ATTR_WUR +#define PREDICT_LIKELY(exp) (exp) +#define PREDICT_UNLIKELY(exp) (exp) +#endif /* defined(__GNUC__) && __GNUC__ >= 3 */ + +/** Expands to a syntactically valid empty statement. */ +#define STMT_NIL (void)0 + +/** Expands to a syntactically valid empty statement, explicitly (void)ing its + * argument. */ +#define STMT_VOID(a) while (0) { (void)(a); } + +#ifdef __GNUC__ +/** STMT_BEGIN and STMT_END are used to wrap blocks inside macros so that + * the macro can be used as if it were a single C statement. */ +#define STMT_BEGIN (void) ({ +#define STMT_END }) +#elif defined(sun) || defined(__sun__) +#define STMT_BEGIN if (1) { +#define STMT_END } else STMT_NIL +#else +#define STMT_BEGIN do { +#define STMT_END } while (0) +#endif /* defined(__GNUC__) || ... */ + +/* Some tools (like coccinelle) don't like to see operators as macro + * arguments. */ +#define OP_LT < +#define OP_GT > +#define OP_GE >= +#define OP_LE <= +#define OP_EQ == +#define OP_NE != + +#endif /* !defined(TOR_COMPAT_H) */ diff --git a/src/lib/cc/include.am b/src/lib/cc/include.am new file mode 100644 index 0000000000..2ae90f97dd --- /dev/null +++ b/src/lib/cc/include.am @@ -0,0 +1,4 @@ + +noinst_HEADERS += \ + src/lib/cc/compat_compiler.h \ + src/lib/cc/torint.h diff --git a/src/lib/cc/torint.h b/src/lib/cc/torint.h new file mode 100644 index 0000000000..55b15402f2 --- /dev/null +++ b/src/lib/cc/torint.h @@ -0,0 +1,379 @@ +/* Copyright (c) 2003, Roger Dingledine + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file torint.h + * \brief Header file to define uint32_t and friends + **/ + +#ifndef TOR_TORINT_H +#define TOR_TORINT_H + +#include "orconfig.h" + +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifdef HAVE_SYS_LIMITS_H +#include <sys/limits.h> +#endif +#ifdef HAVE_MACHINE_LIMITS_H +#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) + /* FreeBSD has a bug where it complains that this file is obsolete, + and I should migrate to using sys/limits. It complains even when + I include both. + __FreeBSD_kernel__ is defined by Debian GNU/kFreeBSD which + does the same thing (but doesn't defined __FreeBSD__). + */ +#include <machine/limits.h> +#endif /* !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) */ +#endif /* defined(HAVE_MACHINE_LIMITS_H) */ +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + +#include <stdbool.h> + +#if (SIZEOF_INT8_T != 0) +#define HAVE_INT8_T +#endif +#if (SIZEOF_INT16_T != 0) +#define HAVE_INT16_T +#endif +#if (SIZEOF_INT32_T != 0) +#define HAVE_INT32_T +#endif +#if (SIZEOF_INT64_T != 0) +#define HAVE_INT64_T +#endif +#if (SIZEOF_UINT8_T != 0) +#define HAVE_UINT8_T +#endif +#if (SIZEOF_UINT16_T != 0) +#define HAVE_UINT16_T +#endif +#if (SIZEOF_UINT32_T != 0) +#define HAVE_UINT32_T +#endif +#if (SIZEOF_UINT64_T != 0) +#define HAVE_UINT64_T +#endif +#if (SIZEOF_INTPTR_T != 0) +#define HAVE_INTPTR_T +#endif +#if (SIZEOF_UINTPTR_T != 0) +#define HAVE_UINTPTR_T +#endif + +#if (SIZEOF_CHAR == 1) +#ifndef HAVE_INT8_T +typedef signed char int8_t; +#define HAVE_INT8_T +#endif +#ifndef HAVE_UINT8_T +typedef unsigned char uint8_t; +#define HAVE_UINT8_T +#endif +#endif /* (SIZEOF_CHAR == 1) */ + +#if (SIZEOF_SHORT == 2) +#ifndef HAVE_INT16_T +typedef signed short int16_t; +#define HAVE_INT16_T +#endif +#ifndef HAVE_UINT16_T +typedef unsigned short uint16_t; +#define HAVE_UINT16_T +#endif +#endif /* (SIZEOF_SHORT == 2) */ + +#if (SIZEOF_INT == 2) +#ifndef HAVE_INT16_T +typedef signed int int16_t; +#define HAVE_INT16_T +#endif +#ifndef HAVE_UINT16_T +typedef unsigned int uint16_t; +#define HAVE_UINT16_T +#endif +#elif (SIZEOF_INT == 4) +#ifndef HAVE_INT32_T +typedef signed int int32_t; +#define HAVE_INT32_T +#endif +#ifndef HAVE_UINT32_T +typedef unsigned int uint32_t; +#define HAVE_UINT32_T +#endif +#ifndef UINT16_MAX +#define UINT16_MAX 0xffffu +#endif +#ifndef INT16_MAX +#define INT16_MAX 0x7fff +#endif +#ifndef INT16_MIN +#define INT16_MIN (-INT16_MAX-1) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX 0xffffffffu +#endif +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#endif /* (SIZEOF_INT == 2) || ... */ + +#if (SIZEOF_LONG == 4) +#ifndef HAVE_INT32_T +typedef signed long int32_t; +#define HAVE_INT32_T +#endif +#ifndef HAVE_UINT32_T +typedef unsigned long uint32_t; +#define HAVE_UINT32_T +#ifndef UINT32_MAX +#define UINT32_MAX 0xfffffffful +#endif +#endif /* !defined(HAVE_UINT32_T) */ +#elif (SIZEOF_LONG == 8) +#ifndef HAVE_INT64_T +typedef signed long int64_t; +#define HAVE_INT64_T +#endif +#ifndef HAVE_UINT32_T +typedef unsigned long uint64_t; +#define HAVE_UINT32_T +#endif +#ifndef UINT64_MAX +#define UINT64_MAX 0xfffffffffffffffful +#endif +#endif /* (SIZEOF_LONG == 4) || ... */ + +#if (SIZEOF_LONG_LONG == 8) +#ifndef HAVE_INT64_T +typedef signed long long int64_t; +#define HAVE_INT64_T +#endif +#ifndef HAVE_UINT64_T +typedef unsigned long long uint64_t; +#define HAVE_UINT64_T +#endif +#ifndef UINT64_MAX +#define UINT64_MAX 0xffffffffffffffffull +#endif +#ifndef INT64_MAX +#define INT64_MAX 0x7fffffffffffffffll +#endif +#endif /* (SIZEOF_LONG_LONG == 8) */ + +#if (SIZEOF___INT64 == 8) +#ifndef HAVE_INT64_T +typedef signed __int64 int64_t; +#define HAVE_INT64_T +#endif +#ifndef HAVE_UINT64_T +typedef unsigned __int64 uint64_t; +#define HAVE_UINT64_T +#endif +#ifndef UINT64_MAX +#define UINT64_MAX 0xffffffffffffffffui64 +#endif +#ifndef INT64_MAX +#define INT64_MAX 0x7fffffffffffffffi64 +#endif +#endif /* (SIZEOF___INT64 == 8) */ + +#ifndef INT64_MIN +#define INT64_MIN ((- INT64_MAX) - 1) +#endif + +#ifndef SIZE_MAX +#if SIZEOF_SIZE_T == 8 +#define SIZE_MAX UINT64_MAX +#elif SIZEOF_SIZE_T == 4 +#define SIZE_MAX UINT32_MAX +#else +#error "Can't define SIZE_MAX" +#endif /* SIZEOF_SIZE_T == 8 || ... */ +#endif /* !defined(SIZE_MAX) */ + +#ifndef HAVE_SSIZE_T +#if SIZEOF_SIZE_T == 8 +typedef int64_t ssize_t; +#elif SIZEOF_SIZE_T == 4 +typedef int32_t ssize_t; +#else +#error "Can't define ssize_t." +#endif /* SIZEOF_SIZE_T == 8 || ... */ +#endif /* !defined(HAVE_SSIZE_T) */ + +#if (SIZEOF_VOID_P > 4 && SIZEOF_VOID_P <= 8) +#ifndef HAVE_INTPTR_T +typedef int64_t intptr_t; +#define SIZEOF_INTPTR_T 8 +#endif +#ifndef HAVE_UINTPTR_T +typedef uint64_t uintptr_t; +#define SIZEOF_UINTPTR_T 8 +#endif +#elif (SIZEOF_VOID_P > 2 && SIZEOF_VOID_P <= 4) +#ifndef HAVE_INTPTR_T +typedef int32_t intptr_t; +#define SIZEOF_INTPTR_T 4 +#endif +#ifndef HAVE_UINTPTR_T +typedef uint32_t uintptr_t; +#define SIZEOF_UINTPTR_T 4 +#endif +#else +#error "void * is either >8 bytes or <= 2. In either case, I am confused." +#endif /* (SIZEOF_VOID_P > 4 && SIZEOF_VOID_P <= 8) || ... */ + +#ifndef HAVE_INT8_T +#error "Missing type int8_t" +#endif +#ifndef HAVE_UINT8_T +#error "Missing type uint8_t" +#endif +#ifndef HAVE_INT16_T +#error "Missing type int16_t" +#endif +#ifndef HAVE_UINT16_T +#error "Missing type uint16_t" +#endif +#ifndef HAVE_INT32_T +#error "Missing type int32_t" +#endif +#ifndef HAVE_UINT32_T +#error "Missing type uint32_t" +#endif +#ifndef HAVE_INT64_T +#error "Missing type int64_t" +#endif +#ifndef HAVE_UINT64_T +#error "Missing type uint64_t" +#endif + +/* This assumes a sane (2's-complement) representation. But if you + * aren't 2's complement, and you don't define LONG_MAX, then you're so + * bizarre that I want nothing to do with you. */ +#ifndef USING_TWOS_COMPLEMENT +#error "Seems that your platform doesn't use 2's complement arithmetic. Argh." +#endif +#ifndef LONG_MAX +#if (SIZEOF_LONG == 4) +#define LONG_MAX 0x7fffffffL +#elif (SIZEOF_LONG == 8) +#define LONG_MAX 0x7fffffffffffffffL +#else +#error "Can't define LONG_MAX" +#endif /* (SIZEOF_LONG == 4) || ... */ +#endif /* !defined(LONG_MAX) */ + +#ifndef INT_MAX +#if (SIZEOF_INT == 4) +#define INT_MAX 0x7fffffffL +#elif (SIZEOF_INT == 8) +#define INT_MAX 0x7fffffffffffffffL +#else +#error "Can't define INT_MAX" +#endif /* (SIZEOF_INT == 4) || ... */ +#endif /* !defined(INT_MAX) */ + +#ifndef UINT_MAX +#if (SIZEOF_INT == 2) +#define UINT_MAX 0xffffu +#elif (SIZEOF_INT == 4) +#define UINT_MAX 0xffffffffu +#elif (SIZEOF_INT == 8) +#define UINT_MAX 0xffffffffffffffffu +#else +#error "Can't define UINT_MAX" +#endif /* (SIZEOF_INT == 2) || ... */ +#endif /* !defined(UINT_MAX) */ + +#ifndef SHORT_MAX +#if (SIZEOF_SHORT == 2) +#define SHORT_MAX 0x7fff +#elif (SIZEOF_SHORT == 4) +#define SHORT_MAX 0x7fffffff +#else +#error "Can't define SHORT_MAX" +#endif /* (SIZEOF_SHORT == 2) || ... */ +#endif /* !defined(SHORT_MAX) */ + +#ifndef TIME_MAX + +#if (SIZEOF_TIME_T == SIZEOF_INT) +#define TIME_MAX ((time_t)INT_MAX) +#elif (SIZEOF_TIME_T == SIZEOF_LONG) +#define TIME_MAX ((time_t)LONG_MAX) +#elif (SIZEOF_TIME_T == 8) +#define TIME_MAX ((time_t)INT64_MAX) +#else +#error "Can't define TIME_MAX" +#endif /* (SIZEOF_TIME_T == SIZEOF_INT) || ... */ + +#endif /* !defined(TIME_MAX) */ + +#ifndef TIME_MIN + +#if (SIZEOF_TIME_T == SIZEOF_INT) +#define TIME_MIN ((time_t)INT_MIN) +#elif (SIZEOF_TIME_T == SIZEOF_LONG) +#define TIME_MIN ((time_t)LONG_MIN) +#elif (SIZEOF_TIME_T == 8) +#define TIME_MIN ((time_t)INT64_MIN) +#else +#error "Can't define TIME_MIN" +#endif /* (SIZEOF_TIME_T == SIZEOF_INT) || ... */ + +#endif /* !defined(TIME_MIN) */ + +#ifndef SIZE_MAX +#if (SIZEOF_SIZE_T == 4) +#define SIZE_MAX UINT32_MAX +#elif (SIZEOF_SIZE_T == 8) +#define SIZE_MAX UINT64_MAX +#else +#error "Can't define SIZE_MAX" +#endif /* (SIZEOF_SIZE_T == 4) || ... */ +#endif /* !defined(SIZE_MAX) */ + +#ifdef _WIN32 +# ifdef _WIN64 +# define TOR_PRIuSZ PRIu64 +# else +# define TOR_PRIuSZ PRIu32 +# endif +#else +# define TOR_PRIuSZ "zu" +#endif + +#ifndef SSIZE_MAX +#if (SIZEOF_SIZE_T == 4) +#define SSIZE_MAX INT32_MAX +#elif (SIZEOF_SIZE_T == 8) +#define SSIZE_MAX INT64_MAX +#else +#error "Can't define SSIZE_MAX" +#endif /* (SIZEOF_SIZE_T == 4) || ... */ +#endif /* !defined(SSIZE_MAX) */ + +/** Any ssize_t larger than this amount is likely to be an underflow. */ +#define SSIZE_T_CEILING ((ssize_t)(SSIZE_MAX-16)) +/** Any size_t larger than this amount is likely to be an underflow. */ +#define SIZE_T_CEILING ((size_t)(SSIZE_MAX-16)) + +#endif /* !defined(TOR_TORINT_H) */ + |