#ifndef _RLL_H
#define _RLL_H
/*
 *  r l l . h
 *
 *  This header defines all the data structures and routines that are
 *  used to implement the various parts of the QDOS Runtime Link Library
 *  system.  It therefore as a side effect defines all the data structures
 *  used by the revised object formats introduces with LD v2 and SLB v3
 *
 *  AMENDMENT HISTORY
 *  ~~~~~~~~~~~~~~~~~
 *  January 94  DJW   - Details finalised as LD linker upgraded to be
 *                      able to generate RLL libraries, and programs
 *                      that use RLL libraries.
 *
 *  01 Oct 94   DJW   - Updated to reflect the actual implementation of the
 *                      RLL system and the RLM interfaces.
 *
 *  01 Jan 95   DJW   - Further updates to reflect RLL implementation.
 *
 *  18 Feb 96   DJW   - Removed need for BSS header in RLLs
 *                    - Bought in line with assembler include file 'RLL_IN'
 */

#ifndef _SYS_TYPES
#include <sys/types.h>
#endif

#ifndef _THINGS_H
#include <things.h>
#endif


/*
 *  BSS header
 *  ~~~~~~~~~~
 *
 *  The BSS header is present in all binary files that are not
 *  RLLs (which have the relevant information in the RLL header).
 *  The BSS header is used to give information about the rest 
 *  of the RLL BSS area.
 *
 *  NOTES:
 *
 *  1.  Theoretically this section can be omitted if there is no
 *      data at all in the BSS area.  In practise it is impossible
 *      to write a C program that has no requirement for relocation.
 *      Its absence therefore indicates one of:
 *      -   A program that was produced by LD v1.xx
 *      -   A program produced with an alternative linker such as LINK.
 *      -   A program that needs no relocation
 *          (and therefore not written in C)
 *
 *  2.  Any of the offsets into the BSS area can be zero if that
 *      area is not present.
 *
 *  3.  In a RLL, the BSS area is embedded into the RLL_HEADER
 */

typedef struct {
    char    bss_iden[8];            /* Preset to RLL_BSSFLAG */
    long    bss_rlib;               /* Offset to RLIB area */
    long    bss_xdef;               /* Offset to XDEF area */
    long    bss_xref;               /* Offset to XREF area */
    long    bss_reloc;              /* Offset to RELOC area */
    long    bss_udata;              /* Offset tp UDATA area */
    long    bss_usize;              /* Size of UDATA area */
    } BSS_HEADER;

#define BSSFLAG "<<BSS>>"

/*
 *  BSS RLIB area
 *  ~~~~~~~~~~~~~
 *
 *  This area is used to hold information about the dependencies of
 *  this program or RLLs.   It can also be set for RLLs to indicate
 *  that they themselves depend on further RLLs.
 *
 *  NOTES:
 *
 *  1.  This section will only be present if this program or library
 *      needs other RLL's to function.  It will be absent in a program
 *      or RLL that has no further dependencies.
 *
 *  2.  The library name is a zero terminated C style string.
 *
 *  3.  There is one occurence of the version/name combination for
 *      every RLL referenced by this module.
 */

typedef struct {
    char    rlib_iden[8];            /* Preset to BSS_RLIBFLAG */
    short   rlib_count;              /* Number of RLLs used by this module */
    struct {
        char    version[4];         /* Version number of library */
        char    name[16];           /* Name of library (as C string) */
      } rlib[1];
    } BSS_RLIB;

#define BSS_RLIBFLAG    "<<RLIB>>"

/*
 *  BSS XDEF Area
 *  ~~~~~~~~~~~~~
 *
 *  This area contains the list of symbols that are globally visible
 *  in this particular program or RLL.
 *
 *  NOTES:
 *
 *  1)  This section will always be present in a RLL as it defines the
 *      symbols in the RLL that can be referenced from outside the RLL.
 *
 *  2)  This section is optional in a program.   It will only be present
 *      if the linker has been instructed to include symbol information
 *      in the binary program file.  Typically this would only be done
 *      when producing versions of programmers for use with a debugger.
 *
 *  3)  The symbol name is actually variable length.  It will always
 *      be a string, but with no 0 end byte.  If necessary an additional
 *      0 byte will be added to get back to an even address.
 *
 *  4)  The table is terminated by an entry with an offset of zero.
 */

typedef struct {
    char    xdef_iden[8];               /* Preset to BSS_XDEFFLAG */
    struct {
        long    offset;                /* Offset in program */
        char    symlen;                /* Symbol length */
        char    symname[1];            /* Symbol name */
      } xdef[1];
    } BSS_XDEF;

#define BSS_XDEFFLAG    "<<XDEF>>"
#define BSS_XDEF_END    0x0             /* Value used to indicate end of area */

/*
 *  BSS XREF area
 *  ~~~~~~~~~~~~~
 *
 *  The BSS XREF area is used to define all the areas of this
 *  program or RLL that refer to external references.
 *
 *  NOTES:
 *
 *  1)  This section is only present if this program or RLL has a dependency
 *      on further RLLs.
 *
 *  2)  Much of this area is really variable length, and does not map
 *      well onto a C structure.
 *
 *      The symbol name consists of a string (with no automatic terminating
 *      zero byte), with an extra zero byte padding added if necessary to
 *      get back to an even address.  This is then followed by a series of
 *      word length entries that give the offsets relative to the previous
 *      one for the next address that needs relocation to an external reference
 *
 *  3)  A value of 0xFFFE as an offset indicates that 32766 should be added 
 *      to the current external reference address, but no external reference
 *      should actually done.  This is used when addresses to be an external
 *      reference are more than 32766 bytes apart.
 *
 *  4)  The LD linker will always assume that the information in this area
 *      is redundant after the load process has finished.   It will therefore
 *      re-use any space occupied by this area as part of the UDATA area.
 *      There is an implicit assumption that the program or RLL start-up
 *      code will clear the UDATA area to zeroes.
 */

