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