home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 05.zip / BS1 part 5 / SASC_6.0_Disk_7.adf / Source_And_Examples / source / libinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-30  |  8.1 KB  |  268 lines

  1. #define  _USEOLDEXEC_ 1
  2. #include <exec/types.h>
  3. #include <exec/nodes.h>
  4. #include <exec/memory.h>
  5. #include <exec/resident.h>
  6. #include <exec/libraries.h>
  7. #include <exec/execbase.h>
  8. #include <libraries/dos.h>
  9. #include <proto/exec.h>
  10. #include <proto/dos.h>
  11. #include <string.h>
  12.  
  13.  
  14. /* Prototypes */
  15. ULONG __saveds __asm _LibExpunge( register __a6 struct MyLibrary *libbase );
  16. ULONG __saveds __asm _LibInit( register __a0 APTR seglist,
  17.                                 register __d0 struct MyLibrary *libbase );
  18. int __saveds __asm __UserLibInit(register __a6 struct MyLibrary *libbase );
  19. void __saveds __asm __UserLibCleanup(register __a6 struct MyLibrary *libbase);
  20.  
  21. struct MyLibrary {
  22.         struct       Library ml_Lib;
  23.         ULONG        ml_SegList;
  24.         ULONG        ml_Flags;
  25.         APTR         ml_ExecBase;      /*              pointer to exec base */
  26. #ifndef ONE_GLOBAL_SECTION
  27.         long *       ml_relocs;        /*             pointer to relocs.    */
  28.         struct MyLibrary  *ml_origbase; /* pointer to original library base  */
  29.         long         ml_numjmps;
  30. #endif
  31. };
  32.  
  33. typedef LONG (*myPFL)();   /* pointer to function returning 32-bit int        */
  34.  
  35. /* library initialization table, used for AUTOINIT libraries                */
  36. struct InitTable {
  37.         ULONG        *it_DataSize;       /* library data space size         */
  38.         myPFL        *it_FuncTable;      /* table of entry points           */
  39.         APTR         it_DataInit;        /* table of data initializers      */
  40.         myPFL        it_InitFunc;        /* initialization function to run  */
  41. };
  42.  
  43.  
  44. /* symbols generated by blink */
  45. extern char __far _LibID[];             /* ID string                        */
  46. extern char __far _LibName[];           /* Name string                      */
  47. extern char __far RESLEN;               /* size of init data                */
  48. extern long __far NEWDATAL;             /* size of global data              */
  49. extern long __far NUMJMPS;              /* number of jmp vectors to copy    */
  50. extern myPFL _LibFuncTab[];             /* my function table                */
  51. extern long __far _LibVersion;          /* Version of library               */
  52. extern long __far _LibRevision;         /* Revision of library              */
  53. #define MYVERSION ((long)&_LibVersion)
  54. #define MYREVISION ((long)&_LibRevision)
  55. #define DATAWORDS ((long)&NEWDATAL)     /* magic to get right tpye of reloc */ 
  56. #define SIZEJMPTAB ((long)libbase->ml_origbase->ml_numjmps)
  57.                                         /* size in bytes of jmp table       */
  58.  
  59. /* From libent.o, needed to determine where data is loaded by loadseg       */
  60. extern long far _Libmergeddata; 
  61.  
  62.  
  63. struct InitTable __far _LibInitTab =  {
  64.         (long *)(&RESLEN+sizeof(struct MyLibrary)),
  65.         _LibFuncTab,
  66.         NULL,                        /* will initialize my own data */
  67.         _LibInit,
  68. };
  69.  
  70. __saveds __asm
  71. ULONG _LibInit( register __a0 APTR seglist,
  72.         register __d0 struct MyLibrary *libbase )
  73. {
  74. #ifdef ONE_GLOBAL_SECTION
  75.     long *reloc;
  76. #endif
  77.     long *sdata;
  78.     char *ddata;
  79.     long nrelocs;
  80.  
  81.       
  82.     libbase->ml_SegList = (ULONG) seglist;
  83.  
  84.     /* init. library structure (since I don't do automatic data init.) */
  85.     libbase->ml_Lib.lib_Node.ln_Type = NT_LIBRARY;
  86.     libbase->ml_Lib.lib_Node.ln_Name =  _LibName;
  87.     libbase->ml_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
  88.     libbase->ml_Lib.lib_Version = MYVERSION;
  89.     libbase->ml_Lib.lib_Revision = MYREVISION;
  90.     libbase->ml_Lib.lib_IdString = (APTR) _LibID;
  91. #ifndef ONE_GLOBAL_SECTION
  92.     libbase->ml_relocs = NULL;
  93.     libbase->ml_origbase = libbase;
  94.     sdata = (long *)_LibInitTab.it_FuncTable;
  95. #if 1
  96.     libbase->ml_numjmps = (long)&NUMJMPS;
  97. #else
  98.     libbase->ml_numjmps = 0;
  99.     while (*sdata != -1)
  100.     {
  101.       libbase->ml_numjmps += 6;
  102.       sdata++;
  103.     }
  104. #endif
  105.  
  106. #endif
  107.  
  108.      /* Start of copy of global data after structure */
  109.     ddata = (char *)libbase + sizeof(struct MyLibrary); 
  110.  
  111.     sdata = (long *)&_Libmergeddata; /* where loadseg loaded the data */
  112.     memcpy(ddata, (void *)sdata, DATAWORDS*4);
  113.  
  114.     /* perform relocs if we want one global section for all programs */
  115.     /* that have this lib open. If we want a global section for each */
  116.     /* open, copy the relocs, and do them on each open call.         */
  117.     sdata = sdata + DATAWORDS;
  118.     nrelocs = *sdata;
  119. #ifdef ONE_GLOBAL_SECTION
  120.     sdata++;
  121.     while (nrelocs > 0)
  122.     {
  123.        reloc = (long *)((long)ddata + *sdata++);
  124.        *reloc += (long)ddata;
  125.        nrelocs--;
  126.     }
  127.     
  128.     if (__UserLibInit(libbase) != 0)
  129.        return NULL; /* abort if user init failed */
  130.  
  131. #else
  132.     if (nrelocs) 
  133.     {
  134.       if ((libbase->ml_relocs = AllocMem((nrelocs * 4) + 4, MEMF_PUBLIC)) == NULL)
  135.         return 0;
  136.       memcpy((void *)libbase->ml_relocs, (void *)sdata, (nrelocs * 4) + 4);
  137.     }
  138. #endif
  139.  
  140.     return ( (ULONG) libbase );
  141. }
  142.  
  143. LONG __saveds __asm
  144. _LibOpen( register __a6 struct        MyLibrary *libbase )
  145. {
  146. #ifndef ONE_GLOBAL_SECTION
  147.     struct ExecBase *SysBase = *(struct ExecBase **)4;
  148.     char *newlib;
  149.     long *sdata, *ddata, *reloc;
  150.     long nrelocs;
  151. #endif
  152.  
  153.     /* mark us as having another customer */
  154.     libbase->ml_Lib.lib_OpenCnt++;
  155.  
  156.     /* clear delayed expunges (standard procedure)                */
  157.     libbase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
  158.  
  159. #ifndef ONE_GLOBAL_SECTION
  160.     /* Allocate new lib base */
  161.     newlib = AllocMem((long)(sizeof(struct MyLibrary) + 
  162.                              ((long)&RESLEN) + SIZEJMPTAB), 
  163.                              MEMF_PUBLIC|MEMF_CLEAR);
  164.  
  165.     if (newlib == NULL) return 0;
  166.         
  167.     /* copy over data */
  168.     memcpy(newlib, (char *)libbase - SIZEJMPTAB, 
  169.            (long)(sizeof (struct MyLibrary) + DATAWORDS*4 + SIZEJMPTAB));
  170.     
  171.     libbase = (struct MyLibrary *)(newlib+SIZEJMPTAB);
  172.     libbase->ml_relocs = NULL;
  173.     
  174.     /* perform relocs */       
  175.     ddata = (long *)((char *)libbase + sizeof(struct MyLibrary)); 
  176.     sdata = libbase->ml_origbase->ml_relocs;
  177.     if (sdata)
  178.     {
  179.        nrelocs = *sdata++;
  180.        while (nrelocs > 0)
  181.        {
  182.           reloc = (long *)((long)ddata + *sdata++);
  183.           *reloc += (long)ddata;
  184.           nrelocs--;
  185.        }
  186.     }
  187.               
  188.     if (__UserLibInit(libbase) != 0)
  189.     {
  190.        FreeMem(newlib, (long)(sizeof(struct MyLibrary) + 
  191.                              ((long)&RESLEN) + SIZEJMPTAB));
  192.        return NULL; /* abort if user init failed */
  193.     }
  194.     
  195.     /* now we need to flush the cache because we copied the jmp table */
  196.     if (SysBase->LibNode.lib_Version >= 36) 
  197.       CacheClearU();
  198.  
  199.  
  200. #endif
  201.  
  202.     return ( (LONG) libbase );
  203. }
  204.  
  205. ULONG __saveds __asm
  206. _LibClose( register __a6 struct MyLibrary *libbase )
  207. {
  208.     ULONG retval = 0;
  209.     
  210. #ifndef ONE_GLOBAL_SECTION
  211.     struct MyLibrary *origbase;
  212.     if (libbase != libbase->ml_origbase)
  213.     {
  214.        __UserLibCleanup(libbase);
  215.        origbase = libbase->ml_origbase;
  216.        FreeMem((char *)libbase-SIZEJMPTAB, 
  217.                (long)(sizeof(struct MyLibrary) + ((long)&RESLEN)+SIZEJMPTAB));
  218.        libbase = origbase;
  219.     }
  220. #endif
  221.  
  222.     if (( --libbase->ml_Lib.lib_OpenCnt == 0 ) &&
  223.                         ( libbase->ml_Lib.lib_Flags & LIBF_DELEXP ))
  224.     {
  225.         /* no more people have me open,
  226.          * and I have a delayed expunge pending
  227.          */
  228.          retval = _LibExpunge( libbase ); /* return segment list        */
  229.     }
  230.  
  231.     return (retval);
  232. }
  233.  
  234. ULONG __saveds __asm
  235. _LibExpunge( register __a6 struct MyLibrary *libbase )
  236. {
  237.     ULONG seglist = 0;
  238.     LONG  libsize;
  239.  
  240. #ifndef ONE_GLOBAL_SECTION
  241.     libbase = libbase->ml_origbase;
  242. #endif
  243.  
  244.     libbase->ml_Lib.lib_Flags |= LIBF_DELEXP;
  245.     if ( libbase->ml_Lib.lib_OpenCnt == 0 )
  246.     {
  247.         /* really expunge: remove libbase and freemem        */
  248. #ifndef ONE_GLOBAL_SECTION
  249.         if (libbase->ml_relocs)
  250.            FreeMem(libbase->ml_relocs, (*libbase->ml_relocs * 4) + 4);
  251. #else
  252.         __UserLibCleanup(libbase);
  253. #endif
  254.         seglist = libbase->ml_SegList;
  255.  
  256.         Remove( (struct Node *) libbase);
  257.  
  258.         libsize = libbase->ml_Lib.lib_NegSize + libbase->ml_Lib.lib_PosSize;
  259.         FreeMem( (char *) libbase - libbase->ml_Lib.lib_NegSize,(LONG) libsize );
  260.     }
  261.  
  262.     /* return NULL or real seglist                                */
  263.     return ( (ULONG) seglist );
  264. }
  265.  
  266.  
  267.  
  268.