typedef struct {
    char    xref_iden[8];           /* Preset to BSS_RELOCFLAG */
    struct {
        short   count;              /* Count of relocation entries */
        char    status;             /* current relocation status */
        char    symlen;             /* Length of the symbol being relocated */
        char    symname[1];         /* Symbol name (really variable length) */
      } xref[1];
    } BSS_XREF;

#define BSS_XREF_FLAG   "<<XREF>>"  /* First 8 bytes of area */
#define BSS_XREF_SKIP   0xfffe      /* Value used to skip 32766 bytes */
#define BSS_XREF_END    0x0         /* Value used to indicate end of area */

/*
 *  RELOC Area
 *  ~~~~~~~~~~
 *
 *  This area contains the relocation information for the current file.
 *
 *  NOTES:
 *
 *  1)  This area is only present if runtime program relocation is
 *      required.   In practise this is always true for C programs,
 *      but not necessarily for programs written in other languages.
 *
 *  2)  A value of 0x00 for bss_next indicates the end of this table.
 *
 *  3)  A value of 0xFE indicates that 254 should be added to the current
 *      relocation address, but no relocation actually done.  This is used
 *      when addresses to be relocated are more than 254 bytes apart.
 *
 *  4)  The LD linker will always assume that the information in this area
 *      is redundant after the load process has finished.   It will therefore
 *      re-use any space occupied by this area as part of the UDATA area.
 *      There is an implicit assumption that the program or RLL start-up
 *      code will clear the UDATA area to zeroes.
 */

typedef struct {
    char    reloc_iden[10];         /* Preset to BSS_RELOCFLAG */
    long    reloc_init;             /* Initial offset to first relocation point */
    unsigned char  reloc_next[1];   /* displacement to next point */
    }  BSS_RELOC;

#define BSS_RELOCFLAG   "<<RELOC>>"
#define BSS_RELOC_END     0x00        /* value in bss_next to end table */
#define BSS_RELOC_SKIP    0xff        /* value in bss_next to skip 254 bytes */

/*
 *  RLL Library Header
 *  ~~~~~~~~~~~~~~~~~~
 *  The RLL Header is only present in a Runtime Link Library.
 *  All RLLs start with this standard header.   This give important
 *  information about the RLL BSS part of the library.  It is used
 *  by the RLM to decide exactly what needs loading permanently
 *  into store, and what only needs loading termporarily.
 *
 *  NOTES:
 *
 *  1). Any of the offsets into BSS area, or the addresses of the
 *      initialisation routines can be zero if the section is absent.
 *
 *  2). The offsets are relative to the start of the RLL code (which
 *      is effectively the offset into the file holding the RLL).
 *
 *  3)  The start of the RLL information is the same as that present
 *      in the BSS Header of a program.
 */

typedef struct {
    THING_LINKAGE   linkage;    /*  Standard THING header */
    char    th_filler[15];      /* Filler to make name up to 16 charcaters */
    THING_HEADER    header;     /* Standard thing header */

    /* RLL specific data */
    char    rll_iden[8];            /* Should always be RLLIDEN */
    BSS_HEADER * rll_bss;           /* Offset to BSS header */

    int     (*rll_loadinit)();      /* Offset to Load Initialisation routine */
    int     (*rll_linkinit)();      /* Offset to Link Initialisation routine */

    long    rll_fwdl;           /* zero if not required */
    long    rll_revl;           /* zero if not required */
    short   rll_time;           /* zero if not required */
    short   rll_cnt;            /* zero if not required */
    long    rll_jbst;           /* zero if not required */
    } RLL_HEADER;

#define RLLFLAG "THG%"
#define RLLTYPE 0
#define RLLIDEN "<<RLL>>"


/*
 *
 *  Runtime Library Manager (RLM) definitions
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *  The following definitions are present in the Runtime Linker Thing
 *  which is used to actually hold the code of a RLL while in memory.
 */


#define RLM_FLAG    "%RLM"          /* Flag used to identify RLM thing */

/*
 *  RLM Thing header
 */
typedef struct {
    long    flag;
    long    type;
    long    base;
    long    call;
    } RLM_HEADER;

/*
 *  The following is the definition of the structure that
 *  is used when reading the RLM globals variables
 */
typedef struct {
    unsigned char  dbgdir[34];
    unsigned char  libdir[34];
    short          timeout;
    short          debug;
    short          mode;
    } RLM_READVALUES;

#ifdef __STDC__
#define _P_(params)  params
#else
#define _P_(params)
#endif

/*
 *  Functions supported by the RLM
 */
int RLM_LinkCode        _P_((char *, BSS_HEADER *, jobid_t, chanid_t));
int RLM_LinkRLL         _P_((char *, char *, BSS_XREF *, jobid_t, chanid_t));
int RLM_UnlinkRLL       _P_((char *, char *, BSS_XREF *, chanid_t));
int RLM_LoadLib         _P_((char *, timeout_t, chanid_t));
int RLM_SetTimeout      _P_((short));
int RLM_SetLoadMode     _P_((short));
int RLM_SetLoadDir      _P_((char *));
int RLM_SetDebugDir     _P_((char *));
int RLM_SetDebugMode    _P_((short));
int RLM_ReadSettings    _P_((RLM_READVALUES *));
int RLM_RelocLD         _P_((char *, BSS_HEADER *));
int RLM_RelocGST        _P_((char *, long *));
int RLM_RelocLD_Old     _P_((char *, void *));

#undef _P_

#endif /* _RLL_H */

