Runtime Link Library System




This section documents the format of the RLL areas as they are held within programs or RLL libraries. It will not normally be necessary for users to be aware of these details unless they plan to build programs that will directly manipulating the object files.

Binary File formats.

The format of binary programs and RLL Libraries will always conform to the following general outline:

Programs RLL Libraries
Program start-up code RLL Header
.... program code .... .... library code ....
BSS Areas BSS Areas
The following section names are reserved and should not be used in any user supplied code or the results are unpredictable:

The RLL Header (for Runtime Link Libraries), BSS Header and RLL BSS Areas are generated automatically by the LD linker. The RLL library code is similar to that of a standard binary program, except that it starts with the RLL Header instead of the standard start-up module (normally crt.o) that is used for an binary program.

RLL Header

The RLL header is only present in a RLL library. It is the first item in such a RLL library. Its purpose is to help the RLM with deciding if a particular RLL is of the right version, and how large the various areas are that need to be loaded into memory.

The RLL header starts with a THING linkage block, plus a series of other fields that are relevant to the RLL Library layout as follows:

Size Description
38 bytes Standard THING header.
long Version ID
string Thing name as a QDOS/SMS format string.
This is followed by a THING header of the format
Long pre-set to standard value of "THG%"
Long pre-set to 0 to indicate a utility THING
This is followed immediately by a table of the form
8 bytes Pre-set to "<<RLL>>"
Long File offset to BSS Header.
Long File offset of RLL Load initialisation routine or zero if not present. This routine is invoked when a RLL is loaded into memory.
Long File offset of RLL Link initialisation routine. This routine is expected to be invoked whenever a program or RLL links to this library.
The file offset fields are stored in the binary file as file offsets, but are converted to absolute pointers during the program or RLL initialisation phase.
Byte Re-entrant state flag. If set non-zero then the library is marked as re-entrant.
Byte Position-Independent flag. If set non-zero then the library is marked as position-independent. This means that there are no relocation entries associated with this library.
This is followed by the following area that is used internally by the RLM at runtime:
Long Link to next RLL, 0 if absent
Long Link to previous RLL, 0 if absent
Short Timeout value
Short Timeout that has expired
Long Job Id for this RLL, 0 if not used.


  1. Any of the fields in this table can be zero if the area does not exist.

  2. All offsets are relative to the start of the THING linkage block (i.e. the start of the RLL file).

  3. The BSS Header will specify where the UDATA starts. Normally this will be immediately following the BSS Header and the RLM will allocate enough additional space for the UDATA area when loading the RLL.

    The other BSS areas will normally be allocated memory space dynamically as required by the RLM and released when no longer required. This default behaviour can be over-ridden by additional parameters to the LD linker to specify that these additional areas should be kept.

BSS Areas

The BSS Areas hold all the information to do with program relocation and to do with externally visible symbols. The BSS areas are present in both Runtime Link Libraries and EXECable programs. Some of the areas may be zero length (i.e not exist) if they are not required. This would be the case of a traditional program that uses static linking. The BSS areas consist of the following sub-areas:

BSS Header area
RLIB area
XREF area
XDEF area
RELOC area
UDATA area
Each of the above areas is put into a separate section by the linker so it is obvious where they start and end when examining a linker listing.

Note that this format was introduced with LD v2 (which was first released as part of C68 release 4.30). Prior to this release, the BSS areas merely consisted of the RELOC area discussed below without the RELOC header. All the additional areas mentioned did not exist.

For standard programs it is desirable to keep runtime memory requirements to a minimum. As many of the areas in the BSS section are not normally required after the initialisation phase has completed, the LD linker normally tries to set the program up to re-use such space for UDATA (Unitialised Data) purposes. The start of the UDATA is set as follows:

This is done so that after the initialisation phase of an EXECutable program or after the RLM has loaded a RLL the space used for BSS purposes can be re-used as effeciently as possible.

There are special qualifiers to the LD linker -f runtime parameter option to modify this behaviour as follows:

