1/* vi: set sw=4 ts=4: */ 2/* 3 Copyright 2006, Bernhard Fischer 4 5 Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 6*/ 7#ifndef __PLATFORM_H 8#define __PLATFORM_H 1 9 10/* Convenience macros to test the version of gcc. */ 11#undef __GNUC_PREREQ 12#if defined __GNUC__ && defined __GNUC_MINOR__ 13# define __GNUC_PREREQ(maj, min) \ 14 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) 15#else 16# define __GNUC_PREREQ(maj, min) 0 17#endif 18 19/* __restrict is known in EGCS 1.2 and above. */ 20#if !__GNUC_PREREQ (2,92) 21# ifndef __restrict 22# define __restrict /* Ignore */ 23# endif 24#endif 25 26/* Define macros for some gcc attributes. This permits us to use the 27 macros freely, and know that they will come into play for the 28 version of gcc in which they are supported. */ 29 30#if !__GNUC_PREREQ (2,7) 31# ifndef __attribute__ 32# define __attribute__(x) 33# endif 34#endif 35 36#undef inline 37#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 199901L 38/* it's a keyword */ 39#else 40# if __GNUC_PREREQ (2,7) 41# define inline __inline__ 42# else 43# define inline 44# endif 45#endif 46 47#ifndef __const 48# define __const const 49#endif 50 51# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 52# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 53# define ATTRIBUTE_PACKED __attribute__ ((__packed__)) 54# define ATTRIBUTE_ALIGNED(m) __attribute__ ((__aligned__(m))) 55# if __GNUC_PREREQ (3,0) 56# define ALWAYS_INLINE __attribute__ ((always_inline)) inline 57# if !ENABLE_WERROR 58# define ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) 59# define ATTRIBUTE_UNUSED_RESULT __attribute__ ((warn_unused_result)) 60# else 61# define ATTRIBUTE_DEPRECATED /* n/a */ 62# define ATTRIBUTE_UNUSED_RESULT /* n/a */ 63# endif 64# else 65# define ALWAYS_INLINE inline 66# define ATTRIBUTE_DEPRECATED /* n/a */ 67# define ATTRIBUTE_UNUSED_RESULT /* n/a */ 68# endif 69 70/* -fwhole-program makes all symbols local. The attribute externally_visible 71 forces a symbol global. */ 72# if __GNUC_PREREQ (4,1) 73# define ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((__externally_visible__)) 74# else 75# define ATTRIBUTE_EXTERNALLY_VISIBLE 76# endif /* GNUC >= 4.1 */ 77 78/* We use __extension__ in some places to suppress -pedantic warnings 79 about GCC extensions. This feature didn't work properly before 80 gcc 2.8. */ 81#if !__GNUC_PREREQ (2,8) 82# ifndef __extension__ 83# define __extension__ 84# endif 85#endif 86 87/* gcc-2.95 had no va_copy but only __va_copy. */ 88#if !__GNUC_PREREQ (3,0) 89# include <stdarg.h> 90# if !defined va_copy && defined __va_copy 91# define va_copy(d,s) __va_copy((d),(s)) 92# endif 93#endif 94 95/* ---- Endian Detection ------------------------------------ */ 96 97#if (defined __digital__ && defined __unix__) 98# include <sex.h> 99# define __BIG_ENDIAN__ (BYTE_ORDER == BIG_ENDIAN) 100# define __BYTE_ORDER BYTE_ORDER 101#elif !defined __APPLE__ 102# include <byteswap.h> 103# include <endian.h> 104#endif 105 106#ifdef __BIG_ENDIAN__ 107# define BB_BIG_ENDIAN 1 108# define BB_LITTLE_ENDIAN 0 109#elif __BYTE_ORDER == __BIG_ENDIAN 110# define BB_BIG_ENDIAN 1 111# define BB_LITTLE_ENDIAN 0 112#else 113# define BB_BIG_ENDIAN 0 114# define BB_LITTLE_ENDIAN 1 115#endif 116 117#if BB_BIG_ENDIAN 118#define SWAP_BE16(x) (x) 119#define SWAP_BE32(x) (x) 120#define SWAP_BE64(x) (x) 121#define SWAP_LE16(x) bswap_16(x) 122#define SWAP_LE32(x) bswap_32(x) 123#define SWAP_LE64(x) bswap_64(x) 124#else 125#define SWAP_BE16(x) bswap_16(x) 126#define SWAP_BE32(x) bswap_32(x) 127#define SWAP_BE64(x) bswap_64(x) 128#define SWAP_LE16(x) (x) 129#define SWAP_LE32(x) (x) 130#define SWAP_LE64(x) (x) 131#endif 132 133/* ---- Networking ------------------------------------------ */ 134#ifndef __APPLE__ 135# include <arpa/inet.h> 136#else 137# include <netinet/in.h> 138#endif 139 140#ifndef __socklen_t_defined 141typedef int socklen_t; 142#endif 143 144/* ---- Compiler dependent settings ------------------------- */ 145#if (defined __digital__ && defined __unix__) 146# undef HAVE_MNTENT_H 147#else 148# define HAVE_MNTENT_H 1 149#endif /* ___digital__ && __unix__ */ 150 151/* linux/loop.h relies on __u64. Make sure we have that as a proper type 152 * until userspace is widely fixed. */ 153#ifndef __GNUC__ 154#if defined __INTEL_COMPILER 155__extension__ typedef __signed__ long long __s64; 156__extension__ typedef unsigned long long __u64; 157#endif /* __INTEL_COMPILER */ 158#endif /* ifndef __GNUC__ */ 159 160/*----- Kernel versioning ------------------------------------*/ 161#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) 162 163/* ---- miscellaneous --------------------------------------- */ 164 165#if defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ < 5 && !defined(__dietlibc__) && \ 166 !defined(_NEWLIB_VERSION) && !(defined __digital__ && defined __unix__) 167# error "Sorry, this libc version is not supported :(" 168#endif 169 170/* Don't perpetuate e2fsck crap into the headers. Clean up e2fsck instead. */ 171 172#if defined __GLIBC__ || defined __UCLIBC__ || defined __dietlibc__ || defined \ 173 _NEWLIB_VERSION 174#include <features.h> 175#define HAVE_FEATURES_H 176#include <stdint.h> 177#define HAVE_STDINT_H 178#else 179/* Largest integral types. */ 180#if __BIG_ENDIAN__ 181typedef long intmax_t; 182typedef unsigned long uintmax_t; 183#else 184__extension__ 185typedef long long intmax_t; 186__extension__ 187typedef unsigned long long uintmax_t; 188#endif 189#endif 190 191/* Size-saving "small" ints (arch-dependent) */ 192#if defined(i386) || defined(__x86_64__) || defined(__mips__) || defined(__cris__) 193/* add other arches which benefit from this... */ 194typedef signed char smallint; 195typedef unsigned char smalluint; 196#else 197/* for arches where byte accesses generate larger code: */ 198typedef int smallint; 199typedef unsigned smalluint; 200#endif 201 202/* ISO C Standard: 7.16 Boolean type and values <stdbool.h> */ 203#if (defined __digital__ && defined __unix__) 204/* old system without (proper) C99 support */ 205#define bool smalluint 206#else 207/* modern system, so use it */ 208#include <stdbool.h> 209#endif 210 211/* Try to defeat gcc's alignment of "char message[]"-like data */ 212#define ALIGN1 __attribute__((aligned(1))) 213#define ALIGN2 __attribute__((aligned(2))) 214 215 216/* uclibc does not implement daemon() for no-mmu systems. 217 * For 0.9.29 and svn, __ARCH_USE_MMU__ indicates no-mmu reliably. 218 * For earlier versions there is no reliable way to check if we are building 219 * for a mmu-less system; the user should pass EXTRA_CFLAGS="-DBB_NOMMU" 220 * on his own. 221 */ 222#if defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \ 223 __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__ 224#define BB_MMU 0 225#define BB_NOMMU 1 226#define USE_FOR_NOMMU(...) __VA_ARGS__ 227#define USE_FOR_MMU(...) 228#else 229#define BB_MMU 1 230/* BB_NOMMU is not defined in this case! */ 231#define USE_FOR_NOMMU(...) 232#define USE_FOR_MMU(...) __VA_ARGS__ 233#endif 234 235/* Platforms that haven't got dprintf need to implement fdprintf() in 236 * libbb. This would require a platform.c. It's not going to be cleaned 237 * out of the tree, so stop saying it should be. */ 238#if !defined(__dietlibc__) 239/* Needed for: glibc */ 240/* Not needed for: dietlibc */ 241/* Others: ?? (add as needed) */ 242#define fdprintf dprintf 243#endif 244 245#if defined(__dietlibc__) 246static ALWAYS_INLINE char* strchrnul(const char *s, char c) 247{ 248 while (*s && *s != c) ++s; 249 return (char*)s; 250} 251#endif 252 253/* Don't use lchown with glibc older than 2.1.x ... uClibc lacks it */ 254#if (defined __GLIBC__ && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 1) || defined __UC_LIBC__ 255# define lchown chown 256#endif 257 258/* THIS SHOULD BE CLEANED OUT OF THE TREE ENTIRELY */ 259#ifndef FNM_LEADING_DIR 260#define FNM_LEADING_DIR 0 261#endif 262 263#if (defined __digital__ && defined __unix__) 264#include <standards.h> 265#define HAVE_STANDARDS_H 266#include <inttypes.h> 267#define HAVE_INTTYPES_H 268#define PRIu32 "u" 269 270/* use legacy setpgrp(pid_t,pid_t) for now. move to platform.c */ 271#define bb_setpgrp() do { pid_t __me = getpid(); setpgrp(__me,__me); } while (0) 272 273#if !defined ADJ_OFFSET_SINGLESHOT && defined MOD_CLKA && defined MOD_OFFSET 274#define ADJ_OFFSET_SINGLESHOT (MOD_CLKA | MOD_OFFSET) 275#endif 276#if !defined ADJ_FREQUENCY && defined MOD_FREQUENCY 277#define ADJ_FREQUENCY MOD_FREQUENCY 278#endif 279#if !defined ADJ_TIMECONST && defined MOD_TIMECONST 280#define ADJ_TIMECONST MOD_TIMECONST 281#endif 282#if !defined ADJ_TICK && defined MOD_CLKB 283#define ADJ_TICK MOD_CLKB 284#endif 285 286#else 287#define bb_setpgrp() setpgrp() 288#endif 289 290#if defined(__linux__) 291#include <sys/mount.h> 292/* Make sure we have all the new mount flags we actually try to use. */ 293#ifndef MS_BIND 294#define MS_BIND (1<<12) 295#endif 296#ifndef MS_MOVE 297#define MS_MOVE (1<<13) 298#endif 299#ifndef MS_RECURSIVE 300#define MS_RECURSIVE (1<<14) 301#endif 302#ifndef MS_SILENT 303#define MS_SILENT (1<<15) 304#endif 305 306/* The shared subtree stuff, which went in around 2.6.15. */ 307#ifndef MS_UNBINDABLE 308#define MS_UNBINDABLE (1<<17) 309#endif 310#ifndef MS_PRIVATE 311#define MS_PRIVATE (1<<18) 312#endif 313#ifndef MS_SLAVE 314#define MS_SLAVE (1<<19) 315#endif 316#ifndef MS_SHARED 317#define MS_SHARED (1<<20) 318#endif 319 320 321#if !defined(BLKSSZGET) 322#define BLKSSZGET _IO(0x12, 104) 323#endif 324#if !defined(BLKGETSIZE64) 325#define BLKGETSIZE64 _IOR(0x12,114,size_t) 326#endif 327#endif 328 329#endif /* platform.h */ 330