xref: /netbsd-src/external/bsd/elftoolchain/dist/common/_elftc.h (revision 5ac3bc719ce6e70593039505b491894133237d12)
1 /*	$NetBSD: _elftc.h,v 1.10 2024/03/03 17:37:29 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2009 Joseph Koshy
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * Id: _elftc.h 3975 2022-04-30 20:10:58Z jkoshy
29  */
30 
31 /**
32  ** Miscellaneous definitions needed by multiple components.
33  **/
34 
35 #ifndef	_ELFTC_H
36 #define	_ELFTC_H
37 
38 #ifndef	NULL
39 #define NULL 	((void *) 0)
40 #endif
41 
42 #ifndef	offsetof
43 #define	offsetof(T, M)		((int) &((T*) 0) -> M)
44 #endif
45 
46 /* --QUEUE-MACROS-- [[ */
47 
48 /*
49  * Supply macros missing from <sys/queue.h>
50  */
51 
52 /*
53  * Copyright (c) 1991, 1993
54  *	The Regents of the University of California.  All rights reserved.
55  *
56  * Redistribution and use in source and binary forms, with or without
57  * modification, are permitted provided that the following conditions
58  * are met:
59  * 1. Redistributions of source code must retain the above copyright
60  *    notice, this list of conditions and the following disclaimer.
61  * 2. Redistributions in binary form must reproduce the above copyright
62  *    notice, this list of conditions and the following disclaimer in the
63  *    documentation and/or other materials provided with the distribution.
64  * 3. Neither the name of the University nor the names of its contributors
65  *    may be used to endorse or promote products derived from this software
66  *    without specific prior written permission.
67  *
68  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
69  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
70  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
71  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
72  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
73  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
74  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
75  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
76  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
77  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
78  * SUCH DAMAGE.
79  */
80 
81 #ifndef	LIST_FOREACH_SAFE
82 #define	LIST_FOREACH_SAFE(var, head, field, tvar)		\
83 	for ((var) = LIST_FIRST((head));			\
84 	    (var) && ((tvar) = LIST_NEXT((var), field), 1);	\
85 	    (var) = (tvar))
86 #endif
87 
88 #ifndef	SLIST_FOREACH_SAFE
89 #define	SLIST_FOREACH_SAFE(var, head, field, tvar)		\
90 	for ((var) = SLIST_FIRST((head));			\
91 	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);	\
92 	    (var) = (tvar))
93 #endif
94 
95 #ifndef	STAILQ_CONCAT
96 #define	STAILQ_CONCAT(head1, head2) do {			\
97 	if (!STAILQ_EMPTY((head2))) {				\
98 		*(head1)->stqh_last = (head2)->stqh_first;	\
99 		(head1)->stqh_last = (head2)->stqh_last;	\
100 		STAILQ_INIT((head2));				\
101 	}							\
102 } while (/*CONSTCOND*/0)
103 #endif
104 
105 #ifndef	STAILQ_EMPTY
106 #define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
107 #endif
108 
109 #ifndef	STAILQ_ENTRY
110 #define	STAILQ_ENTRY(type)					\
111 struct {							\
112 	struct type *stqe_next;	/* next element */		\
113 }
114 #endif
115 
116 #ifndef	STAILQ_FIRST
117 #define	STAILQ_FIRST(head)	((head)->stqh_first)
118 #endif
119 
120 #ifndef	STAILQ_HEAD
121 #define	STAILQ_HEAD(name, type)					\
122 struct name {							\
123 	struct type *stqh_first; /* first element */		\
124 	struct type **stqh_last; /* addr of last next element */ \
125 }
126 #endif
127 
128 #ifndef	STAILQ_HEAD_INITIALIZER
129 #define	STAILQ_HEAD_INITIALIZER(head)				\
130 	{ NULL, &(head).stqh_first }
131 #endif
132 
133 #ifndef	STAILQ_FOREACH
134 #define	STAILQ_FOREACH(var, head, field)			\
135 	for ((var) = ((head)->stqh_first);			\
136 		(var);						\
137 		(var) = ((var)->field.stqe_next))
138 #endif
139 
140 #ifndef	STAILQ_FOREACH_SAFE
141 #define STAILQ_FOREACH_SAFE(var, head, field, tvar)		\
142        for ((var) = STAILQ_FIRST((head));			\
143 	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);	\
144 	    (var) = (tvar))
145 #endif
146 
147 #ifndef	STAILQ_INIT
148 #define	STAILQ_INIT(head) do {					\
149 	(head)->stqh_first = NULL;				\
150 	(head)->stqh_last = &(head)->stqh_first;		\
151 } while (/*CONSTCOND*/0)
152 #endif
153 
154 #ifndef	STAILQ_INSERT_HEAD
155 #define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
156 	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
157 		(head)->stqh_last = &(elm)->field.stqe_next;		\
158 	(head)->stqh_first = (elm);					\
159 } while (/*CONSTCOND*/0)
160 #endif
161 
162 #ifndef	STAILQ_INSERT_TAIL
163 #define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
164 	(elm)->field.stqe_next = NULL;					\
165 	*(head)->stqh_last = (elm);					\
166 	(head)->stqh_last = &(elm)->field.stqe_next;			\
167 } while (/*CONSTCOND*/0)
168 #endif
169 
170 #ifndef	STAILQ_INSERT_AFTER
171 #define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
172 	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
173 		(head)->stqh_last = &(elm)->field.stqe_next;		\
174 	(listelm)->field.stqe_next = (elm);				\
175 } while (/*CONSTCOND*/0)
176 #endif
177 
178 #ifndef	STAILQ_LAST
179 #define STAILQ_LAST(head, type, field)					\
180 	(STAILQ_EMPTY((head)) ?					\
181 	    NULL : ((struct type *)(void *)				\
182 	    ((char *)((head)->stqh_last) - offsetof(struct type, field))))
183 #endif
184 
185 #ifndef	STAILQ_NEXT
186 #define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
187 #endif
188 
189 #ifndef	STAILQ_REMOVE
190 #define	STAILQ_REMOVE(head, elm, type, field) do {			\
191 	if ((head)->stqh_first == (elm)) {				\
192 		STAILQ_REMOVE_HEAD((head), field);			\
193 	} else {							\
194 		struct type *curelm = (head)->stqh_first;		\
195 		while (curelm->field.stqe_next != (elm))		\
196 			curelm = curelm->field.stqe_next;		\
197 		if ((curelm->field.stqe_next =				\
198 			curelm->field.stqe_next->field.stqe_next) == NULL) \
199 			    (head)->stqh_last = &(curelm)->field.stqe_next; \
200 	}								\
201 } while (/*CONSTCOND*/0)
202 #endif
203 
204 #ifndef	STAILQ_REMOVE_HEAD
205 #define	STAILQ_REMOVE_HEAD(head, field) do {				\
206 	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == \
207 	    NULL)							\
208 		(head)->stqh_last = &(head)->stqh_first;		\
209 } while (/*CONSTCOND*/0)
210 #endif
211 
212 /*
213  * The STAILQ_SORT macro is adapted from Simon Tatham's O(n*log(n))
214  * mergesort algorithm.
215  */
216 #ifndef	STAILQ_SORT
217 #define	STAILQ_SORT(head, type, field, cmp) do {			\
218 	STAILQ_HEAD(, type) _la, _lb;					\
219 	struct type *_p, *_q, *_e;					\
220 	int _i, _sz, _nmerges, _psz, _qsz;				\
221 									\
222 	_sz = 1;							\
223 	do {								\
224 		_nmerges = 0;						\
225 		STAILQ_INIT(&_lb);					\
226 		while (!STAILQ_EMPTY((head))) {				\
227 			_nmerges++;					\
228 			STAILQ_INIT(&_la);				\
229 			_psz = 0;					\
230 			for (_i = 0; _i < _sz && !STAILQ_EMPTY((head));	\
231 			     _i++) {					\
232 				_e = STAILQ_FIRST((head));		\
233 				if (_e == NULL)				\
234 					break;				\
235 				_psz++;					\
236 				STAILQ_REMOVE_HEAD((head), field);	\
237 				STAILQ_INSERT_TAIL(&_la, _e, field);	\
238 			}						\
239 			_p = STAILQ_FIRST(&_la);			\
240 			_qsz = _sz;					\
241 			_q = STAILQ_FIRST((head));			\
242 			while (_psz > 0 || (_qsz > 0 && _q != NULL)) {	\
243 				if (_psz == 0) {			\
244 					_e = _q;			\
245 					_q = STAILQ_NEXT(_q, field);	\
246 					STAILQ_REMOVE_HEAD((head),	\
247 					    field);			\
248 					_qsz--;				\
249 				} else if (_qsz == 0 || _q == NULL) {	\
250 					_e = _p;			\
251 					_p = STAILQ_NEXT(_p, field);	\
252 					STAILQ_REMOVE_HEAD(&_la, field);\
253 					_psz--;				\
254 				} else if (cmp(_p, _q) <= 0) {		\
255 					_e = _p;			\
256 					_p = STAILQ_NEXT(_p, field);	\
257 					STAILQ_REMOVE_HEAD(&_la, field);\
258 					_psz--;				\
259 				} else {				\
260 					_e = _q;			\
261 					_q = STAILQ_NEXT(_q, field);	\
262 					STAILQ_REMOVE_HEAD((head),	\
263 					    field);			\
264 					_qsz--;				\
265 				}					\
266 				STAILQ_INSERT_TAIL(&_lb, _e, field);	\
267 			}						\
268 		}							\
269 		(head)->stqh_first = _lb.stqh_first;			\
270 		(head)->stqh_last = _lb.stqh_last;			\
271 		_sz *= 2;						\
272 	} while (_nmerges > 1);						\
273 } while (/*CONSTCOND*/0)
274 #endif
275 
276 #ifndef	TAILQ_FOREACH_SAFE
277 #define TAILQ_FOREACH_SAFE(var, head, field, tvar)                      \
278 	for ((var) = TAILQ_FIRST((head));                               \
279 	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);            \
280 	    (var) = (tvar))
281 #endif
282 
283 /* ]] --QUEUE-MACROS-- */
284 
285 /*
286  * VCS Ids.
287  *
288  * The place holder below is intended to be replaced with a project-specific
289  * definition of the ELFTC_VCSID macro.
290  */
291 
292 #ifndef	ELFTC_VCSID
293 #define	ELFTC_VCSID(ID)		/**/
294 #endif
295 
296 #ifndef	ELFTC_VCSID
297 
298 #if defined(__DragonFly__) || defined(__NetBSD__)
299 
300 #define	ELFTC_VCSID(ID)		__RCSID(ID)
301 
302 #elif defined(__FreeBSD__)
303 
304 #define	ELFTC_VCSID(ID)		__FBSDID(ID)
305 
306 #elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__GLIBC__) || \
307     defined(__GNU__) || defined(__linux__) || defined(__minix)
308 
309 #if defined(__GNUC__)
310 #define	ELFTC_VCSID(ID)		__asm__(".ident\t\"" ID "\"")
311 #else
312 #define	ELFTC_VCSID(ID)		/**/
313 #endif
314 
315 #endif
316 
317 #endif	/* ELFTC_VCSID */
318 
319 /*
320  * The place holder below is meant to be replaced by a declaration
321  * of the downstream project's revision control macro.
322  *
323  * E.g. on NetBSD, this place holder would be replaced by:
324  *
325  *   #if !defined(__RCSID)
326  *   #define __RCSID(ID)
327  *   #endif
328  */
329 #if !defined(__RCSID)
330 #define __RCSID(ID) /**/
331 #endif  /* !defined(__RCSID) */
332 
333 /*
334  * Provide an equivalent for getprogname(3).
335  */
336 
337 #ifndef	ELFTC_GETPROGNAME
338 
339 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
340     defined(__minix) || defined(__NetBSD__)
341 
342 #include <stdlib.h>
343 
344 #define	ELFTC_GETPROGNAME()	getprogname()
345 
346 #endif	/* __APPLE__ || __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */
347 
348 
349 #if defined(__GLIBC__) || defined(__linux__)
350 #ifndef _GNU_SOURCE
351 /*
352  * GLIBC based systems have a global 'char *' pointer referencing
353  * the executable's name.
354  */
355 extern const char *program_invocation_short_name;
356 #endif	/* !_GNU_SOURCE */
357 
358 #define	ELFTC_GETPROGNAME()	program_invocation_short_name
359 
360 #endif	/* __GLIBC__ || __linux__ */
361 
362 
363 #if defined(__OpenBSD__)
364 
365 extern const char *__progname;
366 
367 #define	ELFTC_GETPROGNAME()	__progname
368 
369 #endif	/* __OpenBSD__ */
370 
371 #endif	/* ELFTC_GETPROGNAME */
372 
373 
374 /*
375  * Per-OS configuration.
376  *
377  * The following symbols are supported by this configuration fragment,
378  * although not all the OSes so referenced are fully supported.
379  *
380  * Cross-compilation:
381  *
382  * HAVE_NBTOOL_CONFIG_H : cross-compiling NetBSD tools on various OSes.
383  *
384  * Native compilation:
385  *
386  * __APPLE__     : compiling under Mac OS X.
387  * __DragonFly__ : compiling under DragonFlyBSD.
388  * __GLIBC__     : compiling under GNU based systems, such as GNU/kFreeBSD.
389  * __linux__     : compiling under GNU/Linux systems.
390  * __FreeBSD__   : compiling under FreeBSD.
391  * __minix       : compiling under Minix3.
392  * __NetBSD__    : compiling (native) under NetBSD.
393  * __OpenBSD__   : compiling under OpenBSD.
394  */
395 
396 #if defined(HAVE_NBTOOL_CONFIG_H)
397 
398 #include <sys/param.h>
399 #include <sys/endian.h>
400 
401 #ifndef	roundup2
402 #define	roundup2	roundup
403 #endif
404 
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
408 
409 #define	ELFTC_HAVE_MMAP				1
410 #define	ELFTC_HAVE_STRMODE			1
411 
412 #elif defined(__APPLE__)
413 
414 #include <libkern/OSByteOrder.h>
415 #define	htobe32(x)	OSSwapHostToBigInt32(x)
416 #define	roundup2	roundup
417 
418 #define	ELFTC_BYTE_ORDER			_BYTE_ORDER
419 #define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
420 #define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
421 
422 #define	ELFTC_HAVE_MMAP				1
423 #define	ELFTC_HAVE_STRMODE			1
424 
425 #define ELFTC_NEED_BYTEORDER_EXTENSIONS		1
426 
427 #elif defined(__DragonFly__)
428 
429 #include <osreldate.h>
430 #include <sys/endian.h>
431 
432 #define	ELFTC_BYTE_ORDER			_BYTE_ORDER
433 #define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
434 #define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
435 
436 #define	ELFTC_HAVE_MMAP				1
437 
438 #elif defined(__GLIBC__) || defined(__linux__)
439 
440 #include <endian.h>
441 
442 #define	ELFTC_BYTE_ORDER			__BYTE_ORDER
443 #define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		__LITTLE_ENDIAN
444 #define	ELFTC_BYTE_ORDER_BIG_ENDIAN		__BIG_ENDIAN
445 
446 #define	ELFTC_HAVE_MMAP				1
447 
448 /*
449  * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3).
450  */
451 #define	ELFTC_HAVE_STRMODE			0
452 
453 /* Whether we need to supply {be,le}32dec. */
454 #define ELFTC_NEED_BYTEORDER_EXTENSIONS		1
455 
456 #define	roundup2	roundup
457 
458 #elif defined(__FreeBSD__)
459 
460 #include <osreldate.h>
461 #include <sys/endian.h>
462 
463 #define	ELFTC_BYTE_ORDER			_BYTE_ORDER
464 #define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
465 #define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
466 
467 #define	ELFTC_HAVE_MMAP				1
468 #define	ELFTC_HAVE_STRMODE			1
469 #if __FreeBSD_version <= 900000
470 #define	ELFTC_BROKEN_YY_NO_INPUT		1
471 #endif
472 
473 #elif defined(__minix)
474 #define	ELFTC_HAVE_MMAP				0
475 
476 #elif defined(__NetBSD__)
477 
478 #include <sys/param.h>
479 #include <sys/endian.h>
480 
481 #define	ELFTC_BYTE_ORDER			_BYTE_ORDER
482 #define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
483 #define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
484 
485 #define	ELFTC_HAVE_MMAP				1
486 #define	ELFTC_HAVE_STRMODE			1
487 #if __NetBSD_Version__ <= 599002100
488 /* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */
489 /* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */
490 #  define ELFTC_BROKEN_YY_NO_INPUT		1
491 #endif
492 
493 #elif defined(__OpenBSD__)
494 
495 #include <sys/param.h>
496 #include <sys/endian.h>
497 
498 #define	ELFTC_BYTE_ORDER			_BYTE_ORDER
499 #define	ELFTC_BYTE_ORDER_LITTLE_ENDIAN		_LITTLE_ENDIAN
500 #define	ELFTC_BYTE_ORDER_BIG_ENDIAN		_BIG_ENDIAN
501 
502 #define	ELFTC_HAVE_MMAP				1
503 #define	ELFTC_HAVE_STRMODE			1
504 
505 #define	ELFTC_NEED_BYTEORDER_EXTENSIONS		1
506 #define	roundup2	roundup
507 
508 #endif	/* __OpenBSD__ */
509 
510 #endif	/* _ELFTC_H */
511