Document revision date: 19 July 1999 | |
Previous | Contents | Index |
Since accessible memory may be available at addresses lower than those occupied by the guard region, compilers must generate code that never extends the stack past the guard pages into accessible memory that is not allocated to the thread's stack.
A general strategy is to access each page of memory down to and possibly including the page corresponding to the intended new value for the SP. If the stack is to be extended by an amount larger than the size of a memory page, then a series of accesses is required that works from higher to lower addressed pages. If any access results in a memory access violation, then the code has made an invalid attempt to extend the stack of the current thread.
An access can be performed by using either a load or a store operation; however, be sure to use an instruction that is guaranteed to make an access to memory. For example, do not use an LDQ R31,* instruction, because the Alpha architecture does not allow any memory access, even a read access, whose result is discarded because of the R31 destination. |
This standard defines two methods for stack limit checking: implicit and explicit.
Two mutually exclusive strategies for implicit stack limit checking are:
The stack frame format (see Section 3.4.3) and entry code rules (see Section 3.7.5) generally do not ensure access to the lowest address of a new stack region without introducing an extra access solely for that purpose. Consequently, this standard uses the second strategy. While the amount of implicit stack extension that can be achieved is smaller, the check is achieved at no additional cost.
This standard requires that the minimum guard region size is 8192 bytes, the size of the smallest memory protection granularity allowed by the Alpha architecture.
Therefore, if the stack is being extended by an amount less than or equal to 4096 and a reserve region is not required, then explicit stack limit checking is not required.
However, because asynchronous interrupts and calls to other procedures may also cause stack extension without explicit stack limit checking, stack extension with implicit limit checking must adhere to a strict set of conventions:
These conventions ensure that the stack pointer is not decremented so that it points to accessible storage beyond the stack limit without this error being detected (either by the guard region being accessed by the thread or by an explicit stack limit check failure).
As a matter of practice, the system can provide multiple guard pages in the guard region. When a stack overflow is detected as a result of access to the guard region, one or more guard pages can be unprotected for use by the exception-handling facility, and one or more guard pages can remain protected to provide implicit stack limit checking during exception processing. However, the size of the guard region and the number of guard pages is system defined and is not defined by this standard.
If the stack is being extended by an amount of unknown size or by a known size greater than the maximum implicit check size (4096), then a code sequence that follows the rules for implicit stack limit checking can be executed in a loop to access the new stack region incrementally in segments lesser than or equal to the minimum page size (8192 bytes). At least one access must occur in each such segment. The first access must occur between SP and SP - 4096 because, in the absence of more specific information, the previous guaranteed access relative to the current stack pointer may be as much as 4096 bytes greater than the current stack pointer address. The last access must be within 4096 bytes of the intended new value of the stack pointer. These accesses must occur in order, starting with the highest addressed segment and working toward the lowest addressed segment.
A simple algorithm that is consistent with this requirement (but achieves up to twice the minimum number of accesses) is to perform a sequence of accesses in a loop starting with the previous value of SP, decrementing by the minimum no-check extension size (4096) to, but not including, the first value that is less than the new value for the stack pointer. |
The stack must not be extended incrementally in procedure prologues. A procedure prologue that needs to extend the stack by an amount of unknown size or known size greater than the minimum implicit check size must test new stack segments as just described in a loop that does not modify SP, and then update the stack with one instruction that copies the new stack pointer value into the SP.
An explicit stack limit check can be performed either by inline code that is part of a prologue or by a run-time support routine that is tailored to be called from a procedure prologue. |
The size of the reserve region must be included in the increment size
used for stack limit checks, after which it is not included in the
amount by which the stack is actually extended. (Depending on the size
of the reserve region, this may partially or even completely eliminate
the ability to use implicit stack limit checking.)
3.10.1.4 Stack Overflow Handling
If a stack overflow is detected, one of the following results:
Note that if a transparent stack extension is performed, a stack overflow that occurs in a called procedure might cause the stack to be extended. Therefore, the TEB stack limit value must be considered volatile and potentially modified by external procedure calls and by handling of exceptions.
This chapter defines the argument-passing data types that are used to call a procedure for both VAX and Alpha environments. All features defined here apply to both OpenVMS VAX and OpenVMS Alpha systems unless otherwise noted.
Each data type implemented for a high-level language uses one of the following classes of VAX data types for procedure parameters and elements of file records:
When existing data types fail to satisfy the semantics of a language, new data types, including certain language-specific ones, are added to this standard. These data types can generally be passed by immediate value (if 32 bits or less), by reference, or by descriptor.
Each data type code presented in this chapter indicates a unique data format. Use these encodings whenever you need to identify data types to achieve greater commonality across user software.
The encoding given in Sections 4.1 and 4.2 can help you to identify data types, such as in a descriptor. However, in addition to their use in descriptors, these data type codes are also useful for identifying VAX and Alpha data types in areas outside the scope of the calling standard. Therefore, each data-type code indicates a unique data format independent of its use in descriptors.
Some data types are composed of a recordlike structure consisting of two or more elementary data types. For example, the F_floating complex (FC) data type is made up of two F_floating data types, and the varying character string (VT) data type is made up of a word (unsigned, WU) data type followed by a character string (T) data type.
Unless stated otherwise, all data types in this standard represent
signed quantities. The unsigned quantities do not allocate space for
the sign; all bit or character positions are used for significant data.
4.1 Atomic Data Types
Table 4-1 shows how atomic data types are defined and encoded for VAX and Alpha environments.
Symbol | Code | Name/Description |
---|---|---|
DSC$K_DTYPE_Z | 0 |
Unspecified
The calling program has specified no data type. The default argument for the called procedure should be the correct type. |
DSC$K_DTYPE_BU | 2 |
Byte (unsigned)
8-bit unsigned quantity. |
DSC$K_DTYPE_WU | 3 |
Word (unsigned)
16-bit unsigned quantity. |
DSC$K_DTYPE_LU | 4 |
Longword (unsigned)
32-bit unsigned quantity. |
DSC$K_DTYPE_QU | 5 |
Quadword (unsigned)
64-bit unsigned quantity. |
DSC$K_DTYPE_OU | 25 |
Octaword (unsigned)
128-bit unsigned quantity. |
DSC$K_DTYPE_B | 6 |
Byte integer (signed)
8-bit signed two's complement integer. |
DSC$K_DTYPE_W | 7 |
Word integer (signed)
16-bit signed two's complement integer. |
DSC$K_DTYPE_L | 8 |
Longword integer (signed)
32-bit signed two's complement integer. |
DSC$K_DTYPE_Q | 9 |
Quadword integer (signed)
64-bit signed two's complement integer. |
DSC$K_DTYPE_O | 26 |
Octaword integer (signed)
128-bit signed two's complement integer. |
DSC$K_DTYPE_F | 10 |
F_floating
32-bit F_floating quantity representing a single-precision number. |
DSC$K_DTYPE_D 1 | 11 |
D_floating
64-bit D_floating quantity representing a double-precision number. |
DSC$K_DTYPE_G | 27 |
G_floating
64-bit G_floating quantity representing a double-precision number. |
+DSC$K_DTYPE_H 2 | 28 |
H_floating
128-bit H_floating quantity representing a quadruple-precision number. |
DSC$K_DTYPE_FC | 12 |
F_floating complex
Ordered pair of F_floating quantities representing a single-precision complex number. The lower addressed quantity is the real part; the higher addressed quantity is the imaginary part. |
DSC$K_DTYPE_DC | 13 |
D_floating complex
Ordered pair of D_floating quantities representing a double-precision complex number. The lower addressed quantity is the real part; the higher addressed quantity is the imaginary part. |
DSC$K_DTYPE_GC | 29 |
G_floating complex
Ordered pair of G_floating quantities representing a double-precision complex number. The lower addressed quantity is the real part; the higher addressed quantity is the imaginary part. |
+DSC$K_DTYPE_HC 2 | 30 |
H_floating complex
Ordered pair of H_floating quantities representing a quadruple-precision complex number. The lower addressed quantity is the real part; the higher addressed quantity is the imaginary part. |
++DSC$K_DTYPE_FS | 52 |
S_floating
32-bit IEEE S_floating quantity representing a single-precision number. |
++DSC$K_DTYPE_FT | 53 |
T_floating
64-bit IEEE T_floating quantity representing a double-precision number. |
++DSC$K_DTYPE_FSC | 54 |
S_floating complex
Ordered pair of S_floating quantities representing a single-precision complex number. The lower addressed quantity is the real part; the higher addressed quantity is the imaginary part. |
++DSC$K_DTYPE_FTC | 55 |
T_floating complex
Ordered pair of T_floating quantities representing a single-precision complex number. The lower addressed quantity is the real part; the higher addressed quantity is the imaginary part. |
++DSC$K_DTYPE_FX | 57 |
X_floating
128-bit IEEE X_floating quantity representing an extended-precision number. |
++DSC$K_DTYPE_FXC | 58 |
X_floating complex
Ordered pair of X_floating quantities representing an extended-precision complex number. The lower addressed quantity is the real part; the higher addressed quantity is the imaginary part. |
String data types are ordinarily described by a string descriptor. Table 4-2 shows how the string data types are defined and encoded for OpenVMS VAX and OpenVMS Alpha environments.
Symbol | Code | Name/Description |
---|---|---|
DSC$K_DTYPE_T | 14 |
Character string
A single 8-bit character (atomic data type) or a sequence of 0 to 2 16 - 1 eight-bit characters (string data type). |
DSC$K_DTYPE_VT | 37 |
Varying character string
A 16-bit unsigned count of the current number of 8-bit characters in the following string, followed by a string of 0 to 2 16 - 1 eight-bit characters (see Section 4.5 for details). When this data type is used with descriptors, it can only be used with the varying string and varying string array descriptors, because the length field is interpreted differently from the other 8-bit string data types. (See Sections 4.5, 5.8, and 5.9 for further discussion.) |
DSC$K_DTYPE_NU | 15 | Numeric string, unsigned |
DSC$K_DTYPE_NL | 16 | Numeric string, left separate sign |
DSC$K_DTYPE_NLO | 17 | Numeric string, left overpunched sign |
DSC$K_DTYPE_NR | 18 | Numeric string, right separate sign |
DSC$K_DTYPE_NRO | 19 | Numeric string, right overpunched sign |
DSC$K_DTYPE_NZ | 20 | Numeric string, zoned sign |
DSC$K_DTYPE_P | 21 | Packed-decimal string |
DSC$K_DTYPE_V | 1 |
Aligned bit string
A string of 0 to 2 16 - 1 contiguous bits. The first bit is bit <0> of the first byte, and the last bit is any bit in the last byte. Remaining bits in the last byte must be 0 on read and are cleared on write. Unlike the unaligned bit string (VU) data type, when the aligned bit string (V) data type is used in array descriptors, the ARSIZE field is in units of bytes, not bits, because allocation is a multiple of 8 bits. |
DSC$K_DTYPE_VU | 34 |
Unaligned bit string
The data is 0 to 2 16 - 1 contiguous bits located arbitrarily with respect to byte boundaries. See also aligned bit string (V) data type. Because additional information is required to specify the bit position of the first bit, this data type can be used only with the unaligned bit string and unaligned bit array descriptors (see Sections 5.10 and 5.11). |
Table 4-3 shows how miscellaneous data types are defined and encoded for the OpenVMS VAX and OpenVMS Alpha environments.
Symbol | Code | Name/Description |
---|---|---|
+DSC$K_DTYPE_ZI | 22 | Sequence of instructions |
+DSC$K_DTYPE_ZEM | 23 | Procedure entry mask |
DSC$K_DTYPE_DSC | 24 |
Descriptor
This data type allows a descriptor to be a data type; thus, levels of descriptors are allowed. |
+DSC$K_DTYPE_BPV | 32 |
Bound procedure value (for VAX environment only)
A two-longword entity in which the first longword contains the address of a procedure entry mask and the second longword is the environment value. The environment value is determined in a language-specific manner when the original bound procedure value is generated. When the bound procedure is called, the calling program loads the second longword into R1. When the environment value is not needed, this data type can be passed using the immediate value mechanism. In this case, the argument list entry contains the address of the procedure entry mask and the second longword is omitted. |
DSC$K_DTYPE_BLV | 33 |
Bound label value
A two-longword entity in which the first longword contains the address of an instruction and the second longword is the language-specific environment value. The environment value is determined in a language-specific manner when the original bound label value is generated. |
DSC$K_DTYPE_ADT | 35 |
Absolute date and time
A 64-bit unsigned, scaled, binary integer representing a date and time in 100-nanosecond units offset from the OpenVMS operating system base date and time, which is 00:00 o'clock, November 17, 1858 (the Smithsonian base date and time for astronomical calendars). The value 0 indicates that the date and time have not been specified, so a default value or distinctive print format can be used. Note that the ADT data type is the same as the OpenVMS date format for positive values only. |
Previous | Next | Contents | Index |
privacy and legal statement | ||
5973PRO_009.HTML |