home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / libnix-0.8-src.lha / libnix-0.8 / sources / startup / libinitr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  12.7 KB  |  361 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /* this works with gcc too and makes life easier                              */
  4. /*                                                                            */
  5. /******************************************************************************/
  6.  
  7. #define __USE_SYSBASE
  8.  
  9. /******************************************************************************/
  10. /*                                                                            */
  11. /* includes                                                                   */
  12. /*                                                                            */
  13. /******************************************************************************/
  14.  
  15. #include <exec/types.h>
  16. #include <exec/resident.h>
  17. #include <proto/exec.h>
  18. #define EXTENDED /* multibase library */
  19. #include "libinit.h"
  20. #include "stabs.h"
  21.  
  22. /******************************************************************************/
  23. /*                                                                            */
  24. /* *** VERY *** nessecary for relocation!                                     */
  25. /*                                                                            */
  26. /******************************************************************************/
  27.  
  28. int *reloc=(int *)&reloc;
  29.  
  30. /******************************************************************************/
  31. /*                                                                            */
  32. /* *** FIRST *** function - prevents a crash when called from CLI!            */
  33. /*                                                                            */
  34. /******************************************************************************/
  35.  
  36. int safefail()
  37. {
  38.   return -1;
  39. }
  40.  
  41. /******************************************************************************/
  42. /*                                                                            */
  43. /* defines                                                                    */
  44. /*                                                                            */
  45. /******************************************************************************/
  46.  
  47. #define SETA4(x) asm volatile ("movel a4,sp@-; movel %0,a4" :/* */: "g" (x))
  48. #define RESA4(x) asm volatile ("movel sp@+,a4;")
  49.  
  50. /******************************************************************************/
  51. /*                                                                            */
  52. /* imports                                                                    */
  53. /*                                                                            */
  54. /******************************************************************************/
  55.  
  56. extern const UWORD LibVersion;
  57. extern const UWORD LibRevision;
  58.  
  59. extern const BYTE LibName[];
  60. extern const BYTE LibIdString[];
  61.  
  62. extern APTR  __LibTable__[];
  63. extern APTR  __FuncTable__[];
  64.  
  65. extern const int __datadata_relocs[];
  66.  
  67. extern int   __UserLibInit(_LIB *);
  68. extern void  __UserLibCleanUp();
  69.  
  70. /******************************************************************************/
  71. /*                                                                            */
  72. /* resident structure                                                         */
  73. /*                                                                            */
  74. /******************************************************************************/
  75.  
  76. const APTR InitTab[4];
  77.  
  78. static const struct Resident RomTag = {
  79.   RTC_MATCHWORD,
  80.   (struct Resident *)&RomTag,
  81.   (APTR)((&RomTag)+1),
  82.   RTF_AUTOINIT,
  83.   0,
  84.   NT_LIBRARY,
  85.   0,
  86.   (BYTE *)LibName,
  87.   (BYTE *)LibIdString,
  88.   (APTR)&InitTab
  89. };
  90.  
  91. /******************************************************************************/
  92. /*                                                                            */
  93. /* autoinit table for use with initial MakeLibrary()                          */
  94. /*                                                                            */
  95. /******************************************************************************/
  96.  
  97. const APTR InitTab[4] = {
  98.   (APTR)sizeof(_LIB),
  99.   (APTR)&__LibTable__[1],
  100.   0,
  101.   (APTR)LibInit
  102. };
  103.  
  104. /******************************************************************************/
  105. /*                                                                            */
  106. /* support function(s) to be inlined                                          */
  107. /*                                                                            */
  108. /******************************************************************************/
  109.  
  110. static inline APTR __GetDataSeg()
  111. {
  112.   APTR res;
  113.   asm ("lea ___a4_init-0x7ffe,%0" : "=a" (res));
  114.   return res;
  115. }
  116.  
  117. static inline ULONG __GetDBSize()
  118. {
  119.   ULONG res;
  120.   asm ("movel #___data_size,%0; addl #___bss_size,%0" : "=d" (res));
  121.   return res;
  122. }
  123.  
  124. static inline ULONG __DSize()
  125. {
  126.   ULONG res;
  127.   asm ("movel #___data_size,%0" : "=d" (res));
  128.   return res;
  129. }
  130.  
  131. /******************************************************************************/
  132. /*                                                                            */
  133. /* initialization function called by MakeLibrary()                            */
  134. /*                                                                            */
  135. /******************************************************************************/
  136.  
  137. struct Library *LibInit()
  138. {
  139.   register APTR SegList asm("a0");
  140.   register struct Library *lib asm("d0");
  141.   _LIB *Library = (_LIB *)lib;
  142.  
  143.   /* init global library base */
  144.  
  145.   Library->LibNode.lib_Node.ln_Type = NT_LIBRARY;
  146.   Library->LibNode.lib_Node.ln_Name = (UBYTE *)LibName;
  147.   Library->LibNode.lib_Flags        = LIBF_CHANGED | LIBF_SUMUSED;
  148.   Library->LibNode.lib_Version      = (UWORD)LibVersion;
  149.   Library->LibNode.lib_Revision     = (UWORD)LibRevision;
  150.   Library->LibNode.lib_IdString     = (UBYTE *)LibIdString;
  151.   Library->SegList                  = SegList;
  152.   Library->DataSeg                  = __GetDataSeg();
  153.   Library->DataSize                 = __GetDBSize();
  154.   Library->Parent                   = Library;
  155.  
  156.   /* this will be added to SysBase->LibList */
  157.  
  158.   return (struct Library *)Library;
  159. }
  160.  
  161. /******************************************************************************/
  162. /*                                                                            */
  163. /* LibOpen() will be called for every OpenLibrary()                           */
  164. /*                                                                            */
  165. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  166. /*                                                                            */
  167. /******************************************************************************/
  168.  
  169. /* forced to be placed in the code section (required!) */
  170.  
  171. const ULONG *const FuncTable=(ULONG *)&__FuncTable__[0];
  172.  
  173. struct Library *LibOpen()
  174. {
  175.   register struct Library *lib asm("a6");
  176.   _LIB *Library = (_LIB *)lib, *NewLibrary;
  177.   long *relocs,numrel;
  178.  
  179.   /* any memory allocation can cause a call of THIS library expunge vector.
  180.      if OpenCnt is zero the library might go away ... So fake a user :-) */
  181.  
  182.   Library->LibNode.lib_OpenCnt++;
  183.  
  184.   /* create new library base */
  185.  
  186.   if ((NewLibrary=(_LIB *)MakeLibrary((APTR)&FuncTable[1],NULL,(APTR)&LibInit,sizeof(_LIB)+Library->DataSize,0)) != NULL)
  187.   {
  188.     int result;
  189.  
  190.     /* one user */
  191.  
  192.     NewLibrary->LibNode.lib_OpenCnt++;
  193.  
  194.     /* copy dataseg */
  195.  
  196.     CopyMem(NewLibrary->DataSeg,(UBYTE *)NewLibrary+sizeof(_LIB),__DSize());
  197.  
  198.     /* relocate */
  199.  
  200.     relocs=(long *)&__datadata_relocs[0];
  201.     if ((numrel=*relocs++))
  202.     {
  203.       int origmem=(int)NewLibrary->DataSeg, mem=(int)((UBYTE *)NewLibrary+sizeof(_LIB));
  204.  
  205.       do
  206.        { 
  207.          *(long *)(mem + *relocs++) -= origmem - mem;
  208.        }
  209.       while(--numrel);
  210.     }
  211.     NewLibrary->DataSeg = (APTR)((UBYTE *)NewLibrary+sizeof(_LIB)+0x7ffe);
  212.  
  213.     /* our 'real' parent */
  214.  
  215.     NewLibrary->Parent  = Library;
  216.  
  217.     /* assume user-init won't fail */
  218.  
  219.     Library->LibNode.lib_Flags &= LIBF_DELEXP;
  220.     Library->LibNode.lib_OpenCnt++;
  221.  
  222.     /* now call user-init */
  223.  
  224.     SETA4(NewLibrary->DataSeg);
  225.     result=__UserLibInit(NewLibrary);
  226.     RESA4(0);
  227.  
  228.     /* all ok? */
  229.  
  230.     if (result!=0)
  231.     {
  232.       ULONG NegSize;
  233.  
  234.       --Library->LibNode.lib_OpenCnt;
  235.       NegSize = Library->LibNode.lib_NegSize;
  236.       FreeMem((APTR)((UBYTE *)NewLibrary-(UBYTE *)NegSize),NegSize+NewLibrary->LibNode.lib_PosSize);
  237.       NewLibrary = NULL;
  238.     }
  239.   }
  240.  
  241.   /* end of expunge protection */
  242.  
  243.   --Library->LibNode.lib_OpenCnt;
  244.  
  245.   return (struct Library *)NewLibrary;
  246. }
  247.  
  248. /******************************************************************************/
  249. /*                                                                            */
  250. /* CloseLibrary() entry for the private library bases                         */
  251. /*                                                                            */
  252. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  253. /*                                                                            */
  254. /******************************************************************************/
  255.  
  256. APTR LibClose()
  257. {
  258.   register struct Library *lib asm("a6");
  259.   _LIB *Library = (_LIB *)lib;
  260.   APTR SegList=0;
  261.   ULONG NegSize;
  262.  
  263.   if (--Library->Parent->LibNode.lib_OpenCnt==0 && (Library->LibNode.lib_Flags&LIBF_DELEXP))
  264.     SegList=LibExpunge();
  265.  
  266.   /* call user-exit */
  267.  
  268.   SETA4(Library->DataSeg);
  269.   __UserLibCleanUp();
  270.   RESA4(0);
  271.  
  272.   /* free library */
  273.  
  274.   NegSize = Library->LibNode.lib_NegSize;
  275.   FreeMem((APTR)((UBYTE *)Library-(UBYTE *)NegSize),NegSize+Library->LibNode.lib_PosSize);
  276.  
  277.   /* SegList or NULL (still in use) */
  278.  
  279.   return SegList;
  280. }
  281.  
  282. /******************************************************************************/
  283. /*                                                                            */
  284. /* remove library from memory if possible                                     */
  285. /*                                                                            */
  286. /* !!! CAUTION: This function runs in a forbidden state !!!                   */
  287. /*                                                                            */
  288. /******************************************************************************/
  289.  
  290. APTR LibExpunge()
  291. {
  292.   register struct Library *lib asm("a6");
  293.   _LIB *Library = ((_LIB *)lib)->Parent;
  294.   APTR SegList=0;
  295.  
  296.   /* set delayed expunge flag */
  297.  
  298.   Library->LibNode.lib_Flags |= LIBF_DELEXP;
  299.  
  300.   /* still in use? */
  301.  
  302.   if (Library->LibNode.lib_OpenCnt == 0)
  303.   {
  304.     ULONG NegSize;
  305.  
  306.     /* return the seglist for UnLoadSeg() */
  307.  
  308.     SegList = Library->SegList;
  309.  
  310.     /* remove library from SysBase->LibList */
  311.  
  312.     Remove((struct Node *)Library);
  313.  
  314.     /* free library */
  315.  
  316.     NegSize = Library->LibNode.lib_NegSize;
  317.     FreeMem((APTR)((UBYTE *)Library-(UBYTE *)NegSize),NegSize+Library->LibNode.lib_PosSize);
  318.   }
  319.   return SegList;
  320. }
  321.  
  322. /******************************************************************************/
  323. /*                                                                            */
  324. /* a do nothing stub (required!)                                              */
  325. /*                                                                            */
  326. /******************************************************************************/
  327.  
  328. APTR LibExtFunc()
  329. {
  330.   return 0;
  331. }
  332.  
  333. /******************************************************************************/
  334. /*                                                                            */
  335. /* add these functions to 'liblist'                                           */
  336. /*                                                                            */
  337. /******************************************************************************/
  338.  
  339. ADD2LIST(LibOpen,   __LibTable__,22);
  340. ADD2LIST(LibExtFunc,__LibTable__,22);
  341. ADD2LIST(LibExpunge,__LibTable__,22);
  342. ADD2LIST(LibExtFunc,__LibTable__,22);
  343. asm(".stabs \"___LibTable__\",20,0,0,-1");
  344.  
  345. /******************************************************************************/
  346. /*                                                                            */
  347. /* add these functions to 'funclist'                                          */
  348. /*                                                                            */
  349. /******************************************************************************/
  350.  
  351. ADD2LIST(LibExtFunc,__FuncTable__,22);
  352. ADD2LIST(LibClose,  __FuncTable__,22);
  353. ADD2LIST(LibExpunge,__FuncTable__,22);
  354. ADD2LIST(LibExtFunc,__FuncTable__,22);
  355.  
  356. /******************************************************************************/
  357. /*                                                                            */
  358. /* end of libinitr.c                                                          */
  359. /*                                                                            */
  360. /******************************************************************************/
  361.