keepbss Start the UDATA area after the end of the BSS Header.

This option would rarely be needed but is included for completeness.

keepxdef Do not start the UDATA area until after the end of the XDEF area.

This is the default for a RLL, and is also appropriate for a program which keeps the external symbol information available in memory.

keeprlib Do not start the UDATA area until after the end of the RLIB area.

This option will rarely be used, but it might be relevant if using some debugging software that can use the information stored here to load symbol information from RLL libraries.

keepxref Do not start the UDATA area until after the end of the XREF area.

This will be appropriate to programs that want to be able to load/unload RLLs dynamically at runtime.

keepreloc Do not start the UDATA area until after the end of the RELOC area.

This will very rarely be used, but there might be times when it can be usefully used in conjunction with debugging software.

keepudata This option is used to force a the generated program or RLL to include the UDATA area as part of the file. Normally any additional space above that being re-used (if any) from earlier sections in the BSS area is simply set as a dataspace value in the file header. This reduces the resultant file size.

This setting will be relevant if you want to be able to load code via the LRESPR keyword as that ignores the dataspace value in a file header and only allocates memory according to the physical size of the file.

Note that this is the only option that it would make sense to combine with one of the earlier options. All the other options are effectively mutually exclusive.

BSS Header

This section is present in ALL programs whether they are using RLLs or not. It is used to help determine what other parts of the BSS area are present, and where they start.

Size Description
8 bytes Preset to "<<BSS1>>"
long File offset to XDEF area or 0 if not present
long Size of XDEF area
long File offset to RLIB area or 0 if not present
long Size of RLIB area
long File offset to XREF area or 0 if not present
long Size of XREF area
long File offset to RELOC area or 0 if not present
long Size of RELOCF area
long File offset to UDATA area
long Size of UDATA area

Any of the above fields can be zero if the area does not exist. When stored in a file, all offsets are relative to the start of the file. During the program or RLL initialisation phase once the BSS Header has been loaded into memory, these offsets are changed to be absolute addresses (if the area concerened is being kept in memory).

Note that in systems linked using LD v1.x which did not use this format. Instead the usage was as follows:

XDEF area

This area contains a list of externally visible symbols within the current program or library, and their location within the program or library.

Normally one would only expect the XDEF area to be present for RLL libraries, but there is nothing precluding it being present in standard EXECable programs. In particular you may want to include this area in a program so that debugging software can obtain a list of global symbols from this area.

The format is as follows:

Size Description
8 bytes Preset to "<<XDEF>>"
Repeating entries for each symbol that is globally visible then follows this. The format of these entries is
long Offset within the program or library to which this symbol refers.
byte Length of symbol name
string The symbol name (with no zero terminating byte). An additional zero byte padding will be added at the end if necessary to ensure that this symbol ends on an even boundary. The symbol is case significant.
Writing a long of zero as the offset entry indicates the end of the XDEF area.

RLIB area

This area is used to indicate which Runtime Link Libraries are required to satisfy the external references that are still outstanding for this program or library.

Size Description
8 bytes Preset to "<<RLIB>>"
Repeating entries for each RLL that is referenced by this program or RLL then follows this. The entries are of the form
1 byte Entry number of this RLL in the table (starting at 1).
1 byte Set non-zero to indicate that this library should not be linked in automatically at program initialisation. Normally one would expect RLL's to be automatically loaded and linked by the program start-up code, but this allows for those cases where the programmer wants to control this process himself.
4 bytes Version number of the library

The linker will generate this value by taking the version field from the RLL Header of an RLL.

string Thing name of the RLL library as a zero terminated C string. This will NOT include the version number characters. If the string plus its terminating NULL byte would are of an odd length then an additional NULL byte is added to ensure that the entry terminates on an even boundary.

The linker will generate this value by taking the RLL Thing name field from the RLL Header of an RLL.

Writing a byte of zero as the entry number indicates the end of the RLIB area. An additional zero byte will be inserted to make sure the RLIB area termiantes on an even address.

