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.
The format of binary programs and RLL Libraries will always conform to the following general outline:
|Program start-up code||RLL Header|
|.... program code ....||.... library code ....|
|BSS Areas||BSS Areas|
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.
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:
|38 bytes||Standard THING header.|
|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 that has expired|
|Long||Job Id for this RLL, 0 if not used.|
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.
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:
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:
UDATAis set to start at the same point as the BSS Header.
UDATAis set to start after the BSS Header.
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
-f runtime parameter option to modify
this behaviour as follows:
||Start the UDATA area after the end of the BSS Header.
This option would rarely be needed but is included for completeness.
||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.
||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.
||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.
||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.
||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.
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.
|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:
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:
|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.|
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.
|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.|
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:
|8 bytes||Preset to "<<XREF>>"|
|There is then an entry for each symbol that is
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
|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.
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:
|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
|A byte of 0 terminates the BSS Relocation table.|
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.