source: EcnlProtoTool/trunk/prototool/src/libbb/platform.h@ 279

Last change on this file since 279 was 279, checked in by coas-nagasima, 7 years ago

ファイルを追加、更新。

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr
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 0
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.