HP 3000 Manuals

The MPE XL Programming Environment [ HP Link Editor/XL Reference Manual ] MPE/iX 5.0 Documentation


HP Link Editor/XL Reference Manual

The MPE XL Programming Environment 

The paragraphs which follow in this section cover the aspects of the MPE
XL environment that affect HP Link Editor/XL and how it links programs.

Virtual Memory 

A program running under MPE XL has at least two spaces, where a space is
a fixed-length block of virtual memory.  One is a code space and the
other is a data space.  A virtual address is composed of a space
identifier and a space offset, both of which are 32 bits long.  Thus,
virtual memory consists of over 4 billion spaces, each of which can
contain over 4 billion bytes (four gigabytes).  (Some implementations of
HP Precision Architecture restrict space identifiers to 16 bits, allowing
only 65,536 spaces.)

Even though a virtual memory address is 64 bits long, most addressing can
be done with 32-bit addresses.  There are eight space registers that hold
space identifiers.  When loading or storing a word in memory using a
32-bit address, one of the last four space registers is selected
automatically.  Its selection is based on the high-order two bits of the
address.  This method of addressing allows one gigabyte (or quadrant) of
each space selected by the space registers to be addressed:  the first
quadrant of the first space, the second quadrant of the second space, the
third quadrant of the third space, and the fourth quadrant of the fourth
space.  Figure 7-1 shows the code and data spaces divided into quadrants:

[]
Figure 7-1. Code and Data Quadrants The link editor places all code and literals in the first quadrant of the code space, and all data in the second quadrant of the data space. Thus, every executable module, whether in a executable program file or in an executable library, consists of one code space and one data space. When the program is loaded, a new code space is created for the code in the executable program file and for each executable library that is loaded to satisfy external references. Only one data space is created. The data spaces in each executable module are loaded one after another into a single data space. If you run a program that is already loaded (someone else is also running it), the code spaces already loaded can be reused. Only a data space must be created for the second program (process). The code and literals can be shared because they cannot be modified by a process. External Calls An external call is a procedure call that transfers control from one executable module to another. These calls are not resolved during the link operation for two reasons. First, the link editor builds (using LINK or ADDXL) one executable module at a time. Therefore, it does not know where the called procedure is located. Second, since space identifiers are assigned at run time, there is no way to predict what the space identifier for either code space will be. Because the link editor cannot resolve external calls, it builds an import stub during linking for each procedure that is called but not defined in the executable module. It also allocates an entry in the External Reference Table (XRT) for the unresolved procedure. The import stub contains a short sequence of code that is used at run time to transfer to the procedure's entry point. The import stub uses the XRT entry to find both the space identifier and the space offset of the target procedure. The import stub then saves the current value of space register 4 (which corresponds to the first quadrant of the code space), and copies the new space identifier into space register 4. This ensures that the space register always contains the space identifier of the current code space. The loader locates each procedure referenced in the XRT and initializes each XRT entry with the appropriate values. When a procedure is called externally, it must restore the space identifier of the calling procedure before returning to it. To do this, the link editor builds an export stub for every procedure that can be called externally. The export stub gives an alternate entry point to the procedure that is executed by an external call. All internal calls (that is, calls to procedures in the same executable module) use the ordinary procedure entry point. External calls use the export stub as the entry point. On LISTPROG and LISTXL symbol listings, export stubs are shown as entry symbols, while the ordinary entry points are shown as code symbols. Privilege Levels The HP Precision Architecture provides four levels of privilege. Level 0 is the most privileged and allows complete access to all system resources. Level 3 is the least privileged. MPE XL establishes the following meanings for the privilege levels: 0 Restricted to the MPE/XL kernel. 1 Reserved for future use. 2 Privileged Mode. Programs with PM capability execute at this level. This privilege level provides access to most operating system features and security checks are streamlined. 3 User Mode. Most programs run at this level. Programs access operating system features only through documented intrinsics, and access is subject to full security checking. All procedures have two privilege levels: the privilege level at which it runs, the execution privilege level; and the privilege level at which callers must be running in order for the call to succeed, the call or xleast privilege level. When a procedure call occurs, the execution privilege level of the calling procedure must have the same or a higher (numerically lower) privilege level than the call privilege level of the procedure being called. (If not, the calling program is aborted with a privilege violation.) The execution privilege level of the called procedure is promoted to the execution privilege level of the calling procedure, when the calling level is more privileged; otherwise the called procedure's execution privilege level remains unchanged. The execution and call privilege levels for procedure entry points are shown in the symbol listings produced by the link editor commands, LISTOBJ, LISTPROG, LISTRL, and LISTXL. Privilege level promotion and security checking are performed by the operating system during an external procedure call. Internal calls cannot perform promotion. When internal procedure calls require a promotion, the link editor builds a promotion stub that turns the internal call into an external call. A promotion stub is a combination of an import stub and an export stub. Long Branch Stubs for Procedure Calls Compilers generate a single branch-and-link instruction for all procedure calls. The instruction has a limited addressing range - 256K bytes in either direction from the call. If the call is external, the link editor places the import stub within this range. If the call is internal, the target may be out of range. In this case, the link editor builds a long branch stub within reach of the call. A long branch stub consists of two instructions that reach the target anywhere in the code space. Long branch stubs are also used for millicode calls and interchunk branching for HP COBOL II programs. Procedure Labels The address of a procedure is a data item called a procedure label, or plabel. A plabel can be passed as a parameter from one procedure to another, so that an indirect call through the plabel might not be an internal call. To accommodate this possibility, all indirect procedure calls are external calls, even if the call happens to be in the same code space as the procedure being called. A plabel is therefore the address of an XRT entry, not the address of the procedure itself. The indirect procedure call obtains the space identifier and offset from the XRT entry just like an import stub. If you obtain a plabel through the HPGETPROCPLABEL intrinsic, the intrinsic creates an XRT entry and returns its address. If you obtain a plabel by taking the address of a procedure in your source program (for example, by passing a subprogram or function name by reference in HP FORTRAN 77) the link editor automatically allocates an XRT entry and creates a plabel stub that instructs the loader to initialize the XRT entry appropriately. The code in the plabel stub is identical to an export stub. Plabel stubs are shown in LISTPROG and LISTXL symbol listings as plab symbols. Note that if a routine resides in an executable library, and its address is taken (as in HP C), it will not necessarily be the same as the address that is taken from the user's program. The addresses will be the same if they are being compared in the same program or library. In other words, if your program compares the addresses of routines within the program, it will work as you expect. Likewise, comparing the addresses of two routines which reside in the same executable library will work as you expect. But, if your program compares the address of a routine taken from within the program code with the address of a routine taken from within the library, those addressses will not be the same. You will be comparing the address of an import stub with the address of an export stub. HP Link Editor/XL Environment Files When you use the LINK and ADDXL commands, the link editor includes two files, NRT0.LIB.SYS and XL0.LIB.SYS, into the executable modules that are produced. These files define: * The standard subspaces that control how the link editor arranges the code and data spaces. Since MPE XL compilers group the various parts of a relocatable object file into separate subspaces, the link editor can combine like subspaces together within each space. Standard subspaces are defined for millicode, literals, code, stack unwind descriptors, Pascal outer block global variables, static initialized data and static uninitialized data. Compilers also define an additional subspace for each locality set. * The standard symbols that are used by the compiler libraries and system debuggers. For example, the symbols $UNWIND_START and $UNWIND_END declare the beginning and end of the region containing stack unwind descriptors. Stack Unwinding Whenever a traceback of procedure calls is made, the process is referred to as unwinding the stack. The traceback can occur as a result of a multi-level procedure return in languages that support it (for example, non-local GOTO or escape in Pascal), or from a program abort or a debugging request. Regardless of the cause, each stack frame must be examined to determine the procedure that created it and its size. Given the size of the current stack frame, the previous stack frame can be located. All MPE XL compilers create static tables of unwind descriptors that make stack unwinding possible. The tables are placed in pre-defined subspaces so that the link editor can build one combined stack unwind table during a LINK or ADDXL operation. Each descriptor describes the stack frame for a procedure, which is identified as a range of addresses in the code space. Thus, given any code address as a starting point, the appropriate descriptor can be located. The descriptor, in turn, identifies the size and type of the current stack frame. From this information, the address of the caller of that procedure and the address of the caller's stack frame can be determined, and the unwinding can continue until the bottom of the stack is reached.


MPE/iX 5.0 Documentation