With most compilers languages a program has to be first compiled (i.e. translated from the source text to machine code) and then linked (i.e. joined up with other program portions and library functions and saved as a program file) before it can be executed. Load-time linking (abbreviated 'LTL') omits the last step until the program is to be executed. Only then does the so-called loader assemble the program, though without saving it as a program file. Thus the linking process takes place in RAM, immediately before the execution of the program.
This text desribes a protocol permitting a shell to communicate with a loader (i.e. a program that implements load-time linking). This protocol was used for the first time by the development environment Chatwin and the Oberon-System STJ-Oberon-2. But the protocol has been constructed in such a way that in principle it can also be used by other shells and loaders.
The communication between shell and loader takes place via a cookie named OBNL. This points to a routine with which the shell can call the loader. Hence the cookie must be created by the loader.
The routine to which the OBNL cookie points is defined as follows:
int cdecl obnload ( OBNCOMM *com );
i.e. that the routine passes on the stack a pointer to a OBNCOMM structure and that the routine returns a 16-bit value in register d0.
The OBNCOMM structure is built up as follows:
typedef struct _obncomm { int type; void *ptr; int chr; void *env; } OBNCOMM;
The field type contains one message number at a time. Depending on this number, the other entries of the structure are then filled.
'int' is a signed 16-bit integer, 'void *' is a pointer to 'something' i.e. it is not at first specified particularly what type of data the pointer points to.
The shell can send the following messages to the loader:
Message Number CL_INIT 0x6500 CL_COMMAND 0x6501 CL_TIME 0x6502
Messages from the shell to the loader always start with 'CL_'.
Please note: These are not AES messages! The communication takes place via the routine to which the OBNL cookie points.
With the message CL_INIT the shell inform the loader that it supports the LTL protocol. At the same time it passes to the loader the address of a function via which the loader can trigger actions in the shell.
The function in the shell has the same parameters as the function to which the OBNL cookie points:
int cdecl obnshell ( OBNCOMM *com );
Assignment of the OBNCOMM structure:
type | CL_INIT
|
ptr | Address of the function in the shell
|
chr | Undefined
|
env | Undefined
|
The shell is to execute a command that requires a load-time linking. After this it passes on the complete command to the loader.
Assignment of the OBNCOMM structure:
type | CL_COMMAND
|
ptr | Pointer to a NULL-terminated string that contains the complete
command that was input (incl. parameters)
|
chr | Undefined
|
env | Pointer to the environment
|
If there has been no user input for some time and the shell also has nothing to do otherwise, it can inform the loader about this so that it is free to perform tasks in the background if desired.
Assignment of the OBNCOMM structure:
type | CL_TIME
|
ptr | Undefined
|
chr | Undefined
|
env | Undefined
|
The loader can send the following messages to the shell:
Message Number LC_WRCHAR 0x6503 LC_WRSTR 0x6504 LC_OUTBUF 0x6505 LC_CLOSEWIN 0x6506 LC_OPENWIN 0x6507
Messages from the loader to the shell always start with 'LC_'.
Please note: These are not AES messages! The communication takes place via the routine that the shell has informed the loader about at CL_INIT.
The loader sends to the shell a character that is to be output on the console.
Assignment of the OBNCOMM structure:
type | LC_WRCHAR
|
ptr | Undefined
|
chr | The character to be output
|
env | Undefined
|
The loader sends to the shell a NULL-terminated string that is to be output in the console.
Assignment of the OBNCOMM structure:
type | LC_WRSTR
|
ptr | Pointer to the string to be output
|
chr | Undefined
|
env | Undefined
|
The loader directs the shell to output to the console immediately any characters that may still be left in the buffer.
Assignment of the OBNCOMM structure:
type | LC_OUTBUF
|
ptr | Undefined
|
chr | Undefined
|
env | Undefined
|
The loader directs the shell to close all windows that may be open at the time. This call is required at the launch of a GEM module under Single-TOS.
Assignment of the OBNCOMM structure:
type | LC_CLOSEWIN
|
ptr | Undefined
|
chr | Undefined
|
env | Undefined
|
The loader directs the shell to reopen all windows closed previously with LC_CLOSEWIN.
Assignment of the OBNCOMM structure:
type | LC_OPENWIN
|
ptr | Undefined
|
chr | Undefined
|
env | Undefined
|
As an example one should show here briefly how Chatwin (shell) and STJ-Oberon-2 (loader) implement the LTL protocol:
The Oberon loader installs the OBNL cookie and then launches
Chatwin.
Chatwin recognizes by the presence of the cookie that LTL is
desired and declares itself to the loader with the CL_INIT call.
During this Chatwin passes a pointer to a function via which the loader
in turn can trigger actions in Chatwin.
Whenever Chatwin is directed now to launch a file with the
extension '*.OBJ', it passes this file and any parameters that may be
required via the message CL_COMMAND to the loader.
The loader now has to launch the program. If it is dealing with
a TOS program, then it can direct the outputs of this program via
the LC_WRCHAR and LC_WRSTR messages to Chatwin's console window. If it
is dealing with a GEM program, then the loader can direct Chatwin
under Single-TOS to close all its windows (LC_CLOSEWIN message) before
the program is launched.
Note: Chatwin recognizes by the extension whether a
load-time linking is to be performed for a given file. In older
versions the extension '*.OBJ' is fixed, as of Chatwin 3.04 the
extension can be specified in the environmental variable $LTLEXT. Due
to this Chatwin is prepared also for other languages that do not use
'*.OBJ' as extensions for the object files.
If there has been no user input for some time and also there
are no other tasks pending, Chatwin cedes CPU time to the loader by
sending a CL_TIME message. Due to this the loader can perform certain
tasks in the background.
A special protocol exists for program termination: When Chatwin
is terminated, the loader terminates as well.