printf: fix printf "%u\n" +18446744073709551614
[oweals/busybox.git] / include / platform.h
index 413c2224c1f1a15ac16366101b0232e722e39bef..c365d5c8c15e4014a96fccc66e6a2c12769d14fd 100644 (file)
 
 #define UNUSED_PARAM __attribute__ ((__unused__))
 #define NORETURN __attribute__ ((__noreturn__))
+
+#if __GNUC_PREREQ(4,5)
+# define bb_unreachable(altcode) __builtin_unreachable()
+#else
+# define bb_unreachable(altcode) altcode
+#endif
+
 /* "The malloc attribute is used to tell the compiler that a function
  * may be treated as if any non-NULL pointer it returns cannot alias
  * any other pointer valid when the function returns. This will often
@@ -76,8 +83,8 @@
 # define UNUSED_PARAM_RESULT
 #endif
 
-/* used by unit test machinery to run registration functions */
-#define INIT_LAST __attribute__ ((constructor(2000)))
+/* used by unit test machinery to run registration functions before calling main() */
+#define INIT_FUNC __attribute__ ((constructor))
 
 /* -fwhole-program makes all symbols local. The attribute externally_visible
  * forces a symbol global.  */
  * and/or smaller by using modified ABI. It is usually only needed
  * on non-static, busybox internal functions. Recent versions of gcc
  * optimize statics automatically. FAST_FUNC on static is required
- * only if you need to match a function pointer's type */
-#if __GNUC_PREREQ(3,0) && defined(i386) /* || defined(__x86_64__)? */
+ * only if you need to match a function pointer's type.
+ * FAST_FUNC may not work well with -flto so allow user to disable this.
+ * (-DFAST_FUNC= )
+ */
+#ifndef FAST_FUNC
+# if __GNUC_PREREQ(3,0) && defined(i386)
 /* stdcall makes callee to pop arguments from stack, not caller */
-# define FAST_FUNC __attribute__((regparm(3),stdcall))
+#  define FAST_FUNC __attribute__((regparm(3),stdcall))
 /* #elif ... - add your favorite arch today! */
-#else
-# define FAST_FUNC
+# else
+#  define FAST_FUNC
+# endif
 #endif
 
 /* Make all declarations hidden (-fvisibility flag only affects definitions) */
@@ -217,6 +229,7 @@ typedef uint64_t bb__aliased_uint64_t FIX_ALIASING;
  * a lvalue. This makes it more likely to not swap them by mistake
  */
 #if defined(i386) || defined(__x86_64__) || defined(__powerpc__)
+# define BB_UNALIGNED_MEMACCESS_OK 1
 # define move_from_unaligned_int(v, intp)  ((v) = *(bb__aliased_int*)(intp))
 # define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp))
 # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p))
@@ -225,6 +238,7 @@ typedef uint64_t bb__aliased_uint64_t FIX_ALIASING;
 # define move_to_unaligned32(u32p, v)   (*(bb__aliased_uint32_t*)(u32p) = (v))
 /* #elif ... - add your favorite arch today! */
 #else
+# define BB_UNALIGNED_MEMACCESS_OK 0
 /* performs reasonably well (gcc usually inlines memcpy here) */
 # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int)))
 # define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long)))
@@ -240,6 +254,17 @@ typedef uint64_t bb__aliased_uint64_t FIX_ALIASING;
 } while (0)
 #endif
 
+/* Unaligned, fixed-endian accessors */
+#define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); })
+#define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); })
+#define put_unaligned_le32(val, buf) move_to_unaligned32(buf, SWAP_LE32(val))
+#define put_unaligned_be32(val, buf) move_to_unaligned32(buf, SWAP_BE32(val))
+
+/* unxz needs an aligned fixed-endian accessor.
+ * (however, the compiler does not realize it's aligned, the cast is still necessary)
+ */
+#define get_le32(u32p) ({ uint32_t v = *(bb__aliased_uint32_t*)(u32p); SWAP_LE32(v); })
+
 
 /* ---- Size-saving "small" ints (arch-dependent) ----------- */
 
@@ -366,10 +391,12 @@ typedef unsigned smalluint;
 #define HAVE_DPRINTF 1
 #define HAVE_MEMRCHR 1
 #define HAVE_MKDTEMP 1
