Updated PCI IDs to latest snapshot.
[tangerine.git] / compiler / c_lib / source / include / libcore / libheader.c
blob97f95ddabf15b7c884429962d148385e83334850
1 /*
2 ** © Copyright 1996-97 Andreas R. Kleinert
3 ** All Rights Reserved.
4 **
5 ** Copyright © 1997-2003, The AROS Development Team. All rights reserved.
6 ** $Id$
7 **
8 ** This file needs to be at the start of a compiled module. Most of the
9 ** time this is done by including it in the *_init.c of the module.
11 ** This file is based on a file from the CLib37x.lha package of Andreas R.
12 ** Kleinert (of which a more recent version is available on aminet) and
13 ** adapted to fit in the AROS build framework.
14 **
15 ** To be able to compile modules with a license incompatible with the AROS
16 ** Public License users may relicense this file under any license of their
17 ** choice.
20 #define __USE_SYSBASE /* perhaps only recognized by SAS/C */
22 #include <exec/types.h>
23 #include <exec/memory.h>
24 #include <exec/libraries.h>
25 #include <exec/execbase.h>
26 #include <exec/resident.h>
27 #include <exec/initializers.h>
29 #ifdef __MAXON__
30 #include <pragma/exec_lib.h>
31 #include <linkerfunc.h>
32 #else
33 #include <proto/exec.h> /* all other compilers */
34 #endif
35 #include <libcore/compiler.h>
36 #include <libcore/base.h>
38 /* If the file with the #defines for this library is not "libdefs.h",
39 then you can redefine it. */
40 #ifndef LC_LIBDEFS_FILE
41 # define LC_LIBDEFS_FILE "libdefs.h"
42 #endif
44 /* Include the file with the #defines for this library */
45 #include LC_LIBDEFS_FILE
47 #ifndef LC_LIBHEADERTYPEPTR
48 # define LC_LIBHEADERTYPEPTR struct LibHeader *
49 #endif
50 #ifndef LC_LIB_FIELD
51 # define LC_LIB_FIELD(libBase) (libBase)->lh_LibNode
52 #endif
53 #ifndef LC_SYSBASE_FIELD
54 # define LC_SYSBASE_FIELD(libBase) (libBase)->lh_SysBase
55 #endif
56 #ifndef LC_SEGLIST_FIELD
57 # define LC_SEGLIST_FIELD(libBase) (libBase)->lh_SegList
58 #endif
59 #ifndef LC_RESIDENTNAME
60 # define LC_RESIDENTNAME LC_BUILDNAME(ROMTag)
61 #endif
62 #ifndef LC_RESIDENTPRI
63 # define LC_RESIDENTPRI 0
64 #endif
65 #ifndef LC_RESIDENTFLAGS
66 # define LC_RESIDENTFLAGS RTF_AUTOINIT
67 #endif
68 #ifndef LC_LIBBASESIZE
69 # define LC_LIBBASESIZE sizeof (struct LibHeader)
70 #endif
72 /* -----------------------------------------------------------------------
73 entry:
75 If someone tries to start a library as an executable, it must return
76 (LONG) -1 as result. That's what we are doing here.
77 ----------------------------------------------------------------------- */
80 /* FIXME: egcs 1.1b and possibly other incarnations of gcc have
81 * two nasty problems with entry() that prevents using the
82 * C version of this function on AROS 68k native.
84 * First of all, if inlining is active (-O3), the optimizer will decide
85 * that entry() is simple enough to be inlined, and it doesn't generate
86 * its code until all other functions have been compiled. Delaying asm
87 * output for a global (non static) function is probably silly because
88 * the optimizer can't eliminate its stand alone istance anyway.
90 * The second problem is that even without inlining, the code generator
91 * adds a nop instruction immediately after rts. This is probably done
92 * to help the 68040/60 pipelines, but it adds two more bytes before the
93 * library resident tag, which causes all kinds of problems on native
94 * AmigaOS.
96 * The workaround is to embed the required assembler instructions
97 * (moveq #-1,d0 ; rts) in a constant variable.
99 #if (defined(__mc68000__) && (AROS_FLAVOUR & AROS_FLAVOUR_NATIVE))
100 const LONG LC_BUILDNAME(entry) = 0x70FF4E75;
101 #else
102 LONG ASM LC_BUILDNAME(entry) (void)
104 return(-1);
106 #endif
108 /* Predeclarations */
109 extern const int LIBEND TEXT_SECTION; /* The end of the library */
110 extern const APTR LIBFUNCTABLE[] TEXT_SECTION; /* The function table */
111 static const struct InitTable LC_BUILDNAME(InitTab) TEXT_SECTION;
112 static const struct DataTable LC_BUILDNAME(DataTab) TEXT_SECTION;
114 extern const char ALIGNED LC_BUILDNAME(LibName) [] TEXT_SECTION;
115 extern const char ALIGNED LC_BUILDNAME(LibID) [] TEXT_SECTION;
116 extern const char ALIGNED LC_BUILDNAME(Copyright) [] TEXT_SECTION;
118 AROS_UFP3 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(InitLib),
119 AROS_LDA(LC_LIBHEADERTYPEPTR, lh, D0),
120 AROS_LDA(BPTR, segList, A0),
121 AROS_LDA(struct ExecBase *, sysBase, A6)
123 AROS_LP1 (BPTR, LC_BUILDNAME(ExpungeLib),
124 AROS_LDA(LC_LIBHEADERTYPEPTR, lh, D0),
125 struct ExecBase *, sysBase, 0, LibHeader
128 /* -------------------------------------------------------------------------
129 ROMTag and Library inilitalization structure:
131 Below you find the ROMTag, which is the most important "magic" part of
132 a library (as for any other resident module). You should not need to
133 modify any of the structures directly, since all the data is referenced
134 from constants from somewhere else.
136 You may place the ROMTag directly after the LibStart (-> StartUp.c)
137 function as well.
139 EndResident can be placed somewhere else - but it must follow the
140 ROMTag and it must not be placed in a different SECTION.
141 ------------------------------------------------------------------------- */
142 struct Resident const ALIGNED LC_RESIDENTNAME TEXT_SECTION =
144 RTC_MATCHWORD, /* This is a romtag */
145 (struct Resident *)&LC_RESIDENTNAME,
146 (APTR) &LIBEND,
147 LC_RESIDENTFLAGS,
148 VERSION_NUMBER,
149 NT_TYPE,
150 LC_RESIDENTPRI,
151 (char *) &LC_BUILDNAME(LibName)[0],
152 (char *) &LC_BUILDNAME(LibID)[6],
153 (APTR) &LC_BUILDNAME(InitTab)
156 static struct InitTable /* do not change */
158 ULONG LibBaseSize;
159 const APTR *FunctionTable;
160 const struct DataTable *DataTable;
161 APTR InitLibTable;
163 const LC_BUILDNAME(InitTab) TEXT_SECTION =
165 LC_LIBBASESIZE,
166 &LIBFUNCTABLE[0],
167 &LC_BUILDNAME(DataTab),
168 (APTR)LC_BUILDNAME(InitLib)
171 static struct DataTable /* do not change */
173 UWORD ln_Type_Init; UWORD ln_Type_Offset; UWORD ln_Type_Content;
174 UBYTE ln_Name_Init; UBYTE ln_Name_Offset; ULONG ln_Name_Content;
175 UWORD lib_Flags_Init; UWORD lib_Flags_Offset; UWORD lib_Flags_Content;
176 UWORD lib_Version_Init; UWORD lib_Version_Offset; UWORD lib_Version_Content;
177 UWORD lib_Revision_Init; UWORD lib_Revision_Offset; UWORD lib_Revision_Content;
178 UBYTE lib_IdString_Init; UBYTE lib_IdString_Offset; ULONG lib_IdString_Content;
179 ULONG ENDMARK;
181 const LC_BUILDNAME(DataTab) TEXT_SECTION =
183 INITBYTE(OFFSET(Node, ln_Type), NT_TYPE),
184 0x80, (UBYTE) OFFSET(Node, ln_Name), (ULONG) &LC_BUILDNAME(LibName[0]),
185 INITBYTE(OFFSET(Library, lib_Flags), LIBF_SUMUSED|LIBF_CHANGED),
186 INITWORD(OFFSET(Library, lib_Version), VERSION_NUMBER),
187 INITWORD(OFFSET(Library, lib_Revision), REVISION_NUMBER),
188 0x80, (UBYTE) OFFSET(Library, lib_IdString), (ULONG) &LC_BUILDNAME(LibID)[0],
189 (ULONG) 0
192 const char ALIGNED LC_BUILDNAME(LibName) [] TEXT_SECTION = NAME_STRING;
193 const char ALIGNED LC_BUILDNAME(LibID) [] TEXT_SECTION = VERSION_STRING;
194 const char ALIGNED LC_BUILDNAME(Copyright) [] TEXT_SECTION = COPYRIGHT_STRING;
196 /* Use supplied functions to initialize the non-standard parts of the
197 library */
198 #ifndef LC_NO_INITLIB
199 # ifdef LC_STATIC_INITLIB
200 static
201 # endif
202 ULONG SAVEDS STDARGS LC_BUILDNAME(L_InitLib) (LC_LIBHEADERTYPEPTR lh);
203 # define __L_InitLib LC_BUILDNAME(L_InitLib)
204 #else
205 # define __L_InitLib(x) 1
206 #endif
207 #ifndef LC_NO_OPENLIB
208 # ifdef LC_STATIC_OPENLIB
209 static
210 # endif
211 ULONG SAVEDS STDARGS LC_BUILDNAME(L_OpenLib) (LC_LIBHEADERTYPEPTR lh);
212 # define __L_OpenLib LC_BUILDNAME(L_OpenLib)
213 #else
214 # define __L_OpenLib(x) 1
215 #endif
216 #ifndef LC_NO_CLOSELIB
217 # ifdef LC_STATIC_CLOSELIB
218 static
219 # endif
220 void SAVEDS STDARGS LC_BUILDNAME(L_CloseLib) (LC_LIBHEADERTYPEPTR lh);
221 # define __L_CloseLib LC_BUILDNAME(L_CloseLib)
222 #else
223 # define __L_CloseLib(x) /* eps */
224 #endif
225 #ifndef LC_NO_EXPUNGELIB
226 # ifdef LC_STATIC_EXPUNGELIB
227 static
228 # endif
229 void SAVEDS STDARGS LC_BUILDNAME(L_ExpungeLib) (LC_LIBHEADERTYPEPTR lh);
230 # define __L_ExpungeLib LC_BUILDNAME(L_ExpungeLib)
231 #else
232 # define __L_ExpungeLib(x) /* eps */
233 #endif
236 #ifdef AROS_LC_SETFUNCS
237 #include <aros/symbolsets.h>
239 THIS_PROGRAM_HANDLES_SYMBOLSETS
241 DECLARESET(INIT)
242 DECLARESET(EXIT)
243 DECLARESET(CTORS)
244 DECLARESET(DTORS)
245 DECLARESET(INITLIB)
246 DECLARESET(EXPUNGELIB)
247 DECLARESET(OPENLIB)
248 DECLARESET(CLOSELIB)
250 #endif
252 #ifdef SysBase
253 # define __LC_OLD_SYSBASE SysBase
254 # undef SysBase
255 #endif
257 /* In these functions always take the LC_SYSBASE_FIELD as SysBase */
258 #define SysBase (LC_SYSBASE_FIELD(lh))
260 /* -----------------------------------------------------------------------
261 InitLib:
263 This one is single-threaded by the Ramlib process. Theoretically you
264 can do, what you like here, since you have full exclusive control over
265 all the library code and data. But due to some bugs in Ramlib V37-40,
266 you can easily cause a deadlock when opening certain libraries here
267 (which open other libraries, that open other libraries, that...)
268 ----------------------------------------------------------------------- */
270 AROS_UFH3 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(InitLib),
271 AROS_UFHA(LC_LIBHEADERTYPEPTR, lh, D0),
272 AROS_UFHA(BPTR, segList, A0),
273 AROS_UFHA(struct ExecBase *, sysBase, A6)
276 AROS_USERFUNC_INIT
278 int ok = TRUE;
280 LC_SYSBASE_FIELD(lh) = sysBase;
281 #ifndef NOEXPUNGE
282 LC_SEGLIST_FIELD(lh) = segList;
283 #endif
285 #ifdef AROS_LC_SETFUNCS
286 # ifndef AROS_LC_SET_NOLIBS
287 ok = set_open_libraries();
288 # endif
289 ok = ok && set_call_funcs(SETNAME(INIT), 1, 1);
290 if ( ok )
292 /* ctors get called in inverse order than init funcs */
293 set_call_funcs(SETNAME(CTORS), -1, 0);
295 ok = set_call_libfuncs(SETNAME(INITLIB), 1, 1, lh);
297 #endif
299 #ifndef LC_NO_INITLIB
300 ok = ok && __L_InitLib(lh);
301 #endif
302 if (!ok)
304 __L_ExpungeLib (lh);
306 #ifdef AROS_LC_SETFUNCS
307 set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 0, lh);
308 set_call_funcs(SETNAME(DTORS), 1, 0);
309 set_call_funcs(SETNAME(EXIT), -1, 0);
310 # ifndef AROS_LC_SET_NOLIBS
311 set_close_libraries();
312 # endif
313 #endif
316 ULONG negsize, possize, fullsize;
317 UBYTE *negptr = (UBYTE *) lh;
319 negsize = LC_LIB_FIELD(lh).lib_NegSize;
320 possize = LC_LIB_FIELD(lh).lib_PosSize;
321 fullsize = negsize + possize;
322 negptr -= negsize;
324 FreeMem (negptr, fullsize);
327 return NULL;
329 else
330 return (lh);
332 AROS_USERFUNC_EXIT
335 /* -----------------------------------------------------------------------
336 OpenLib:
338 This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since
339 a Wait() call would break this Forbid/Permit(), you are not allowed to
340 start any operations that may cause a Wait() during their processing.
341 It's possible, that future OS versions won't turn the multi-tasking
342 off, but instead use semaphore protection for this function.
344 Currently you only can bypass this restriction by supplying your own
345 semaphore mechanism.
346 ----------------------------------------------------------------------- */
347 AROS_LH1 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(OpenLib),
348 AROS_LHA (ULONG, version, D0),
349 LC_LIBHEADERTYPEPTR, lh, 1, LibHeader
352 AROS_LIBFUNC_INIT
354 #ifdef __MAXON__
355 GetBaseReg();
356 InitModules();
357 #endif
361 #ifdef AROS_LC_SETFUNCS
362 set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh) &&
363 #endif
364 __L_OpenLib (lh)
367 #ifndef NOEXPUNGE
368 LC_LIB_FIELD(lh).lib_OpenCnt++;
369 #else
370 LC_LIB_FIELD(lh).lib_OpenCnt = 1;
371 #endif /* NOEXPUNGE */
373 LC_LIB_FIELD(lh).lib_Flags &= ~LIBF_DELEXP;
375 return (lh);
378 return NULL;
380 AROS_LIBFUNC_EXIT
384 /* -----------------------------------------------------------------------
385 CloseLib:
387 This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since
388 a Wait() call would break this Forbid/Permit(), you are not allowed to
389 start any operations that may cause a Wait() during their processing.
390 It's possible, that future OS versions won't turn the multi-tasking
391 off, but instead use semaphore protection for this function.
393 Currently you only can bypass this restriction by supplying your own
394 semaphore mechanism.
395 ----------------------------------------------------------------------- */
396 AROS_LH0 (BPTR, LC_BUILDNAME(CloseLib),
397 LC_LIBHEADERTYPEPTR, lh, 2, LibHeader
400 AROS_LIBFUNC_INIT
402 #ifndef NOEXPUNGE
403 LC_LIB_FIELD(lh).lib_OpenCnt--;
405 __L_CloseLib (lh);
406 #endif
408 #ifdef AROS_LC_SETFUNCS
409 set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);
410 #endif
412 #ifndef NOEXPUNGE
413 if(!LC_LIB_FIELD(lh).lib_OpenCnt)
415 if(LC_LIB_FIELD(lh).lib_Flags & LIBF_DELEXP)
417 return AROS_LC1(BPTR, LC_BUILDNAME(ExpungeLib),
418 AROS_LCA(LC_LIBHEADERTYPEPTR, lh, D0),
419 struct ExecBase *, SysBase, 3, LibHeader
423 #endif /* NOEXPUNGE */
425 return (NULL);
427 AROS_LIBFUNC_EXIT
430 /* -----------------------------------------------------------------------
431 ExpungeLib:
433 This one is enclosed within a Forbid/Permit pair by Exec V37-40. Since
434 a Wait() call would break this Forbid/Permit(), you are not allowed to
435 start any operations that may cause a Wait() during their processing.
436 It's possible, that future OS versions won't turn the multi-tasking
437 off, but instead use semaphore protection for this function.
439 Currently you only can bypass this restriction by supplying your own
440 semaphore mechanism but since expunging can't be done twice, one should
441 avoid it here.
442 ----------------------------------------------------------------------- */
443 AROS_LH1 (BPTR, LC_BUILDNAME(ExpungeLib),
444 AROS_LHA(LC_LIBHEADERTYPEPTR, lh, D0),
445 struct ExecBase *, sysBase, 3, LibHeader
448 AROS_LIBFUNC_INIT
450 #ifndef NOEXPUNGE
451 BPTR seglist;
453 if (
454 #ifdef AROS_LC_PRE_EXPUNGELIB
455 AROS_LC_PRE_EXPUNGELIB(lh) &&
456 #endif
458 !LC_LIB_FIELD(lh).lib_OpenCnt)
460 ULONG negsize, possize, fullsize;
461 UBYTE *negptr = (UBYTE *)lh;
463 seglist = LC_SEGLIST_FIELD(lh);
465 Remove((struct Node *)lh);
467 __L_ExpungeLib (lh);
469 #ifdef AROS_LC_SETFUNCS
470 set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 0, lh);
471 set_call_funcs(SETNAME(DTORS), 1, 0);
472 set_call_funcs(SETNAME(EXIT), -1, 0);
473 # ifndef AROS_LC_SET_NOLIBS
474 set_close_libraries();
475 # endif
476 #endif
478 negsize = LC_LIB_FIELD(lh).lib_NegSize;
479 possize = LC_LIB_FIELD(lh).lib_PosSize;
480 fullsize = negsize + possize;
481 negptr -= negsize;
483 FreeMem(negptr, fullsize);
485 #ifdef __MAXON__
486 CleanupModules();
487 #endif
489 return(seglist);
492 LC_LIB_FIELD(lh).lib_Flags |= LIBF_DELEXP;
493 #endif /* NOEXPUNGE */
495 return (NULL);
497 AROS_LIBFUNC_EXIT
500 /* -----------------------------------------------------------------------
501 ExtFunct:
503 This is a function which is reserved for later extension.
504 ----------------------------------------------------------------------- */
505 AROS_LH0 (LC_LIBHEADERTYPEPTR, LC_BUILDNAME(ExtFuncLib),
506 LC_LIBHEADERTYPEPTR, lh, 4, LibHeader
509 AROS_LIBFUNC_INIT
510 return(NULL);
511 AROS_LIBFUNC_EXIT
514 #undef SysBase
515 #ifdef __LC_OLD_SYSBASE
516 # define SysBase __LC_OLD_SYSBASE
517 # undef __LC_OLD_SYSBASE
518 #endif
520 #ifdef __SASC
523 This is only for SAS/C - its intention is to turn off internal CTRL-C
524 handling for standard C function and to avoid calls to exit() et al.
527 #ifdef ARK_OLD_STDIO_FIX
529 ULONG XCEXIT = NULL; /* these symbols may be referenced by */
530 ULONG _XCEXIT = NULL; /* some functions of sc.lib, but should */
531 ULONG ONBREAK = NULL; /* never be used inside a shared library */
532 ULONG _ONBREAK = NULL;
533 ULONG base = NULL;
534 ULONG _base = NULL;
535 ULONG ProgramName = NULL;
536 ULONG _ProgramName = NULL;
537 ULONG StackPtr = NULL;
538 ULONG _StackPtr = NULL;
539 ULONG oserr = NULL;
540 ULONG _oserr = NULL;
541 ULONG OSERR = NULL;
542 ULONG _OSERR = NULL;
544 #endif /* ARK_OLD_STDIO_FIX */
546 void __regargs __chkabort(void) { } /* a shared library cannot be */
547 void __regargs _CXBRK(void) { } /* CTRL-C aborted when doing I/O */
549 #endif /* __SASC */
551 #ifdef AROS_LC_SETFUNCS
552 DEFINESET(INIT)
553 DEFINESET(EXIT)
554 DEFINESET(CTORS)
555 DEFINESET(DTORS)
556 DEFINESET(INITLIB)
557 DEFINESET(EXPUNGELIB)
558 DEFINESET(OPENLIB)
559 DEFINESET(CLOSELIB)
560 #endif