In describing the representation and use of procedure descriptors, it is necessary to consider the requirements of procedures that have more than one entry. For that purpose, we define the following terms: The primary entry of a non-null frame procedure is the entry whose prologue is described by the primary procedure descriptor. A secondary entry is any entry other than the primary entry. Note that due to the effects of optimization, the primary entry of a procedure does not necessarily correspond to the lexically first entry to be declared in the program source or to the entry with the lowest address in the code.
Procedure descriptors (also known as function entries) on Windows NT for Alpha Systems consist of a structure as shown in Figure 8-1. The fields of this structure are defined in as follows.
Figure 8-1 Procedure Descriptor
RUNTIME_FUNCTION longword-aligned
31 210
+---------------+--------------+---------------+---------------+
| BeginAddress |RD*| :0
| | |
+---------------+--------------+---------------+---------------+
| EndAddress |RD*| :4
| | |
+---------------+--------------+---------------+---------------+
| ExceptionHandler |EM*| :8
| |RD*|
+---------------+--------------+---------------+---------------+
| HandlerData |DT*| :12
| | |
+---------------+--------------+---------------+-----------+---+
| PrologEndAddress |EM*| :16
| | |
+---------------+--------------+---------------+-----------+---+
sizeof(RUNTIME_FUNCTION) == 20
* EM is an abbreviation for ExceptionMode
RD is an abbreviation for "Reserved to Digital"
DT is an abbreviation for DescriptorType
BeginAddress
The address of the first instruction of the range of instructions that is described by the procedure descriptor. In common simple cases, this is the address of the first instruction and entry point of a procedure.
Note that BeginAddress is a longword address of an instruction, in which the two low-order bits are reserved for future use (see below).
EndAddress
The address of the first instruction following the range of instructions that is described by the procedure descriptor. In common simple cases, this is the address of the instruction immediately following the last instruction of the procedure.
Note EndAddress is a longword address of an instruction, in which the two low-order bits are reserved for future use (see below).
ExceptionHandler
The address of the exception handler for the range of instructions described by this procedure descriptor. If there is no associated handler, then this field contains null (0).
Note ExceptionHandler is a longword address. Bit 0 of the longword that contains this field is part of the ExceptionMode field; bit 1 is reserved.
This field (exclusive of the reserved bit) must be null in a secondary procedure descriptor.
HandlerData
The longword address or the immediate value of associated data for use by the handler for this procedure. If ExceptionHandler is null, then the low-order two bits of the longword that contains this field are used for the DescriptorType field and the remaining bits must be zero. This field (exclusive of the DescriptorType bits) must be zero in a secondary procedure descriptor.
PrologEndAddress
Serves to describe a portion of the code between BeginAddress and EndAddress that is prologue code and/or to relate one procedure descriptor to another when both correspond to the same procedure.
If BeginAddress ≤≤ PrologEndAddress < EndAddress, then PrologEndAddress is the address of the first instruction following a (the) prologue of the procedure. (In a procedure that has no prologue, PrologEndAddress = BeginAddress.)
Such a procedure descriptor is always the primary procedure descriptor for the procedure.
Otherwise, PrologEndAddress contains the address of the primary procedure descriptor associated with this descriptor. In this case, note that the ExceptionHandler, HandlerData (exclusive of the DescriptorType bits), and ExceptionMode fields must be zero. The specific characteristics of this procedure descriptor are further determined by the contents of the DescriptorType field as follows:
This case is typically used for code that follows the prologue associated with a secondary entry (as described below) or for code that is not contiguous with the code that contains the (an) entry point of a procedure.
This case is typically used to describe the prologue code associated with a secondary entry of a procedure that has multiple entry points (as can occur, for example, in Fortran or assembler). Note that if a secondary entry for a procedure has no prologue code, then a separate procedure descriptor for the prologue is omitted (rather than using a procedure descriptor in which BeginAddress is the same as EndAddress).
This case is typically used when, for optimization, it is desirable to have an initial entry sequence that is not subject to unwinding prior to the beginning of the prologue (such as for so-called shrink-wrapping) or to have a final epilogue sequence that is longer than and/or different from that described in subsection "Reserved Instruction Sequence for Procedure Exit" of Section 3.2.6. In both cases, the procedure descriptor describes code that can be considered to execute in a null procedure context (see Section 3.1.4, Null Frame Procedure) but that is also part of a larger procedure.
Note All other combinations are reserved for future use.
It follows from these rules that, given a procedure descriptor, it is always possible to find the unique primary procedure descriptor for the procedure in, at most, one step without any further lookups or searches.
If there is more than one combination of procedure descriptors that can correctly describe the code of a procedure, then any of them may be used; however, one that uses the smallest number of procedure descriptors is strongly recommended. Recall that every such combination must include exactly one primary procedure descriptor.
Note PrologEndAddress is a longword address. The low two bits of the longword that contains this field are used for the ExceptionMode field.
ExceptionMode
Encodes the caller's desired exception reporting behavior when calling certain mathematically oriented library routines. The 3-bit integer value is formed from bit 0 of the ExceptionHandler field (the MSB) and bits 0 (the LSB) and 1 of the PrologEndAddress field.
The possible values for this field are as follows:
Name | Meaning |
EXCEPTION_MODE_SILENT | Raise no exceptions; create only finite values (no infinities, denormals nor NaNs). In this mode, either the function result or the C language errno variable must be examined for any error indication. This is the default mode. |
EXCEPTION_MODE_SIGNAL | Raise exceptions for all error conditions except for underflow, which results in a zero result. |
EXCEPTION_MODE_SIGNAL_ALL | Raise exceptions for all error conditions (including underflow). |
EXCEPTION_MODE_FULL_IEEE | Raise no exceptions except as controlled by separate IEEE exception enable bits; create infinite, denormal and NaN values according to the IEEE floating-point standard. |
EXCEPTION_MODE_CALLER | Perform the exception mode behavior specified by this procedure's caller. |
This field must be zero in a secondary procedure descriptor.
For a more complete description of these exception modes and how they are used, see the Windows NT for Alpha Systems system documentation.
DescriptorType
Encodes the specific kind of descriptor present for secondary procedure descriptors. See PrologEndAddress above for details.
The set of procedure descriptors of an executable image are all collected together in a single contiguous array and sorted according to the values of the BeginAddress field.
Several of the fields of a procedure descriptor are defined as longword addresses (of type void *); however, the low-order two bits of each of those fields is reserved for other purposes. It is necessary to mask off these two bits prior to use for its normal purpose.
For example, a C macro to obtain the BeginAddress value given a pointer to a procedure descriptor might be written as follows:
#define BEGIN_ADDRESS(PD) (((PD)->BeginAddress) & (~3))
For purposes of call chain tracing (see Chapter 7, Procedure Invocations and Call Chains) and unwinding (see Section 5.2, Unwinding), the properties of a procedure are determined in part by the values in the procedure descriptor as defined above and in part by reverse execution of the procedure prologue.
These properties are determined as follows.
REGISTER _FRAME
Value of 1 if there is no instruction in the prologue that stores into the stack.
BASE _REG _IS _FP
Value of 1 if the last instruction in the prologue is an instruction that copies the contents of the stack pointer (SP) to the frame pointer (FP).
HANDLER _VALID
Value of 1 if the ExceptionHandler field of the procedure descriptor is non-null.
EXCEPTION _MODE
Specified in the ExceptionMode field of the procedure descriptor.
SP _SET
The unsigned offset in instructions (longwords) from the entry address of the procedure given in the BeginAddress field of the descriptor to the one and only one instruction in the procedure prologue that modifies the stack pointer. (This offset is assumed to be zero when there is no such instruction because the procedure has a FRAME_SIZE of 0.)
ENTRY _LENGTH
The unsigned offset in instructions (longwords) formed by taking the PrologEndAddress less the BeginAddress and dividing by 4.
FRAME _SIZE
The unsigned size in quadwords of the fixed portion of the stack frame for this procedure. This value is found in the displacement field (divided by 8) of the instruction that modifies the stack pointer, or is zero if there is no such instruction.
Note If a procedure requires a frame size that is too large to be represented using the displacement field of an instruction, then the size must be loaded from memory or otherwise materialized into a register and then subtracted from the stack pointer using a SUBQ*,*,SP instruction.
BEGIN _ADDRESS
Specified in the BeginAddress field of the procedure descriptor.
END _ADDRESS
Specified in the EndAddress field of the procedure descriptor.
PROLOG _END _ADDRESS
Specified in the PrologEndAddress field of the procedure descriptor.
HANDLER _ADDRESS
Specified in the ExceptionHandler field of the procedure descriptor.
HANDLER _DATA
Specified in the HandlerData field of the procedure descriptor.
ENTRY _RA
Always register R26.