+#define HAVE_TTYNAME_R 1
 #define HAVE_PTSNAME_R 1
 #define HAVE_SETBIT 1
 #define HAVE_SIGHANDLER_T 1
 #define HAVE_STPCPY 1
+#define HAVE_MEMPCPY 1
 #define HAVE_STRCASESTR 1
 #define HAVE_STRCHRNUL 1
 #define HAVE_STRSEP 1
@@ -384,6 +411,7 @@ typedef unsigned smalluint;
 #define HAVE_MNTENT_H 1
 #define HAVE_NET_ETHERNET_H 1
 #define HAVE_SYS_STATFS_H 1
+#define HAVE_PRINTF_PERCENTM 1
 
 #if defined(__UCLIBC__)
 # if UCLIBC_VERSION < KERNEL_VERSION(0, 9, 32)
@@ -439,6 +467,7 @@ typedef unsigned smalluint;
 # undef HAVE_DPRINTF
 # undef HAVE_UNLOCKED_STDIO
 # undef HAVE_UNLOCKED_LINE_OPS
+# undef HAVE_PRINTF_PERCENTM
 #endif
 
 #if defined(__dietlibc__)
@@ -450,6 +479,8 @@ typedef unsigned smalluint;
 #endif
 
 #if defined(__FreeBSD__)
+/* users say mempcpy is not present in FreeBSD 9.x */
+# undef HAVE_MEMPCPY
 # undef HAVE_CLEARENV
 # undef HAVE_FDATASYNC
 # undef HAVE_MNTENT_H
@@ -459,6 +490,7 @@ typedef unsigned smalluint;
 # undef HAVE_STRVERSCMP
 # undef HAVE_XTABS
 # undef HAVE_UNLOCKED_LINE_OPS
+# undef HAVE_PRINTF_PERCENTM
 # include <osreldate.h>
 # if __FreeBSD_version < 1000029
 #  undef HAVE_STRCHRNUL /* FreeBSD added strchrnul() between 1000028 and 1000029 */
@@ -474,13 +506,26 @@ typedef unsigned smalluint;
 #endif
 
 #if defined(ANDROID) || defined(__ANDROID__)
-# undef HAVE_DPRINTF
-# undef HAVE_GETLINE
-# undef HAVE_STPCPY
+# if __ANDROID_API__ < 8
+   /* ANDROID < 8 has no [f]dprintf at all */
+#  undef HAVE_DPRINTF
+# elif __ANDROID_API__ < 21
+   /* ANDROID < 21 has fdprintf */
+#  define dprintf fdprintf
+# else
+   /* ANDROID >= 21 has standard dprintf */
+# endif
+# if __ANDROID_API__ < 21
+#  undef HAVE_TTYNAME_R
+#  undef HAVE_GETLINE
+#  undef HAVE_STPCPY
+# endif
+# undef HAVE_MEMPCPY
 # undef HAVE_STRCHRNUL
 # undef HAVE_STRVERSCMP
 # undef HAVE_UNLOCKED_LINE_OPS
 # undef HAVE_NET_ETHERNET_H
+# undef HAVE_PRINTF_PERCENTM
 #endif
 
 /*
@@ -500,6 +545,11 @@ extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC;
 extern char *mkdtemp(char *template) FAST_FUNC;
 #endif
 
+#ifndef HAVE_TTYNAME_R
+#define ttyname_r bb_ttyname_r
+extern int ttyname_r(int fd, char *buf, size_t buflen);
+#endif
+
 #ifndef HAVE_SETBIT
 # define setbit(a, b)  ((a)[(b) >> 3] |= 1 << ((b) & 7))
 # define clrbit(a, b)  ((a)[(b) >> 3] &= ~(1 << ((b) & 7)))
@@ -513,6 +563,18 @@ typedef void (*sighandler_t)(int);
 extern char *stpcpy(char *p, const char *to_add) FAST_FUNC;
 #endif
 
+#ifndef HAVE_MEMPCPY
+#include <string.h>
+/* In case we are wrong about !HAVE_MEMPCPY, and toolchain _does_ have
+ * mempcpy(), avoid colliding with it:
+ */
+#define mempcpy bb__mempcpy
+static ALWAYS_INLINE void *mempcpy(void *dest, const void *src, size_t len)
+{
+       return memcpy(dest, src, len) + len;
+}
+#endif
+
 #ifndef HAVE_STRCASESTR
 extern char *strcasestr(const char *s, const char *pattern) FAST_FUNC;
 #endif