3
0

platform.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Copyright 2006, Bernhard Reutner-Fischer
  4. *
  5. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  6. */
  7. #ifndef BB_PLATFORM_H
  8. #define BB_PLATFORM_H 1
  9. /* Assume all these functions exist by default. Platforms where it is not
  10. * true will #undef them below.
  11. */
  12. #define HAVE_FDPRINTF 1
  13. #define HAVE_MEMRCHR 1
  14. #define HAVE_MKDTEMP 1
  15. #define HAVE_SETBIT 1
  16. #define HAVE_STRCASESTR 1
  17. #define HAVE_STRCHRNUL 1
  18. #define HAVE_STRSEP 1
  19. #define HAVE_STRSIGNAL 1
  20. #define HAVE_VASPRINTF 1
  21. /* Convenience macros to test the version of gcc. */
  22. #undef __GNUC_PREREQ
  23. #if defined __GNUC__ && defined __GNUC_MINOR__
  24. # define __GNUC_PREREQ(maj, min) \
  25. ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
  26. #else
  27. # define __GNUC_PREREQ(maj, min) 0
  28. #endif
  29. /* __restrict is known in EGCS 1.2 and above. */
  30. #if !__GNUC_PREREQ(2,92)
  31. # ifndef __restrict
  32. # define __restrict
  33. # endif
  34. #endif
  35. /* Define macros for some gcc attributes. This permits us to use the
  36. macros freely, and know that they will come into play for the
  37. version of gcc in which they are supported. */
  38. #if !__GNUC_PREREQ(2,7)
  39. # ifndef __attribute__
  40. # define __attribute__(x)
  41. # endif
  42. #endif
  43. #undef inline
  44. #if defined(__STDC_VERSION__) && __STDC_VERSION__ > 199901L
  45. /* it's a keyword */
  46. #elif __GNUC_PREREQ(2,7)
  47. # define inline __inline__
  48. #else
  49. # define inline
  50. #endif
  51. #ifndef __const
  52. # define __const const
  53. #endif
  54. #define UNUSED_PARAM __attribute__ ((__unused__))
  55. #define NORETURN __attribute__ ((__noreturn__))
  56. /* "The malloc attribute is used to tell the compiler that a function
  57. * may be treated as if any non-NULL pointer it returns cannot alias
  58. * any other pointer valid when the function returns. This will often
  59. * improve optimization. Standard functions with this property include
  60. * malloc and calloc. realloc-like functions have this property as long
  61. * as the old pointer is never referred to (including comparing it
  62. * to the new pointer) after the function returns a non-NULL value."
  63. */
  64. #define RETURNS_MALLOC __attribute__ ((malloc))
  65. #define PACKED __attribute__ ((__packed__))
  66. #define ALIGNED(m) __attribute__ ((__aligned__(m)))
  67. /* __NO_INLINE__: some gcc's do not honor inlining! :( */
  68. #if __GNUC_PREREQ(3,0) && !defined(__NO_INLINE__)
  69. # define ALWAYS_INLINE __attribute__ ((always_inline)) inline
  70. /* I've seen a toolchain where I needed __noinline__ instead of noinline */
  71. # define NOINLINE __attribute__((__noinline__))
  72. # if !ENABLE_WERROR
  73. # define DEPRECATED __attribute__ ((__deprecated__))
  74. # define UNUSED_PARAM_RESULT __attribute__ ((warn_unused_result))
  75. # else
  76. # define DEPRECATED
  77. # define UNUSED_PARAM_RESULT
  78. # endif
  79. #else
  80. # define ALWAYS_INLINE inline
  81. # define NOINLINE
  82. # define DEPRECATED
  83. # define UNUSED_PARAM_RESULT
  84. #endif
  85. /* -fwhole-program makes all symbols local. The attribute externally_visible
  86. forces a symbol global. */
  87. #if __GNUC_PREREQ(4,1)
  88. # define EXTERNALLY_VISIBLE __attribute__(( visibility("default") ))
  89. //__attribute__ ((__externally_visible__))
  90. #else
  91. # define EXTERNALLY_VISIBLE
  92. #endif
  93. /* At 4.4 gcc become much more anal about this, need to use "aliased" types */
  94. #if __GNUC_PREREQ(4,4)
  95. # define FIX_ALIASING __attribute__((__may_alias__))
  96. #else
  97. # define FIX_ALIASING
  98. #endif
  99. /* We use __extension__ in some places to suppress -pedantic warnings
  100. about GCC extensions. This feature didn't work properly before
  101. gcc 2.8. */
  102. #if !__GNUC_PREREQ(2,8)
  103. # ifndef __extension__
  104. # define __extension__
  105. # endif
  106. #endif
  107. /* gcc-2.95 had no va_copy but only __va_copy. */
  108. #if !__GNUC_PREREQ(3,0)
  109. # include <stdarg.h>
  110. # if !defined va_copy && defined __va_copy
  111. # define va_copy(d,s) __va_copy((d),(s))
  112. # endif
  113. #endif
  114. /* FAST_FUNC is a qualifier which (possibly) makes function call faster
  115. * and/or smaller by using modified ABI. It is usually only needed
  116. * on non-static, busybox internal functions. Recent versions of gcc
  117. * optimize statics automatically. FAST_FUNC on static is required
  118. * only if you need to match a function pointer's type */
  119. #if __GNUC_PREREQ(3,0) && defined(i386) /* || defined(__x86_64__)? */
  120. /* stdcall makes callee to pop arguments from stack, not caller */
  121. # define FAST_FUNC __attribute__((regparm(3),stdcall))
  122. /* #elif ... - add your favorite arch today! */
  123. #else
  124. # define FAST_FUNC
  125. #endif
  126. /* Make all declarations hidden (-fvisibility flag only affects definitions) */
  127. /* (don't include system headers after this until corresponding pop!) */
  128. #if __GNUC_PREREQ(4,1)
  129. # define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN _Pragma("GCC visibility push(hidden)")
  130. # define POP_SAVED_FUNCTION_VISIBILITY _Pragma("GCC visibility pop")
  131. #else
  132. # define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
  133. # define POP_SAVED_FUNCTION_VISIBILITY
  134. #endif
  135. /* ---- Endian Detection ------------------------------------ */
  136. #include <limits.h>
  137. #if defined(__digital__) && defined(__unix__)
  138. # include <sex.h>
  139. #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
  140. || defined(__APPLE__)
  141. # include <sys/resource.h> /* rlimit */
  142. # include <machine/endian.h>
  143. # define bswap_64 __bswap64
  144. # define bswap_32 __bswap32
  145. # define bswap_16 __bswap16
  146. #else
  147. # include <byteswap.h>
  148. # include <endian.h>
  149. #endif
  150. #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN
  151. # define BB_BIG_ENDIAN 1
  152. # define BB_LITTLE_ENDIAN 0
  153. #elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
  154. # define BB_BIG_ENDIAN 0
  155. # define BB_LITTLE_ENDIAN 1
  156. #elif defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN
  157. # define BB_BIG_ENDIAN 1
  158. # define BB_LITTLE_ENDIAN 0
  159. #elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN
  160. # define BB_BIG_ENDIAN 0
  161. # define BB_LITTLE_ENDIAN 1
  162. #elif defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
  163. # define BB_BIG_ENDIAN 1
  164. # define BB_LITTLE_ENDIAN 0
  165. #elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
  166. # define BB_BIG_ENDIAN 0
  167. # define BB_LITTLE_ENDIAN 1
  168. #elif defined(__386__)
  169. # define BB_BIG_ENDIAN 0
  170. # define BB_LITTLE_ENDIAN 1
  171. #else
  172. # error "Can't determine endianness"
  173. #endif
  174. #if ULONG_MAX > 0xffffffff
  175. # define bb_bswap_64(x) bswap_64(x)
  176. #endif
  177. /* SWAP_LEnn means "convert CPU<->little_endian by swapping bytes" */
  178. #if BB_BIG_ENDIAN
  179. # define SWAP_BE16(x) (x)
  180. # define SWAP_BE32(x) (x)
  181. # define SWAP_BE64(x) (x)
  182. # define SWAP_LE16(x) bswap_16(x)
  183. # define SWAP_LE32(x) bswap_32(x)
  184. # define SWAP_LE64(x) bb_bswap_64(x)
  185. # define IF_BIG_ENDIAN(...) __VA_ARGS__
  186. # define IF_LITTLE_ENDIAN(...)
  187. #else
  188. # define SWAP_BE16(x) bswap_16(x)
  189. # define SWAP_BE32(x) bswap_32(x)
  190. # define SWAP_BE64(x) bb_bswap_64(x)
  191. # define SWAP_LE16(x) (x)
  192. # define SWAP_LE32(x) (x)
  193. # define SWAP_LE64(x) (x)
  194. # define IF_BIG_ENDIAN(...)
  195. # define IF_LITTLE_ENDIAN(...) __VA_ARGS__
  196. #endif
  197. /* ---- Unaligned access ------------------------------------ */
  198. /* NB: unaligned parameter should be a pointer, aligned one -
  199. * a lvalue. This makes it more likely to not swap them by mistake
  200. */
  201. #if defined(i386) || defined(__x86_64__) || defined(__powerpc__)
  202. # include <stdint.h>
  203. typedef int bb__aliased_int FIX_ALIASING;
  204. typedef uint16_t bb__aliased_uint16_t FIX_ALIASING;
  205. typedef uint32_t bb__aliased_uint32_t FIX_ALIASING;
  206. # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp))
  207. # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p))
  208. # define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p))
  209. # define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v))
  210. # define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v))
  211. /* #elif ... - add your favorite arch today! */
  212. #else
  213. /* performs reasonably well (gcc usually inlines memcpy here) */
  214. # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int)))
  215. # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2))
  216. # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4))
  217. # define move_to_unaligned16(u16p, v) do { \
  218. uint16_t __t = (v); \
  219. memcpy((u16p), &__t, 4); \
  220. } while (0)
  221. # define move_to_unaligned32(u32p, v) do { \
  222. uint32_t __t = (v); \
  223. memcpy((u32p), &__t, 4); \
  224. } while (0)
  225. #endif
  226. /* ---- Compiler dependent settings ------------------------- */
  227. #if (defined __digital__ && defined __unix__) \
  228. || defined __APPLE__ \
  229. || defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__
  230. # undef HAVE_MNTENT_H
  231. # undef HAVE_SYS_STATFS_H
  232. #else
  233. # define HAVE_MNTENT_H 1
  234. # define HAVE_SYS_STATFS_H 1
  235. #endif
  236. /*----- Kernel versioning ------------------------------------*/
  237. #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
  238. /* ---- Miscellaneous --------------------------------------- */
  239. #if defined __GLIBC__ || defined __UCLIBC__ \
  240. || defined __dietlibc__ || defined _NEWLIB_VERSION
  241. # include <features.h>
  242. #endif
  243. /* Size-saving "small" ints (arch-dependent) */
  244. #if defined(i386) || defined(__x86_64__) || defined(__mips__) || defined(__cris__)
  245. /* add other arches which benefit from this... */
  246. typedef signed char smallint;
  247. typedef unsigned char smalluint;
  248. #else
  249. /* for arches where byte accesses generate larger code: */
  250. typedef int smallint;
  251. typedef unsigned smalluint;
  252. #endif
  253. /* ISO C Standard: 7.16 Boolean type and values <stdbool.h> */
  254. #if (defined __digital__ && defined __unix__)
  255. /* old system without (proper) C99 support */
  256. # define bool smalluint
  257. #else
  258. /* modern system, so use it */
  259. # include <stdbool.h>
  260. #endif
  261. /* Try to defeat gcc's alignment of "char message[]"-like data */
  262. #if 1 /* if needed: !defined(arch1) && !defined(arch2) */
  263. # define ALIGN1 __attribute__((aligned(1)))
  264. # define ALIGN2 __attribute__((aligned(2)))
  265. # define ALIGN4 __attribute__((aligned(4)))
  266. #else
  267. /* Arches which MUST have 2 or 4 byte alignment for everything are here */
  268. # define ALIGN1
  269. # define ALIGN2
  270. # define ALIGN4
  271. #endif
  272. /* uclibc does not implement daemon() for no-mmu systems.
  273. * For 0.9.29 and svn, __ARCH_USE_MMU__ indicates no-mmu reliably.
  274. * For earlier versions there is no reliable way to check if we are building
  275. * for a mmu-less system.
  276. */
  277. #if ENABLE_NOMMU || \
  278. (defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \
  279. __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__)
  280. # define BB_MMU 0
  281. # define USE_FOR_NOMMU(...) __VA_ARGS__
  282. # define USE_FOR_MMU(...)
  283. #else
  284. # define BB_MMU 1
  285. # define USE_FOR_NOMMU(...)
  286. # define USE_FOR_MMU(...) __VA_ARGS__
  287. #endif
  288. /* Don't use lchown with glibc older than 2.1.x */
  289. #if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 1
  290. # define lchown chown
  291. #endif
  292. #if defined(__digital__) && defined(__unix__)
  293. # include <standards.h>
  294. # include <inttypes.h>
  295. # define PRIu32 "u"
  296. /* use legacy setpgrp(pid_t,pid_t) for now. move to platform.c */
  297. # define bb_setpgrp() do { pid_t __me = getpid(); setpgrp(__me, __me); } while (0)
  298. # if !defined ADJ_OFFSET_SINGLESHOT && defined MOD_CLKA && defined MOD_OFFSET
  299. # define ADJ_OFFSET_SINGLESHOT (MOD_CLKA | MOD_OFFSET)
  300. # endif
  301. # if !defined ADJ_FREQUENCY && defined MOD_FREQUENCY
  302. # define ADJ_FREQUENCY MOD_FREQUENCY
  303. # endif
  304. # if !defined ADJ_TIMECONST && defined MOD_TIMECONST
  305. # define ADJ_TIMECONST MOD_TIMECONST
  306. # endif
  307. # if !defined ADJ_TICK && defined MOD_CLKB
  308. # define ADJ_TICK MOD_CLKB
  309. # endif
  310. #else
  311. # define bb_setpgrp() setpgrp()
  312. #endif
  313. #if defined(__GLIBC__)
  314. # define fdprintf dprintf
  315. #endif
  316. #if defined(__dietlibc__)
  317. # undef HAVE_STRCHRNUL
  318. #endif
  319. #if defined(__WATCOMC__)
  320. # undef HAVE_FDPRINTF
  321. # undef HAVE_MEMRCHR
  322. # undef HAVE_MKDTEMP
  323. # undef HAVE_SETBIT
  324. # undef HAVE_STRCASESTR
  325. # undef HAVE_STRCHRNUL
  326. # undef HAVE_STRSEP
  327. # undef HAVE_STRSIGNAL
  328. # undef HAVE_VASPRINTF
  329. #endif
  330. #if defined(__FreeBSD__)
  331. # undef HAVE_STRCHRNUL
  332. #endif
  333. /*
  334. * Now, define prototypes for all the functions defined in platform.c
  335. * These must come after all the HAVE_* macros are defined (or not)
  336. */
  337. #ifndef HAVE_FDPRINTF
  338. extern int fdprintf(int fd, const char *format, ...);
  339. #endif
  340. #ifndef HAVE_MEMRCHR
  341. extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC;
  342. #endif
  343. #ifndef HAVE_MKDTEMP
  344. extern char *mkdtemp(char *template) FAST_FUNC;
  345. #endif
  346. #ifndef HAVE_SETBIT
  347. # define setbit(a, b) ((a)[(b) >> 3] |= 1 << ((b) & 7))
  348. # define clrbit(a, b) ((a)[(b) >> 3] &= ~(1 << ((b) & 7)))
  349. #endif
  350. #ifndef HAVE_STRCASESTR
  351. extern char *strcasestr(const char *s, const char *pattern) FAST_FUNC;
  352. #endif
  353. #ifndef HAVE_STRCHRNUL
  354. extern char *strchrnul(const char *s, int c) FAST_FUNC;
  355. #endif
  356. #ifndef HAVE_STRSEP
  357. extern char *strsep(char **stringp, const char *delim) FAST_FUNC;
  358. #endif
  359. #ifndef HAVE_STRSIGNAL
  360. /* Not exactly the same: instead of "Stopped" it shows "STOP" etc */
  361. # define strsignal(sig) get_signame(sig)
  362. #endif
  363. #ifndef HAVE_VASPRINTF
  364. extern int vasprintf(char **string_ptr, const char *format, va_list p) FAST_FUNC;
  365. #endif
  366. #endif