XREF area

This area contains a list of locations that will need relocation relative to an external symbols (normally expected to be from a RLL library). The list is in alphabetical order. The format is:

Size Description
8 bytes Preset to "<<XREF>>"
There is then an entry for each symbol that is externally referenced.
The format of these entries is as follows:
byte Byte that indicates which RLL should be used to satisfy this symbol. The value will be the number (starting from 1) of an entry in the RLIB area that describes the RLL needed.

A special value of $80 (i.e top bit set) is used to indicate that none of the libraries in the RLIB area satisfy this reference (i.e. It was an unsatisfied reference at link stage). This allows for the case in which programmers want to provide a RLL later during the running of their program.

string C style string that is the name of the symbol whose address needs to be added to the location for relocation purposes. This symbol name is case significant.
There is then a series of repeating 3 byte entries that describe the relocation that needs to be done for this symbol.
Byte This byte is used to specify information about how this relocation entry must be applied. It is a bit significant field. The meaning of the bits is based on the byte that defines a truncation rules within an SROFF XREF entry although a meaning has also been assigned to bit 7 that is not used in the SROFF format, and the bits that are not relevant in this context are not used. The meanings of the bits are as follows
Bit Meaning
7 The remaining bits of this byte and the 16 bits of the next two bytes are used to reset the relocation point to the given offset in the program or RLL.
6 Not used.
5 Result is PC-relative.
4 Result is unsigned.
3 Result is signed.
2 Result is a long word (4 bytes).
1 Result is a word (2 bytes).
0 Result is a bytes.
Word If bit 7 of the previous byte was not set, then this is a 2 byte field giving the location within the program or library that needs the relocation information applied as an offset relative to the previous relocation point.

If bit 7 of the previous byte was set, then these two bytes contain the bottom 16 bits of the address to reset the relocation point.

The end of a the relocation entries for a particular symbol is indicated by writing a zero byte.

The end of the XREF area is indicated by writing a word of value zero. If necessary an additional zero byte is writen to ensure that the XDEF area ends on an even address.

RELOC area

This area contains relocation information for the current loaded file. This table is used after a program or RLL has been loaded into memory to adjust all instructions that use absolute addressing and thus need adjusting by the address at which the code was loaded. Each relocation is assumed to be of type "long".

The format of the RELOC area is:

Size Description
8 bytes Preset to "<<RELOC>"

Note that relocation tables generated by LD v1.xx did not have this field present, but were otherwise identical

Long Offset to the first address in the program or RLL library that needs relocation. This offset is relative to the start of the program or library.

It is always assumed that relocation applies to longs. It is performed by adding the base address of the program to the location that is being relocated.

There are then a series of entries defining each address that needs relocation. The format of these entries is:
byte Offset relative to the last location that was relocated to the next address to be relocated

A special value of 0xFF can be used to add 254 to the relocation pointer without actually doing relocation. This allows for locations that need relocation applied being more than 254 bytes apart

A byte of 0 terminates the BSS Relocation table.

UDATA area

This area is used to hold uninitialised program variables.

To minimise the size of program files, this area need for this space is not normally stored in a program file, but is instead set up dynamically as part of the program initialisation code. Under QDOS a value is set in the Data Space field of a file header to get the operating system to automatically allocate additional memory (if required) as part of loading a program file.

Many of the BSS areas are only required during the program initialisation phase. Once this has been done, the space is no longer needed. Therefore runtime memory requirements can be minimised by re-using this space for UDATA purposes. Exactly which areas can be re-used is described elsewhere in this document and varies according to whether this is a standard program; a RLL library; or whether the developer has some special non-standard requirements concerning re-use.

The C standard specifies that a user program is entitled to assume that uninitialised program variables contain zero if they are numeric and NULL if they are pointers. The program initialisation code will therefore ensure that any space that is re-used in this way is re-initialised to zeros before passing control to the users program.

Amendment History

June 1997

July 1998

31st May 1999