1 #ifndef _AROS_SYMBOLSETS_H
2 #define _AROS_SYMBOLSETS_H
5 Copyright © 1995-2005, 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>
20 const LONG
* const versionptr
;
24 #define SETNAME(set) __##set##_LIST__
26 #define DECLARESET(set) \
27 extern const void * SETNAME(set)[] __attribute__((weak));
29 #define DEFINESET(set) \
30 const void * SETNAME(set)[] __attribute__((weak))={0,0};
32 #define ADD2SET(symbol, _set, pri)\
33 static const void *__aros_set_##_set##_##symbol __attribute__((__section__(".aros.set." #_set "." #pri))) __used = (void *)&symbol;
35 #define SETELEM(symbol, _set) \
37 extern const void *__aros_set_##_set##_##symbol; \
38 &__aros_set_##_set##_##symbol; \
42 ctors and dtors sets are used by c++ to store static constructors/destructors
45 The functions have to be invoked respectively right before the program enters
46 the main() function and right after the program exits the main() function.
48 #define ADD2CTORS(symbol, pri) ADD2SET(symbol, ctors, pri)
49 #define ADD2DTORS(symbol, pri) ADD2SET(symbol, dtors, pri)
52 init and exit sets are like the ctors and dtors sets, except that they take
53 precedence on them, that is functions stored in the init set are called
54 before the ones stored in the ctors set, and functions stored in the
55 exit set are called after the ones stored in the dtors set.
57 Moreover, init functions return an int, instead of void like the ctor functions.
58 This return value is equal to 0 if the function returned with success, otherwise
59 it holds an error code.
62 #define ADD2INIT(symbol, pri) ADD2SET(symbol, init, pri)
63 #define ADD2EXIT(symbol, pri) ADD2SET(symbol, exit, pri)
66 initlib, expungelib, openlib, closelib sets are similar to the init and exit
67 sets, only they are specific to the initialisation phase of libraries.
68 initlib/expungelib are only called when a library is loaded/unloaded from
69 memory. openlib/closelib is called every time a library is opened/closed.
70 The library base is passed to each of the functions present in the sets as
73 The return argument is also an int, and just like with the init/exit sets,
74 a zero value indicates an (de)initialization failure, a one indicates succes.
75 The calling of the functions in the initlib and the openlib sets stops when
76 the first zero value is met. The functions in the expungelib and the
77 closelib are always called.
79 These sets have a lower priority then the INIT and the CTORS sets. So when
80 a library is loaded first the init set is called, then the ctors set and
81 finally the initlib set.
84 #define ADD2INITLIB(symbol, pri) ADD2SET(symbol, initlib, pri)
85 #define ADD2EXPUNGELIB(symbol, pri) ADD2SET(symbol, expungelib, pri)
86 #define ADD2OPENLIB(symbol, pri) ADD2SET(symbol, openlib, pri)
87 #define ADD2CLOSELIB(symbol, pri) ADD2SET(symbol, closelib, pri)
88 #define ADD2OPENDEV(symbol, pri) ADD2SET(symbol, opendev, pri)
89 #define ADD2CLOSEDEV(symbol, pri) ADD2SET(symbol, closedev, pri)
91 /* this macro generates the necessary symbols to open and close automatically
92 a library. An error message will be shown if the library cannot be opened. */
93 #define ADD2LIBS(name, ver, btype, bname) \
96 AROS_IMPORT_ASM_SYM(int, dummy, __includelibrarieshandling); \
98 const LONG bname##_version __attribute__((weak)) = ver; \
100 const struct libraryset libraryset_##bname = \
102 name, &bname##_version, (void *)&bname \
104 ADD2SET(libraryset_##bname, libs, 0)
106 #define ASKFORLIBVERSION(bname, ver) \
107 const LONG bname##_version = ver
109 /* Traverse the set from the first element to the last one, or vice versa,
110 depending on the value of 'direction': >=0 means first -> last, <0 means
114 direction - first->last | last->first
115 pos - integer variable holding the current position in the set
116 elem - variable of the same type of the elements in the set. holds the
118 #define ForeachElementInSet(set, direction, pos, elem) \
121 pos = (direction >= 0) ? 1 : ((long *)(set))[0]; \
122 elem = (void *)(set)[pos], (direction >= 0) ? elem != NULL : (pos) != 0; \
123 pos += (direction >= 0) ? 1 : -1 \
126 /* You must use this macro in the part of your program which handles symbol sets,
127 or else your program won't link when symbolsets are used.
128 This is so to ensure that symbolsets are properly handled and thus things get
129 properly initialized. */
130 #define THIS_PROGRAM_HANDLES_SYMBOLSETS \
131 AROS_MAKE_ASM_SYM(int, __this_program_requires_symbol_sets_handling, __this_program_requires_symbol_sets_handling, 0); \
132 AROS_EXPORT_ASM_SYM(__this_program_requires_symbol_sets_handling);
136 /* Function prototypes from autoinit and libinit */
137 extern int set_call_funcs(const void *set
[], int direction
, int test_fail
);
138 extern int set_call_libfuncs(const void **set
, int order
, int test_fail
, void *libbase
);
139 extern int set_call_devfuncs
152 #define set_open_libraries() set_open_libraries_list(SETNAME(LIBS))
153 #define set_close_libraries() set_close_libraries_list(SETNAME(LIBS))
154 extern int set_open_libraries_list(const void *list
[]);
155 extern void set_close_libraries_list(const void *list
[]);