|
HP OpenVMS systems documentation |
Previous | Contents | Index |
A thread can obtain an invocation handle corresponding to any invocation context block by using the following function format:
LIB$GET_INVO_HANDLE(invo_context) |
Argument | OpenVMS Usage | Type | Access | Mechanism |
---|---|---|---|---|
invo_context | invo_context_blk | structure | read | by reference |
Argument:
invo_context
Address of an invocation context block. Here, only the frame pointer and stack pointer fields of an invocation context block must be defined. |
Function Value Returned:
invo_handle
Invocation handle of the invocation context that was passed. If the returned value is LIB$K_INVO_HANDLE_NULL, the invocation context that was passed was invalid. |
A thread can obtain an invocation handle of the procedure context preceding that of a specified procedure context by using the following function format:
LIB$GET_PREV_INVO_HANDLE(invo_handle) |
Argument | OpenVMS Usage | Type | Access | Mechanism |
---|---|---|---|---|
invo_handle | invo_handle | longword (unsigned) | read | by value |
Argument:
invo_handle
An invocation handle that represents a target invocation context. |
Function Value Returned:
invo_handle
An invocation handle for the invocation context that is previous to that which was specified as the target. |
A given procedure invocation context's fields can be updated with new register contents by calling a system library function in following format:
LIB$PUT_INVO_REGISTERS(invo_handle, invo_context, invo_mask) |
Argument | OpenVMS Usage | Type | Access | Mechanism |
---|---|---|---|---|
invo_handle | invo_handle | longword (unsigned) | read | by value |
invo_context | invo_context_blk | structure | read | by reference |
invo_mask | mask_quadword | quadword (unsigned) | read | by reference |
Arguments:
invo_handle
Handle for the invocation to be updated. |
|
invo_context
Address of an invocation context block that contains new register contents. Each register that is set in the invo_mask parameter, except SP, is updated using the value found in the corresponding IREG or FREG field. The program counter and processor status can also be updated in this way. (The SP register cannot be updated using this routine.) No other fields of the invocation context block are used. |
|
invo_mask
Address of a 64-bit bit vector, where each bit corresponds to a register field in the passed invo_context. Bits 0 through 30 correspond to IREG[0] through IREG[30], bit 31 corresponds to PROGRAM_COUNTER, bits 32 through 62 correspond to FREG[0] through FREG[30], and bit 63 corresponds to PROCESSOR_STATUS. (If bit 30, which corresponds to SP, is set, then no changes are made.) |
Function Value Returned:
status
Status value. A value of 1 indicates success. When the initial context represents the bottom of the call stack or when bit 30 of the invo_mask argument is set, a value of 0 is returned (and nothing is changed). |
While this routine can be used to update the frame pointer (FP), great care must be taken to assure that a valid stack frame and execution environment result; otherwise, execution may become unpredictable. |
This standard states that a standard call (see Section 1.4) may be accomplished in any way that presents the called routine with the required environment. However, typically, most standard-conforming external calls are implemented with a common sequence of instructions and conventions. Because a common set of call conventions is so pervasive, these conventions are included for reference as part of this standard.
One important feature of the calling standard is that the same
instruction sequence can be used to call each of the different types of
procedure. Specifically, the caller does not have to know which type of
procedure is being called.
3.6.1 Call Conventions
The call conventions describe the rules and methods used to communicate certain information between the caller and the called procedure during invocation and return. For a standard call, these conventions include the following:
Figure 3-10 Argument Information Register (R25) Format
Field Name | Contents | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
AI$B_ARG_COUNT | Unsigned byte <7:0> that specifies the number of 64-bit argument items in the argument list (known as the "argument count"). | ||||||||||||||||||||||||
AI$V_ARG_REG_INFO |
An 18-bit vector field <25:8> divided into six groups of 3 bits
that correspond to the six arguments passed in registers. These groups
describe how each of the first six arguments are passed in registers
with the first group <10:8> describing the first argument. The
encoding for each group for the argument register usage follows:
|
||||||||||||||||||||||||
Bits 26--63 | Reserved and must be 0. |
One implication of the stack alignment requirement is that low-level interrupt and exception-fielding software must be prepared to handle and correct the alignment before calling handler routines, in case the stack pointer is not octaword aligned at the time of an interrupt or exception. |
Because the Alpha hardware architecture has the property of instructions that cannot contain full virtual addresses, it is sometimes referred to as a base register architecture. In a base register architecture, normal memory references within a limited range from a given address are expressed by using displacements relative to the contents of a register containing that address (base register). Base registers for external program segments, either data or code, are usually loaded indirectly through a program segment of address constants.
The fundamental program section containing address constants that a procedure uses to access other static storage, external procedures, and variables is termed a linkage section. Any register used to access the contents of the linkage section is termed a linkage pointer.
A procedure's linkage section includes the procedure descriptor for the procedure, addresses of all external variables and procedures referenced by the procedure, and other constants a compiler may choose to reference using a linkage pointer.
When a standard procedure is called, the caller must provide the procedure value for that procedure in R27. Static procedure values are defined to be the address of the procedure's descriptor. Because the procedure descriptor is part of the linkage section, calling this type of procedure value provides a pointer into the linkage section for that procedure in R27. This linkage pointer can then be used by the called procedure as a base register to address locations in its linkage section. For this reason, most compilers generate references to items in the linkage section as offsets from a pointer to the procedure's descriptor.
Compilers usually arrange (as part of the environment setup) to have the environment setup code (for bound procedures) load R27 with the address of the procedure's descriptor so it can be used as a linkage pointer as previously described. For an example, see Section 3.6.4.
Although not required, linkages to external procedures are typically represented in the calling procedure's linkage section as a linkage pair. As shown in Figure 3-11 and described in Table 3-8, a linkage pair (LKP) block with two fields should be octaword aligned and defined by LKP$K_SIZE as 16 bytes.
Figure 3-11 Linkage Pair Block Format
Field Name | Contents |
---|---|
LKP$Q_ENTRY | Absolute address of the first instruction of the called procedure's entry code sequence. |
LKP$Q_PROC_VALUE | Contains the procedure value of the procedure to be called. Normally, this field is the absolute address of a procedure descriptor for the procedure to be called, but in certain cases, it could be a bound procedure value (such as for procedures that are called through certain types of transfer vectors). |
In general, an object module contains a procedure descriptor for each entry point in the module. The descriptors are allocated in a linkage section. For each external procedure Q that is referenced in a module, the module's linkage section also contains a linkage pair denoting Q (which is a pointer to Q's procedure descriptor and entry code address).
The following code example calls an external procedure Q as represented by a linkage pair. In this example, R4 is the register that currently contains the address of the current procedure's descriptor.
LDQ R26,Q_DESC-MY_DESC(R4) ;Q's entry address into R26 LDQ R27,Q_DESC-MY_DESC+8(R4) ;Q's procedure value into R27 MOVQ #AI_LITERAL,R25 ;Load Argument Information register JSR R26,(R26) ;Call to Q. Return address in R26 |
Because Q's procedure descriptor (statically defined procedure value)
is in Q's linkage section, Q can use the value in R27 as a base address
for accessing data in its linkage section. Q accesses external
procedures and data in other program sections through pointers in its
linkage section. Therefore, R27 serves as the root pointer through
which all data can be referenced.
3.6.3 Calling Computed Addresses
Most calls are made to a fixed address whose value is determined by the time the program starts execution. However, certain cases are possible that cause the exact address to be unknown until the code is finally executed. In this case, the procedure value representing the procedure to be called is computed in a register.
The following code example illustrates a call to a computed procedure value (simple or bound) that is contained in R4:
LDQ R26,8(R4) ;Entry address to scratch register MOV R4,R27 ;Procedure value to R27 MOV #AI_LITERAL,R25 ;Load Argument Information register JSR R26,(R26) ;Call entry address. |
For interoperation with translated images, see Chapter 5
3.6.4 Simple and Bound Procedures
There are two distinct classes of procedures:
A simple procedure is a procedure that does not need direct access to the stack of its execution environment. A bound procedure is a procedure that does need direct access to the stack of its execution environment, typically to reference an up-level variable or to perform a nonlocal GOTO operation. Both a simple procedure and a bound procedure have an associated procedure descriptor, as described in previous sections.
When a bound procedure is called, the caller must pass some kind of pointer to the called code that allows it to reference its up-level environment. Typically, this pointer is the frame pointer for that environment, but many variations are possible. When the caller is executing its program within that outer environment, it can usually make such a call directly to the code for the nested procedure without recourse to any additional procedure descriptors. However, when a procedure value for the nested procedure must be passed outside of that environment to a call site that has no knowledge of the target procedure, a bound procedure descriptor is created so that the nested procedure can be called just like a simple procedure.
Bound procedure values, as defined by this standard, are designed for
multilanguage use and utilize the properties of procedure descriptors
to allow callers of procedures to use common code to call both bound
and simple procedures.
3.6.4.1 Bound Procedure Descriptors
Bound procedure descriptors provide a mechanism to interpose special processing between a call and the called routine without modifying either. The descriptor may contain (or reference) data used as part of that processing. Between native and translated images, the OpenVMS Alpha operating system uses linker and image-activator created bound procedure descriptors to mediate the handling of parameter and result passing (see Section 5.2). Language processors on OpenVMS Alpha systems use bound procedure descriptors to implement bound procedure values (see Section 3.6.4.2). Other uses are possible.
The minimum size of the descriptor is 24 bytes (defined by PDSC$K_MIN_BOUND_SIZE). An optional PDSC extension in 8-byte increments provides the specific environment values as defined by the implementation.
The fields defined in the bound procedure descriptor are illustrated in Figure 3-12 and described in Table 3-9.
Figure 3-12 Bound Procedure Descriptor (PDSC)
Field Name | Contents | ||
---|---|---|---|
PDSC$W_FLAGS |
Vector of flag bits <15:0> that must be a copy of the flag bits
(except for KIND bits) contained in the quadword pointed to by
PDSC$Q_PROC_VALUE.
|
||
PDSC$V_FUNC_RETURN |
A 4-bit field <11:8> that describes which registers are used for
the function value return (if there is one) and what format is used for
those registers.
PDSC$V_FUNC_RETURN in a bound procedure descriptor must be the same as the PDSC$V_FUNC_RETURN of the procedure descriptor for the procedure for which the environment is established. Table 5-4 lists and describes the possible encoding values of PDSC$V_FUNC_RETURN. |
||
Bits 12--15 | Reserved and must be 0. | ||
PDSC$W_SIGNATURE_OFFSET |
A 16-bit signed byte offset from the start of the procedure descriptor.
This offset designates the start of the procedure signature block (if
any). In a bound procedure, a 0 in this field indicates the actual
signature block must be sought in the procedure descriptor indicated by
the PDSC$Q_PROC_VALUE field. A 1 in this field indicates a standard
default signature. (An offset value of 1 is not a valid offset because
both procedure descriptors and signature blocks must be quadword
aligned. See Section 5.2 for details of the procedure signature
block.)
Note that a nonzero signature offset in a bound procedure value normally occurs only in the case of bound procedures used as part of the implementation of calls from native OpenVMS Alpha code to translated OpenVMS VAX images. In any case, if a nonzero offset is present, it takes precedence over signature information that might occur in any related procedure descriptor. |
||
PDSC$Q_ENTRY | Address of the transfer code sequence. | ||
PDSC$Q_PROC_VALUE | Value of the procedure to be called by the transfer code. The value can be either the address of a procedure descriptor for the procedure or possibly another bound procedure value. | ||
PDSC$Q_ENVIRONMENT | An environment value to pass to the procedure. The choice of environment value is system implementation specific. For more information, see Section 3.6.4.2. |
Previous | Next | Contents | Index |