HP 3000 Manuals

MPE/iX Shared Globals Technical Overview [ COMMUNICATOR 3000 MPE/iX General Release 5.0 (Core Software Release C.50.00) ] MPE/iX Communicators


COMMUNICATOR 3000 MPE/iX General Release 5.0 (Core Software Release C.50.00)

MPE/iX Shared Globals Technical Overview 

by Huong Ho and Ed Olander 
Commercial Systems Division 

Intended Audience 

This article is intended for those who would like a more indepth
understanding of Shared Globals on MPE/iX. The readers may include:
application developers, porters, support, and training personnel.  For
those who would like an introduction to this new functionality, please
read the Communicator Overview article, "Introducing Shared Globals on
MPE/iX Loader", in the "Application Development" section.

Introduction 

Shared Globals becomes available on Release 5.0 for application
developers and porters requiring process-level variables for function
communications.  Shared Globals is "shared" data of a load module which
can be shared with other load modules within a single running process.

This article discusses what a developer of MPE/iX needs to know to use
the new Shared Globals functionality.  The sections of this article are
summarized as follows:

   *   How to Use Shared Globals from a Developer's Perspective 

       This section discusses compilers, the Link Editor, and new
       libraries in the following topics:
          *   Compilers
          *   Link Editor
          *   POSIX and Shared Global Developers Must Recompile
          *   $GLOBAL$ Directive Required in Pascal XL Libraries
          *   New Library:  LIBCSHR 
          *   Linking C Application with C Libraries
          *   Guidelines for the Linkage Method
          *   MPE/iX C link and go commands
          *   Summary of Data Binding Rules

   *   A Look Under the Hood--OS Support for Shared Globals 

       This section describes how Shared Globals work in the MPE/iX
       environment to help the developer build a solid foundation of
       understanding.  The topics discussed are:
          *   Overview of Operations
          *   Data External Reference Table (DXRT)
          *   Process Data Dictionary (PDD)
          *   Binding Rules for Data Symbols

   *   RUN Command Example 

       This section provides an example of a Shared Globals program with
       linked runtime libraries.

   *   NM Debug 

       This section provides instructions on using NM Debug with Shared
       Globals.

   *   AIF Procedure Exits 

       This section briefly discusses using Shared Globals with the
       AIF:PE product.

   *   Related Topics 

       This section provides references for more information on Shared
       Globals.

How to Use Shared Globals from a Developer's Perspective 

From a developer's perspective, the necessary components which allow
accesses to Shared Globals are:  the Compilers, Link Editor, library
support, and support from the Operating System.

Compilers.   

The availability of the Shared Globals feature is determined mainly by
the semantics of the language specifications.  The compiler, in support
of this feature, will emit the sequence of instructions to enable
externally referenced data to be imported.  By default, the compiler
generates the optimized, two-instruction sequences for handling up to
2,048 data imports.  To reach beyond this limit, the compiler will have
to generate the extended, three-instruction sequences.  Depending on the
language, the following options can be used to specify the compiler with
the three-instruction sequences to support more than 2,048 data imports:

   *   For HP C/iX, use +k option on the command line.

   *   For HP Pascal/iX, use $more_globals on$ compiler option.

   *   For HP COBOL II/iX, use $control moreglobals compiler option.

For more information regarding the above options, please consult the HP 
Link Editor/iX Technical Addendum (32650-09476) or the appropriate
language manual.

Link Editor.   

The MPE/iX Link Editor has been enhanced to support Shared Globals.  It
now allows global data to be sharable outside the executable module by
making the data imports and exports in the program and executable
libraries available and visible to the MPE/iX loader.  On MPE/iX Release
5.0, the Link Editor has set the default linking mode to NOSHARE for
compatibility reasons.  If you wish to enable or use Shared Global Data,
you must explicitly specify the new Link Editor ;share option in the link
and addxl command lines.  For a complete description of the new Shared
Global Data functionality, please refer to the HP Link Editor/iX 
Technical Addendum (32650-09476).

POSIX and Shared Global Developers Must Recompile.   

POSIX or POSIX-related application developers must recompile and relink
their applications on Release 5.0.  This is due to the addition of Shared
Globals in MPE/iX General Release 5.0, which provides the ability to
create or mix applications using both POSIX and ANSI C libraries.  To
facilitate this capability, the incompatibilities in the data structures
between the POSIX and ANSI C libraries had to be removed.  By
recompiling, you will ensure present and future forward compatibility of
your applications.

