1/*-
2 * Copyright (c) 2009 Joseph Koshy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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
24 * SUCH DAMAGE.
25 *
26 * $Id: _elftc.h 3446 2016-05-03 01:31:17Z emaste $
27 */
28
29/**
30 ** Miscellaneous definitions needed by multiple components.
31 **/
32
33#ifndef	_ELFTC_H
34#define	_ELFTC_H
35
36#ifndef	NULL
37#define NULL 	((void *) 0)
38#endif
39
40#ifndef	offsetof
41#define	offsetof(T, M)		((int) &((T*) 0) -> M)
42#endif
43
44/* --QUEUE-MACROS-- [[ */
45
46/*
47 * Supply macros missing from <sys/queue.h>
48 */
49
50/*
51 * Copyright (c) 1991, 1993
52 *	The Regents of the University of California.  All rights reserved.
53 *
54 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions
56 * are met:
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.
65 *
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
76 * SUCH DAMAGE.
77 */
78
79#ifndef	LIST_FOREACH_SAFE
80#define	LIST_FOREACH_SAFE(var, head, field, tvar)		\
81	for ((var) = LIST_FIRST((head));			\
82	    (var) && ((tvar) = LIST_NEXT((var), field), 1);	\
83	    (var) = (tvar))
84#endif
85
86#ifndef	SLIST_FOREACH_SAFE
87#define	SLIST_FOREACH_SAFE(var, head, field, tvar)		\
88	for ((var) = SLIST_FIRST((head));			\
89	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);	\
90	    (var) = (tvar))
91#endif
92
93#ifndef	STAILQ_CONCAT
94#define	STAILQ_CONCAT(head1, head2) do {			\
95	if (!STAILQ_EMPTY((head2))) {				\
96		*(head1)->stqh_last = (head2)->stqh_first;	\
97		(head1)->stqh_last = (head2)->stqh_last;	\
98		STAILQ_INIT((head2));				\
99	}							\
100} while (/*CONSTCOND*/0)
101#endif
102
103#ifndef	STAILQ_EMPTY
104#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
105#endif
106
107#ifndef	STAILQ_ENTRY
108#define	STAILQ_ENTRY(type)					\
109struct {							\
110	struct type *stqe_next;	/* next element */		\
111}
112#endif
113
114#ifndef	STAILQ_FIRST
115#define	STAILQ_FIRST(head)	((head)->stqh_first)
116#endif
117
118#ifndef	STAILQ_HEAD
119#define	STAILQ_HEAD(name, type)					\
120struct name {							\
121	struct type *stqh_first; /* first element */		\
122	struct type **stqh_last; /* addr of last next element */ \
123}
124#endif
125
126#ifndef	STAILQ_HEAD_INITIALIZER
127#define	STAILQ_HEAD_INITIALIZER(head)				\
128	{ NULL, &(head).stqh_first }
129#endif
130
131#ifndef	STAILQ_FOREACH
132#define	STAILQ_FOREACH(var, head, field)			\
133	for ((var) = ((head)->stqh_first);			\
134		(var);						\
135		(var) = ((var)->field.stqe_next))
136#endif
137
138#ifndef	STAILQ_FOREACH_SAFE
139#define STAILQ_FOREACH_SAFE(var, head, field, tvar)		\
140       for ((var) = STAILQ_FIRST((head));			\
141	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);	\
142	    (var) = (tvar))
143#endif
144
145#ifndef	STAILQ_INIT
146#define	STAILQ_INIT(head) do {					\
147	(head)->stqh_first = NULL;				\
148	(head)->stqh_last = &(head)->stqh_first;		\
149} while (/*CONSTCOND*/0)
150#endif
151
152#ifndef	STAILQ_INSERT_HEAD
153#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
154	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
155		(head)->stqh_last = &(elm)->field.stqe_next;		\
156	(head)->stqh_first = (elm);					\
157} while (/*CONSTCOND*/0)
158#endif
159
160#ifndef	STAILQ_INSERT_TAIL
161#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
162	(elm)->field.stqe_next = NULL;					\
163	*(head)->stqh_last = (elm);					\
164	(head)->stqh_last = &(elm)->field.stqe_next;			\
165} while (/*CONSTCOND*/0)
166#endif
167
168#ifndef	STAILQ_INSERT_AFTER
169#define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
170	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
171		(head)->stqh_last = &(elm)->field.stqe_next;		\
172	(listelm)->field.stqe_next = (elm);				\
173} while (/*CONSTCOND*/0)
174#endif
175
176#ifndef	STAILQ_LAST
177#define STAILQ_LAST(head, type, field)					\
178	(STAILQ_EMPTY((head)) ?					\
179	    NULL : ((struct type *)(void *)				\
180	    ((char *)((head)->stqh_last) - offsetof(struct type, field))))
181#endif
182
183#ifndef	STAILQ_NEXT
184#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
185#endif
186
187#ifndef	STAILQ_REMOVE
188#define	STAILQ_REMOVE(head, elm, type, field) do {			\
189	if ((head)->stqh_first == (elm)) {				\
190		STAILQ_REMOVE_HEAD((head), field);			\
191	} else {							\
192		struct type *curelm = (head)->stqh_first;		\
193		while (curelm->field.stqe_next != (elm))		\
194			curelm = curelm->field.stqe_next;		\
195		if ((curelm->field.stqe_next =				\
196			curelm->field.stqe_next->field.stqe_next) == NULL) \
197			    (head)->stqh_last = &(curelm)->field.stqe_next; \
198	}								\
199} while (/*CONSTCOND*/0)
200#endif
201
202#ifndef	STAILQ_REMOVE_HEAD
203#define	STAILQ_REMOVE_HEAD(head, field) do {				\
204	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == \
205	    NULL)							\
206		(head)->stqh_last = &(head)->stqh_first;		\
207} while (/*CONSTCOND*/0)
208#endif
209
210/*
211 * The STAILQ_SORT macro is adapted from Simon Tatham's O(n*log(n))
212 * mergesort algorithm.
213 */
214#ifndef	STAILQ_SORT
215#define	STAILQ_SORT(head, type, field, cmp) do {			\
216	STAILQ_HEAD(, type) _la, _lb;					\
217	struct type *_p, *_q, *_e;					\
218	int _i, _sz, _nmerges, _psz, _qsz;				\
219									\
220	_sz = 1;							\
221	do {								\
222		_nmerges = 0;						\
223		STAILQ_INIT(&_lb);					\
224		while (!STAILQ_EMPTY((head))) {				\
225			_nmerges++;					\
226			STAILQ_INIT(&_la);				\
227			_psz = 0;					\
228			for (_i = 0; _i < _sz && !STAILQ_EMPTY((head));	\
229			     _i++) {					\
230				_e = STAILQ_FIRST((head));		\
231				if (_e == NULL)				\
232					break;				\
233				_psz++;					\
234				STAILQ_REMOVE_HEAD((head), field);	\
235				STAILQ_INSERT_TAIL(&_la, _e, field);	\
236			}						\
237			_p = STAILQ_FIRST(&_la);			\
238			_qsz = _sz;					\
239			_q = STAILQ_FIRST((head));			\
240			while (_psz > 0 || (_qsz > 0 && _q != NULL)) {	\
241				if (_psz == 0) {			\
242					_e = _q;			\
243					_q = STAILQ_NEXT(_q, field);	\
244					STAILQ_REMOVE_HEAD((head),	\
245					    field);			\
246					_qsz--;				\
247				} else if (_qsz == 0 || _q == NULL) {	\
248					_e = _p;			\
249					_p = STAILQ_NEXT(_p, field);	\
250					STAILQ_REMOVE_HEAD(&_la, field);\
251					_psz--;				\
252				} else if (cmp(_p, _q) <= 0) {		\
253					_e = _p;			\
254					_p = STAILQ_NEXT(_p, field);	\
255					STAILQ_REMOVE_HEAD(&_la, field);\
256					_psz--;				\
257				} else {				\
258					_e = _q;			\
259					_q = STAILQ_NEXT(_q, field);	\
260					STAILQ_REMOVE_HEAD((head),	\
261					    field);			\
262					_qsz--;				\
263				}					\
264				STAILQ_INSERT_TAIL(&_lb, _e, field);	\
265			}						\
266		}							\
267		(head)->stqh_first = _lb.stqh_first;			\
268		(head)->stqh_last = _lb.stqh_last;			\
269		_sz *= 2;						\
270	} while (_nmerges > 1);						\
271} while (/*CONSTCOND*/0)
272#endif
273
274#ifndef	TAILQ_FOREACH_SAFE
275#define TAILQ_FOREACH_SAFE(var, head, field, tvar)                      \
276	for ((var) = TAILQ_FIRST((head));                               \
277	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);            \
278	    (var) = (tvar))
279#endif
280
281/* ]] --QUEUE-MACROS-- */
282
283/*
284 * VCS Ids.
285 */
286
287#ifndef	ELFTC_VCSID
288
289#if defined(__DragonFly__)
290#define	ELFTC_VCSID(ID)		__RCSID(ID)
291#endif
292
293#if defined(__FreeBSD__)
294#define	ELFTC_VCSID(ID)		__FBSDID(ID)
295#endif
296
297#if defined(__APPLE__) || defined(__GLIBC__) || defined(__GNU__) || \
298    defined(__linux__)
299#if defined(__GNUC__)
300#define	ELFTC_VCSID(ID)		__asm__(".ident\t\"" ID "\"")
301#else
302#define	ELFTC_VCSID(ID)		/**/
303#endif
304#endif
305
306#if defined(__minix)
307#if defined(__GNUC__)
308#define	ELFTC_VCSID(ID)		__asm__(".ident\t\"" ID "\"")
309#else
310#define	ELFTC_VCSID(ID)		/**/
311#endif	/* __GNU__ */
312#endif
313
314#if defined(__NetBSD__)
315#define	ELFTC_VCSID(ID)		__RCSID(ID)
316#endif
317
318#if defined(__OpenBSD__)
319#if defined(__GNUC__)
320#define	ELFTC_VCSID(ID)		__asm__(".ident\t\"" ID "\"")
321#else
322#define	ELFTC_VCSID(ID)		/**/
323#endif	/* __GNUC__ */
324#endif
325
326#endif	/* ELFTC_VCSID */
327
328/*
329 * Provide an equivalent for getprogname(3).
330 */
331
332#ifndef	ELFTC_GETPROGNAME
333
334#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
335    defined(__minix) || defined(__NetBSD__)
336
337#include <stdlib.h>
338
339#define	ELFTC_GETPROGNAME()	getprogname()
340
341#endif	/* __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */
342
343
344#if defined(__GLIBC__) || defined(__linux__)
345#ifndef _GNU_SOURCE
346/*
347 * GLIBC based systems have a global 'char *' pointer referencing
348 * the executable's name.
349 */
350extern const char *program_invocation_short_name;
351#endif	/* !_GNU_SOURCE */
352
353#define	ELFTC_GETPROGNAME()	program_invocation_short_name
354
355#endif	/* __GLIBC__ || __linux__ */
356
357
358#if defined(__OpenBSD__)
359
360extern const char *__progname;
361
362#define	ELFTC_GETPROGNAME()	__progname
363
364#endif	/* __OpenBSD__ */
365
366#endif	/* ELFTC_GETPROGNAME */
367
368
369/**
370 ** Per-OS configuration.
371 **/
372
373#if defined(__APPLE__)
374
375#include <libkern/OSByteOrder.h>
376#define	htobe32(x)	OSSwapHostToBigInt32(x)
377#define	htole32(x)	OSSwapHostToLittleInt32(x)
378#ifndef roundup2
379#define	roundup2	roundup
380#endif
381
382#define	ELFTC_BYTE_ORDER			__DARWIN_BYTE_ORDER
383#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		__DARWIN_LITTLE_ENDIAN
384#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		__DARWIN_BIG_ENDIAN
385
386#define	ELFTC_HAVE_MMAP				1
387#define	ELFTC_HAVE_STRMODE			1
388
389#define ELFTC_NEED_BYTEORDER_EXTENSIONS		1
390#endif /* __APPLE__ */
391
392
393#if defined(__DragonFly__)
394
395#include <osreldate.h>
396#include <sys/endian.h>
397
398#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
399#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
400#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
401
402#define	ELFTC_HAVE_MMAP				1
403
404#endif
405
406#if defined(__GLIBC__) || defined(__linux__)
407
408#include <endian.h>
409
410#define	ELFTC_BYTE_ORDER			__BYTE_ORDER
411#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		__LITTLE_ENDIAN
412#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		__BIG_ENDIAN
413
414#define	ELFTC_HAVE_MMAP				1
415
416/*
417 * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3).
418 */
419#define	ELFTC_HAVE_STRMODE			0
420
421/* Whether we need to supply {be,le}32dec. */
422#define ELFTC_NEED_BYTEORDER_EXTENSIONS		1
423
424#ifndef roundup2
425#define	roundup2	roundup
426#endif
427
428#endif	/* __GLIBC__ || __linux__ */
429
430
431#if defined(__FreeBSD__)
432
433#include <osreldate.h>
434#include <sys/endian.h>
435
436#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
437#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
438#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
439
440#define	ELFTC_HAVE_MMAP				1
441#define	ELFTC_HAVE_STRMODE			1
442#if __FreeBSD_version <= 900000
443#define	ELFTC_BROKEN_YY_NO_INPUT		1
444#endif
445#endif	/* __FreeBSD__ */
446
447
448#if defined(__minix)
449#define	ELFTC_HAVE_MMAP				0
450#endif	/* __minix */
451
452
453#if defined(__NetBSD__)
454
455#include <sys/param.h>
456#include <sys/endian.h>
457
458#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
459#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
460#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
461
462#define	ELFTC_HAVE_MMAP				1
463#define	ELFTC_HAVE_STRMODE			1
464#if __NetBSD_Version__ <= 599002100
465/* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */
466/* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */
467#  define ELFTC_BROKEN_YY_NO_INPUT		1
468#endif
469#endif	/* __NetBSD __ */
470
471
472#if defined(__OpenBSD__)
473
474#include <sys/param.h>
475#include <sys/endian.h>
476
477#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
478#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
479#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
480
481#define	ELFTC_HAVE_MMAP				1
482#define	ELFTC_HAVE_STRMODE			1
483
484#define	ELFTC_NEED_BYTEORDER_EXTENSIONS		1
485#define	roundup2	roundup
486
487#endif	/* __OpenBSD__ */
488
489#endif	/* _ELFTC_H */
490