platform.h 10 KB

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