Dynamic Library Specification Author: David Dyer-Bennet MRO1-2/L14 DTN 231-4076 DYER-BENNET AT KL2102, SPAGS::DDB Edition: 1.0, 18-Jan-84 File: DYN1F.MEM This document exists online as KL2137::PS:<DYER-BENNET.PUBLIC>DYN1F.MEM Dynamic Library Specification Page ii Issue History 28 May 88 Issue History Issue 0.1 30-Sep-83 Initial entry. First limited review. Issue 0.2 14-Oct-83 Signalling details. development. Issue 1.0 18-Jan-84 Update with things learned from coding and using the DYNLIB/RTL. Currently in development. Dynamic Library Specification Page iii Issue History 28 May 88 1.0 PRODUCT SUMMARY . . . . . . . . . . . . . . . . . . 1 2.0 TERMINOLOGY AND CONVENTIONS . . . . . . . . . . . . 1 3.0 ENVIRONMENT . . . . . . . . . . . . . . . . . . . . 2 3.1 Users . . . . . . . . . . . . . . . . . . . . . . 2 3.2 Hardware . . . . . . . . . . . . . . . . . . . . . 2 3.3 Software . . . . . . . . . . . . . . . . . . . . . 3 3.3.1 Other Software Required For DYNLIB . . . . . . . 3 3.3.2 Other Software That Requires DYNLIB . . . . . . 3 3.4 Services . . . . . . . . . . . . . . . . . . . . . 3 4.0 SOFTWARE CAPABILITIES . . . . . . . . . . . . . . . 3 4.1 Streaming . . . . . . . . . . . . . . . . . . . . 4 4.2 The Run-time Library . . . . . . . . . . . . . . . 4 4.3 Dynamic Invocation Of Libraries . . . . . . . . . 4 4.3.1 Calling A Routine In A Dynamic Library . . . . . 4 4.3.2 Referring To A Galactic Variable . . . . . . . . 5 4.3.3 Errors Occurring During Dynamic Loading . . . . 6 4.4 Memory Allocation . . . . . . . . . . . . . . . . 7 4.5 Signalling And Condition Handling . . . . . . . . 7 4.5.1 Layered Interrupts . . . . . . . . . . . . . . . 8 4.5.2 Condition Handling . . . . . . . . . . . . . . . 8 4.5.2.1 Fixed interrupt channels . . . . . . . . . . 10 4.5.2.2 APR traps . . . . . . . . . . . . . . . . . 10 4.5.2.3 Character interrupts . . . . . . . . . . . . 10 4.5.3 Performance Considerations . . . . . . . . . . 11 4.5.3.1 Arithmetic Trap Default Actions . . . . . . 11 4.6 Errors And Message Printing . . . . . . . . . . 12 4.7 Dynamic Library Contents . . . . . . . . . . . . 12 4.8 Writing Dynamic Libraries . . . . . . . . . . . 13 4.8.1 The Library Definition . . . . . . . . . . . . 13 4.8.2 The LDLBLK File . . . . . . . . . . . . . . . 14 4.8.3 The LDLJCK File . . . . . . . . . . . . . . . 14 4.8.4 Master Initialization . . . . . . . . . . . . 14 4.8.5 Condition Handling Routines . . . . . . . . . 15 4.9 Details Of Data Structures . . . . . . . . . . . 16 4.9.1 The Dynamic Library Block . . . . . . . . . . 16 4.9.2 The Local Dynamic Library Block . . . . . . . 17 4.9.3 The Signal Block . . . . . . . . . . . . . . . 18 4.9.4 The Condition Code . . . . . . . . . . . . . . 19 4.9.5 The Handler Block . . . . . . . . . . . . . . 19 4.10 Details Of Explicit Calls . . . . . . . . . . . 19 4.10.1 Return Last DYNLIB Error -- DY_$LER . . . . . . 20 4.10.2 Force Loading/Overloading -- DY_$LOD . . . . . 20 4.10.2.1 .DYLOD -- Force loading of library . . . . . 21 4.10.2.2 .DYOLB -- overload one library onto another 21 4.10.2.3 .DYOVC -- overload one vector onto another . 22 4.10.3 Global Master Initialization -- DY_$MIN . . . . 22 4.10.4 Allocate Memory Block -- ME_$ALM . . . . . . . 22 4.10.5 Allocate Pages Of Memory -- ME_$ALP . . . . . . 23 4.10.6 Create A New Section -- ME_$ALS . . . . . . . . Dynamic Library Specification Page iv Issue History 28 May 88 23 4.10.7 Return Memory Block -- ME_$DLM . . . . . . . . 24 4.10.8 Return Memory Pages -- ME_$DLP . . . . . . . . 24 4.10.9 Destroy A Section -- ME_$DLS . . . . . . . . . 25 4.10.10 Sub-contract Memory Management -- ME_$MEM . . . 25 4.10.11 Formatted ASCII Output -- RL_$FAO . . . . . . . 26 4.10.12 Allocate An Interrupt Channel -- SG_$ALC . . . 27 4.10.13 Disable Interrupt Characters -- SG_$DIC . . . . 27 4.10.14 Return An Interrupt Channel -- SG_$DLC . . . . 27 4.10.15 Deallocate A Signal Chain -- SG_$DLG . . . . . 28 4.10.16 Dump An SG Chain -- SG_$DMG . . . . . . . . . . 28 4.10.17 Enable Interrupt Characters -- SG_$EIC . . . . 28 4.10.18 Establish A Condition Handler -- SG_$EST . . . 29 4.10.19 Establish A Handler Locally -- SG_$LES . . . . 29 4.10.20 Remove A Handler Locally -- SG_$LRM . . . . . . 30 4.10.21 Make Signal Block For Last Monitor Error -- SG_$MER . . . . . . . . . . . . . . . . . . . . 30 4.10.22 Print Error Messages -- SG_$PEM . . . . . . . . 30 4.10.23 Remove A Condition Handler -- SG_$REM . . . . . 31 4.10.24 Declare Trap Handler For Section -- SG_$SEC . . 31 4.10.25 Signal -- SG_$SIG . . . . . . . . . . . . . . . 32 4.11 Details Of Galactic Variables Defined . . . . . 32 4.11.1 Signalling Information . . . . . . . . . . . . 32 4.11.1.1 Enable stack pointer -- SG.ENS . . . . . . . 32 4.11.2 Last-ditch Handler Parameters . . . . . . . . 32 4.11.2.1 Maximum depth -- SG.LEV . . . . . . . . . . 33 4.11.2.2 Destination designator -- SG.OUT . . . . . . 33 4.11.2.3 Prefix table address -- SG.PFX . . . . . . . 33 4.11.2.4 Suffix table address -- SG.SFX . . . . . . . 33 4.11.2.5 Default prefix table -- SG.DPX . . . . . . . 33 4.11.2.6 Default suffix table -- SG.DSX . . . . . . . 33 4.12 DYNLIB Bootstrap . . . . . . . . . . . . . . . . 33 5.0 PUBLICATIONS . . . . . . . . . . . . . . . . . . . 34 6.0 PACKAGING . . . . . . . . . . . . . . . . . . . . 34 7.0 INSTALLABILITY . . . . . . . . . . . . . . . . . . 34 Dynamic Library Specification Page v Issue History 28 May 88 8.0 EASE OF USE . . . . . . . . . . . . . . . . . . . 34 9.0 PERFORMANCE . . . . . . . . . . . . . . . . . . . 34 10.0 RELIABILITY . . . . . . . . . . . . . . . . . . . 35 11.0 MAINTAINABILITY . . . . . . . . . . . . . . . . . 35 12.0 MAINTENANCE . . . . . . . . . . . . . . . . . . . 35 13.0 COMPATIBILITY . . . . . . . . . . . . . . . . . . 36 13.1 Compatibility With Existing Libraries . . . . . 36 13.2 Product Compatibility . . . . . . . . . . . . . 36 13.2.1 Dependency Issues . . . . . . . . . . . . . . 36 13.3 Standards Conformance . . . . . . . . . . . . . 36 13.4 Internationalization . . . . . . . . . . . . . . 36 14.0 EVOLVABILITY . . . . . . . . . . . . . . . . . . . 36 15.0 COSTS . . . . . . . . . . . . . . . . . . . . . . 36 16.0 TIMELINESS . . . . . . . . . . . . . . . . . . . . 37 17.0 CONSTRAINTS AND TRADES-OFF . . . . . . . . . . . . 37 18.0 APPROVAL PROCESS . . . . . . . . . . . . . . . . . 37 Dynamic Library Specification Page 1 PRODUCT SUMMARY 28 May 88 1.0 PRODUCT SUMMARY A "routine library" (often called simply a "library" in this document) is a group of routines and data which is intended to provide services to its caller. Because the word "library" appears so often in this document, a routine library is also sometimes called a "package." On TOPS-20, the most familiar form of library is probably the "REL library" as understood by LINK and MAKLIB. A "dynamically linked library" (often called simply a "dynamic library" in this document) is a library which is merged into a program on request at execution time. This document describes a dynamic library system for TOPS-20. This system provides the following benefits as compared to REL libraries: o Provide a discipline for independently-developed packages to share a process peacefully while providing access to the resources they need to do their jobs (resources that require discipline to share successfully include address space, the APR trap system, and the software interrupt system). o Easier software updates. A new version of a package implemented as a dynamic library can be introduced into all programs calling it by simply placing it on the directory from which dynamic libraries are loaded. There is no need to relink programs using it. o More consistent program behavior. If a facility is always provided by the same package of code, then it will always be provided in the same way. o More efficient use of physical memory and swapping space. If a facility provided by a dynamic library is never called during a run of a program, that library will never become part of that process' address space. If several programs are using the same dynamic library, they will share a single copy of its "pure" parts. o Lower cost of engineering other products. Using an existing package to provide a service is much cheaper than having to modify it or write one from scratch. The code to perform dynamic library invocation and related functions will reside in a special dynamic library called the RTL (run-time library). 2.0 TERMINOLOGY AND CONVENTIONS This document specifies the "dynamic library mechanism," which we define as "that which causes a library to be merged into a program on request, and performs other functions necessary to make that useful." To avoid Dynamic Library Specification Page 2 TERMINOLOGY AND CONVENTIONS 28 May 88 confusion, I will from now on call this "DYNLIB." In the rest of this document, when I refer to a "dynamic library" I am referring generically or specifically to some library designed to be called through the services provided by DYNLIB. DYNLIB has associated with it some special facilities for handling traps and interrupts, allocating memory, and performing other tasks necessary to allow many packages to co-exist peacefully in a single process. These facilities are also specified in this document. They are SIG for signalling and condition handling (including interrupt and trap handling), MEM for memory management and section allocation, and RTL for other utility functions (message formatting and printing, etc.). Related to DYNLIB are some rules that must be followed by writers of libraries to be called through DYNLIB. These appear in this document in a paragraph by themselves, beginning with "DYNLIB use rule:". The full set of rules for writing a dynamic library will be documented as part of the development effort of this project. A "OWL/GBP" is a one-word local/global byte pointer, which is interpreted as follows: If it has the form of a one-word global byte-pointer, then it is interpreted as one. If it has the form of a local byte-pointer, then it is interpreted as pointing into the section of memory from which it is fetched. This is equivalent to being able to set an "IFIW" bit in the byte pointer word (which is unfortunately not supported). The GETBP macro in DYNSYM.UNV performs this operation. 3.0 ENVIRONMENT 3.1 Users Dynamic libraries will be written primarily by Digital engineers. Moderately sophisticated customer system programmers may occassionally be called upon to write dynamic libraries, as may Digital software specialists. Dynamic libraries will (eventually) be used implicitly by most higher-level language programs, but this should be transparent to the users. Both application and system programs are likely to invoke dynamic libraries explicitly. Digital-written utilities will also use dynamic libraries extensively. 3.2 Hardware DYNLIB will run on a PDP-10 family processor with extended addressing (i.e. KL model B). KS processors will not be supported. Dynamic Library Specification Page 3 ENVIRONMENT 28 May 88 No microcode changes will be required for DYNLIB. As described below, DYNLIB will encourage the use of extended addressing. Some dynamic libraries may require fixes for extended addressing bugs. This will be the responsibility of the project that produces the dynamic library in question. 3.3 Software 3.3.1 Other Software Required For DYNLIB DYNLIB requires TOPS-20 release 5.1 or later. In a future release of the operating system, support for DYNLIB should be built in. This is discussed under Evolvability. Operating system support of DYNLIB is not a goal of this project. 3.3.2 Other Software That Requires DYNLIB DYNLIB is required for Datatrieve-20 V1.0, dynamic extended RMS (V3), and dynamic callable DBCS (V7) (Dynamic MTHLIB is being produced as part of the Datatrieve project.) All other software projects should consider if they would benefit from using DYNLIB. Language systems should consider invoking their OTS' through DYNLIB. Languages calling SORT, DBCS, and RMS should consider calling them through DYNLIB. 3.4 Services No special services are required for DYNLIB. 4.0 SOFTWARE CAPABILITIES The basic capability of DYNLIB is to map in an EXE file containing some package of code at the time a call is made to it. There are some additional functions associated with this part of DYNLIB, but the bulk of the routines described in this section are actually support routines -- they don't directly assist DYNLIB, but they make it possible to write packages of code that will work together without interference in the DYNLIB environment. These support routines are the complicated part of the project. Please pay close attention to the descriptions of their capabilities and restrictions. Dynamic Library Specification Page 4 SOFTWARE CAPABILITIES 28 May 88 4.1 Streaming "Single-stream" libraries are those like the current SORT which can only handle one stream of operations at a time, but which have a user interface such that you make more than one call for that single stream (some sort of state information is preserved between calls). "Non-streamed" libraries are those like, perhaps, the MTHLIB, which can only handle one stream of operations, but where this doesn't matter to anybody because there is only one call made to perform the operation. There is no "state" saved across calls to these libraries. Note that to really qualify in this category a library must be fully reentrant. "Multi-streamed" libraries are those like callable Datatrieve which support several concurrent streams of operations. This classification can be further divided into "infinitely multi-streamed," where it should always be possible to start another stream, and "limited multi-streamed," where you could easily run out of streams. Where "multi-streamed" is used without qualification, "infinitely multi-streamed" should be assumed. DYNLIB supports non-streamed and infinitely multi-streamed libraries. If a caller attempts to initialize a new LDLBLK to a library that has its busy bit set, a DYNLIB error will be returned. If a library receives a request to start a stream which it is unable to honor, this same error should be signalled by the library. 4.2 The Run-time Library The run-time library (RTL) is a special library that contains the DYNLIB code and associated facilities (memory management, signalling). This is an appropriate place to put generally useful routines that aren't big enough to rate their own library. The MTHLIB has been included in the RTL, for example. 4.3 Dynamic Invocation Of Libraries Most calls for DYNLIB services will be made implicitly, by referring to an address exported from a dynamic library (routine entry point or "galactic variable"). 4.3.1 Calling A Routine In A Dynamic Library To be able to call routines in a dynamic library, you must: 1. Be running in a non-zero section 2. Have a global-format stack pointer in AC17 Dynamic Library Specification Page 5 SOFTWARE CAPABILITIES 28 May 88 3. Have declared as EXTERNAL in your program the names of the routines you wish to call 4. Have linked your program with a library-specific REL file for each of the libraries you call directly (you do not need to consider libraries that may be called by libraries you call) 5. Have linked your program with DYNBOO.REL There are two defined types of library-specific REL file that may be associated with a dynamic library. The normal type is called an "LDLBLK file"; it contains simply the definition of the LDLBLK. The alternative type is called an "LDLJCK file"; it contains definitions of jacket routines for each routine in the library. It may also contain an ordinary LDLBLK with galactic variable information only. Suppose the dynamic library EXAMPL contains a routine RNDNAM. The argument-passing rules for this routine and what registers it preserves are of no concern to DYNLIB (although they must, of course, be agreed between the routine and its caller). To call this routine from MACRO using the LDLBLK file, you must set up the arguments as specified for the routine, and then PUSHJ P, @RNDNAM## This is the normal way of calling a routine in a dynamic library. To call this routine from MACRO using the LDLJCK file, you must set up the arguments as specified for the routine, and then PUSHJ P, RNDNAM## Note the lack of indirection. When converting an existing program, or a program written in a higher-level language, to use dynamic libraries, this mode can be essential. There is no reason for preferring this mode of call in a newly-written MACRO program, and some performance reasons for avoiding it. You may use any number of levels of indirection in the instruction that calls a routine in a dynamic library. It is also perfectly acceptable for the PUSHJ instruction to be XCT'd from somewhere else. However, the EA calc should not depend on the values in the AC's (so don't use indexing, and don't indirect through an AC). Normally, the names for the routines in the LDLJCK file and the names for the transfer vector locations in the LDLBLK file will be the same. Thus, they cannot both be used in the same program. A technique for making it possible to use both calling conventions in a single program is described below. 4.3.2 Referring To A Galactic Variable To refer to a data location in another library, you must: Dynamic Library Specification Page 6 SOFTWARE CAPABILITIES 28 May 88 1. Be running in a non-zero section 2. Have declared as EXTERNAL in your program the names of the galactic variables to which you wish to refer 3. Have linked your program with a library-specific REL file for the library which defines the galactic variable to which you wish to refer To refer to the galactic variable, make an indirect reference through a "local galactic vector" (like a transfer vector, but the things it points to aren't routine entry points) which is provided by the library-specific REL file mentioned above. The method of referring to a galactic variable is the same whether the LDLBLK file or the LDLJCK file is used. There is no provision for referring to galactic variables in languages that do not support the concept of the indirect reference. In version 1 of DYNLIB, referring to a galactic variable before the library which defines it is loaded (either by explicit call to DYNLIB, or by calling a routine in that library) is an error. 4.3.3 Errors Occurring During Dynamic Loading There are three ways errors occurring during dynamic loading are handled, depending on the exact conditions. If the library being loaded is the RTL, an error message is printed on the terminal. This is done to minimize the size of the DYNBOO bootstrap routine. All the code for the fancy error handling described below is contained in the RTL, which is by hypothesis not available in this situation. If the instruction which caused dynamic loading is immediately followed by an ERJMP or ERCAL instruction, control is transferred to the location specified. T1 will contain the address of an SG block chain describing the error. T0 will be trashed. Other registers will be preserved if so specified for the routine being called. or can be determined by calling the DYNLER routine, which returns the signal block for the last error that occurred. If the instruction which caused dynamic loading is not immediately followed by an ERJMP or ERCAL instruction, a signal is generated for the error. This may either be handled by a user error handler, or ignored; if it is ignored, the last-ditch handler will handle it. For dynamic library loading errors, its handling is to print a message describing the error and abort the program. Dynamic Library Specification Page 7 SOFTWARE CAPABILITIES 28 May 88 4.4 Memory Allocation The RTL will contain the master section allocator, and a basic memory manager. All sections must be allocated through the section allocator. An allocated section is managed by its allocator. One alternative it has is to manage it itself. Another is to request that the RTL memory allocator do so for it. DYNLIB use rule: All sections used must be allocated by the DYNLIB section allocator. DYNLIB use rule: Memory in a section may not be used without the "permission" of the allocator of that section. That is, any sort of cooperative arrangement is fine, but in the absence of agreement, keep your fingers in your own sections! Signal blocks must be allocated by the RTL memory allocator, so that they can be released by the SIG facility. A future version of the RTL must support allocation of groups of contiguous sections. Support for a user-written section allocator is also desirable (and seems easy). 4.5 Signalling And Condition Handling To attain the goals of a truly layered product environment, the facilities of the interrupt system and of trapping must be available to each package called by a process, without a package having to worry about which other packages are being used. DYNLIB use rule: user programs may not directly manipulate the APR trap system (in particular, they may not use the APR trap function of the SWTRP% JSYS). User programs should get APR trapping services by using the JOV or other JFCL-class instruction after the instruction they wish to check for overflows, or by handling the condition generated in the absence of JFCL-class instructions. DYNLIB use rule: user programs should not directly manipulate the software interrupt (PSI) system except for assigning events to channels allocated from DYNLIB and handling those interrupts. They should never perform interrupt-specific JSYSes other than DEBRK%. There are two asynchronous types of activities that must be supported. One is asynchronous events requiring attention from the package that started them. These occur as a normal part of processing, are of interest only to the package that initiated the activity, and must be quite quick. This mechanism will be called "layered interrupts". The other is exception (error) conditions generated by the users' code and requests. These occur relatively rarely, and quite often result in an error which is of interest to other packages than the one generating the condition. The occurrence of these conditions need not be Dynamic Library Specification Page 8 SOFTWARE CAPABILITIES 28 May 88 blindingly fast. This mechanism will be called "condition handling." This facility, and the code making it up, is referred to as "SIG" throughout this document. 4.5.1 Layered Interrupts This mechanism is intended for servicing of asynchronous events that belong to a particular package. These are handled by user-specified interrupt handlers at interrupt level. The user allocates a channel from SIG, and attaches conditions to the channel himself. 4.5.2 Condition Handling This mechanism is intended for information of general hierarchical use, particularly for error or exception information. This mechanism is modeled after the signalling / condition handling facilities in BLISS-36, VAX/VMS, and RSX-11. Conditions may be signalled by user software by making a call to a SIG routine. In addition to this use, all events made available by TOPS-20 through APR traps or interrupts will be turned into signals by the SIG facility (APR traps only in V1). To handle conditions, a routine must identify its handler to SIG. Conditions that aren't handled by any level will be dealt with by the "last-ditch" handler. SIG will maintain a list of handlers established. When a condition is signalled, the handlers will be called in order from most recently established to oldest, until one of them handles the situation (see discussion of handler options below). There is no facility for a package to grab complete control of some category of signal; this would violate the hierarchical layering. Because this facility is based on the existing PSI and SWTRP mechanisms, there are some restrictions on the user handlers. In particular, some of them must run at interrupt level. Here are the types of events signalled, the level at which handlers for them must run, and the default actions if they are not handled: Description Level Default Continuable ---------- ----- ------- ----------- APR normal fixup and signal Yes data error interrupt message and exit Yes disk quota interrupt message and exit Yes end of file interrupt message and exit Yes illegal inst. normal message and exit Restarts instr illegal read normal message and exit Restarts instr Dynamic Library Specification Page 9 SOFTWARE CAPABILITIES 28 May 88 illegal write normal message and exit Restarts instr inferior stop interrupt continue Yes non-exist. page interrupt create, continue Yes PDL overflow normal message and exit Yes software signal normal message & continue Yes or exit (based on severity) system resourc. normal message and exit Yes character interrupt ^C exits, Yes others ignored terminal interrupt ignored Yes (carrier transition, break, input available) When a handler is entered for a signal, it has the following options: re-signal from current position, continue interrupted code, unwind to its establisher's caller. A handler must also receive the unwind signal and do appropriate things with it (in particular, it must free dynamic resources that its establisher allocated). The continue option is only available for software signals, signals originating as traps, and signals originating as interrupts that are handled at interrupt level. There are some restrictions on the linkage conventions of routines which must enable for condition handling: o The routines must be running in a non-zero section at the time they enable, and at any time their handlers are invoked o There must be a global-format stack pointer in AC17 with sufficient space available o The routines must be called with PUSHJ 17, adr. o The routines must return a value in AC0. It is this value that may be specified in the unwind call A routine need not be in a dynamic library to enable for condition handling. It can be part of a top-level program or a library called in some other way. A signal block (or error block) will have a fixed heading, including facility identification, condition identification, severity identification, print flags, message text, and pointer to next block. It will contain a pointer to a block containing condition-specific data. The normal appearance of a signal is as a chain of these error blocks. The first one in the chain is the most recent, and for most things is the only one that needs to be examined. However, for error message printing, and for more detailed analysis of a situation, the earlier blocks are available. One of the print flags will indicate that a block is for computer use only, that no message should be printed. Dynamic Library Specification Page 10 SOFTWARE CAPABILITIES 28 May 88 4.5.2.1 Fixed interrupt channels Events that are assigned by TOPS-20 to fixed interrupt channels will be turned into signals by the SIG facility (not in V1). Illegal instruction interrupts can result from monitor call errors. The interrupt will only occur if there is not an ERJMP or ERCAL instruction after the JSYS that failed. The signal block generated for illegal instruction interrupts will include as its message the text of the monitor error message for the JSYS failure. 4.5.2.2 APR traps APR traps will generate signals unless the instruction producing the trap is followed by some flavor of JFCL instruction. The default handling of the signal will be to perform the MTHTRP fixup, print a message, and then continue. An alternative method of handling APR traps (and interrupts from fixed interrupt channels) is discussed under "Performance Considerations", below. 4.5.2.3 Character interrupts General handling of character interrupts won't be provided in the first version. It will probably never be provided. What will be provided is likely to be good enough for everybody. There will be two parts to using character interrupts: defining a character as in interrupt (as opposed to a normal) character, and processing the signal when it comes by. Receiving character interrupt signals is the same as receiving any other signals. There will be a word of signal-specific data giving a mask of the characters that could have caused this signal (combining interrupt characters is discussed directly below, and elsewhere in the document; briefly, it is often sufficient to a program to know that SOME interrupt character, or some from a small set, was typed, and by assigning more than one character to a channel when possible the limited set of channels is conserved). Characters are defined as interrupt characters by making calls to a SIG routine giving bit masks. Each call defines a group of characters which you wish to see treated as interrupt characters. The group of characters given in a call will not necessarily be distinguishable from each other when the signal arrives. If you ask to distinguish between characters that somebody else has already asked to see combined, you lose (and get a code to that effect). As a special exception, ^C, ^T, ^A , and ^Y will never be combined with anything else, although you can request them in combination with other things. (The exact list of characters given this special treatment is Dynamic Library Specification Page 11 SOFTWARE CAPABILITIES 28 May 88 certainly open to debate. It has no particular impact on performance or development time.) At a future date, the software handling this could be re-written to optimize assignment of groups of characters to channels so as to allow you to see any combination you want, subject to the availability of channels. This is not a requirement of any software we know. This extension would only be implemented if required by some future software. Its implementation would be transparent to existing software. 4.5.3 Performance Considerations There are many packages which get called many times during a relatively short program run. For example, MTHLIB, RMS (once per record), sometimes SORT. It is important to minimize the cost of an explicit layer transition. Actual exceptions occur relatively rarely, and when they do often result in program termination or at least user interaction. Accordingly, it is not as important for the actual handling of exceptions to be fast. Trading off slower exception handling for faster layer transitions is a desirable thing to do. (Obviously in an ideal world both would take zero time. If you know how to achieve this, please come explain it to me....) The one possible exception to this is arithmetic traps. These can sometimes occur without indicating a package-level error, and thus may occur frequently in a single run. Some packages treat arithmetic traps as errors. For them, signalling the trap is fine. Some things (written in MACRO) want to test for errors immediately after the instruction that produced them. For them, we are making the default handling of a trap include a check for a JFCL-class instruction right after it. If such an instruction is present, the trap is ignored. To ease conversion of existing libraries, and improve performance of libraries depending extensively on APR traps, there is a facility for requesting that all traps originating in a given section be directed to a specified handler. This option, if invoked, completely bypasses MTHTRP fixups, signal generation, and message printing for APR traps originating in specified sections. 4.5.3.1 Arithmetic Trap Default Actions Fixups are as performed by MTHTRP. Putting a JFCL (of any flavor) after an instruction that may cause an overflow will work normally (MTHTRP looks for them). In the absence of a JFCL, after determining the error and possibly fixing things up MTHTRP generates a signal. If this signal isn't intercepted, the last-ditch handler will print the message it describes. Dynamic Library Specification Page 12 SOFTWARE CAPABILITIES 28 May 88 4.6 Errors And Message Printing The signal block contains information to make printing error messages as easy as possible -- for example, facility names and error messages are present as text, so no decoding is necessary. There are also print flags in the blocks, specifying any special aspects of that block (such as a block which is for computer use only, contains no message, and should not be printed at all). A routine is provided for printing the messages from some initial segment of the signal blocks in a chain in a uniform format. This is used by the last-ditch handler, and is recommended for use by user routines that wish to print messages. 4.7 Dynamic Library Contents A dynamic library consists of several pieces, including An EXE file which contains: o A PDV with the name "DYNLIB$class-name". Word 2 (formerly called .PVSTR) in the PDV should point to the master dynamic library block (DLBLK) for this library. Word 4, .PVVER, by convention contains the version number of the library. o The DLBLK for the library. This block describes the entry points and other exported addresses of the library. o The necessary code and data to perform the library's functions. A REL file which contains information for the caller to link with. The normal case (an LDLBLK file): o The local dynamic library block (LDLBLK) for the library. This block describes the entry points and other exported addresses of the library and contains the address vectors through which references to the actual library objects are made. A special case, useful when converting callers of existing libraries or making the calls from higher-level languages that don't support the concept of pointers to routines (an LDLJCK file): o The local dynamic library block (LDLBLK) for the library. This block describes the entry points and other exported addresses of the library and contains the address vectors through which references to the actual library objects are made. Dynamic Library Specification Page 13 SOFTWARE CAPABILITIES 28 May 88 o A jacket routine for each routine in the library. This routine expects to be called by a simple PUSHJ. It then calls the routine in the library through the transfer vector. 4.8 Writing Dynamic Libraries A library is put together from four parts: 1. The code and data to perform the library functions 2. A definition of the library entry points and characteristics 3. A LDLBLK file 4. A LDLJCK file Parts three and four can (and should) be built automatically from part one by using the $DLBLK, $LDLBLK, and $LDLJCK macros from DYNSYM.UNV. Note that making an existing library into a dynamic library can sometimes be fairly easy, requiring only the production of a library definition. 4.8.1 The Library Definition The library definition provides one place to put all the declarations relating to the dynamic library and its exported addresses. This makes for easy reference, and fewer mistakes since all places using this information get it from the definition. The definition must specify: o Library name -- must be a valid MACRO name o Library abreviation -- two characters o Library macro name -- must be a valid MACRO name o Library version -- TOPS-20 version number word o Default version matching rule for this library o Service class name -- quoted string o File spec for library EXE file -- quoted string o List of DIGITAL-specified entry point names in their specified order. Each entry in this list may be either a single name, or a sublist as follows: 1. Name for this exported address (routine or galactic variable) 2. Jacket entry name for routine (defaults to same as address name) 3. Condition handling flag (defaults to off) All of the entry points defined by DIGITAL must be present, or an error will be issued when you compile the definition. Dynamic Library Specification Page 14 SOFTWARE CAPABILITIES 28 May 88 o List of library-specific entry point names. Same rules as for previous entry o List of DIGITAL-specified galactic variable names in their specified order. All of the galactic variables defined by DIGITAL must be present, or an error will be issued when you compile the definition. o List of library-specific galactic variable names o Value to statically initialize user word in DLBLK to o Value to statically initialize user word in LDLBLK to o Value to statically initialize flag word in DLBLK to o Value to statically initialize flag word in LDLBLK to 4.8.2 The LDLBLK File For each library, there must be a source file to build the LDLBLK file. Its contents should be as follows: SEARCH DYNSYM, library-sym $LDLBLK library-macro END 4.8.3 The LDLJCK File For each library, there must be a source file to build the LDLJCK file. Its contents should be as follows: SEARCH DYNSYM, library-sym $LDLJCK library-macro [, just-routine-jacket-flag] END If the just-routine-jacket-flag is set, the LDLJCK file will contain only the routine jacket information and will need to be loaded along with the LDLBLK file. Furthermore, in this case you must have specified alternate names for all the LDLJCK routine entry points, or else you will have multiply defined global symbols when you link your program. (The just-routine-jacket-flag is not supported in V1.) 4.8.4 Master Initialization The master init routine of a library should, when called, set that library to a clean state. A freshly master initialized library should behave exactly as if a clean copy had been loaded. One of the most important things to do in the master initialization routine is to properly initialize the memory allocation tables. This should be done by using a static data structure made at the time the library was built. Attempting to snoop for free pages in the master initialization routine won't work, since pages used during a run will not be free, and yet should become available after master Dynamic Library Specification Page 15 SOFTWARE CAPABILITIES 28 May 88 initialization. The master initialization routine should not do a RESET% JSYS, that will be done by the top-level program. The master init routine is called with a PUSHJ 17, adr. It may trash all registers. Arguments: None Return values: 1. Completion status. 0 means OK, anything else means failure. A master init routine may also signal a condition that indicates failure. Error conditions: library-dependent 4.8.5 Condition Handling Routines A condition handler is called with a PUSHJ 17, adr. It may use all registers. Arguments: 1. Address of SIG block for signal to handle. If the signal is of class SG%UNW, the handler is expected to perform any necessary cleanup and then exit. No value is returned in this case. If the signal is of any other class, the handler is expected to decide what should be done about the condition, and indicate this to SIG by its return value. Return values: 1. AC0 is the value to be returned by this handlers establisher (ONLY IF AC2 CONTAINS .HNUNW) 2. AC1 is the signal block to pass upwards (ONLY IF AC2 CONTAINS .HNRES) 3. AC2 is the action code describing what action to take: o .HNUNW -- unwind. This causes a return from the establisher of this handler to the caller of the establisher, passing in AC0 the return value specified now in AC0. o .HNCON -- continue. This ends condition handling and causes processing to continue from after or at the instruction that initiated the signal. Dynamic Library Specification Page 16 SOFTWARE CAPABILITIES 28 May 88 o .HNRES -- resignal. This passes the same or a modified condition on to any higher-level condition handlers. In general, a signal block should not be modified unless you own it; to resignal a different condition than the one you received, make a new signal block containing what you want to say, and set its .SGNXT pointer to the block you received. 4.9 Details Of Data Structures 4.9.1 The Dynamic Library Block 1. .DYCNT -- block word count (must be 9 currently) 2. .DYFVN -- Block format version number 3. .DYFLG -- Flag word (DIGITAL defined only) 1. DY%BSY -- Busy: library can't start a stream 2. DY%VER -- Version matching rules. Version number from DLBLK in this library is compared to version number in LDLBLK and this library is accepted if: 1. DY%MAG -- major version of library greater than major version of LDLBLK 2. DY%MAL -- major version of library less than major version of LDLBLK 3. DY%MIG -- major versions equal and minor version of DLBLK greater 4. DY%MIL -- major versions equal and minor version of DLBLK less 4. .DYUSR -- Library-use word 5. .DYVER -- Library version number 6. .DYDTV -- IFIW Address of DIGITAL-specified entry-point vector (DTVEC) 7. .DYCTV -- IFIW Address of library-specific entry-point vector (CTVEC) 8. .DYDGV -- IFIW Address of DIGITAL-specified galactic variable vector (DGVEC) 9. .DYCGV -- IFIW Address of library-specific galactic variable vector (CGVEC) [The possibility of additional entries is reserved to DIGITAL] For each of the four classes of exported addresses described above, there is a separate address vector. Each is a counted vector. DTVEC: diglen+1 IFIW routine entry-point . . . IFIW routine entry-point CTVEC: cuslen+1 IFIW routine entry-point Dynamic Library Specification Page 17 SOFTWARE CAPABILITIES 28 May 88 . . . IFIW routine entry-point CGVEC: cgalen+1 IFIW address . . . IFIW address 4.9.2 The Local Dynamic Library Block This block is linked into a calling program from a library-provided REL file. It provides the section-local indirect words necessary for referring to addresses in other sections. It also provides the information to identify and map in the library being called, if necessary. 1. .LDCNT -- Word count (block length) (must be 11 currently) 2. .LDFVN -- DYNLIB version number for which this LDLBLK was compiled 3. .LDFLG -- Flag word (DIGITAL-defined only). Flags defined are: 1. LD%VMA -- Use version match rules from this LDLBLK rather than from DLBLK 2. LD%VER -- Version matching rules. Version number from DLBLK in library found is compared to version number in this LDLBLK and that library is accepted if: 1. LD%MAG -- major version of library greater than major version of LDLBLK 2. LD%MAL -- major version of library less than major version of LDLBLK 3. LD%MIG -- major versions equal and minor version of DLBLK greater 4. LD%MIL -- major versions equal and minor version of DLBLK less 3. LD%INI -- Initialized: library has been loaded and vectors updated 4. .LDUSR -- User word; may be set by calling program in any way it wants 5. .LDCLS -- OWL/GBP to "service class" string 6. .LDSPC -- OWL/GBP to file spec string 7. .LDVER -- Library version number 8. .LDDTV -- IFIW Address of DIGITAL-specified entry-point vector (LDTVEC) 9. .LDCTV -- IFIW Address of library-specific entry-point vector (LCTVEC) 10. .LDDGV -- IFIW Address of DIGITAL-specified galactic vector 11. .LDCGV -- IFIW Address of library-specific galactic vector (LCGVEC) [The possibility of additional entries is reserved to DIGITAL] Dynamic Library Specification Page 18 SOFTWARE CAPABILITIES 28 May 88 As in the DLBLK, there is a transfer vector for each of the four classes of exported addresses described above. 4.9.3 The Signal Block This data structure represents one level of a signal in progress. The top (most recently added) level of a signal in progress is supplied to routines. Lower levels are available by following the pointer to next block. All of the pointers are expected to point either into the signal block, or into static storage (which need not be released when the signal block is released). The pointers may not point into stack storage, as this may have been released by the time the pointer is used! Block contents: 1. .SGCC -- Condition code 2. .SGNXT -- xFIW address of next block 3. .SGFAC -- OWL/GBP to ASCIZ facility name 4. .SGCND -- OWL/GBP to ASCIZ condition name 5. .SGMSG -- OWL/GBP to ASCIZ message 6. .SGPC -- PC of source of signal 7. .SGCLS -- Class of condition (bit mask) o SG%UNW -- Unwind o SG%APR -- APR trap o SG%DER -- Data error interrupt o SG%QUO -- Disk quota interrupt o SG%EOF -- End of File interrupt o SG%ILI -- Illegal instruction interrupt (or monitor call error) o SG%ILR -- Illegal memory read interrupt o SG%ILW -- Illegal memory write interrupt o SG%INS -- Inferior stop interrupt o SG%NXM -- Non-existent page interrupt o SG%PDL -- PDL overflow interrupt (not useful?) o SG%SOF -- Software-originated signal o SG%RES -- System resources interrupt o SG%CHR -- Character interrupt o SG%TRM -- Terminal interrupt 8. .SGFLG -- flag word (DIGITAL-defined only) o SG%INT -- At interrupt level o SG%NPR -- Do not print this block (computer use only) o SG%DYN -- This block is dynamic and may be thrown away 9. .SGDAT -- xFIW address of signal-specific data, such as: o Character mask for character interrupt o Values involved for APR traps o Page number for nonexistent page traps o Stack pointer for stack overflow traps o User data for software signals Dynamic Library Specification Page 19 SOFTWARE CAPABILITIES 28 May 88 4.9.4 The Condition Code A condition code is a one-word representation of the raw bones of a condition. It is essentially the same as a BLISS-36 condition code. SG%FAC SG%MSG SG%SEV +---+---------------------------+---------------------------+---+ | | | | | +---+---------------------------+---------------------------+---+ 0 0 0 1 1 3 3 3 0 3 4 7 8 2 3 5 Bit 4 (SG%FCD) is set if the facility is customer-defined, clear if DIGITAL-defined. Bit 18 (SG%MCD) is set if the message is customer-defined, set if DIGITAL-defined. SG%ID covers the full condition ID, bits 4-32. SG%SUC is the success bit (35). 4.9.5 The Handler Block A handler block is the set of information describing an establishing of a handler. It is the argument passed to the SIGEST routine. This block may be dynamically allocated, but it must remain in existence (in the same place) throughout the life of the handler it describes. 1. .HNHND -- xFIW address of handler 2. .HNCLS -- Enable mask (see bit definitions above) 3. .HNCIM -- Character interrupt mask 4. .HNUDA -- xFIW address of user data 5. .HNLEN -- Size of block in words 4.10 Details Of Explicit Calls There are many functions that the user may request DYNLIB and related facilities to perform. These functions are implemented in the run-time library; they are called as any dynamic library routine. Unless specified otherwise, errors are reported by signalling. This signal can be prevented by placing an ERJMP or ERCAL instruction immediately following the potentially offending instruction (and in this case the address of the signal block is returned in AC1). The calling sequence for these routines is as follows: Arguments go in sequential registers starting with AC1. Return values go in registers sequentially following the arguments, unless specified otherwise (such as updated values of input arguments). The routines should be called as ordinary routines in a dynamic library -- with PUSHJ P, @routine-name. Dynamic Library Specification Page 20 SOFTWARE CAPABILITIES 28 May 88 Registers 6-17 are preserved unless otherwise specified. 4.10.1 Return Last DYNLIB Error -- DY$LER (Not in V1) Returns the address of the signal block (first of chain) describing the last DYNLIB error, or 0 if no error has been detected. This signal chain is dynamically allocated; if another DYNLIB error occurs between the time you get the information and the time you use it, it will be invalid. You should not attempt to de-allocate this block. Arguments: None Return values: 1. Address of signal block (first of chain), or zero if no error occurred Error conditions: None 4.10.2 Force Loading/Overloading -- DY$LOD (Not in V1) Force the loading of a dynamic library before a reference to an address exported from it occurs. This could be useful, for example, to cause the loading of a library containing a galactic variable you need to reference when there are no routines in that library, or none that you want to call. This call also supports overloading -- deliberately loading information about two libraries into one LDLBLK. This can be useful to replace a few routines in a library with private copies, without having to duplicate the entire library. These private copies could be debugging versions of routines not yet ready to be included in the real library, for example. Arguments: 1. Function 1. .DYLOD -- Force loading of library. This function cannot be applied to the run-time library. 2. .DYOLB -- overload one library onto another 3. .DYOVC -- overload one vector onto another Dynamic Library Specification Page 21 SOFTWARE CAPABILITIES 28 May 88 Other arguments depend on the function code. The normal rules for overloading are as follows: 1. LTVEC entries not containing their default initial state will not be altered. The default initial state is "IFIW LDLBLK-1" for the user-mode implementation. 2. If an MTVEC entry contains 0 in its right half, the corresponding LTVEC entry is not altered. 0 in the right half covers IFIW 0 and location 0 in any section. 3. If the LTVEC is longer than the MTVEC, excess LTVEC locations are not altered. 4. If the MTVEC is longer than the LTVEC, the additional MTVEC entries are ignored. 4.10.2.1 .DYLOD -- Force loading of library Additional arguments: 1. Address of the LDLBLK of the library to load Error conditions: o Any error possible when implicitly loading a dynamic library 4.10.2.2 .DYOLB -- overload one library onto another Load one library over another according to the rules for overloading. Standard version checking is performed on both DYNLIB and library versions for both source and destination libraries. Arguments: 1. Address of LDLBLK of source library (need not be already mapped in) 2. Address of LDLBLK of destination library (need not be already mapped in) Error conditions: o Any error possible when implicitly loading a dynamic library Dynamic Library Specification Page 22 SOFTWARE CAPABILITIES 28 May 88 4.10.2.3 .DYOVC -- overload one vector onto another This function is used to overload only one address vector from one library over another. Standard version checking is performed on both source and destination libraries. Arguments: 1. Address of LDLBLK of source library 2. Address of source vector 3. Address of LDLBLK of destination library 4. Address of destination vector Error conditions: o Any error possible when implicitly loading a dynamic library may occur 4.10.3 Global Master Initialization -- DY$MIN Resets all libraries already mapped in to their uninitialized state by calling the master initialization point in each such library. All registers are trashed. Arguments: None Error conditions: o Any error condition signalled or returned in the defined manner by any of the master initialization routines called is passed on to the caller of DY$MIN. 4.10.4 Allocate Memory Block -- ME$ALM Allocate a block of memory without page alignment. Arguments: 1. Chunk identifier 2. Block size in words Return values: 1. (in T1) Chunk identifier Dynamic Library Specification Page 23 SOFTWARE CAPABILITIES 28 May 88 2. (in T2) Address of block allocated Error conditions: o No room in chunk specified for block requested o Chunk specified is invalid The block returned starts at the address given and is the length specified. The words preceeding and following the block contain RTL information used when the block is released. Since this word is not part of the block given you, it should be no strain to keep your hands off it! 4.10.5 Allocate Pages Of Memory -- ME$ALP (Not in V1) Allocate memory in full, contiguous pages. Arguments: 1. Chunk in which to allocate 2. Number of pages to allocate Return values: 1. Address of first page allocated Error conditions: o Section not under control of RTL o Space requested not available in section requested 4.10.6 Create A New Section -- ME$ALS (Not in v1) Allocates a free section and creates it (the monitor doesn't automatically create a section when you first refer to an address in it, as it does for individual pages within pre-existing sections). Optionally, puts the newly-created section under the control of the RTL memory manager. Dynamic Library Specification Page 24 SOFTWARE CAPABILITIES 28 May 88 This is the only valid way to create a section in the DYNLIB environment. (The section that a new dynamic library is mapped into is allocated through ME$ALS by DYNLIB.) This should probably be extended to allocate groups of contiguous sections. Arguments: 1. Set if section should be controlled by the RTL memory manager Return values: 1. Number of the section allocated Error conditions: o No sections available 4.10.7 Return Memory Block -- ME$DLM Return a block of memory allocated with ME$ALM. Arguments: 1. Address of block to return Return values: None Error conditions: o ME$NAL: Block wasn't allocated 4.10.8 Return Memory Pages -- ME$DLP (Not in V1) Arguments: 1. Address of first page 2. Number of pages Return values: None Dynamic Library Specification Page 25 SOFTWARE CAPABILITIES 28 May 88 Error conditions: o Section not under control of RTL o Some or all of the pages being returned were not allocated 4.10.9 Destroy A Section -- ME$DLS (Not in V1) Sections not under the control of the RTL memory manager are destroyed immediately on request. Sections controlled by the RTL memory manager are "frozen" on this call -- no more space will be allocated out of them. They will be destroyed when all of the space allocated from them is returned. This needs support for groups of sections (as in ME$ALS). Arguments: 1. Section number Return values: None Error conditions: o Section is not allocated 4.10.10 Sub-contract Memory Management -- ME$MEM Create a memory chunk that can be allocated from. Arguments: 1. Address of first word of chunk 2. Address of last word of chunk Return values: 1. Chunk ID in T3 Error conditions: o ME$NCA: No chunk ID available Dynamic Library Specification Page 26 SOFTWARE CAPABILITIES 28 May 88 4.10.11 Formatted ASCII Output -- RL$FAO Format a message given a model string and some arguments to fill in from. Arguments: 1. Destination string pointer 2. Max allowable destination string length 3. Model (pattern) string pointer 4. Address of first arg (others follow at higher addresses). Note that this may be on the stack, or elsewhere; FAO doesn't care 5. Count of args Return values: 1. Destination pointer is updated in T1 2. Count is decremented in T2 3. T3-T5 are trashed The pattern string is a simple ASCIZ string with special escape sequences in it that cause substitution from the list of arguments. Each argument is used at most once, in the order listed. All escape codes begin with an exclamation point. The codes and their meanings are: !/ Put a CRLF into output !_ Put a TAB into output !! Put an exclamation mark into output !^G Put a BEL into output (ASCII 7, not G) !OW Put next arg to output as octal word !SW Put next arg to output as signed decimal word !OH Put next arg to output as octal halfwords (good for PC's) !AA Put 7-bit ASCIZ string at address given by next arg to output !AZ Put ASCIZ string pointed to by next arg to output !AC Put string pointed to by next arg to output, max of next arg chars !%S Put capital S to output if last number printed was not 1 !%s Put lower case s to output if last number printed was not 1 !JFN Put file spec corresponding to JFN in next arg to output !VER Put next arg to output interpreted as version number !JER Put JSYS error text for error code in next arg to Dynamic Library Specification Page 27 SOFTWARE CAPABILITIES 28 May 88 output 4.10.12 Allocate An Interrupt Channel -- SG$ALC (Not in V1) Arguments: None Return values: 1. Channel assigned Error conditions: o No interrupt channels available 4.10.13 Disable Interrupt Characters -- SG$DIC (Not in V1) Requests that a character be made a non-interrupt character. Note that the count of enable versus disable requests is what controls the actual status of a character at any given moment Arguments: 1. Character mask Error conditions: None 4.10.14 Return An Interrupt Channel -- SG$DLC (Not in V1) Arguments: 1. Interrupt channel to return Return values: None Error conditions: o The interrupt channel returned was not allocated Dynamic Library Specification Page 28 SOFTWARE CAPABILITIES 28 May 88 4.10.15 Deallocate A Signal Chain -- SG$DLG Deallocate all blocks in a signal chain flagged as dynamic. Arguments: 1. Address of first block in chain Return value: None Error conditions: o ME$NAL: Block not allocated (for any block along the chain) 4.10.16 Dump An SG Chain -- SG$DMG Print a formatted dump of a chain of SG blocks on the terminal. Arguments: 1. Address of first block in chain Return Value: None Error conditions: None 4.10.17 Enable Interrupt Characters -- SG$EIC (Not in V1) Requests that a set of characters be made interrupt characters. The count of enable versus disable requests is what controls the actual status of a character at any given moment. Arguments: 1. Character mask Return values: None Error conditions: o Insufficient interrupt channels available o Cannot isolate characters you want from previous requests Dynamic Library Specification Page 29 SOFTWARE CAPABILITIES 28 May 88 4.10.18 Establish A Condition Handler -- SG$EST Establish a condition handler for the current routine. SIGEST must be called before anything is done to the stack within the routine. For non-macro programs, the technique for establishing is to make a jacket routine that performs this call. This is done automatically when you set the "jacket" flag in the library definition for this routine. (Not in V1) There are restrictions on the linkage conventions of routines that establish handlers. ALL registers are preserved. Arguments (pushed onto the stack before call): 1. Address of handler block (this block may be dynamically allocated, but it must remain in existence throughout the life of the handler) Return values: None Error conditions: o Invalid handler block o Insufficient room on enable stack 4.10.19 Establish A Handler Locally -- SG$LES This is a version of SG$EST to be called from within BLISS routines. This routine is for use by WIZARDS only!! In particular, unwinding to a routine that enables for condition handling this way is almost certainly a mistake. Registers 2-16 are preserved. Arguments: 1. Address of handler block Return Values: None Error conditions: None Dynamic Library Specification Page 30 SOFTWARE CAPABILITIES 28 May 88 4.10.20 Remove A Handler Locally -- SG$LRM Remove a locally established handler Registers 2-17 are preserved. Arguments: 1. Address of handler block Return value: None Error conditions: o SG$ROS: Cannot remove a handler other than the most recently established 4.10.21 Make Signal Block For Last Monitor Error -- SG$MER (Not in V1) Arguments: None Return values: 1. Address of signal block created Error conditions: o No monitor error has occurred 4.10.22 Print Error Messages -- SG$PEM Prints a sequence of error messages from a chain of signal blocks. Various arguments control depth and format of printing. Arguments: 1. Destination designator 2. Address of signal block 3. Maximum depth to print messages for 4. Address of suffix list 5. Address of prefix list Dynamic Library Specification Page 31 SOFTWARE CAPABILITIES 28 May 88 The prefix and suffix lists are vectors of OWL/GBP to ASCIZ strings, intended to be indexed by severity. The strings pointed to are prefixes and suffixes for messages. Return values: None Error conditions: o Invalid signal block encountered 4.10.23 Remove A Condition Handler -- SG$REM Remove the condition handler established for the current routine. This must be done just before routine exit. All registers are preserved. Arguments (push on stack): 1. Address of handler block (must be same block passed to SIGEST) Return values: None Error conditions: o The handler being removed is not the most recently established one o Invalid handler block 4.10.24 Declare Trap Handler For Section -- SG$SEC (Not in V1) Specify an APR trap and fixed interrupt handler for all events occurring in a specified section. This is provided for convenience in converting existing libraries with their own trap handlers, and to allow use of traps in a library without the overhead of enabling for condition handling. Arguments: 1. Section number 2. Address of handler block Return values: None Dynamic Library Specification Page 32 SOFTWARE CAPABILITIES 28 May 88 Error conditions: o A handler has already been established for the section specified o The section specified does not exist 4.10.25 Signal -- SG$SIG Signal a software condition. Under some conditions, this routine does not return. This is determined by whatever handler finally handles the signal. If it does return, it returns with all registers preserved. Arguments: 1. Address of signal block Return values: None Error conditions: o Invalid signal block 4.11 Details Of Galactic Variables Defined The RTL defines some galactic variables to allow users to control certain aspects of its operation without having to make calls to special routines to set internal values. 4.11.1 Signalling Information SIG makes certain internal information available as galactic variables. 4.11.1.1 Enable stack pointer -- SG.ENS The stack pointer for the enable stack. Each frame on the enable stack holds an establish block describing one handler that is currently established. This is for use by experts only! You can cause a lot of trouble with this, if you want. 4.11.2 Last-ditch Handler Parameters Dynamic Library Specification Page 33 SOFTWARE CAPABILITIES 28 May 88 4.11.2.1 Maximum depth -- SG.LEV No more than this many levels of messages will be printed (blocks in a signal chain for which no message is printed do not count against this limit). To print "all" levels, set this to an outrageously high positive value. Signal chains should never get "too" deep. 4.11.2.2 Destination designator -- SG.OUT Last-ditch messages may be directed to places other than primary output. If attempting to output to the destination specified fails, it will be reset to primary output and the message will be printed there. Setting this to a byte pointer has some potential problems -- it doesn't get copied back to SG.OUT after it's used, so messages will overlay each other in the memory area specified. 4.11.2.3 Prefix table address -- SG.PFX The prefix table is indexed by severity to find the OWL/GBP to an ASCIZ string to print before the message. This is where the "?" before errors or the "[" before informational messages comes from. 4.11.2.4 Suffix table address -- SG.SFX Like SG.PFX, but strings go after the message. This is where the "CRLF" after errors or the "]CRLF" after informational messages comes from. 4.11.2.5 Default prefix table -- SG.DPX This is the default prefix table. By executing XMOVEI T0, @SG.DPX MOVEM T0, @SG.PFX you will reset the LDH to use the default prefix table. You should not attempt to change the contents of the default prefix table -- it may be in write-protected memory. 4.11.2.6 Default suffix table -- SG.DSX This is the default suffix table, very similar to SG.DPX. 4.12 DYNLIB Bootstrap As much of DYNLIB as possible will actually reside in the RTL. Since DYNLIB is used to bring in the RTL, "as much as possible" will be less than "all". Dynamic Library Specification Page 34 SOFTWARE CAPABILITIES 28 May 88 The subset of DYNLIB necessary to bring in the RTL will be available in the file DYNBOO. All programs calling dynamic libraries must link with DYNBOO. 5.0 PUBLICATIONS DYNLIB development will include the preparation of two documents, "How to write a Dynamic Library" and "How to call a dynamic library", intended respectively for developers of dynamic libraries and users of dynamic libraries. These documents will be prepared by the engineering staff, there is no funding for technical writers. There is no plan to distribute these documents outside of Digital. 6.0 PACKAGING The DYNLIB facility is being developed for Datatrieve. We want to make it available to all layered products in the longer run. The first release of DYNLIB will be packaged with Datatrieve-20 version 1. 7.0 INSTALLABILITY DYNLIB will be installed as part of the installation of Datatrieve-20. 8.0 EASE OF USE 9.0 PERFORMANCE Since DYNLIB is intended to be widely used as the basis for building products out of layers of building-blocks, performance can be an important issue. We believe, based on the usage of existing libraries, that the vast majority of the interactions between a caller and a package will be routine calls. Calling a routine in a dynamic library will be done with a single PUSHJ using one level of indirect addressing (unless the user writes code requiring more to get to the transfer vector) after the first call through any given LDLBLK. Referring to an exported address will simply require one additional level of indirection relative to referring to that address locally. Since indirection is necessary to reference outside of the current section anyway, DYNLIB will cost absolutely nothing on references after the first. Dynamic Library Specification Page 35 PERFORMANCE 28 May 88 The first reference to an address exported from a dynamic library will potentially take a long time, since a GTJFN% is performed. This could potentially require searching through thousands of file-names, if the logical names used are defined wrong. There is also the matter of creating a section and mapping the file into that section. On a "reasonably" heavily loaded system, and assuming only moderately perverse search lists, it could take 5 seconds to load a dynamic library. The other DYNLIB functions are very infrequently used and are not performance-critical. Many of the RTL functions have no performance requirements in the Product Requirements document. This is because they aren't required in and of themselves, but turn out to be necessary to meet other requirements. 10.0 RELIABILITY Because the first product using dynamic libraries to be seen by customers, Datatrieve-20, is aimed at inexperienced users, it is especially important that dynamic libraries not introduce any mysterious (from the users' points of view) errors. Ideally, no errors should occur. Next best is for errors to explain themselves clearly. DYNLIB use rule: all programs which call dynamic libraries should check for errors after each call, and present them to the user in a manner compatible with the other user interactions made by the program. 11.0 MAINTAINABILITY DYNLIB and its support procedures will be written in MACRO. I view this as an unfortunate choice, but since DYNLIB is intended to become a bundled part of the TOPS-20 operating system eventually, it should be written in a language which purchasers of TOPS-20 sources can understand. The tools for building libraries must be in macro anyway, since they must be usable at all customer sites. Most of the actual DYNLIB code will live in the RTL, with only a small bootstrap routine to load the RTL on the first call to a dynamic library. DYNLIB will be autopatchable in the field. (What will it be autopatched as part of? At first? Later?) 12.0 MAINTENANCE Maintenance of this product will be performed by Software Engineering. Dynamic Library Specification Page 36 MAINTENANCE 28 May 88 Updates will appear as necessary on the autopatch tapes. 13.0 COMPATIBILITY 13.1 Compatibility With Existing Libraries An existing library that will run in an arbitrary non-zero section, using no traps or interrupts, can be made a dynamic library simply by writing a library definition and an appropriate master initialization routine. A library using traps and interrupts would be somewhat more difficult. The degree of dificulty would depend on how the traps and interrupts were used. It could still be quite simple, on the order of a day's work by somebody who already understood dynamic libraries. 13.2 Product Compatibility 13.2.1 Dependency Issues We must come to a consensus with the TOPS-20 monitor group on interpretation of PDV's. We must come to a consensus with the LINK and monitor groups on LINK-provided memory maps. 13.3 Standards Conformance 13.4 Internationalization No requirements in this area. 14.0 EVOLVABILITY A Monitor DYNLIB facility could be written which would replace DYNBOO. This would, I hope, be relatively simple. All the rest of DYNLIB version would would be preserved, and performance would improve somewhat. 15.0 COSTS DYNLIB is being developed as part of the Datatrieve-20 project. We hope to limit the development of DYNLIB to 4 man-months (including all time spent from writing specification to field-test entry). Dynamic Library Specification Page 37 TIMELINESS 28 May 88 16.0 TIMELINESS The product must be ready to field-test and ship along with Datatrieve-20. 17.0 CONSTRAINTS AND TRADES-OFF Ease of conversion of an existing library is more important than keeping the call overhead of that library within the bounds specified. However, new libraries implemented according to the instructions to be developed as part of DYNLIB must meet the call overhead limits. There may be different techniques for defining a new dynamic library and a dynamic interface to an existing library. 18.0 APPROVAL PROCESS DYNLIB is being developed within the Datatrieve-20 project, but will probably be used by many other projects. The normal approval process as applied to Datatrieve-20 probably will not give sufficient visibility to DYNLIB to ensure that necessary feedback from other groups is received. Special efforts will be made to circulate DYNLIB documents to project leaders and supervisors throughout LSG Software Engineering. Selected consultant-level people within the group will be approached individually for their comments.