home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 488.lha / reslib / reslib.doc.pp / reslib.doc
Text File  |  1991-03-12  |  10KB  |  218 lines

  1. ======================================================================
  2. How to create an Amiga shareable library:
  3. ======================================================================
  4.  
  5. 1) Compile all modules that reference global data with the -ml option.
  6.    Note that global data will be shared between all processes that open 
  7.    the library.
  8.  
  9. 2) Add the __saveds keyword to any function that is callable from outside
  10.    the library.
  11.    
  12. 3) Create a .fd describing your library.  A sample .fd file is included
  13.    for reference.
  14.  
  15. 4) Link with the following command:
  16.  
  17. blink LIBFD <fdfile> [LIBPREFIX <prefix>] [LIBID <idstring>] TO <libname> 
  18.       FROM lib:libent.o lib:libinit.o <modules>
  19.  
  20. where
  21.  
  22. LIBFD <fdfile>    specifies the name of the .fd file you created in step (3).
  23.  
  24. LIBPREFIX         specifies an optional prefix to add to the functions listed
  25.                   in the .fd file.  The default is simply an underscore (_).
  26.                   If for some reason you don't want to use the #pragmas to
  27.                   access the library, you can use the old method of having
  28.                   assembly-language stubs that accept parameters on the stack
  29.                   like a typical C routine, pop them into registers and call
  30.                   the library function for you.  (You must write the stubs
  31.                   yourself in assembler.)  If you do this, the library
  32.                   routines cannot have exactly the same names as the entries
  33.                   in the .fd file, since these names will have been taken
  34.                   by the stub routines.  The LIBPREFIX option specifies a
  35.                   common prefix to be prepended to the function names in the
  36.                   .fd file.  You will be responsible for making sure that the
  37.                   actual function declarations in the library's .c source file
  38.                   match the full name, including any specified prefix.  For
  39.                   example, if your library has a function called 'foo' and
  40.                   you specify a LIBPREFIX of _LIB, you should declare the
  41.                   function in your source code as LIBfoo.  (Remember that
  42.                   Blink always adds an extra underscore to symbol names.)
  43.                   If you always use the automatically-generated #pragma
  44.                   statements to access the library, you can ignore LIBPREFIX.
  45.  
  46. LIBID <idstring>  specifies an optional library ID string (See _LibID, below).
  47.                   LIBID is purely informational and is never required.
  48.  
  49. TO <libname>      specifies the resulting library name.
  50.  
  51. libent.o          contains the RomTag for the library, and MUST BE THE FIRST
  52.                   OBJECT MODULE LISTED.  The source to libent.o (libent.a) is
  53.                   in the SOURCE subdirectory of disk 4 of the compiler 
  54.                   distribution.  You do not need to modify this file for 
  55.                   your library, and probably should not.
  56.  
  57. libinit.o         contains the system-required library entry points Open,
  58.                   Close and Expunge as well as other initialization routines,
  59.                   and MUST BE THE SECOND OBJECT MODULE LISTED.  The source to
  60.                   libinit.o (libinit.c) is in the SOURCE subdirectory of 
  61.                   disk 4 of the compiler distribution.  You may modify this 
  62.                   file to add custom initialization code if you like, but 
  63.                   you are not required to.
  64.  
  65. modules           are your module names.  They may be in any order as long
  66.                   as they are specified after libent.o and libinit.o.
  67.  
  68. ======================================================================
  69. How to call the library:
  70. ======================================================================
  71.  
  72.    Create pragmas for your library with the FD2PRAGMA program, provided on 
  73.    disk 3 of the compiler distribution.  FD2PRAGMA will output a .h file
  74.    containing #pragma statements for all the externally-callable functions
  75.    in your library.  Code that would like to call your library should 
  76.    #include this .h file before referencing any of the library's functions.
  77.    When one of the library functions is called, the compiler will look at 
  78.    the #pragma for that function and determine which registers the library 
  79.    function wants the parameters in.  It will load the proper registers, load 
  80.    your library base in register A6, and call your function.
  81.  
  82.    The user code should declare a variable of type 'struct Library *' named 
  83.    after your library base.  For example, if your library is called 
  84.    'mylib.library', and you have chosen to name your library base 'MyLibBase',
  85.    the declaration in the user's code would look like:
  86.  
  87.       struct Library *MyLibBase;
  88.  
  89.    The library base can be an automatic or a global variable.  Before calling
  90.    any function in your library, the user must initialize the library base
  91.    by calling the OpenLibrary function:
  92.  
  93.       MyLibBase = OpenLibrary("mylib.library", version);  
  94.  
  95.       where version is less that equal to the number in the version
  96.       field of the struct Library (see libinit.c). A version of 0
  97.       will open any version of the library.
  98.       
  99.    The user should always check to make sure that MyLibBase is not NULL, 
  100.    which would indicate that the library could not be loaded or that the 
  101.    revision was not acceptable.
  102.  
  103.    Once the library base pointer is loaded, the user program can call your
  104.    library functions by name just like any other function.  When the program
  105.    is finished with your library, it should call CloseLibrary:
  106.  
  107.       CloseLibrary(MyLibBase);
  108.  
  109.  
  110. ======================================================================
  111. How It Works:
  112. ======================================================================
  113.  
  114.    1) What the compile options do
  115.  
  116.       Modules compiled with -ml do not use register A6, except when calling 
  117.       other libraries, in which case it is restored immediately upon return. 
  118.       Therefore A6 always has a pointer to the current library base.  Further, 
  119.       when __saveds is specified, the compiler generates the instruction  
  120.  
  121.          LEA   LinkerDB(A6),A4 
  122.  
  123.       in the function prolog.  LinkerDB is a symbol generated by Blink that
  124.       specifies the offset from the library base at which user global data
  125.       may be stored.  Thus, the above instruction sets A4 to point to the
  126.       library's global data.  Notice that the standard executable startup
  127.       code, c.o, contains a reference to LinkerDB as well.  When Blink is
  128.       linking a library, it knows to interpret LinkerDB differently than
  129.       when linking a normal program.
  130.  
  131.    2) What the initialization code does
  132.  
  133.       The job of the LibInit function in a shareable library is to set up 
  134.       the library base.  The LibInit() function defined in libinit.c will
  135.       in addition copy global data from the place where LoadSeg loaded it
  136.       (as defined by the Blink-generated symbol _Libmergeddata) to the end 
  137.       of the library base structure.  Once there, any data relocations are
  138.       patched up. From this point on, global data may be referenced relative
  139.       to A4 since A4 has been set to point at the global data.
  140.  
  141.    2) What Blink does
  142.  
  143.       Blink first reads the .fd file and determines the names and number 
  144.       of functions to the library. It creates a jump table of the form:
  145.  
  146.        +---------------------------------+
  147.        |        __LibOpen                |
  148.        |        __LibClose               |
  149.        |        __LibExpunge             |
  150.        |        ROMTAG - 2               | 
  151.        |        user defined functions.  |
  152.        +---------------------------------+         
  153.  
  154.       The names of the user-defined functions are created by prepending the
  155.       specified LIBPREFIX to the function names in the .fd file.  The symbol
  156.       _LibFuncTab points to the table, which is placed into the data section.
  157.  
  158.       Blink also defines the following symbols for libinit.o to use when 
  159.       initializing the library:
  160.  
  161.          _LibName       name of library, as specified by the TO option to
  162.                         BLINK.
  163.  
  164.          _LibID         id for library, as specified by the LIBID option to
  165.                         BLINK.  This is a null string if no LIBID option is
  166.                         specified.
  167.  
  168.          RESLEN         length of data section to be allocated as part of
  169.                         the Library structure.
  170.  
  171.          NEWDATAL       length of initialized data section.
  172.  
  173.   
  174. ======================================================================
  175. Library Format:
  176. ======================================================================
  177.  
  178. The library that blink produces looks like this:
  179.  
  180. Code Hunk 1:  (comes from libent.o)
  181.       moveq #0,d0           ; This is in case someone tries
  182.       rts                   ; to run the library as a program 
  183.    RomTag
  184.       dc.w    RTC_MATCHWORD   ; RomTag information for the library
  185.         dc.l    _LibRomTag      ;   as described in the Rom Kernel manual
  186.         dc.l    endtag          ; |
  187.         dc.b    RTF_AUTOINIT    ; |
  188.         dc.b    VERSION         ; |
  189.         dc.b    NT_LIBRARY      ; |
  190.         dc.b    PRI             ; |
  191.         dc.l    _LibName        ; |
  192.         dc.l    _LibID          ; v
  193.         dc.l    _LibInitTab     ; End of RomTag information
  194.  
  195. Code Hunk 2 - n:  (comes from libinit.o and user modules)
  196.    _LibInit
  197.       <code for LibInit>
  198.    _LibOpen
  199.       <code for LibOpen>
  200.    _LibClose
  201.       <code for LibClose>
  202.    _LibExpunge
  203.       <code for LibExpunge>
  204.    user functions
  205.  
  206. MERGED DATA
  207.   _Libmergeddata                     ; symbol that tells LibInit where the merged
  208.                                      ; data is initially loaded.
  209.   _LibInitTab                        ; struct LibInitTab as specified in libinit.c
  210.       length of global data
  211.       pointer to function jump table
  212.       NULL
  213.       pointer to initialization code (_LibInit)
  214.   USER GLOBAL DATA
  215.  
  216.  
  217. For a quick example, refer to the readme file.
  218.