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)					\
109 struct {							\
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)					\
120 struct 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  */
350 extern 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 
360 extern 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