Linkage convention for function calls
In 64-bit
mode, a routine has two symbols associated
with it: a function descriptor (name) and an entry point (.name). When a call is made to a routine, the program branches to the entry
point directly. Excluding the loading of parameters (if any) in the proper
registers, compilers expand calls to functions to the following two-instruction
sequence:
BL .foo # Branch to foo
ORI R0,R0,0x0000 # Special NOP
The linker does one of two things
when it encounters a BL instruction:
- If foo is imported (not in the same object module), the linker changes
the BL to .foo to a BL to .glink (global
linkage routine) of foo and inserts the .glink into
the object module. Also, if a NOP instruction (ORI R0,R0,0x0000) immediately follows the BL instruction, the linker replaces
the NOP instruction with the LOAD instruction L R2,
20(R1).
- If foo is bound in the same object module as its caller and
a LOAD instruction L R2,20(R1) for 32-bit and L R2,40(R1) for 64-bit, or ORI R0,R0,0 immediately follows the BL instruction, the linker replaces the LOAD instruction with
a NOP (ORI R0,R0,0).
Note:
For any export, the linker inserts
the procedure's descriptor into the object module.
Pointers to functions
In 64-bit
mode, a function pointer is a data type
whose values range over procedure names. Variables of this type appear in
several programming languages, such as C and Fortran. In Fortran, a dummy
argument that appears in an EXTERNAL statement is a function pointer.
Fortran provides support for the use of function pointers in contexts such
as the target of a call statement or an actual argument of such a statement.
A function pointer is a fullword quantity
that is the address of a function descriptor. The function descriptor is a
3-word object. The first word contains the address of the entry point of the
procedure. The second has the address of the TOC of the object module in which
the procedure is bound. The third is the environment pointer for some non-Fortran
languages. There is only one function descriptor per entry point. It is bound
into the same object module as the function it identifies if the function
is external. The descriptor has an external name, which is the same as the
function name but with a different storage class that uniquely identifies
it. This descriptor name is used in all import or export operations.
Function values
Functions return their values according to type:
- In 32-bit mode, INTEGER and LOGICAL of kind 1, 2, and 4 are returned (sign/zero extended) in R3.
- In 64-bit mode, INTEGER and LOGICAL of kind 1, 2, and 4 are returned (right justified) in R3.
- In 64-bit mode, INTEGER and LOGICAL of kind 8 are returned in R3.
- REAL *4 or *8 are returned in FP1. REAL *16 are returned in FP1 and FP2.
- COMPLEX *8 or *16 are returned in FP1
and FP2. COMPLEX *32 are returned in FP1-FP4.
- In 32-bit
mode when -qfloat=complexgcc is specified, COMPLEX*8 is returned in R3-R4 and COMPLEX*16 in R3-R6. In 64-bit mode, COMPLEX*8 is returned in R3 and COMPLEX*16
in R3-R4.
- Vector results are returned in VPR2
- Character strings are returned in a buffer allocated by the caller. The
address and the length of this buffer are passed in R3 and R4 as hidden parameters.
The first explicit parameter word is in R5, and all subsequent parameters
are moved to the next word.
- Structures are returned in a buffer that is allocated by the caller. The
address is passed in R3; there is no length. The first explicit parameter
is in R4.
The Stack floor
In 64-bit mode, the stack floor is a system-defined address below which
the stack cannot grow. All programs in the system must avoid accessing locations
in the stack segment that are below the stack floor.
All programs must maintain other system invariants that are related to
the stack:
- No data is saved or accessed from an address lower than the stack floor.
- The stack pointer is always valid. When the stack frame size is more than
32 767 bytes, you must take care to ensure that its value is changed
in a single instruction. This step ensures that there is no timing window
where a signal handler would either overlay the stack data or erroneously
appear to overflow the stack segment.
Stack overflow
The linkage convention requires no explicit inline check for overflow.
The operating system uses a storage protection mechanism to detect stores
past the end of the stack segment.