1 #ifndef _AROS_SYMBOLSETS_H
2 #define _AROS_SYMBOLSETS_H
5 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
8 Desc: Symbol sets support
12 #include <exec/types.h>
13 #include <exec/libraries.h>
14 #include <exec/execbase.h>
15 #include <aros/asmcall.h>
22 const LONG
*versionptr
;
29 const LONG
* const versionptr
;
30 const IPTR
* const baseoffsetptr
;
33 #define SETNAME(set) __##set##_LIST__
35 #define DECLARESET(set) \
36 extern const void * const SETNAME(set)[] __attribute__((weak));
38 #define DEFINESET(set) \
39 const void * const SETNAME(set)[] __attribute__((weak))={0,0};
41 #define ADD2SET(symbol, _set, pri)\
42 static const void * const __aros_set_##_set##_##symbol __attribute__((__section__(".aros.set." #_set "." #pri))) __used = (void *)&symbol;
44 #define SETELEM(symbol, _set) \
46 extern const void * const __aros_set_##_set##_##symbol; \
47 &__aros_set_##_set##_##symbol; \
51 ctors and dtors sets are used by c++ to store static constructors/destructors
54 The functions have to be invoked respectively right before the program enters
55 the main() function and right after the program exits the main() function.
57 ctors is called in backward order, dtors in forward order.
59 #define ADD2CTORS(symbol, pri) ADD2SET(symbol, CTORS, pri)
60 #define ADD2DTORS(symbol, pri) ADD2SET(symbol, DTORS, pri)
63 init_array and fini_array sets are used by c++ to store static constructors/destructors
64 pointers in them on ARM EABI.
66 The functions have to be invoked respectively right before the program enters
67 the main() function and right after the program exits the main() function.
69 init_array is called in forward order, fini_array in backward order.
71 init_array is called after ctors, fini_array is called before dtors
73 #define ADD2INITARRAY(symbol, pri) ADD2SET(symbol, INIT_ARRAY, pri)
74 #define ADD2FINIARRAY(symbol, pri) ADD2SET(symbol, FINI_ARRAY, pri)
77 init and exit sets are like the ctors and dtors sets, except that they take
78 precedence on them, that is functions stored in the init set are called
79 before the ones stored in the ctors set, and functions stored in the
80 exit set are called after the ones stored in the dtors set.
82 Moreover, init functions return an int, instead of void like the ctor functions.
83 This return value is equal to 0 if the function returned with success, otherwise
84 it holds an error code.
87 #define ADD2INIT(symbol, pri) ADD2SET(symbol, INIT, pri)
88 #define ADD2EXIT(symbol, pri) ADD2SET(symbol, EXIT, pri)
91 initlib, expungelib, openlib, closelib sets are similar to the init and exit
92 sets, only they are specific to the initialisation phase of libraries.
93 initlib/expungelib are only called when a library is loaded/unloaded from
94 memory. openlib/closelib is called every time a library is opened/closed.
95 The library base is passed to each of the functions present in the sets as
98 The return argument is also an int, and just like with the init/exit sets,
99 a zero value indicates an (de)initialization failure, a one indicates succes.
100 The calling of the functions in the initlib and the openlib sets stops when
101 the first zero value is met. The functions in the expungelib and the
102 closelib are always called.
104 These sets have a lower priority then the INIT and the CTORS sets. So when
105 a library is loaded first the init set is called, then the ctors set and
106 finally the initlib set.
109 #define ADD2INITLIB(symbol, pri) ADD2SET(symbol, INITLIB, pri)
110 #define ADD2EXPUNGELIB(symbol, pri) ADD2SET(symbol, EXPUNGELIB, pri)
111 #define ADD2OPENLIB(symbol, pri) ADD2SET(symbol, OPENLIB, pri)
112 #define ADD2CLOSELIB(symbol, pri) ADD2SET(symbol, CLOSELIB, pri)
113 #define ADD2OPENDEV(symbol, pri) ADD2SET(symbol, OPENDEV, pri)
114 #define ADD2CLOSEDEV(symbol, pri) ADD2SET(symbol, CLOSEDEV, pri)
116 /* this macro generates the necessary symbols to open and close automatically
117 a library. An error message will be shown if the library cannot be opened. */
118 #define AROS_LIBSET(name, btype, bname) \
120 extern const LONG __aros_libreq_##bname __attribute__((weak)); \
122 AROS_IMPORT_ASM_SYM(int, dummy, __includelibrarieshandling); \
124 static const struct libraryset __aros_libset_##bname = \
126 name, &__aros_libreq_##bname, (void *)&bname \
128 ADD2SET(__aros_libset_##bname, LIBS, 0)
130 /* NOTE: Users of this symbolset will need to provide:
132 * const IPTR __aros_rellib_offset_##bname = offsetof(struct MyBase, my_bname);
133 * AROS_IMPORT_ASM_SYM(void *, _##bname, __aros_rellib_base_##bname);
135 #define AROS_RELLIBSET(name, btype, bname) \
136 const ULONG __aros_rellib_base_##bname = 0; \
137 extern const IPTR __aros_rellib_offset_##bname; \
138 extern const LONG __aros_libreq_##bname __attribute__((weak)); \
140 AROS_IMPORT_ASM_SYM(int, dummy, __includerellibrarieshandling); \
142 static const struct rellibraryset __aros_rellibset_##bname = \
144 name, &__aros_libreq_##bname, &__aros_rellib_offset_##bname \
146 ADD2SET(__aros_rellibset_##bname, RELLIBS, 0)
149 #define ADD2LIBS(name, ver, btype, bname) \
150 AROS_LIBSET(name, btype, bname) \
151 const LONG __aros_libreq_##bname = ver;
154 #define AROS_LIBREQ(bname, ver) \
156 ".global __aros_libreq_" #bname "." #ver "\n" \
157 "__aros_libreq_" #bname "." #ver "=" #ver);
160 #define SETRELLIBOFFSET(bname, libbasetype, fname) \
161 const IPTR __aros_rellib_offset_##bname = offsetof(libbasetype, fname); \
162 AROS_IMPORT_ASM_SYM(void *, _##bname, __aros_rellib_base_##bname);
164 /* Traverse the set from the first element to the last one, or vice versa,
165 depending on the value of 'direction': >=0 means first -> last, <0 means
169 direction - first->last | last->first
170 pos - integer variable holding the current position in the set
171 elem - variable of the same type of the elements in the set. holds the
173 #define ForeachElementInSet(set, direction, pos, elem) \
176 pos = (direction >= 0) ? 1 : ((long *)(set))[0]; \
177 elem = (void *)(set)[pos], (direction >= 0) ? elem != NULL : (pos) != 0; \
178 pos += (direction >= 0) ? 1 : -1 \
181 /* You must use this macro in the part of your program which handles symbol sets,
182 or else your program won't link when symbolsets are used.
183 This is so to ensure that symbolsets are properly handled and thus things get
184 properly initialized. */
185 #define THIS_PROGRAM_HANDLES_SYMBOLSET(x) \
186 AROS_MAKE_ASM_SYM(int, __##x##__symbol_set_handler_missing, __##x##__symbol_set_handler_missing, 0); \
187 AROS_EXPORT_ASM_SYM(__##x##__symbol_set_handler_missing);
191 /* Function prototypes from autoinit and libinit */
192 extern int _set_call_funcs(const void * const set
[], int direction
, int test_fail
, struct ExecBase
*sysBase
);
193 #define set_call_funcs(set, dir, fail) _set_call_funcs(set, dir, fail, SysBase)
194 extern int set_call_libfuncs(const void * const *set
, int order
, int test_fail
, void *libbase
);
195 extern int set_call_devfuncs
197 const void * const *set
,
209 #define set_open_libraries() set_open_libraries_list(SETNAME(LIBS))
210 #define set_open_rellibraries(base) set_open_rellibraries_list(base,SETNAME(RELLIBS))
211 #define set_close_libraries() set_close_libraries_list(SETNAME(LIBS))
212 #define set_close_rellibraries(base) set_close_rellibraries_list(base,SETNAME(RELLIBS))
213 #define set_open_libraries_list(list) _set_open_libraries_list(list, SysBase)
214 #define set_open_rellibraries_list(base, list) _set_open_rellibraries_list(base, list, SysBase)
215 #define set_close_libraries_list(list) _set_close_libraries_list(list, SysBase)
216 #define set_close_rellibraries_list(base, list) _set_close_rellibraries_list(base, list, SysBase)
217 extern int _set_open_libraries_list(const void * const list
[], struct ExecBase
*sysBase
);
218 extern int _set_open_rellibraries_list(APTR base
, const void * const list
[], struct ExecBase
*sysBase
);
219 extern void _set_close_libraries_list(const void * const list
[], struct ExecBase
*sysBase
);
220 extern void _set_close_rellibraries_list(APTR base
, const void * const list
[], struct ExecBase
*sysBase
);