8.1 Procedure Descriptor Representation

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:

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.

Use of Fields with Low-Bit Conventions

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

Properties of Procedures

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.