HPlogo PA-RISC Procedure Calling Conventions Reference Manual > Chapter 5 Inter-Module Procedure Calls

5.2 External Calls on HP-UX

MPE documents

Complete PDF
Table of Contents

External calls occur on HP-UX, in both shared libraries and the programs which use them. A shared library contains subroutines that are shared by all programs that use them. Shared libraries are attached to the program at run time rather than copied into the program by the linker. Since the shared library code is not copied into the program file and is shared among several programs as a separate load module, an external call mechanism is needed.

In order for the object code in a shared library to be fully sharable, it must be compiled and linked in such a way that it does not depend on its position in the virtual addressing space of any particular process. In other words, the same physical copy of the code must work correctly in each process.

Position independence is achieved by two mechanisms. First, PC-relative addressing is used wherever possible for branches within modules and for accesses to literal data. Second, indirect addressing through a per-process linkage table is used for all accesses to global variables, for inter-module procedure calls and other branches and literal accesses where PC-relative addressing cannot be used. Global variables must be accessed indirectly since they may be allocated in the main program's address space, and even the relative position of the global variables may vary from one process to another.

Position-independent code (PIC) implies that the object code contains no absolute addresses. Such code can be loaded at any address without relocation, and can be shared by several processes whose data segments are allocated uniquely. This requirement extends to DP-relative references to data (these are considered absolute, since the DP register is essentially an absolute constant on HP-UX). In position-independent code all references to code and data must be either PC-relative or indirect. All indirect references are collected in a single linkage table that can be initialized on a per-process basis.

The Linkage Table (LT) itself is addressed in a position-independent manner by using a dedicated register, gr19, as a pointer to the Linkage Table. The linker generates import (calling) and export (called) stubs which set gr19 to the Linkage Table pointer value for the target routine, and handle the inter-space calls needed to branch between shared libraries.

The code in the program file itself does not need to be position independent, but it must access all external procedures through its own linkage table by using import stubs. The Linkage Table in shared libraries is accessed using a dedicated Linkage Table pointer (LTP), whereas the program file accesses the Linkage Table through the DP register.

Position independent code is generated by the compilers when the +z or +Z compilation flag is used. Code which is used in a shared library must be compiled with this flag. Code in the program file is compiled without this flag and the linker places the import/export stubs into the program file to handle calls to and from files which are external to the program load module.

5.2.1 Control Flow of an HP-UX External Call

The code generated by the compiler to perform a procedure call is the same whether the call is external or local. If the linker locates the procedure being called within the program file, it will make the call local by patching the BL instruction to directly reference the entry point of the procedure. If the linker determines that the called procedure is outside of the program file, it makes the call external by inserting an import stub (calling stub) into the calling code, and patching the BL instruction to branch to the stub. For any routine in the program file which the linker detects is called from outside of that program file, an export stub (called stub) is inserted into the program file's code.

When building a shared library (with the linker's ld - b flag), the linker generates import and export stubs for all procedures which can be called from outside of the shared library.

Figure 5-6 below shows the control flow of an external call on HP-UX.

Figure 5-6 HP-UX External Procedure Call

[Figure 5-6]

5.2.2 Calling Code

The calling code in program files is responsible for performing the standard procedure call steps regardless of whether the call is external or local. The linker generates an import stub to perform the additional steps required for external calls.

The import stub (calling stub) of an HP-UX external call performs the following steps:
  1. Loads the target (export stub) address of the procedure from the Linkage Table.

  2. Loads into gr19 the LTP (Linkage Table Pointer) value of the target load module.

  3. Saves the return pointer (RP'), since the export stub will overwrite RP with the return address into the export stub itself.

  4. Performs the interspace branch to the target export stub.

The code sequence of the import stub used in the program file is shown below:

  ;Import Stub (Program file) 

  X':   ADDIL   L'lt_ptr+ltoff,dp       ; load procedure entry point
        LDW     R'lt_ptr+ltoff(1),r21
        LDW     R'lt_ptr+ltoff+4(1),r19 ; load new gr19 value.
        LDSID   (r21),rl              ; load space id of proc. entry
        MTSP    rl,sr0                ; move space id from general
                                      ;   to space register
        BE      0(sr0,r21)            ; branch to target
        STW     rp,-24(sp)            ; save RP'

The difference between a shared library and program file import stub is that the Linkage Table is accessed using gr19 (the LTP) in a shared library, and is accessed using DP in the program file.

The code sequence of the import stub (calling stub) used in a shared library is shown below:

  ;Import Stub (Shared Library) 

  X':   ADDIL   L'ltoff,r19         ; load target (export stub)
                                    ; address
        LDW     R'ltoff(r1),r21     ;
        LDW     R'ltoff+4(r1),r19   ; load new gr19 (LTP) value
        LDSID   (r21),r1            ; load space id of target address
        MTSP    r1,sr0              ; move space id to space register
        BE      0(sr0,r21)          ; branch to target
        STW     rp,-24(sp)          ; save RP'

5.2.3 Called Code

The called code in shared library files is responsible for performing the standard procedure call steps regardless of whether the call is external or local.

The linker generates an export stub to perform the additional steps required for shared library external calls. The export stub is used to trap the return from the procedure and perform the steps necessary for an inter-space branch.

The export stub (called stub) of a shared library external call performs the following steps:
  1. Branches to the target procedure. The value stored in RP at this point is the return point into the export stub.

  2. Upon return from the procedure, restores the return pointer (RP').

  3. Performs an interspace branch to return to the caller.

The code sequence of the export stub is shown below:

  X':   BL,N    X,rp          ; trap the return
        NOP
        LDW     -24(sp),rp    ; restore the original RP
        LDSID   (rp),r1       ; load space id of return address
        MTSP    r1,sr0        ; move space id from general reg.
                              ;   to space reg.
        BE,N    0(sr0,rp)     ; inter-space return




5.1 External Calls on MPE XL


5.3 PIC Requirements for Compilers and Assembly Code