Developers who want to use Shared Globals must also relink and/or
recompile their applications.  If the developers are not POSIX users or
do not plan on using Shared Globals, their applications will continue to
run on Release 5.0 without recompiling.

$GLOBAL$ Directive Required in Pascal XL Libraries.   

XL Libraries containing modules created in Pascal using global variables
(generated by the outer block) must specify the $GLOBAL$ directive.  The
$GLOBAL$ directive tells the compiler to allocate space for global
variables (DP positive area) since the outer block does not exist for
subprograms ($SUBPROGRAM$).

As of Release 5.0, due to changes made for the DXRT (refer to the "A Look
Under the Hood--OS Support for Shared Globals" section in this article),
any attempt to access the DP positive area in a subprogram compiled
without the $GLOBAL$ directive will result in a data memory protection
trap.


\ \ \ Important Details \ Please Read If you did not specify the $GLOBAL$ directive in a subprogram prior to Release 5.0, and you declared global data, you MUST include it in your source code for Release 5.0 and recompile. Otherwise, the program will abort with a data memory protection trap when it attempts to access the global data area.
For more information on using the $GLOBAL$ directive refer to Chapter 2 in the HP Pascal/iX Programmer's Guide (31502-90002) (3.0 version or later). New Library: LIBCSHR. A new C library, LIBCSHR.LIB.SYS, has been developed to support Shared Globals. To enable this functionality, the developer can use the LIBCSHR library to link the application with other user XLs in addition to XL.PUB.SYS. Linking LIBCSHR requires the new ;share option to be specified. For further information on LIBCSHR, please refer to the "HP C/iX Enhancements for MPE/iX 5.0" article in the "Application Development" section of this Communicator. Linking C Application with C Libraries. Following are the three suggested linking methods for C application and libraries: 1. Archive linking - Link with LIBC, which is non-sharable. All libc functions are completely integrated into the application. link from= cobj; to= cprog; rl= libcansi.lib.sys, libc.lib.sys 2. Semi-shared linking - Link with LIBCINIT, which is designed to reinitialize the XL.PUB.SYS global pointers and redirect them to the program's globals at process startup. Most of the libc functions are in XL.PUB.SYS and are partly shared by the application. link from= cobj; to= cprog; rl= libcansi.lib.sys, libcinit.lib.sys 3. Shared linking - Link with LIBCSHR, which is completely sharable. All the libc functions are in XL.PUB.SYS. They are shared by the application's linked executable libraries. It is the recommended method for sharing global data. link from= cobj; to= cprog; rl= libcansi.lib.sys, libcshr.lib.sys; share Guidelines for the Linkage Method. * Use non-shared linkage for self-contained and highly portable applications. This is the traditional linkage method. * Use semi-shared linkage for applications that want partial sharing but maintain a high degree of compatibility. This is the current shared linkage method. * Use shared linkage for applications that want maximum sharing without any of the semi-shared linkage restrictions or workarounds. This is the new, true shared linkage method. MPE/iX C LINK and GO Commands. The two command scripts, ccxllk.pub.sys and ccxlgo.pub.sys, are modified to link with the new LIBCSHR library. Summary of the Data Binding Rules. The MPE/iX Loader allows for duplicate data exports, therefore, it is important for the user to know the rules by which the loader selects a particular data export. The export data selection rules and import binding rules will be summarized here for convenience. All of these rules have been implemented on MPE/iX. The first four rules were derived from HP-UX. The motivation for each rule will be discussed in the next section. ________________________________________________________________________ | | | 1. The precedence rule is observed from left to right. | | 2. Initialized data (data universal) wins over uninitialized data | | (storage request). | | 3. For data universals, the first encounter wins over the | | remaining. | | 4. For storage requests, the largest size wins. | | 5. The most privileged data wins. | | 6. The memory resident data wins over the non-memory resident | | data. | ________________________________________________________________________ A Look Under the Hood--OS Support for Shared Globals This section discusses the theory of operations. Its purpose is to give the reader the necessary information so that a proper understanding of Shared Globals operation in the MPE/iX environment could be obtained. The Shared Globals functionality required the introduction of two new data structures within the MPE/iX Loader. They are the PDD (Process Data Dictionary) and the DXRT (Data External Reference Table.) (These data structures are discussed in more detail later in this section. At this point in the discussion our intent is to introduce them.) The PDD, which is primarily a load-time data structure, contains one particular instance of each data export from all opened program and library files used by the process. The DXRT, which is a runtime data structure initialized at load time, contains the addresses of all Shared Global Data (SGD) items imported by all functions within a load module. By means of indirect addressing through the DXRT, the SGD item is obtained by the function importing it. In addition to the new data structures, the design required the establishment of two sets of binding rules. One set pertains to adding data exports to the PDD and the other for matching import symbols to export symbols. The first is called the Rules for Exporting Data Symbols and the second, the Rules for Importing Data Symbols. The following figure gives a pictorial overview of the functions of the PDD, DXRT, and the two sets of binding rules.
[FFN44]
Shared Globals Load Model Please study the area above the solid line in the figure before reading the next paragraph. The figure above shows two opened files for the process: the program file and a library file. Each file has an export list which lists all the exports, both code and data, used by all functions in the executable file. In the figure, the program file is exporting the data item errno of size 4 bytes, and the library file is exporting data items foo of size 4 bytes, foo of size 8 bytes, and errno of size 4 bytes. The foo duplicates in the library file will only exist if they reside in separate load modules. All data exports for an executable file are read by the loader. These data exports are passed through a filter which implements the Rules for Exporting Data Symbols. The output from this filter are those data exports which will reside in the PDD. In the figure above, the PDD contains the particular export of errno from the program file (the first encountered of identical duplicates is selected) and foo of size 8 bytes (the largest duplicate is selected). Now turn your attention to the area below the solid line. Again, study this area before reading the following paragraph. After the PDD is loaded with one particular instance of each data export from all opened executable files in the process, a DXRT for each load module from all executable files is initialized. Executable files contain an import list for each load module which contains both code and data. After the load module has been loaded, its import list is read for all data imports. In the figure above, the single program load module imports errno (also, note that this load module contains errno in its global data area) and the library file has three load modules. The first load module imports foo of size 4 bytes, the second load module imports foo of size 8 bytes (note that this load module contains foo in its global data area), and the third load module imports errno. As each import is read from the load module's import list, the PDD is searched for a corresponding export. If an export with a matching name is found, the Rules for Importing Data Symbols are applied and, if successful, the address of the export is placed in the imports corresponding DXRT location. This action is illustrated by the arrows emanating from boxes in the DXRT. Global data is referenced by a positive offset from DP and the import's indirect address is computed as a negative offset from DP. Overview of Loader Operation. The MPE/iX Loader employs a particular standard binding sequence extensively throughout its operation. Within this section, you will find: * A general definition of the loader binding concept, * The Library Symbol Table (LST) enhancement for Shared Globals, * The loader's roles and functions * The algorithm it uses to handle the code and data symbol resolution. Binding Sequence. A binding sequence is an ordered list of the executable files (program and libraries) that is maintained by the loader. It implements two binding schemes: static binding and dynamic binding. * Static Binding sequence is a list of the program and libraries processed by the static loader during the loading of the program. Library selection is determined in the following order: 1. The list of executable libraries specified in the xl= string or lib= option of the RUN command at runtime. 2. The list of executable libraries specified in the xl= parameter of the LINK command at runtime or the ALTPROG command in the MPE/iX Link Editor facility at link time. 3. The default list of system libraries (namely, the subsystem library XL.PUB.SYS and the system library NL.PUB.SYS). * Dynamic Binding sequence is a list of libraries processed by the dynamic loader upon the invocation of the MPE intrinsic HPGETPROCPLABEL during the execution of the program. The selection of the libraries is determined in the following order: 1. The library specified by the firstfile parameter of the HPGETPROCPLABEL procedure, which may generate a new sequence or be part of the previous binding sequence (static or dynamic) during a dynamic load. 2. The default list of system libraries (XL.PUB.SYS and NL.PUB.SYS) if the firstfile parameter is empty or unused. LST Enhancement. Prior to the 5.0 Release the Library Symbol Table (LST) header contained two lists: * Symbol definition records list (a symbol directory implemented as a hash table list) exported by a load module * Symbol reference records list (an import table list indexed by a load module number) imported by a load module The symbol records in these two lists are tagged with the symbol types and scopes, such as stub externals (code imports) and code universals (code exports). Until recently, the MPE/iX executable libraries and programs did not recognize nor include the data symbols in these two lists. To enable the handling of Shared Global Data (SGD), the Link Editor has been changed to add the data symbols to these lists. Functional Description. The MPE/iX Loader has been modified to traverse through the binding sequences to locate all exported symbols (code and data) in the hash list of each executable file, starting from the program file at load time or from the library indicated by the firstfile parameter of HPGETPROCPLABEL at process runtime. The loader then tries to satisfy all external references (code and data imports) in the import list of each load module occurring for a particular load (either static or dynamic) and prepares the program to be in a runtime executable state. To handle symbols (code and data) resolution and linkage for the program execution, the loader establishes the following necessary supporting data structures and mechanisms for the program execution: * Code symbol resolution and linkage a. Allocates and initializes the global data of the program and libraries into process data (private) space. It assigns and maintains the load module Data Pointer (DP) for the global data reference in the DP positive area. b. Loads the program and libraries into separate process code (text) spaces and stores the Linkage Pointer (LP) at the DP-4 location for the External Reference Table (XRT) access. c. Builds the XRT and initializes the XRT entries with the necessary linkage to connect a program or library's external code references to entry points in another library. * Data symbol resolution and linkage a. Copies all the data export symbols from the file's LST export list into the Process Data Dictionary (PDD) by enforcing a set of exported data binding rules (see "Binding Rules for Data Symbols" section) to select a unique instance of the data export. b. At the end of the binding sequence for the code-load path, the loader initializes the Data External Reference Table (DXRT) entries in the DP negative area. It uses a set of imported data binding rules (see "Binding Rules for Data Symbols" section) to link the data imports with the address of the data exports stored in the PDD. This enables the program data exports to bind XL data imports and vice versa.
NOTE Code symbol resolution is unidirectional and forward bounded. The program's code import can be bound to the XL's code export but the reverse is not possible. Let's assume MPE binding is like peeling an onion with the program being the outermost layer and the system libraries being the innermost layers. Then, code symbols from an outer layer are resolved through the inner layers. But, code symbols exported by an outer layer are not visible to the code symbols imported by the inner layer. Unlike code, data symbol resolution is bidirectional and in dual binding (forward and backward). This makes data sharing in MPE/iX similar to HP-UX.
Algorithm. The new loader extends the current algorithm to: * Handle the data symbol which the Link Editor and compilers make visible through the executable files' export and import lists. * Establish the binding rules that guarantee all duplicate data exports are resolved to a unique instance of the symbol and all data imports from all load modules are completely bound. * Build and initialize the DXRT through which the global data is shared. * Abort the load when the binding rules are not satisfied. The loader's enhanced algorithm to support Shared Global Data is as follows: 1. The loader begins the binding sequence with a program name and ordered list libraries. 2. It loads the program load module and adds its unresolved code symbols (code imports) into a list of the process unresolved symbols (the unsat list). It then moves all data export symbols in the program file into the PDD, a hash implemented repository for all unique instances of data export found in all open executable files for a process. Duplicates are discarded using the exported data binding rules. 3. The loader loops until there are no more symbols to be processed in the unsat list or load modules to be examined from the remaining list of libraries in the current binding sequence. a. It gets the next file in the binding sequence. b. For each code symbol in the unsat list, it searches the library hash list to look for a matching code export and stops at the first symbol it finds. c. It loads the load module that exported the symbol, binds the code import to the code export through the XRT layout and adds the code imports of the load module into the unsat list. d. It moves all data exports in the library into the PDD and discards the duplicates using the exported data binding rules. As the data exports are moved, their load modules are checked for shared function pointer usage (XRT fixup). e. For each load module's exported XRT fixup symbols, it loads each load module that has these symbols, adds the code imports to the unsat list and repeats step b onward. f. It goes back to the loop and repeats the above steps until the end of the binding sequence or an empty list of unsatisfied externals. 4. At the end of the code-load path, when all code symbols have been resolved, the loader builds a global data area DP for all unloaded modules that export the data symbols. 5. For each load module in the current binding sequence, the loader reads the list of imported data symbols and binds each imported data symbol with its export by initializing the DXRT. In addition, for each load module it applies all required loader fixups. 6. If the lmap flag is set to true, the loader prints the load map for the load modules. When all load modules are completed, it prints the contents of the PDD. Data External Reference Table (DXRT).
[FFN45]
Data External Reference Table Code linkage is managed through the XRT. Likewise, for Shared Global Data, the Data External Reference Table (DXRT) is introduced to handle global data linkage. Usage. The Data External Reference Table is used as a data linkage table that resolves all unsatisfied data imports to known data exports' locations. It functions in a similar way to an XRT for unsatisfied code imports by providing the indirect data references to the running process. It is accessed at runtime by the importing load module to obtain the address of the data exports. Structure. The DXRT table is generated by the loader when a load module is loaded on a process. It is created for every SGD load module, which contains valid Shared Globals declarations or definitions. It is built on a load module basis (i.e., one for the program and one for each XL module). Its size is determined and set by the Link Editor at link time. Each load module data import usually requires one DXRT slot or entry (4 bytes in length) to be initialized to the addresses of the actual data symbol being imported. For new (SGD) load modules, the DXRT is allocated by the Link Editor as a part of the load module DP area. For old (non-SGD) load modules, a single dummy page is inserted by the loader and used to page align the DP. Because there are no DXRTs for the non-SGD load module, only the 8-bytes of the page are really used to store the filler and the LP, and the page is prefixed to the load module DP. The DXRT is maintained in the process DP negative area with the base being at DP-C. For completeness, the whole DP negative area is now referred to as the DXRT, even though the first 8-bytes are not really part of the DXRT (LP at DP-4 and a word filler at DP-8). The table grows backward and is 0-based. It is deallocated during a call to the POSIX exec function or after the termination of a process. Access. The DXRT is a random access table where each imported data symbol is assigned by the Link Editor with a unique index within a single load module. The loader initializes the DXRT entry for the load module based on this indexing. For example, if the errno global was assigned with an index 8 by the Link Editor, then the address of errno would be loaded into the 9th entry (DP-2C; 0-based) in the DXRT table. The Link Editor will have emitted code into the load module that will negatively index into the 9th entry of the table and pick up the address where errno actually lives. Until recently, the DP negative area only contained the filler word and the LP used for the procedure calling mechanism. With the addition of Shared Globals, the DP negative area is now fully expanded and it is used to store the DXRT for external data references. Its access rights (read and write) have been determined by the Link Editor, usually at Read 3 Write 0, to the appropriate privilege level to secure and protect the DP negative area. Since the access rights could only be handled at the page level, the load module's DP area now has to be page aligned. Process Data Dictionary (PDD). The Process Data Dictionary (PDD) is the repository of all data symbol resolution that has taken place on a process. Its chief functions are: * Maintain information on all resolutions. * Enforce resolution semantics by controlling the addition of new symbols. The loader uses the dictionary to arbitrate among duplicate definitions. Adding Data Symbols. The PDD is established in the following manner: * When an executable file is opened and one of the load modules has its shared data flag set to true, all the data exports of all load modules in the file are added to the dictionary. * Duplicate data exports are eliminated by the loader according to the rules specified in the following section, "Binding Rules for Data Symbols". Each data symbol in the PDD is marked according to its load point. Load points are distinct invocations of the loader. The invocation of the loader at runtime generates a static load point, and calls to the HPGETPROCPLABEL intrinsic at runtime generates dynamic load points. By using the load point mark, data symbols added to the PDD during a dynamic load that fails can be removed. Also, the load point mark detects when symbols from one load point try to replace symbols of a different load point. This situation leads to a failed load. Binding Data Symbols. During the binding of data imports the dictionary is searched by hashing the import symbol name to find its data export. If found, the import is bound to the export. Imports from any load point can be bound to exports from any load point. Binding Rules for Data Symbols. Most operating systems today allow some form of code and data sharing. These systems generally bind code and data in a similar manner. HP-UX Implementation. HP-UX treats code and data synonymously. * It accepts an ordered list of libraries as input, either at runtime or at program link time. * It builds a global dictionary of code symbols and data symbols. This dictionary remembers which symbol is exported by which library. There are no duplicates in this dictionary. Duplicates are discarded according to some pre-fixed rules. * It resolves all references (imports) for a particular symbol, code and data to the same instance of that symbol. MPE/iX Implementation. MPE/iX does not handle code symbols and data synonymously. Code symbol resolution is unidirectional and forward bounded. Unlike code, data symbol resolution is bidirectional and in dual binding mode (forward and backward). This makes data sharing in MPE/iX similar to UNIX versions. To understand the difference between code and data binding consider the following example. Suppose we have the following binding sequence, where the load modules are each in different user libraries with some exports and imports. The binding sequence is: Program, load module1, load module2, load module3, load module4 * For code symbols, the binding works as follows: The imports of foo from Program and load module2 are bound to the exports from load module1 and load module3, respectively. The import of foo from load module4 fails because it does not see the symbols exported by load modules earlier in the binding sequence. Program load module2 load module4 load module1 load module3 --------- --------- --------- --------- --------- | | | | | | | | | | |imp foo|-->|exp foo| |imp foo|-->|exp foo| |imp foo| | | | | | | | | | | --------- --------- --------- --------- --------- | v Unresolved symbol!! * For data symbols, the binding works as follows: Based on the rules for choosing data exports, the loader selects one of the two data exported foos and binds all imports to that. This load will succeed because even load module4 can see all the data symbols. Program load module2 load module4 load module1 load module3 --------- --------- --------- --------- --------- | | | | | | | | | | |imp foo|-| |exp foo| |imp foo|-->|exp foo|<--|imp foo| | | | | | | | | | | | | --------- | --------- --------- | --------- --------- | | -------------------------- There is no industry standard that governs the semantics of data symbol resolution in shared libraries. There is, however, a widespread acceptance of the UNIX-like way of implementing Shared Globals. UNIX System V and HP-UX implement a very similar scheme and form a de facto standard. The MPE/iX scheme exports a feature set and semantic that is close to these de facto standards. The need is that code ported from UNIX systems not require rewrites or reorganization. Load modules can export data symbols whether or not they import data, export code or import code symbols. This capability in many ways will be quite foreign to the way the loader currently does code symbol resolution. Allowing load modules to export data symbols even when their code is not loaded illustrates the degree to which the loader was modified to permit the porting of UNIX applications to be as seamless as possible.
\ \ \ Important Details \ Please Read An exception is the MPE/iX subsystem library--XL.PUB.SYS. The subsystem library must have at least one load module active (code-loaded) before data-only load modules are allowed. This requirement does not apply if a data label is requested via the HPGETPROCPLABEL intrinsic from the subsystem library. This requirement is necessary to keep the subsystem library from being opened needlessly.
Binding Semantics. A. Success Criterion - When attempting to load SGD load modules, the following two conditions must be met for a successful load. * All imports of data symbols from all load modules must be satisfied. * All exports of duplicate data symbols must be resolved to a unique instance of the symbol and this instance must satisfy all the rules for exporting data symbols. B. Exporting data symbols - This describes all the rules needed to define the addition of a symbol to the PDD in an unambiguous manner. The primary issue is to resolve duplicate export data. The first class of rules deal with differing sizes, initializations, alignments, and the order of resolution. HP-UX and MPE/iX already have rules in these areas. The second class of rules deal with differing access rights and memory residency requirements. * HP-UX rules - They are derived from the HP-UX Implementation. The first definition of a symbol with initial value wins over all other instances of the symbol - (defined and storage requests). For duplicate definitions of storage requests, the following rules are used to break ties: * The data symbol with the largest data size wins. * The symbol with the most restrictive alignment wins. This rule will never be invoked since the Link Editor automatically aligns storage requests based on size. Thus, data size of one byte is byte aligned, of 2 bytes is half-word aligned, of 3 to 4 bytes is word aligned, and 5 or greater bytes is double word aligned. * The level of allowed incompatibility is dictated by the parmcheck option provided by the Link Editor and the compiler options $global$ and $external$ provided by Pascal. This information is passed along to the loader. * If there is more than one selection possible then the symbol from the first load module in the binding sequence wins. * Duplicate data symbols that occur between the static load and dynamic loads or between dynamic loads which require a replacement of an existing symbol, will cause the load to fail with an error status. This status and the associated error message indicates that one data export cannot replace another of the same name across load points. C. MPE/iX specific rules - Rules are defined for data properties specific to MPE/iX. These rules apply only to storage requests. For initialized data, these rules are never needed. * Each symbol has two privilege levels associated with it--a read and a write level. Both those levels vary from 0 to 3. The principle is to select the most privileged symbol. This is because the load module defining the privileged symbol expects access to be secure and any load module importing it can always promote its privilege level to match that of the symbol itself. The most privileged symbol is the one with the lowest write privilege. Between two symbols with the same write privilege level, the one with the lower read privilege is considered more privileged. This leads to the anomaly that W2R3 is more privileged than W3R0. The assumption is that symbols with a lower read privilege than a write privilege are rare indeed. * Memory resident symbols take precedence over standard symbols. D. Importing data symbols - This describes the constraints enforced on a load module importing a symbol from the PDD. As in the case of symbol exports, HP-UX does not deal with access rights and memory residency. It does, however, define rules for data sizes and alignment. The rules defined here are compatible with HP-UX with extensions in the areas of access rights and memory residency. For a symbol import to succeed, all the following rules must be satisfied. If any one is not satisfied then the load fails. * HP-UX rules - They are derived from the HP-UX implementation. * If the importing symbol expects alignment that exceeds the alignment of the symbol in the PDD, then the load fails. * If the importing symbol requires a size that exceeds the size of the symbol in the PDD, then the load fails. ___________________________________________________ NOTE Data imports have NO size information. Therefore, to increase the probability of selecting the correct export, all the data exports from each file in the binding sequence are moved into the PDD. ___________________________________________________ * MPE/iX specific rules - The importing symbol's type is checked against the type of the symbol in the PDD. The level of allowed incompatibility is dictated by the parmcheck option provided by the Link Editor and the compiler options $global$ and $external$ provided by Pascal. * If the importing symbol is more privileged than the symbol in the PDD, then the load fails. * If the importing symbol is resident and the symbol in the PDD is not, then the load fails. E. Algorithm for selecting the best export amongst duplicates - The figure below depicts in schematic form the algorithm implemented in the MPE/iX Loader.
[FFN46]
Binding Semantics-Exporting Data Symbols To the left of the vertical dotted line at the top of the figure is the system function check_export(). The first parameter is a newly encountered foo data symbol, which is a duplicate of the foo in the PDD referred to below as the "current symbol". The objective of the check_export function is to select which of the foos is the appropriate one to keep - based on the rules established under bullet B above. To the right of the vertical dotted line is the sequence of logical decisions that are in accordance with the rules pertaining to duplicate exports. There are three outcomes from the function: a. A signal to fail the load (Fail Load) b. Which of the two symbols to select (select current symbol, replace current symbol, or equal-select the current symbol) c. Based on size, privilege, and memory residency a choice could not be made. (Neither is most stringent. A dummy symbol is created to hold the most stringent values). Describing the creation of a "dummy symbol" leads to a greater understanding of the export selection criteria. Consider for example the following situation: the current foo (the one in the PDD) is 4 bytes in size, nonprivileged (R3W3) and memory resident; the newly encountered foo is 8 bytes in size, privileged (R2W2) and not memory resident. When we apply the rules we get the following: Example of Selecting the Most Stringent ------------------------------------------------------------------------------------------------- | | | | | | Selection | Newly | Current | Selected | | Parameter | Encounter | PDD | Symbol | | | | | | ------------------------------------------------------------------------------------------------- | | | | | | size | 8 bytes | 4 bytes | New | | | | | | ------------------------------------------------------------------------------------------------- | | | | | | privilege | R2W2 | R3W3 | New | | | | | | ------------------------------------------------------------------------------------------------- | | | | | | memory resident | no | yes | Current | | | | | | ------------------------------------------------------------------------------------------------- Looking at the right most column in the above table, we see that we cannot make a choice between the duplicates. Therefore, we create a "dummy" symbol for the symbol name foo with the following attributes: eight bytes in size, privileged (R2W2) and memory resident. If another foo is found, it is compared with the dummy foo. If the new foo can be selected then the dummy is removed, if not, the dummy is kept with its parameters updated if necessary. If the dummy foo can't be replaced by a foo in the libraries, the load fails (i.e., the number of dummy symbols must be zero at the end of load). RUN Command Example :run progfile[;xl= "lib1[, lib2]"][;lmap] This section shows an example of the mechanics needed to use Shared Globals in a C language context. Included is a sample of the user's program and library. The C compiler is invoked to compile both sources followed by the call to the Link Editor. Finally the program is run. Program Source. /* Program Name: reals */ /* ----- INCLUDE FILES -------- */ #include "libdef" /* ----- Type definitions ----- */ /* Global declaration * First the exports: */ double a,b = 3.3; /* Second the imports: */ extern double c,d; /* Function Prototypes */ void proca(); /* ------ MAIN PROGRAM -------- */ main() { printf("------- Starting the Program -------\n"); a = 2.2; printf("The initial values of A and B are:\ %4.1f %4.1f\n", a,b); proca(); printf("------- Re-entry to the Program -------\n"); a = c; b = d; printf("A and B should now match C and D:\n"); printf(" A now equals %4.1f and\ B now equals %4.1f\n", a,b); } Library Source. /* Function Name: realxls */ /* ----- INCLUDE FILES -------- */ #include "libdef" /* ----- Type definitions ----- */ /* Global declaration * First the exports: */ double c = 4.4, d; /* Second the imports: */ extern double a,b; /* ------ FUNCTION IMPLEMENTATION --------- */ void proca() { printf("-------- Now in Proca -------\n"); d = 5.5; printf("Set the two exported variables\ C and D to:\n"); printf(" C = %4.1f;D = %4.1f\n",c,d); printf("The shared values of A and B are:\ A = %4.1f ; B = %4.1f\n", a,b); } Source Compilation. :ccxl reals realo $null END OF COMPILE :ccxl realxls realxlo $null END OF COMPILE Object Linking. :linkedit HP Link Editor/iX (HP30315A.05.00) Hewlett-Packard Co 1986 LinkEd> link from=realo;to=realp;rl=libcshr.lib.sys;share LinkEd> buildxl realxl LinkEd> addxl realxlo;merge;share 1 OBJECT FILE HAS BEEN ADDED. LinkEd> exit Program Execution. The output of the tested program is produced by the following command. :run realp;xl="realxl" The Program Output. ____________________________________________________________ | | | ------- Starting the Program ------- | | The initial values of A and B are: 2.2 3.3 | | -------- Now in Proca ------- | | Set the two exported variables C and D to: | | C = 4.4;D = 5.5 | | The shared values of A and B are: A = 2.2 ; B = 3.3| | ------- Re-entry to the Program ------- | | A and B should now match C and D: | | A now equals 4.4 and B now equals 5.5 | | | | END OF PROGRAM | | : | ____________________________________________________________ LMAP Option. The lmap option on the RUN command has been extended to give a listing of the export symbols, the import data symbols, the XL.PUB.SYS modules loaded on the process and the data symbols that compose the Process Data Dictionary (PDD). Please refer to the MPE/iX Commands Reference Manual (Volumes I and II) (32650-60115) or the online help facility under the RUN command for a discussion on the extended features. NM Debug The Native Mode Debug has been enhanced to display the process-specific address of the external data symbols for Shared Globals' debugging purpose. The two debug commands, PROCLIST() and NMADDR(), have been modified to support Shared Globals. PROCLIST returns the list of process symbol address as corresponding to the symbol names in the given executable file. NMADDR returns the process symbol address for a given symbol name. The lookupid parameter of the PROCLIST and NMADDR commands has been extended to include a new option, datashared designed to retrieve Shared Global Data (SGD). SGD information is also returned when using the dataany and datauniv options since SGDs symbols fall within a subset of these options. The examples of the PROCLIST and NMADDR commands are enhanced as follows: proclist sharedxl,datashared proclist shared_var, sharedxl, datashared, 2, listfile = nmaddr("shared_var","datashared") = nmaddr("shared_var","dataany") = nmaddr("shared_var","datauniv") Below is an example of how to use PROCLIST and NMADDR to locate and list the shared data symbols in NM Debug. These symbols could be cross-checked with the information displayed by the loader lmap. :run intprgp;xl="libintxl";debug _______________________________________________________ | | | DEBUG/iX B.74.14 | | | | DEBUG Intrinsic at: 2ac.00005004 ?$START$ | | | | $1 ($21) nmdebug > proclist ,intprgp,datashared | | | | 281.416350e0 a | | 281.41635000 b | | | | $2 ($21) nmdebug > proclist ,libintxl,datashared| | | | 281.41635000 b | | 281.416370a0 c | | 281.416370a4 d | | | | $3 ($21) nmdebug > = nmaddr("b","datashared") | | | | $281.41635000 | | | | $4 ($21) nmdebug > = nmaddr("b","dataany") | | | | $281.41635000 | | | | $5 ($21) nmdebug > = nmaddr("b","datauniv") | | | | $281.41635000 | _______________________________________________________ AIF: Procedure Exits The AIF: Procedure Exits (PE) product has been enhanced to support and handle programs and executable libraries using Shared Globals. For more information regarding Shared Globals on the AIF:PE product, please refer to the Communicator article, "AIF Enhancements", in the "System Management" chapter. Related Topics * For a complete description of the new Shared Global Data functionality (i.e., how to build, use and display Shared Globals), read the HP Link Editor/iX Technical Addendum (32650-09476). * For information on using Shared Globals to allow POSIX and non-POSIX C programs to link with POSIX and non-POSIX executable libraries (XLs), refer to the Communicator Technical article, "POSIX Libraries in XLs". * For background information on Shared Globals, read the December '93 INTERACT Volume #13, Issue 12 "Shared Libraries on MPE/iX" article by Rajesh Desai. This paper provides a complete, comparative analysis between the Shared Libraries on HP-UX and the Executable Libraries on MPE/iX. * For additional information on the new Libc/iX library, LIBCSHR.LIB.SYS, refer to the Communicator article, "HP C/iX Enhancements for MPE/iX 5.0," in the "Application Development" chapter. * For another loader related topic regarding the ability to load executable files (program and libraries) and dynamically load procedures from the executable libraries in the Hierarchical File System (HFS) directory, read the Communicator article, "Loading Programs and XLs from HFS," in the "POSIX/Opens Solutions" chapter, describing HFS Loader functionality available on Release 5.0.


MPE/iX Communicators