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,v 1.3 2022/09/01 05:49:04 miod Exp $
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#define	ELFTC_VCSID(ID)		/* intentionally disabled */
320#endif
321
322#endif	/* ELFTC_VCSID */
323
324/*
325 * Provide an equivalent for getprogname(3).
326 */
327
328#ifndef	ELFTC_GETPROGNAME
329
330#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
331    defined(__minix) || defined(__NetBSD__)
332
333#include <stdlib.h>
334
335#define	ELFTC_GETPROGNAME()	getprogname()
336
337#endif	/* __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */
338
339
340#if defined(__GLIBC__) || defined(__linux__)
341#ifndef _GNU_SOURCE
342/*
343 * GLIBC based systems have a global 'char *' pointer referencing
344 * the executable's name.
345 */
346extern const char *program_invocation_short_name;
347#endif	/* !_GNU_SOURCE */
348
349#define	ELFTC_GETPROGNAME()	program_invocation_short_name
350
351#endif	/* __GLIBC__ || __linux__ */
352
353
354#if defined(__OpenBSD__)
355
356extern const char *__progname;
357
358#define	ELFTC_GETPROGNAME()	__progname
359
360#endif	/* __OpenBSD__ */
361
362#endif	/* ELFTC_GETPROGNAME */
363
364
365/**
366 ** Per-OS configuration.
367 **/
368
369#if defined(__APPLE__)
370
371#include <libkern/OSByteOrder.h>
372#define	htobe32(x)	OSSwapHostToBigInt32(x)
373#define	roundup2	roundup
374
375#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
376#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
377#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
378
379#define	ELFTC_HAVE_MMAP				1
380#define	ELFTC_HAVE_STRMODE			1
381
382#define ELFTC_NEED_BYTEORDER_EXTENSIONS		1
383#endif /* __APPLE__ */
384
385
386#if defined(__DragonFly__)
387
388#include <osreldate.h>
389#include <sys/endian.h>
390
391#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
392#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
393#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
394
395#define	ELFTC_HAVE_MMAP				1
396
397#endif
398
399#if defined(__GLIBC__) || defined(__linux__)
400
401#include <endian.h>
402
403#define	ELFTC_BYTE_ORDER			__BYTE_ORDER
404#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		__LITTLE_ENDIAN
405#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		__BIG_ENDIAN
406
407#define	ELFTC_HAVE_MMAP				1
408
409/*
410 * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3).
411 */
412#define	ELFTC_HAVE_STRMODE			0
413
414/* Whether we need to supply {be,le}32dec. */
415#define ELFTC_NEED_BYTEORDER_EXTENSIONS		1
416
417#define	roundup2	roundup
418
419#endif	/* __GLIBC__ || __linux__ */
420
421
422#if defined(__FreeBSD__)
423
424#include <osreldate.h>
425#include <sys/endian.h>
426
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
430
431#define	ELFTC_HAVE_MMAP				1
432#define	ELFTC_HAVE_STRMODE			1
433#if __FreeBSD_version <= 900000
434#define	ELFTC_BROKEN_YY_NO_INPUT		1
435#endif
436#endif	/* __FreeBSD__ */
437
438
439#if defined(__minix)
440#define	ELFTC_HAVE_MMAP				0
441#endif	/* __minix */
442
443
444#if defined(__NetBSD__)
445
446#include <sys/param.h>
447#include <sys/endian.h>
448
449#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
450#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
451#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
452
453#define	ELFTC_HAVE_MMAP				1
454#define	ELFTC_HAVE_STRMODE			1
455#if __NetBSD_Version__ <= 599002100
456/* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */
457/* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */
458#  define ELFTC_BROKEN_YY_NO_INPUT		1
459#endif
460#endif	/* __NetBSD __ */
461
462
463#if defined(__OpenBSD__)
464
465#include <sys/param.h>	/* roundup roundup2 */
466#include <sys/endian.h>
467
468#define	ELFTC_BYTE_ORDER			_BYTE_ORDER
469#define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
470#define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
471
472#define	ELFTC_HAVE_MMAP				1
473#define	ELFTC_HAVE_STRMODE			1
474
475#define	ELFTC_NEED_BYTEORDER_EXTENSIONS		1
476#define	roundup2	roundup
477
478#endif	/* __OpenBSD__ */
479
480#endif	/* _ELFTC_H */
481