Fully synchronize sys/boot from FreeBSD-5.x, but add / to the module path
[dragonfly.git] / sys / sys / linker_set.h
index 1dfc145..3468b21 100644 (file)
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/linker_set.h,v 1.4.2.1 2000/08/02 21:52:20 peter Exp $
- * $DragonFly: src/sys/sys/linker_set.h,v 1.2 2003/06/17 04:28:58 dillon Exp $
+ * $DragonFly: src/sys/sys/linker_set.h,v 1.3 2003/11/10 06:12:17 dillon Exp $
  */
 
 #ifndef _SYS_LINKER_SET_H_
 #define _SYS_LINKER_SET_H_
 
+#ifndef _SYS_CDEFS_H_
+#include <sys/cdefs.h>
+#endif
+
 /*
  * The following macros are used to declare global sets of objects, which
  * are collected by the linker into a `struct linker_set' as defined below.
  * For ELF, this is done by constructing a separate segment for each set.
- * For a.out, it is done automatically by the linker.
  *
- * In the MAKE_SET macros below, the lines:
+ * In the __MAKE_SET macros below, the lines:
  *
  *   static void const * const __set_##set##_sym_##sym = &sym;
  *
  * are present only to prevent the compiler from producing bogus
  * warnings about unused symbols.
  */
-#ifdef __ELF__
+#ifndef __ELF__
+#error only ELF is supported
+#endif
 
-/*
- * Alpha GAS needs an align before the section change.  It seems to assume
- * that after the .previous, it is aligned, so the following .align 3 is
- * ignored.  Since the previous instructions often contain strings, this is
- * a problem.
- */
+#if 0
 
-#ifdef __alpha__
-#define MAKE_SET(set, sym)                                             \
-       static void const * const __set_##set##_sym_##sym = &sym;       \
-       __asm(".align 3");                                              \
-       __asm(".section .set." #set ",\"aw\"");                         \
-       __asm(".quad " #sym);                                           \
-       __asm(".previous")
-#else
-#define MAKE_SET(set, sym)                                             \
+#define __MAKE_SET(set, sym)                                           \
        static void const * const __set_##set##_sym_##sym = &sym;       \
-       __asm(".section .set." #set ",\"aw\"");                         \
+       __asm(".section set_" #set ",\"aw\"");                          \
        __asm(".long " #sym);                                           \
        __asm(".previous")
+
 #endif
-#define TEXT_SET(set, sym) MAKE_SET(set, sym)
-#define DATA_SET(set, sym) MAKE_SET(set, sym)
 
-#else
+#define __MAKE_SET(set, sym)                                            \
+        static void const * const __set_##set##_sym_##sym               \
+       __section("set_" #set) __unused = &sym
+
+#define TEXT_SET(set, sym) __MAKE_SET(set, sym)
+#define DATA_SET(set, sym) __MAKE_SET(set, sym)
+#define BSS_SET(set, sym) __MAKE_SET(set, sym)
+#define ABS_SET(set, sym) __MAKE_SET(set, sym)
+#define SET_ENTRY(set, sym) __MAKE_SET(set, sym)
+
+#define SET_DECLARE(set, ptype)                                \
+       extern ptype *__CONCAT(__start_set_,set);       \
+       extern ptype *__CONCAT(__stop_set_,set)
+
+#define SET_BEGIN(set)         (&__CONCAT(__start_set_,set))
+#define SET_LIMIT(set)         (&__CONCAT(__stop_set_,set))
 
 /*
- * NB: the constants defined below must match those defined in
- * ld/ld.h.  Since their calculation requires arithmetic, we
- * can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
+ * Iterate over all the elements of a set.
+ *
+ * Sets always contain addresses of things, and "pvar" points to words
+ * containing those addresses.  Thus is must be declared as "type **pvar",
+ * and the address of each set item is obtained inside the loop by "*pvar".
  */
-#define MAKE_SET(set, sym, type) \
-       static void const * const __set_##set##_sym_##sym = &sym; \
-       __asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym)
-#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23)
-#define DATA_SET(set, sym) MAKE_SET(set, sym, 25)
+#define SET_FOREACH(pvar, set)                         \
+       for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)
 
-#endif
+#define SET_ITEM(set, i)                               \
+       ((SET_BEGIN(set))[i])
 
-struct linker_set {
-       int     ls_length;
-       void    *ls_items[1];           /* really ls_length of them,
-                                                * trailing NULL */
-};
+/*
+ * Provide a count of the items in a set.
+ */
+#define SET_COUNT(set)                                 \
+       (SET_LIMIT(set) - SET_BEGIN(set))
 
 #endif /* _SYS_LINKER_SET_H_ */