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.
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).
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.
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