source: MondoRescue/branches/3.3/mindi-busybox/include/platform.h@ 3723

Last change on this file since 3723 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 16.2 KB
Line 
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
10
11/* Convenience macros to test the version of gcc. */
12#undef __GNUC_PREREQ
13#if defined __GNUC__ && defined __GNUC_MINOR__
14# define __GNUC_PREREQ(maj, min) \
15 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
16#else
17# define __GNUC_PREREQ(maj, min) 0
18#endif
19
20/* __restrict is known in EGCS 1.2 and above. */
21#if !__GNUC_PREREQ(2,92)
22# ifndef __restrict
23# define __restrict
24# endif
25#endif
26
27#if !__GNUC_PREREQ(2,7)
28# ifndef __attribute__
29# define __attribute__(x)
30# endif
31#endif
32
33#undef inline
34#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 199901L
35/* it's a keyword */
36#elif __GNUC_PREREQ(2,7)
37# define inline __inline__
38#else
39# define inline
40#endif
41
42#ifndef __const
43# define __const const
44#endif
45
46#define UNUSED_PARAM __attribute__ ((__unused__))
47#define NORETURN __attribute__ ((__noreturn__))
48/* "The malloc attribute is used to tell the compiler that a function
49 * may be treated as if any non-NULL pointer it returns cannot alias
50 * any other pointer valid when the function returns. This will often
51 * improve optimization. Standard functions with this property include
52 * malloc and calloc. realloc-like functions have this property as long
53 * as the old pointer is never referred to (including comparing it
54 * to the new pointer) after the function returns a non-NULL value."
55 */
56#define RETURNS_MALLOC __attribute__ ((malloc))
57#define PACKED __attribute__ ((__packed__))
58#define ALIGNED(m) __attribute__ ((__aligned__(m)))
59
60/* __NO_INLINE__: some gcc's do not honor inlining! :( */
61#if __GNUC_PREREQ(3,0) && !defined(__NO_INLINE__)
62# define ALWAYS_INLINE __attribute__ ((always_inline)) inline
63/* I've seen a toolchain where I needed __noinline__ instead of noinline */
64# define NOINLINE __attribute__((__noinline__))
65# if !ENABLE_WERROR
66# define DEPRECATED __attribute__ ((__deprecated__))
67# define UNUSED_PARAM_RESULT __attribute__ ((warn_unused_result))
68# else
69# define DEPRECATED
70# define UNUSED_PARAM_RESULT
71# endif
72#else
73# define ALWAYS_INLINE inline
74# define NOINLINE
75# define DEPRECATED
76# define UNUSED_PARAM_RESULT
77#endif
78
79/* used by unit test machinery to run registration functions before calling main() */
80#define INIT_FUNC __attribute__ ((constructor))
81
82/* -fwhole-program makes all symbols local. The attribute externally_visible
83 * forces a symbol global. */
84#if __GNUC_PREREQ(4,1)
85# define EXTERNALLY_VISIBLE __attribute__(( visibility("default") ))
86//__attribute__ ((__externally_visible__))
87#else
88# define EXTERNALLY_VISIBLE
89#endif
90
91/* At 4.4 gcc become much more anal about this, need to use "aliased" types */
92#if __GNUC_PREREQ(4,4)
93# define FIX_ALIASING __attribute__((__may_alias__))
94#else
95# define FIX_ALIASING
96#endif
97
98/* We use __extension__ in some places to suppress -pedantic warnings
99 * about GCC extensions. This feature didn't work properly before
100 * gcc 2.8. */
101#if !__GNUC_PREREQ(2,8)
102# ifndef __extension__
103# define __extension__
104# endif
105#endif
106
107/* FAST_FUNC is a qualifier which (possibly) makes function call faster
108 * and/or smaller by using modified ABI. It is usually only needed
109 * on non-static, busybox internal functions. Recent versions of gcc
110 * optimize statics automatically. FAST_FUNC on static is required
111 * only if you need to match a function pointer's type */
112#if __GNUC_PREREQ(3,0) && defined(i386) /* || defined(__x86_64__)? */
113/* stdcall makes callee to pop arguments from stack, not caller */
114# define FAST_FUNC __attribute__((regparm(3),stdcall))
115/* #elif ... - add your favorite arch today! */
116#else
117# define FAST_FUNC
118#endif
119
120/* Make all declarations hidden (-fvisibility flag only affects definitions) */
121/* (don't include system headers after this until corresponding pop!) */
122#if __GNUC_PREREQ(4,1) && !defined(__CYGWIN__)
123# define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN _Pragma("GCC visibility push(hidden)")
124# define POP_SAVED_FUNCTION_VISIBILITY _Pragma("GCC visibility pop")
125#else
126# define PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
127# define POP_SAVED_FUNCTION_VISIBILITY
128#endif
129
130/* gcc-2.95 had no va_copy but only __va_copy. */
131#if !__GNUC_PREREQ(3,0)
132# include <stdarg.h>
133# if !defined va_copy && defined __va_copy
134# define va_copy(d,s) __va_copy((d),(s))
135# endif
136#endif
137
138
139/* ---- Endian Detection ------------------------------------ */
140
141#include <limits.h>
142#if defined(__digital__) && defined(__unix__)
143# include <sex.h>
144#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
145 || defined(__APPLE__)
146# include <sys/resource.h> /* rlimit */
147# include <machine/endian.h>
148# define bswap_64 __bswap64
149# define bswap_32 __bswap32
150# define bswap_16 __bswap16
151#else
152# include <byteswap.h>
153# include <endian.h>
154#endif
155
156#if 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(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
169# define BB_BIG_ENDIAN 1
170# define BB_LITTLE_ENDIAN 0
171#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
172# define BB_BIG_ENDIAN 0
173# define BB_LITTLE_ENDIAN 1
174#elif defined(__386__)
175# define BB_BIG_ENDIAN 0
176# define BB_LITTLE_ENDIAN 1
177#else
178# error "Can't determine endianness"
179#endif
180
181#if ULONG_MAX > 0xffffffff
182# define bb_bswap_64(x) bswap_64(x)
183#endif
184
185/* SWAP_LEnn means "convert CPU<->little_endian by swapping bytes" */
186#if BB_BIG_ENDIAN
187# define SWAP_BE16(x) (x)
188# define SWAP_BE32(x) (x)
189# define SWAP_BE64(x) (x)
190# define SWAP_LE16(x) bswap_16(x)
191# define SWAP_LE32(x) bswap_32(x)
192# define SWAP_LE64(x) bb_bswap_64(x)
193# define IF_BIG_ENDIAN(...) __VA_ARGS__
194# define IF_LITTLE_ENDIAN(...)
195#else
196# define SWAP_BE16(x) bswap_16(x)
197# define SWAP_BE32(x) bswap_32(x)
198# define SWAP_BE64(x) bb_bswap_64(x)
199# define SWAP_LE16(x) (x)
200# define SWAP_LE32(x) (x)
201# define SWAP_LE64(x) (x)
202# define IF_BIG_ENDIAN(...)
203# define IF_LITTLE_ENDIAN(...) __VA_ARGS__
204#endif
205
206
207/* ---- Unaligned access ------------------------------------ */
208
209#include <stdint.h>
210typedef int bb__aliased_int FIX_ALIASING;
211typedef long bb__aliased_long FIX_ALIASING;
212typedef uint16_t bb__aliased_uint16_t FIX_ALIASING;
213typedef uint32_t bb__aliased_uint32_t FIX_ALIASING;
214typedef uint64_t bb__aliased_uint64_t FIX_ALIASING;
215
216/* NB: unaligned parameter should be a pointer, aligned one -
217 * a lvalue. This makes it more likely to not swap them by mistake
218 */
219#if defined(i386) || defined(__x86_64__) || defined(__powerpc__)
220# define BB_UNALIGNED_MEMACCESS_OK 1
221# define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp))
222# define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp))
223# define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p))
224# define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p))
225# define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v))
226# define move_to_unaligned32(u32p, v) (*(bb__aliased_uint32_t*)(u32p) = (v))
227/* #elif ... - add your favorite arch today! */
228#else
229# define BB_UNALIGNED_MEMACCESS_OK 0
230/* performs reasonably well (gcc usually inlines memcpy here) */
231# define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int)))
232# define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long)))
233# define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2))
234# define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4))
235# define move_to_unaligned16(u16p, v) do { \
236 uint16_t __t = (v); \
237 memcpy((u16p), &__t, 2); \
238} while (0)
239# define move_to_unaligned32(u32p, v) do { \
240 uint32_t __t = (v); \
241 memcpy((u32p), &__t, 4); \
242} while (0)
243#endif
244
245
246/* ---- Size-saving "small" ints (arch-dependent) ----------- */
247
248#if defined(i386) || defined(__x86_64__) || defined(__mips__) || defined(__cris__)
249/* add other arches which benefit from this... */
250typedef signed char smallint;
251typedef unsigned char smalluint;
252#else
253/* for arches where byte accesses generate larger code: */
254typedef int smallint;
255typedef unsigned smalluint;
256#endif
257
258/* ISO C Standard: 7.16 Boolean type and values <stdbool.h> */
259#if (defined __digital__ && defined __unix__)
260/* old system without (proper) C99 support */
261# define bool smalluint
262#else
263/* modern system, so use it */
264# include <stdbool.h>
265#endif
266
267
268/*----- Kernel versioning ------------------------------------*/
269
270#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
271
272#ifdef __UCLIBC__
273# define UCLIBC_VERSION KERNEL_VERSION(__UCLIBC_MAJOR__, __UCLIBC_MINOR__, __UCLIBC_SUBLEVEL__)
274#else
275# define UCLIBC_VERSION 0
276#endif
277
278
279/* ---- Miscellaneous --------------------------------------- */
280
281#if defined __GLIBC__ \
282 || defined __UCLIBC__ \
283 || defined __dietlibc__ \
284 || defined __BIONIC__ \
285 || defined _NEWLIB_VERSION
286# include <features.h>
287#endif
288
289/* Define bb_setpgrp */
290#if defined(__digital__) && defined(__unix__)
291/* use legacy setpgrp(pid_t, pid_t) for now. move to platform.c */
292# define bb_setpgrp() do { pid_t __me = getpid(); setpgrp(__me, __me); } while (0)
293#else
294# define bb_setpgrp() setpgrp()
295#endif
296
297/* fdprintf is more readable, we used it before dprintf was standardized */
298#include <unistd.h>
299#define fdprintf dprintf
300
301/* Useful for defeating gcc's alignment of "char message[]"-like data */
302#if !defined(__s390__)
303 /* on s390[x], non-word-aligned data accesses require larger code */
304# define ALIGN1 __attribute__((aligned(1)))
305# define ALIGN2 __attribute__((aligned(2)))
306# define ALIGN4 __attribute__((aligned(4)))
307#else
308/* Arches which MUST have 2 or 4 byte alignment for everything are here */
309# define ALIGN1
310# define ALIGN2
311# define ALIGN4
312#endif
313
314/*
315 * For 0.9.29 and svn, __ARCH_USE_MMU__ indicates no-mmu reliably.
316 * For earlier versions there is no reliable way to check if we are building
317 * for a mmu-less system.
318 */
319#if ENABLE_NOMMU || \
320 (defined __UCLIBC__ && \
321 UCLIBC_VERSION > KERNEL_VERSION(0, 9, 28) && \
322 !defined __ARCH_USE_MMU__)
323# define BB_MMU 0
324# define USE_FOR_NOMMU(...) __VA_ARGS__
325# define USE_FOR_MMU(...)
326#else
327# define BB_MMU 1
328# define USE_FOR_NOMMU(...)
329# define USE_FOR_MMU(...) __VA_ARGS__
330#endif
331
332#if defined(__digital__) && defined(__unix__)
333# include <standards.h>
334# include <inttypes.h>
335# define PRIu32 "u"
336# if !defined ADJ_OFFSET_SINGLESHOT && defined MOD_CLKA && defined MOD_OFFSET
337# define ADJ_OFFSET_SINGLESHOT (MOD_CLKA | MOD_OFFSET)
338# endif
339# if !defined ADJ_FREQUENCY && defined MOD_FREQUENCY
340# define ADJ_FREQUENCY MOD_FREQUENCY
341# endif
342# if !defined ADJ_TIMECONST && defined MOD_TIMECONST
343# define ADJ_TIMECONST MOD_TIMECONST
344# endif
345# if !defined ADJ_TICK && defined MOD_CLKB
346# define ADJ_TICK MOD_CLKB
347# endif
348#endif
349
350#if defined(__CYGWIN__)
351# define MAXSYMLINKS SYMLOOP_MAX
352#endif
353
354#if defined(ANDROID) || defined(__ANDROID__)
355# define BB_ADDITIONAL_PATH ":/system/sbin:/system/bin:/system/xbin"
356# define SYS_ioprio_set __NR_ioprio_set
357# define SYS_ioprio_get __NR_ioprio_get
358#endif
359
360
361/* ---- Who misses what? ------------------------------------ */
362
363/* Assume all these functions and header files exist by default.
364 * Platforms where it is not true will #undef them below.
365 */
366#define HAVE_CLEARENV 1
367#define HAVE_FDATASYNC 1
368#define HAVE_DPRINTF 1
369#define HAVE_MEMRCHR 1
370#define HAVE_MKDTEMP 1
371#define HAVE_TTYNAME_R 1
372#define HAVE_PTSNAME_R 1
373#define HAVE_SETBIT 1
374#define HAVE_SIGHANDLER_T 1
375#define HAVE_STPCPY 1
376#define HAVE_MEMPCPY 1
377#define HAVE_STRCASESTR 1
378#define HAVE_STRCHRNUL 1
379#define HAVE_STRSEP 1
380#define HAVE_STRSIGNAL 1
381#define HAVE_STRVERSCMP 1
382#define HAVE_VASPRINTF 1
383#define HAVE_USLEEP 1
384#define HAVE_UNLOCKED_STDIO 1
385#define HAVE_UNLOCKED_LINE_OPS 1
386#define HAVE_GETLINE 1
387#define HAVE_XTABS 1
388#define HAVE_MNTENT_H 1
389#define HAVE_NET_ETHERNET_H 1
390#define HAVE_SYS_STATFS_H 1
391
392#if defined(__UCLIBC__)
393# if UCLIBC_VERSION < KERNEL_VERSION(0, 9, 32)
394# undef HAVE_STRVERSCMP
395# endif
396# if UCLIBC_VERSION >= KERNEL_VERSION(0, 9, 30)
397# ifndef __UCLIBC_SUSV3_LEGACY__
398# undef HAVE_USLEEP
399# endif
400# endif
401#endif
402
403#if defined(__WATCOMC__)
404# undef HAVE_DPRINTF
405# undef HAVE_GETLINE
406# undef HAVE_MEMRCHR
407# undef HAVE_MKDTEMP
408# undef HAVE_SETBIT
409# undef HAVE_STPCPY
410# undef HAVE_STRCASESTR
411# undef HAVE_STRCHRNUL
412# undef HAVE_STRSEP
413# undef HAVE_STRSIGNAL
414# undef HAVE_STRVERSCMP
415# undef HAVE_VASPRINTF
416# undef HAVE_UNLOCKED_STDIO
417# undef HAVE_UNLOCKED_LINE_OPS
418# undef HAVE_NET_ETHERNET_H
419#endif
420
421#if defined(__CYGWIN__)
422# undef HAVE_CLEARENV
423# undef HAVE_FDPRINTF
424# undef HAVE_MEMRCHR
425# undef HAVE_PTSNAME_R
426# undef HAVE_STRVERSCMP
427# undef HAVE_UNLOCKED_LINE_OPS
428#endif
429
430/* These BSD-derived OSes share many similarities */
431#if (defined __digital__ && defined __unix__) \
432 || defined __APPLE__ \
433 || defined __OpenBSD__ || defined __NetBSD__
434# undef HAVE_CLEARENV
435# undef HAVE_FDATASYNC
436# undef HAVE_GETLINE
437# undef HAVE_MNTENT_H
438# undef HAVE_PTSNAME_R
439# undef HAVE_SYS_STATFS_H
440# undef HAVE_SIGHANDLER_T
441# undef HAVE_STRVERSCMP
442# undef HAVE_XTABS
443# undef HAVE_DPRINTF
444# undef HAVE_UNLOCKED_STDIO
445# undef HAVE_UNLOCKED_LINE_OPS
446#endif
447
448#if defined(__dietlibc__)
449# undef HAVE_STRCHRNUL
450#endif
451
452#if defined(__APPLE__)
453# undef HAVE_STRCHRNUL
454#endif
455
456#if defined(__FreeBSD__)
457/* users say mempcpy is not present in FreeBSD 9.x */
458# undef HAVE_MEMPCPY
459# undef HAVE_CLEARENV
460# undef HAVE_FDATASYNC
461# undef HAVE_MNTENT_H
462# undef HAVE_PTSNAME_R
463# undef HAVE_SYS_STATFS_H
464# undef HAVE_SIGHANDLER_T
465# undef HAVE_STRVERSCMP
466# undef HAVE_XTABS
467# undef HAVE_UNLOCKED_LINE_OPS
468# include <osreldate.h>
469# if __FreeBSD_version < 1000029
470# undef HAVE_STRCHRNUL /* FreeBSD added strchrnul() between 1000028 and 1000029 */
471# endif
472#endif
473
474#if defined(__NetBSD__)
475# define HAVE_GETLINE 1 /* Recent NetBSD versions have getline() */
476#endif
477
478#if defined(__digital__) && defined(__unix__)
479# undef HAVE_STPCPY
480#endif
481
482#if defined(ANDROID) || defined(__ANDROID__)
483# if __ANDROID_API__ < 8
484 /* ANDROID < 8 has no [f]dprintf at all */
485# undef HAVE_DPRINTF
486# elif __ANDROID_API__ < 21
487 /* ANDROID < 21 has fdprintf */
488# define dprintf fdprintf
489# else
490 /* ANDROID >= 21 has standard dprintf */
491# endif
492# if __ANDROID_API__ < 21
493# undef HAVE_TTYNAME_R
494# undef HAVE_GETLINE
495# undef HAVE_STPCPY
496# endif
497# undef HAVE_MEMPCPY
498# undef HAVE_STRCHRNUL
499# undef HAVE_STRVERSCMP
500# undef HAVE_UNLOCKED_LINE_OPS
501# undef HAVE_NET_ETHERNET_H
502#endif
503
504/*
505 * Now, define prototypes for all the functions defined in platform.c
506 * These must come after all the HAVE_* macros are defined (or not)
507 */
508
509#ifndef HAVE_DPRINTF
510extern int dprintf(int fd, const char *format, ...);
511#endif
512
513#ifndef HAVE_MEMRCHR
514extern void *memrchr(const void *s, int c, size_t n) FAST_FUNC;
515#endif
516
517#ifndef HAVE_MKDTEMP
518extern char *mkdtemp(char *template) FAST_FUNC;
519#endif
520
521#ifndef HAVE_TTYNAME_R
522#define ttyname_r bb_ttyname_r
523extern int ttyname_r(int fd, char *buf, size_t buflen);
524#endif
525
526#ifndef HAVE_SETBIT
527# define setbit(a, b) ((a)[(b) >> 3] |= 1 << ((b) & 7))
528# define clrbit(a, b) ((a)[(b) >> 3] &= ~(1 << ((b) & 7)))
529#endif
530
531#ifndef HAVE_SIGHANDLER_T
532typedef void (*sighandler_t)(int);
533#endif
534
535#ifndef HAVE_STPCPY
536extern char *stpcpy(char *p, const char *to_add) FAST_FUNC;
537#endif
538
539#ifndef HAVE_MEMPCPY
540#include <string.h>
541/* In case we are wrong about !HAVE_MEMPCPY, and toolchain _does_ have
542 * mempcpy(), avoid colliding with it:
543 */
544#define mempcpy bb__mempcpy
545static ALWAYS_INLINE void *mempcpy(void *dest, const void *src, size_t len)
546{
547 return memcpy(dest, src, len) + len;
548}
549#endif
550
551#ifndef HAVE_STRCASESTR
552extern char *strcasestr(const char *s, const char *pattern) FAST_FUNC;
553#endif
554
555#ifndef HAVE_STRCHRNUL
556extern char *strchrnul(const char *s, int c) FAST_FUNC;
557#endif
558
559#ifndef HAVE_STRSEP
560extern char *strsep(char **stringp, const char *delim) FAST_FUNC;
561#endif
562
563#ifndef HAVE_STRSIGNAL
564/* Not exactly the same: instead of "Stopped" it shows "STOP" etc */
565# define strsignal(sig) get_signame(sig)
566#endif
567
568#ifndef HAVE_USLEEP
569extern int usleep(unsigned) FAST_FUNC;
570#endif
571
572#ifndef HAVE_VASPRINTF
573extern int vasprintf(char **string_ptr, const char *format, va_list p) FAST_FUNC;
574#endif
575
576#ifndef HAVE_GETLINE
577# include <stdio.h> /* for FILE */
578# include <sys/types.h> /* size_t */
579extern ssize_t getline(char **lineptr, size_t *n, FILE *stream) FAST_FUNC;
580#endif
581
582#endif
Note: See TracBrowser for help on using the repository browser.