|
HP OpenVMS Calling Standard
4.8.2.1 Invocation Context Block
The context of a specific procedure invocation is provided through the
use of a data structure called an invocation context
block (ICB). Table 4-16 describes the contents of the
OpenVMS I64 invocation context block.
Table 4-16 Contents of the Invocation Context Block
Field |
Size |
Description |
LIBICB$L_CONTEXT_LENGTH
|
Longword
|
Unsigned total length in bytes of the invocation context block. See
Section 4.8.3.1.
|
LIBICB$V_FRAME_FLAGS
|
3 Bytes
|
See Table 4-17.
|
LIBICB$B_BLOCK_VERSION
|
Byte
|
ICB version; initial value of 2 for OpenVMS I64 (1 is for OpenVMS
Alpha). See Section 4.8.3.1.
|
LIBICB$IH_IREG
|
128 Quadwords
|
Array of general registers (only those allocated; unallocated registers
are uninitialized).
LIBICB$IH_IREG[0] is reserved.
IREG[1], the global data pointer, can be referenced using the
symbol LIBICB$IH_GP.
IREG[12], the memory stack pointer, can be referenced using the
symbol LIBICB$IH_SP.
IREG[13], the thread pointer, can be referenced using the symbol
LIBICB$IH_TP.
IREG[25], the argument information register, can be referenced
using the symbol LIBICB$IH_AI.
|
LIBICB$IH_GRNAT
|
2 Quadwords
|
General register NaT collection.
1
|
LIBICB$FO_F2_F31
|
30 Octawords
|
Floating-point registers F2-F31. Array of floating-point register
values in register format, as saved by a SPILL instruction.
|
LIBICB$PH_F32_F127
|
Quadword
|
Pointer to array of floating point values in register format for
registers F32-F127, as saved by SPILL instruction. A pointer value of 0
indicates that the contents of registers F32-F127 are not defined.
|
LIBICB$IH_BRANCH
|
8 Quadwords
|
Array of branch registers.
|
LIBICB$IH_RSC
|
Quadword
|
Register Stack Configuration register.
|
LIBICB$IH_BSP
|
Quadword
|
Backing store pointer.
|
LIBICB$IH_BSPSTORE
|
Quadword
|
Backing store write pointer.
|
LIBICB$IH_RNAT
|
Quadword
|
RSE NaT collection register.
|
LIBICB$IH_CCV
|
Quadword
|
Compare and Exchange Value register.
|
LIBICB$IH_UNAT
|
Quadword
|
User NaT collection register.
|
LIBICB$IH_PFS
|
Quadword
|
Previous function state.
|
LIBICB$IH_LC
|
Quadword
|
Loop count register.
|
LIBICB$IH_EC
|
Quadword
|
Epilogue Count register.
|
LIBICB$IH_CSD
|
Quadword
|
Copy of the AR.CSD.
|
LIBICB$IH_SSD
|
Quadword
|
Copy of the AR.SSD.
|
LIBICB$Q_PRED
|
Quadword
|
Predicate collection register, P0-P63. This field is a bitvector with
bit 0 reserved.
|
LIBICB$IH_PC
|
Quadword
|
Current instruction pointer; the slot number overlays <1:0>.
|
LIBICB$IH_CFM
|
Quadword
|
Current Frame Marker.
|
LIBICB$IH_UM
|
Quadword
|
User mask bits from PSR.
|
LIBICB$O_GR_VALID
|
Octaword
|
General Register validity mask.
2
|
LIBICB$L_FR_VALID
|
Longword
|
Floating-Point Register validity mask for registers F2-F31.
2
|
LIBICB$Q_BR_VALID
|
Quadword
|
Branch Register validity mask.
2
|
LIBICB$Q_AR_VALID
|
Quadword
|
Application Register validity mask.
2
|
LIBICB$Q_OTHER_VALID
|
Quadword
|
PC and CFM validity mask.
2
|
LIBICB$Q_PR_VALID
|
Quadword
|
Predicate Register validity mask.
2
|
LIBICB$IH_ORIGINAL_SPILL_ADDR
|
Quadword
|
Original address of the general register spill area
(normally &icb->LIBICB$IH_IREG[0]).
1
|
LIBICB$IH_PSP
|
Quadword
|
Previous stack pointer.
|
LIBICB$IH_RETURN_PC
|
Quadword
|
Return PC.
|
LIBICB$IH_PREV_BSP
|
Quadword
|
Previous BSP
|
LIBICB$PH_CHFCTX_ADDR
|
Quadword
|
Pointer to condition handler facility context block.
|
LIBICB$IH_OSSD
|
Quadword
|
Copy of OSSD from Unwind Information Block.
|
LIBICB$IH_HANDLER_FV
|
Quadword
|
Condition Handler Function Value.
|
LIBICB$PH_LSDA
|
Quadword
|
Address of the Language Specific Data Area of the Unwind Information
Block
|
Beginning of User Override Parameters (offset
LIBICB$R_UO_BASE)
|
LIBICB$Q_UO_FLAGS
|
Quadword
|
Operational flags:
LIBICB$V_UO_FLAG_CACHE_UNWIND - Cache unwind information during a
walk of the call stack. See Section 4.8.3.2.
|
LIBICB$IH_UO_IDENT
|
Quadword
|
User context variable; passed by value to the callback routines. See
Section 4.8.5.
|
LIBICB$PH_UO_READ_MEM
|
Quadword
|
Pointer to user
read memory routine. See Section 4.8.5.3.
|
LIBICB$PH_UO_GETUEINFO
|
Quadword
|
Pointer to user
get unwind entry information routine. See Section 4.8.5.1.
|
LIBICB$PH_UO_GETCONTEXT
|
Quadword
|
Pointer to user
get initial context routine. See Section 4.8.5.2.
|
LIBICB$PH_UO_WRITE_MEM
|
Quadword
|
Pointer to user
write memory routine. See Section 4.8.5.4.
|
LIBICB$PH_UO_WRITE_REG
|
Quadword
|
Pointer to user
write register routine. See Section 4.8.5.5.
|
LIBICB$PH_UO_MALLOC
|
Quadword
|
Pointer to user
memory allocate routine. See Section 4.8.5.6.
|
LIBICB$PH_UO_FREE
|
Quadword
|
Pointer to user
memory free routine. See Section 4.8.5.7.
|
End of user override parameters (length of LIBICB$K_UO_LENGTH)
|
LIBICB$L_ALERT_CODE
|
Longword
|
Stack walk detailed status. Alert codes are enumerated in the LIBICB
include files (see Section 4.8.3.7).
|
LIBICB$IH_SYSTEM_DEFINED [n]
|
n Quadwords
|
Variable-sized area; unused and undefined at this time.
|
1Bits in the field LIBICB$IH_GRNAT represent the NaT bits
for the general registers. The bit position for a given register is
relative to its original spill location, the base address of which is
stored at LIBICB$IH_ORIGINAL_SPILL_ADDR. The first quadword of
LIBICB$IH_GRNAT contains the NaT bits for R0-R63, the second quadword
contains the NaT bits for R64-R127. The formula for the bit
corresponding to register Rn within each quadword is
uint64 * spill = (uint64 *)icb->LIBICB$IH_ORIGINAL_SPILL_ADDR;
uint64 bitpos = (((uint64)&spill[n]) >> 3) & 63;
uint64 bitmask = 1LL << bitpos;
2The valid bit mask indicates which registers have
been realized for a given invocation context. Normally, scratch
registers are not realizable except for a context immediately preceding
an exception or AST frame. Refer to the LIBICB include files to find
the bit position for the Application Registers, AR.RSC being bit 0.
Table 4-17 Flags in LIBICB$V_FRAME_FLAGS Field of the invocation context block
Flag |
Description |
LIBICB$V_BOTTOM_OF_STACK
|
Set to 1 if this is the bottom of the stack and there is absolutely no
previous frame.
|
LIBICB$V_HANDLER_PRESENT
|
Set to 1 if this frame has a condition handler.
|
LIBICB$V_IN_PROLOGUE
|
Set to 1 if the PC is in a prologue region.
|
LIBICB$V_IN_EPILOGUE
|
Set to 1 if the PC is in an epilogue region.
|
LIBICB$V_HAS_MEM_STK_FRAME
|
Set to 1 if this frame has a memory stack.
|
LIBICB$V_HAS_REG_STK_FRAME
|
Set to 1 if this frame has a register stack.
|
Static scratch registers, unless saved and described in the unwind
table information, are not realizable except for an invocation context
preceding an exception or AST frame.
4.8.2.2 Invocation Context Handle
To refer to a specific procedure invocation at run time, an
invocation context handle (ICH) can be used. The
invocation context handle is a quadword that uniquely identifies any
one of the active frames on a call stack, even when one or more of the
frames correspond to procedures that have no associated stack storage.
The characteristics of the caller are used to determine the invocation
context handle. If the caller has a register frame, then the RSE
Backing Store Pointer (BSP) is used as the handle; otherwise, the
caller's Stack Pointer is used. (The caller's Stack Pointer is
sometimes called Stack Pointer on Entry or Previous Stack Pointer
(PSP).)
4.8.3 Invocation Context Block Access Routines
A thread can manipulate the invocation context of any procedure in the
thread's virtual address space by calling the run-time library
functions described in this section.
Note
The OpenVMS I64 stack tracing routines use heap storage
during the analysis of unwind descriptors. The default heap storage
mechanism uses a LIBRTL implementation of the C RTL function
malloc, the use of which may result in virtual memory being
expanded using the $EXPREG system service. See Section 4.8.5 on how to
override the defaults. See also Section 4.8.3.12.
|
4.8.3.1 Initializing the Invocation Context Block
When allocating a new invocation context block, the user must perform
the following steps prior to calling any of the routines described in
Section 4.8.3:
- Allocate the block on an octaword (16-byte) boundary.
- Clear (set to all zero bytes) the entire block.
- Initialize the LIBICB$L_CONTEXT_LENGTH field to
LIBICB$K_INVO_CONTEXT_BLK_SIZE and the LIBICB$B_BLOCK_VERSION field to
LIBICB$K_INVO_CONTEXT_VERSION.
- Set any required parameters in the user override portion
of the invocation context block.
- Set the LIBICB$V_UO_FLAG_CACHE_UNWIND flag if appropriate. See
also Section 4.8.3.2 and Section 4.8.3.12 regarding subsequent use of
LIB$I64_PREV_INVO_END.
Failure to do so will cause these routines to return an error status.
Note that this is a change from Alpha, where initialization was not
necessary.
To simplify the initialization process, the following convenience
routines are provided:
4.8.3.2 Walking the Call Stack
During the course of program execution, it is sometimes necessary to
walk the call stack. Frame-based exception handling is one case where
this is done. Call stack navigation is possible only in the reverse
direction (in a latest-to-earliest or top-to-bottom sequence).
To walk the call stack, perform the following steps:
- Given a program state (which contains a register set), build an
invocation context.
For the current routine, an initial invocation
context block can be obtained by calling the
LIB$I64_GET_CURR_INVO_CONTEXT routine (see Section 4.8.3.7).
- Repeatedly call the LIB$I64_GET_PREV_INVO_CONTEXT routine (see
Section 4.8.3.8) until the desired invocation context, or the end of the
call chain, has been reached.
LIB$I64_GET_PREV_INVO_CONTEXT
indicates the end of the invocation call chain if either of the
following conditions is true:
- The OSSD$V_BOTTOM_OF_STACK flag is set for the target frame (see
Table A-14).
- The return address (IP) of the target frame is zero.
To make the stack walk more efficient, you can set the
LIBICB$V_UO_FLAG_CACHE_UNWIND flag. This causes unwind information to
be carried over from one call to LIB$I64_GET_PREV_INVO_CONTEXT to the
next. At the conclusion of the stack walk, you must call
LIB$I64_PREV_INVO_END to free any cached unwind information. This is
the recommended practice, but not the default behavior.
Compilers are allowed to optimize high-level language procedure calls
in such a way that they do not appear in the invocation chain. For
example, inline procedures never appear in the invocation chain.
Make no assumptions about the relative positions of any memory used for
procedure frame information. There is no guarantee that successive
stack frames will always appear at higher addresses.
4.8.3.3 LIB$I64_CREATE_INVO_CONTEXT
This convenience routine simplifies creating and properly initializing
an invocation context block. The routine allocates an invocation
context block from heap storage and initializes it according to the
steps described in Section 4.8.3.1. Users of this routine should call
LIB$I64_FREE_INVO_CONTEXT when the invocation context block is no
longer required.
This routine sets the cache unwind flag LIBICB$V_UO_FLAG_CACHE_UNWIND
in the invocation context block to speed the stack walk. Do not use
this routine in conjunction with LIB$I64_INIT_INVO_CONTEXT, as the same
initialization is performed by both routines.
LIB$I64_CREATE_INVO_CONTEXT ([malloc] [, free] [, ident])
|
Argument |
OpenVMS Usage |
Type |
Access |
Mechanism |
malloc
|
function_value
|
procedure
|
read
|
by value
|
free
|
function_value
|
procedure
|
read
|
by value
|
ident
|
user_value
|
quadword
|
read
|
by value
|
Arguments:
|
malloc
A procedure reference for a user callback routine that allocates
memory. See Section 4.8.5.6 for details of this routine. This is an
optional argument. The default is to use an implementation of the C RTL
routine
malloc. If specified, this routine is used to allocate
the invocation context block and is also placed in the invocation
context block field LIBICB$PH_UO_MALLOC for use during the stack walk.
|
|
free
A procedure reference for a user callback routine that deallocates
memory. This value is placed in the invocation context block field
LIBICB$PH_UO_FREE. See Section 4.8.5.7 for details on this routine. This
is an optional argument; however, it must be specified if
malloc is specified. The default is to use an
implementation of the C RTL routine
free.
|
|
ident
Specifies a user ident value to be placed in the invocation
context block LIBICB$IH_UO_IDENT field. In turn, this value is passed
to the
malloc and
free routines, described in Section 4.8.5.6 and
Section 4.8.5.7 respectively. This is an optional argument; the default
value is zero.
|
Function Value Returned:
|
invo_context
A non-zero value represents the address of the invocation context
block allocated.
A value of 0 indicates failure.
|
4.8.3.4 LIB$I64_FREE_INVO_CONTEXT
Deallocates an invocation context block that was previously allocated
using LIB$I64_CREATE_INVO_CONTEXT. This routine calls
LIB$I64_PREV_INVO_END as a convenience.
LIB$I64_FREE_INVO_CONTEXT (invo_context)
|
Argument |
OpenVMS Usage |
Type |
Access |
Mechanism |
invo_context
|
invo_context_blk
|
structure
|
modify
|
by reference
|
Argument:
|
invo_context
Address of an invocation context block.
|
Function Value Returned:
4.8.3.5 LIB$I64_INIT_INVO_CONTEXT
Initializes an invocation context block that the user has already
allocated (on the stack, or from heap, or other storage) in accordance
with Section 4.8.3.1. Use this routine as an alternative to
LIB$I64_CREATE_INVO_CONTEXT, which both allocates and initializes an
invocation context block.
LIB$I64_INIT_INVO_CONTEXT (invo_context, invo_version
[, cache_unwind_flag])
|
Argument |
OpenVMS Usage |
Type |
Access |
Mechanism |
invo_context
|
invo_context_blk
|
structure
|
modify
|
by reference
|
invo_version
|
version_number
|
byte
|
read
|
by value
|
cache_unwind_flag
|
flag
|
longword
|
read
|
by value
|
Arguments:
|
invo_context
Address of an invocation context block.
|
|
invo_version
The value LIBICB$K_INVO_CONTEXT_VERSION. This is used to verify
the operating environment.
|
|
cache_unwind_flag
A flag indicating if the cache unwind flag,
LIBICB$V_UO_FLAG_CACHE_UNWIND, should be set in the invocation context
block. A value of zero clears the flag; a value of one sets the flag.
This is an optional argument. The default is zero.
|
Function Value Returned:
|
status
A value of 1 indicates success.
A value of 0 indicates a version number mismatch.
|
|