revert between 56095 -> 55830 in arch
[AROS.git] / arch / .unmaintained / morphos / Include / libcore / libheader.c
blobc68abfe9d7a13b0851777a278f6c3b0cedddff79
1 /*
2 ** $VER: libheader.c 37.15 (14.8.97)
3 **
4 ** This file must be compiled and must be passed as the first
5 ** object to link to the linker.
6 **
7 ** (C) Copyright 1996-97 Andreas R. Kleinert
8 ** All Rights Reserved.
9 */
11 #define __USE_SYSBASE /* perhaps only recognized by SAS/C */
13 #include <exec/types.h>
14 #include <exec/memory.h>
15 #include <exec/libraries.h>
16 #include <exec/execbase.h>
17 #include <exec/resident.h>
18 #include <exec/initializers.h>
20 #ifdef __MAXON__
21 #include <pragma/exec_lib.h>
22 #include <linkerfunc.h>
23 #else
24 #include <proto/exec.h> /* all other compilers */
25 #endif
26 #include <libcore/compiler.h>
27 #include <libcore/base.h>
29 #ifndef LC_LIBHEADERTYPEPTR
30 # define LC_LIBHEADERTYPEPTR struct LibHeader *
31 #endif
32 #ifndef LC_LIB_FIELD
33 # define LC_LIB_FIELD(libBase) (libBase)->lh_LibNode
34 #endif
35 #ifndef LC_SYSBASE_FIELD
36 # define LC_SYSBASE_FIELD(libBase) (libBase)->lh_SysBase
37 #endif
38 #ifndef LC_SEGLIST_FIELD
39 # define LC_SEGLIST_FIELD(libBase) (libBase)->lh_SegList
40 #endif
41 #ifndef LC_RESIDENTNAME
42 # define LC_RESIDENTNAME LC_BUILDNAME(ROMTag)
43 #endif
44 #ifndef LC_RESIDENTPRI
45 # define LC_RESIDENTPRI 0
46 #endif
47 #ifndef LC_RESIDENTFLAGS
48 #ifdef __MORPHOS__
49 # define LC_RESIDENTFLAGS RTF_PPC | RTF_AUTOINIT
50 #else
51 # define LC_RESIDENTFLAGS RTF_AUTOINIT
52 #endif
53 #endif
54 #ifndef LC_LIBBASESIZE
55 # define LC_LIBBASESIZE sizeof (struct LibHeader)
56 #endif
57 /* If the file with the #defines for this library is not "libdefs.h",
58 then you can redefine it. */
59 #ifndef LC_LIBDEFS_FILE
60 # define LC_LIBDEFS_FILE "libdefs.h"
61 #endif
63 /* Include the file with the #defines for this library */
64 #include LC_LIBDEFS_FILE
66 /* -----------------------------------------------------------------------
67 entry:
69 If someone tries to start a library as an executable, it must return
70 (LONG) -1 as result. That's what we are doing here.
71 ----------------------------------------------------------------------- */
74 /* FIXME: egcs 1.1b and possibly other incarnations of gcc have
75 * two nasty problems with entry() that prevents using the
76 * C version of this function on AROS 68k native.
78 * First of all, if inlining is active (-O3), the optimizer will decide
79 * that entry() is simple enough to be inlined, and it doesn't generate
80 * its code until all other functions have been compiled. Delaying asm
81 * output for a global (non static) function is probably silly because
82 * the optimizer can't eliminate its stand alone istance anyway.
84 * The second problem is that even without inlining, the code generator
85 * adds a nop instruction immediately after rts. This is probably done
86 * to help the 68040/60 pipelines, but it adds two more bytes before the
87 * library resident tag, which causes all kinds of problems on native
88 * AmigaOS.
90 * The workaround is to embed the required assembler instructions
91 * (moveq #-1,d0 ; rts) in a constant variable.
93 #if (defined(__mc68000__) && (AROS_FLAVOUR & AROS_FLAVOUR_NATIVE))
94 const LONG entry = 0x70FF4E75;
95 #else
96 LONG ASM LC_BUILDNAME(entry) (void)
98 return(-1);
100 #endif
102 /* Predeclarations */
103 extern const int LIBEND; /* The end of the library */
104 extern const APTR LIBFUNCTABLE[]; /* The function table */
105 static const struct InitTable LC_BUILDNAME(InitTab);
106 static const struct DataTable LC_BUILDNAME(DataTab);
108 extern const char ALIGNED LC_BUILDNAME(LibName) [];
109 extern const char ALIGNED LC_BUILDNAME(LibID) [];
110 extern const char ALIGNED LC_BUILDNAME(Copyright) [];
112 #ifdef __MORPHOS__
113 LC_LIBHEADERTYPEPTR LC_BUILDNAME(LIB_InitLib)(LC_LIBHEADERTYPEPTR lh, BPTR segList, struct ExecBase *sysBase);
114 #else
115 AROS_LD2 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(InitLib),
116 AROS_LDA(LC_LIBHEADERTYPEPTR, lh, D0),
117 AROS_LDA(BPTR, segList, A0),
118 struct ExecBase *, sysBase, 0, LibHeader
120 #endif
121 AROS_LD1 (BPTR, LC_BUILDNAME(ExpungeLib),
122 AROS_LDA(LC_LIBHEADERTYPEPTR, lh, D0),
123 struct ExecBase *, sysBase, 0, LibHeader
126 /* -------------------------------------------------------------------------
127 ROMTag and Library inilitalization structure:
129 Below you find the ROMTag, which is the most important "magic" part of
130 a library (as for any other resident module). You should not need to
131 modify any of the structures directly, since all the data is referenced
132 from constants from somewhere else.
134 You may place the ROMTag directly after the LibStart (-> StartUp.c)
135 function as well.
137 EndResident can be placed somewhere else - but it must follow the
138 ROMTag and it must not be placed in a different SECTION.
139 ------------------------------------------------------------------------- */
140 struct Resident const ALIGNED LC_RESIDENTNAME =
142 RTC_MATCHWORD, /* This is a romtag */
143 (struct Resident *)&LC_RESIDENTNAME,
144 (APTR) &LIBEND,
145 LC_RESIDENTFLAGS,
146 VERSION_NUMBER,
147 NT_TYPE,
148 LC_RESIDENTPRI,
149 (char *) &LC_BUILDNAME(LibName)[0],
150 (char *) &LC_BUILDNAME(LibID)[6],
151 (APTR) &LC_BUILDNAME(InitTab)
154 static struct InitTable /* do not change */
156 ULONG LibBaseSize;
157 const APTR *FunctionTable;
158 const struct DataTable *DataTable;
159 APTR InitLibTable;
163 const LC_BUILDNAME(InitTab) =
165 LC_LIBBASESIZE,
166 &LIBFUNCTABLE[0],
167 #ifdef __MORPHOS__
168 NULL,
169 #else
170 &LC_BUILDNAME(DataTab),
171 #endif
172 (APTR) AROS_SLIB_ENTRY(LC_BUILDNAME(InitLib), LibHeader)
175 #ifndef __MORPHOS__
176 static struct DataTable /* do not change */
178 UWORD ln_Type_Init; UWORD ln_Type_Offset; UWORD ln_Type_Content;
179 UBYTE ln_Name_Init; UBYTE ln_Name_Offset; ULONG ln_Name_Content;
180 UWORD lib_Flags_Init; UWORD lib_Flags_Offset; UWORD lib_Flags_Content;
181 UWORD lib_Version_Init; UWORD lib_Version_Offset; UWORD lib_Version_Content;
182 UWORD lib_Revision_Init; UWORD lib_Revision_Offset; UWORD lib_Revision_Content;
183 UBYTE lib_IdString_Init; UBYTE lib_IdString_Offset; ULONG lib_IdString_Content;
184 ULONG ENDMARK;
186 const LC_BUILDNAME(DataTab) =
188 INITBYTE(OFFSET(Node, ln_Type), NT_TYPE),
189 0x80, (UBYTE) OFFSET(Node, ln_Name), (ULONG) &LC_BUILDNAME(LibName[0]),
190 INITBYTE(OFFSET(Library, lib_Flags), LIBF_SUMUSED|LIBF_CHANGED),
191 INITWORD(OFFSET(Library, lib_Version), VERSION_NUMBER),
192 INITWORD(OFFSET(Library, lib_Revision), REVISION_NUMBER),
193 0x80, (UBYTE) OFFSET(Library, lib_IdString), (ULONG) &LC_BUILDNAME(LibID)[0],
194 (ULONG) 0
196 #endif
198 const char ALIGNED LC_BUILDNAME(LibName) [] = NAME_STRING;
199 const char ALIGNED LC_BUILDNAME(LibID) [] = VERSION_STRING;
200 const char ALIGNED LC_BUILDNAME(Copyright) [] = COPYRIGHT_STRING;
202 /* Use supplied functions to initialize the non-standard parts of the
203 library */
204 #ifndef LC_NO_INITLIB
205 # ifdef LC_STATIC_INITLIB
206 static
207 # endif
208 ULONG SAVEDS STDARGS LC_BUILDNAME(L_InitLib) (LC_LIBHEADERTYPEPTR lh);
209 # define __L_InitLib LC_BUILDNAME(L_InitLib)
210 #else
211 # define __L_InitLib(x) 1
212 #endif
213 #ifndef LC_NO_OPENLIB
214 # ifdef LC_STATIC_OPENLIB
215 static
216 # endif
217 ULONG SAVEDS STDARGS LC_BUILDNAME(L_OpenLib) (LC_LIBHEADERTYPEPTR lh);
218 # define __L_OpenLib LC_BUILDNAME(L_OpenLib)
219 #else
220 # define __L_OpenLib(x) 1
221 #endif
222 #ifndef LC_NO_CLOSELIB
223 # ifdef LC_STATIC_CLOSELIB
224 static
225 # endif
226 void SAVEDS STDARGS LC_BUILDNAME(L_CloseLib) (LC_LIBHEADERTYPEPTR lh);
227 # define __L_CloseLib LC_BUILDNAME(L_CloseLib)
228 #else
229 # define __L_CloseLib(x) /* eps */
230 #endif
231 #ifndef LC_NO_EXPUNGELIB
232 # ifdef LC_STATIC_EXPUNGELIB
233 static
234 # endif
235 void SAVEDS STDARGS LC_BUILDNAME(L_ExpungeLib) (LC_LIBHEADERTYPEPTR lh);
236 # define __L_ExpungeLib LC_BUILDNAME(L_ExpungeLib)
237 #else
238 # define __L_ExpungeLib(x) /* eps */
239 #endif
241 #ifndef SysBase
242 # define SysBase (LC_SYSBASE_FIELD(lh))
243 # define __LC_OWN_SYSBASE
244 #endif
246 /* -----------------------------------------------------------------------
247 InitLib:
249 This one is single-threaded by the Ramlib process. Theoretically you
250 can do, what you like here, since you have full exclusive control over
251 all the library code and data. But due to some bugs in Ramlib V37-40,
252 you can easily cause a deadlock when opening certain libraries here
253 (which open other libraries, that open other libraries, that...)
254 ----------------------------------------------------------------------- */
255 #ifdef __MORPHOS__
256 LC_LIBHEADERTYPEPTR LC_BUILDNAME(LIB_InitLib)(LC_LIBHEADERTYPEPTR lh, BPTR segList, struct ExecBase *sysBase)
258 #else
259 AROS_LH2 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(InitLib),
260 AROS_LHA(LC_LIBHEADERTYPEPTR, lh, D0),
261 AROS_LHA(BPTR, segList, A0),
262 struct ExecBase *, sysBase, 0, LibHeader
264 #endif
266 AROS_LIBFUNC_INIT
267 LC_SYSBASE_FIELD(lh) = sysBase;
268 LC_SEGLIST_FIELD(lh) = segList;
270 #ifndef LC_NO_INITLIB
271 if (__L_InitLib (lh))
272 return (lh);
274 __L_ExpungeLib (lh);
277 ULONG negsize, possize, fullsize;
278 UBYTE *negptr = (UBYTE *) lh;
280 negsize = LC_LIB_FIELD(lh).lib_NegSize;
281 possize = LC_LIB_FIELD(lh).lib_PosSize;
282 fullsize = negsize + possize;
283 negptr -= negsize;
285 FreeMem (negptr, fullsize);
288 return (NULL);
289 #else
290 return (lh);
291 #endif /* LC_NO_INITLIB */
292 AROS_LIBFUNC_EXIT
295 /* -----------------------------------------------------------------------
296 OpenLib:
298 This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since
299 a Wait() call would break this Forbid/Permit(), you are not allowed to
300 start any operations that may cause a Wait() during their processing.
301 It's possible, that future OS versions won't turn the multi-tasking
302 off, but instead use semaphore protection for this function.
304 Currently you only can bypass this restriction by supplying your own
305 semaphore mechanism.
306 ----------------------------------------------------------------------- */
307 AROS_LH1 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(OpenLib),
308 AROS_LHA (ULONG, version, D0),
309 LC_LIBHEADERTYPEPTR, lh, 1, LibHeader
312 AROS_LIBFUNC_INIT
313 #ifdef __MAXON__
314 GetBaseReg();
315 InitModules();
316 #endif
318 if (__L_OpenLib (lh))
320 #ifndef NOEXPUNGE
321 LC_LIB_FIELD(lh).lib_OpenCnt++;
322 #else
323 LC_LIB_FIELD(lh).lib_OpenCnt = 1;
324 #endif /* NOEXPUNGE */
326 LC_LIB_FIELD(lh).lib_Flags &= ~LIBF_DELEXP;
328 return (lh);
331 return NULL;
332 AROS_LIBFUNC_EXIT
336 /* -----------------------------------------------------------------------
337 CloseLib:
339 This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since
340 a Wait() call would break this Forbid/Permit(), you are not allowed to
341 start any operations that may cause a Wait() during their processing.
342 It's possible, that future OS versions won't turn the multi-tasking
343 off, but instead use semaphore protection for this function.
345 Currently you only can bypass this restriction by supplying your own
346 semaphore mechanism.
347 ----------------------------------------------------------------------- */
348 AROS_LH0 (BPTR, LC_BUILDNAME(CloseLib),
349 LC_LIBHEADERTYPEPTR, lh, 2, LibHeader
352 AROS_LIBFUNC_INIT
353 #ifndef NOEXPUNGE
354 LC_LIB_FIELD(lh).lib_OpenCnt--;
356 __L_CloseLib (lh);
358 if(!LC_LIB_FIELD(lh).lib_OpenCnt)
360 if(LC_LIB_FIELD(lh).lib_Flags & LIBF_DELEXP)
362 return AROS_LC1(BPTR, LC_BUILDNAME(ExpungeLib),
363 AROS_LCA(LC_LIBHEADERTYPEPTR, lh, D0),
364 struct ExecBase *, SysBase, 3, LibHeader
368 #endif /* NOEXPUNGE */
370 return (NULL);
371 AROS_LIBFUNC_EXIT
374 /* -----------------------------------------------------------------------
375 ExpungeLib:
377 This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since
378 a Wait() call would break this Forbid/Permit(), you are not allowed to
379 start any operations that may cause a Wait() during their processing.
380 It's possible, that future OS versions won't turn the multi-tasking
381 off, but instead use semaphore protection for this function.
383 Currently you only can bypass this restriction by supplying your own
384 semaphore mechanism but since expunging can't be done twice, one should
385 avoid it here.
386 ----------------------------------------------------------------------- */
387 AROS_LH1 (BPTR, LC_BUILDNAME(ExpungeLib),
388 AROS_LHA(LC_LIBHEADERTYPEPTR, lh, D0),
389 struct ExecBase *, sysBase, 3, LibHeader
392 AROS_LIBFUNC_INIT
393 #ifndef NOEXPUNGE
394 BPTR seglist;
396 if(!LC_LIB_FIELD(lh).lib_OpenCnt)
398 ULONG negsize, possize, fullsize;
399 UBYTE *negptr = (UBYTE *)lh;
401 seglist = LC_SEGLIST_FIELD(lh);
403 Remove((struct Node *)lh);
405 __L_ExpungeLib (lh);
407 negsize = LC_LIB_FIELD(lh).lib_NegSize;
408 possize = LC_LIB_FIELD(lh).lib_PosSize;
409 fullsize = negsize + possize;
410 negptr -= negsize;
412 FreeMem(negptr, fullsize);
414 #ifdef __MAXON__
415 CleanupModules();
416 #endif
418 return(seglist);
421 LC_LIB_FIELD(lh).lib_Flags |= LIBF_DELEXP;
422 #endif /* NOEXPUNGE */
424 return (NULL);
425 AROS_LIBFUNC_EXIT
428 /* -----------------------------------------------------------------------
429 ExtFunct:
431 This is a function which is reserved for later extension.
432 ----------------------------------------------------------------------- */
433 AROS_LH0 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(ExtFuncLib),
434 LC_LIBHEADERTYPEPTR, lh, 4, LibHeader
437 AROS_LIBFUNC_INIT
438 return(NULL);
439 AROS_LIBFUNC_EXIT
442 #ifdef __LC_OWN_SYSBASE
443 # undef SysBase
444 #endif
446 #ifdef __SASC
449 This is only for SAS/C - its intention is to turn off internal CTRL-C
450 handling for standard C function and to avoid calls to exit() et al.
453 #ifdef ARK_OLD_STDIO_FIX
455 ULONG XCEXIT = NULL; /* these symbols may be referenced by */
456 ULONG _XCEXIT = NULL; /* some functions of sc.lib, but should */
457 ULONG ONBREAK = NULL; /* never be used inside a shared library */
458 ULONG _ONBREAK = NULL;
459 ULONG base = NULL;
460 ULONG _base = NULL;
461 ULONG ProgramName = NULL;
462 ULONG _ProgramName = NULL;
463 ULONG StackPtr = NULL;
464 ULONG _StackPtr = NULL;
465 ULONG oserr = NULL;
466 ULONG _oserr = NULL;
467 ULONG OSERR = NULL;
468 ULONG _OSERR = NULL;
470 #endif /* ARK_OLD_STDIO_FIX */
472 void __regargs __chkabort(void) { } /* a shared library cannot be */
473 void __regargs _CXBRK(void) { } /* CTRL-C aborted when doing I/O */
475 #endif /* __SASC */