2 * Copyright (c) 2009 Joseph Koshy
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $Id: _elftc.h 2922 2013-03-17 22:53:15Z kaiwang27 $
30 ** Miscellanous definitions needed by multiple components.
37 #define NULL ((void *) 0)
41 #define offsetof(T, M) ((int) &((T*) 0) -> M)
44 /* --QUEUE-MACROS-- [[ */
47 * Supply macros missing from <sys/queue.h>
51 * Copyright (c) 1991, 1993
52 * The Regents of the University of California. All rights reserved.
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
57 * 1. Redistributions of source code must retain the above copyright
58 * notice, this list of conditions and the following disclaimer.
59 * 2. Redistributions in binary form must reproduce the above copyright
60 * notice, this list of conditions and the following disclaimer in the
61 * documentation and/or other materials provided with the distribution.
62 * 3. Neither the name of the University nor the names of its contributors
63 * may be used to endorse or promote products derived from this software
64 * without specific prior written permission.
66 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
67 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
68 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
69 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
70 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
71 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
72 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
73 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
74 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
75 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
79 #ifndef SLIST_FOREACH_SAFE
80 #define SLIST_FOREACH_SAFE(var, head, field, tvar) \
81 for ((var) = SLIST_FIRST((head)); \
82 (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
87 #define STAILQ_CONCAT(head1, head2) do { \
88 if (!STAILQ_EMPTY((head2))) { \
89 *(head1)->stqh_last = (head2)->stqh_first; \
90 (head1)->stqh_last = (head2)->stqh_last; \
91 STAILQ_INIT((head2)); \
93 } while (/*CONSTCOND*/0)
97 #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
101 #define STAILQ_ENTRY(type) \
103 struct type *stqe_next; /* next element */ \
108 #define STAILQ_FIRST(head) ((head)->stqh_first)
112 #define STAILQ_HEAD(name, type) \
114 struct type *stqh_first; /* first element */ \
115 struct type **stqh_last; /* addr of last next element */ \
119 #ifndef STAILQ_HEAD_INITIALIZER
120 #define STAILQ_HEAD_INITIALIZER(head) \
121 { NULL, &(head).stqh_first }
124 #ifndef STAILQ_FOREACH
125 #define STAILQ_FOREACH(var, head, field) \
126 for ((var) = ((head)->stqh_first); \
128 (var) = ((var)->field.stqe_next))
131 #ifndef STAILQ_FOREACH_SAFE
132 #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
133 for ((var) = STAILQ_FIRST((head)); \
134 (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
139 #define STAILQ_INIT(head) do { \
140 (head)->stqh_first = NULL; \
141 (head)->stqh_last = &(head)->stqh_first; \
142 } while (/*CONSTCOND*/0)
145 #ifndef STAILQ_INSERT_HEAD
146 #define STAILQ_INSERT_HEAD(head, elm, field) do { \
147 if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
148 (head)->stqh_last = &(elm)->field.stqe_next; \
149 (head)->stqh_first = (elm); \
150 } while (/*CONSTCOND*/0)
153 #ifndef STAILQ_INSERT_TAIL
154 #define STAILQ_INSERT_TAIL(head, elm, field) do { \
155 (elm)->field.stqe_next = NULL; \
156 *(head)->stqh_last = (elm); \
157 (head)->stqh_last = &(elm)->field.stqe_next; \
158 } while (/*CONSTCOND*/0)
161 #ifndef STAILQ_INSERT_AFTER
162 #define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
163 if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
164 (head)->stqh_last = &(elm)->field.stqe_next; \
165 (listelm)->field.stqe_next = (elm); \
166 } while (/*CONSTCOND*/0)
170 #define STAILQ_LAST(head, type, field) \
171 (STAILQ_EMPTY((head)) ? \
172 NULL : ((struct type *)(void *) \
173 ((char *)((head)->stqh_last) - offsetof(struct type, field))))
177 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
180 #ifndef STAILQ_REMOVE
181 #define STAILQ_REMOVE(head, elm, type, field) do { \
182 if ((head)->stqh_first == (elm)) { \
183 STAILQ_REMOVE_HEAD((head), field); \
185 struct type *curelm = (head)->stqh_first; \
186 while (curelm->field.stqe_next != (elm)) \
187 curelm = curelm->field.stqe_next; \
188 if ((curelm->field.stqe_next = \
189 curelm->field.stqe_next->field.stqe_next) == NULL) \
190 (head)->stqh_last = &(curelm)->field.stqe_next; \
192 } while (/*CONSTCOND*/0)
195 #ifndef STAILQ_REMOVE_HEAD
196 #define STAILQ_REMOVE_HEAD(head, field) do { \
197 if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == \
199 (head)->stqh_last = &(head)->stqh_first; \
200 } while (/*CONSTCOND*/0)
204 * The STAILQ_SORT macro is adapted from Simon Tatham's O(n*log(n))
205 * mergesort algorithm.
208 #define STAILQ_SORT(head, type, field, cmp) do { \
209 STAILQ_HEAD(, type) _la, _lb; \
210 struct type *_p, *_q, *_e; \
211 int _i, _sz, _nmerges, _psz, _qsz; \
217 while (!STAILQ_EMPTY((head))) { \
221 for (_i = 0; _i < _sz && !STAILQ_EMPTY((head)); \
223 _e = STAILQ_FIRST((head)); \
227 STAILQ_REMOVE_HEAD((head), field); \
228 STAILQ_INSERT_TAIL(&_la, _e, field); \
230 _p = STAILQ_FIRST(&_la); \
232 _q = STAILQ_FIRST((head)); \
233 while (_psz > 0 || (_qsz > 0 && _q != NULL)) { \
236 _q = STAILQ_NEXT(_q, field); \
237 STAILQ_REMOVE_HEAD((head), \
240 } else if (_qsz == 0 || _q == NULL) { \
242 _p = STAILQ_NEXT(_p, field); \
243 STAILQ_REMOVE_HEAD(&_la, field);\
245 } else if (cmp(_p, _q) <= 0) { \
247 _p = STAILQ_NEXT(_p, field); \
248 STAILQ_REMOVE_HEAD(&_la, field);\
252 _q = STAILQ_NEXT(_q, field); \
253 STAILQ_REMOVE_HEAD((head), \
257 STAILQ_INSERT_TAIL(&_lb, _e, field); \
260 (head)->stqh_first = _lb.stqh_first; \
261 (head)->stqh_last = _lb.stqh_last; \
263 } while (_nmerges > 1); \
264 } while (/*CONSTCOND*/0)
267 #ifndef TAILQ_FOREACH_SAFE
268 #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
269 for ((var) = TAILQ_FIRST((head)); \
270 (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
274 /* ]] --QUEUE-MACROS-- */
282 #if defined(__DragonFly__)
283 #define ELFTC_VCSID(ID) __RCSID(ID)
286 #if defined(__FreeBSD__)
287 #define ELFTC_VCSID(ID) __FBSDID(ID)
290 #if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
291 #if defined(__GNUC__)
292 #define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"")
294 #define ELFTC_VCSID(ID) /**/
299 #if defined(__GNUC__)
300 #define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"")
302 #define ELFTC_VCSID(ID) /**/
306 #if defined(__NetBSD__)
307 #define ELFTC_VCSID(ID) __RCSID(ID)
310 #if defined(__OpenBSD__)
311 #if defined(__GNUC__)
312 #define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"")
314 #define ELFTC_VCSID(ID) /**/
315 #endif /* __GNUC__ */
318 #endif /* ELFTC_VCSID */
321 * Provide an equivalent for getprogname(3).
324 #ifndef ELFTC_GETPROGNAME
326 #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__minix) || \
331 #define ELFTC_GETPROGNAME() getprogname()
333 #endif /* __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */
336 #if defined(__GLIBC__)
339 * GLIBC based systems have a global 'char *' pointer referencing
340 * the executable's name.
342 extern const char *program_invocation_short_name;
344 #define ELFTC_GETPROGNAME() program_invocation_short_name
346 #endif /* __GLIBC__ */
349 #if defined(__OpenBSD__)
351 extern const char *__progname;
353 #define ELFTC_GETPROGNAME() __progname
355 #endif /* __OpenBSD__ */
357 #endif /* ELFTC_GETPROGNAME */
361 ** Per-OS configuration.
364 #if defined(__DragonFly__)
366 #include <osreldate.h>
367 #include <sys/endian.h>
369 #define ELFTC_BYTE_ORDER _BYTE_ORDER
370 #define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN
371 #define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN
373 #define ELFTC_HAVE_MMAP 1
377 #if defined(__GLIBC__)
381 #define ELFTC_BYTE_ORDER __BYTE_ORDER
382 #define ELFTC_BYTE_ORDER_LITTLE_ENDIAN __LITTLE_ENDIAN
383 #define ELFTC_BYTE_ORDER_BIG_ENDIAN __BIG_ENDIAN
385 #define ELFTC_HAVE_MMAP 1
388 * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3).
390 #define ELFTC_HAVE_STRMODE 0
392 /* Whether we need to supply {be,le}32dec. */
393 #define ELFTC_NEED_BYTEORDER_EXTENSIONS 1
395 #define roundup2 roundup
397 #endif /* __GLIBC__ */
400 #if defined(__FreeBSD__)
402 #include <osreldate.h>
403 #include <sys/endian.h>
405 #define ELFTC_BYTE_ORDER _BYTE_ORDER
406 #define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN
407 #define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN
409 #define ELFTC_HAVE_MMAP 1
410 #define ELFTC_HAVE_STRMODE 1
411 #if __FreeBSD_version <= 900000
412 #define ELFTC_BROKEN_YY_NO_INPUT 1
414 #endif /* __FreeBSD__ */
418 #define ELFTC_HAVE_MMAP 0
422 #if defined(__NetBSD__)
424 #include <sys/param.h>
425 #include <sys/endian.h>
427 #define ELFTC_BYTE_ORDER _BYTE_ORDER
428 #define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN
429 #define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN
431 #define ELFTC_HAVE_MMAP 1
432 #define ELFTC_HAVE_STRMODE 1
433 #if __NetBSD_Version__ <= 599002100
434 /* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */
435 /* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */
436 # define ELFTC_BROKEN_YY_NO_INPUT 1
438 #endif /* __NetBSD __ */
441 #if defined(__OpenBSD__)
443 #include <sys/param.h>
444 #include <sys/endian.h>
446 #define ELFTC_BYTE_ORDER _BYTE_ORDER
447 #define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN
448 #define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN
450 #define ELFTC_HAVE_MMAP 1
451 #define ELFTC_HAVE_STRMODE 1
453 #define ELFTC_NEED_BYTEORDER_EXTENSIONS 1
454 #define roundup2 roundup
456 #endif /* __OpenBSD__ */
458 #endif /* _ELFTC_H */