Intermodule calls using the toc

The data section is accessed through TOC using a feature that allows intermodule calls to be used.

Because the only access from the text to the data section is through the TOC, the TOC provides a feature that allows intermodule calls to be used. As a result, routines can be linked together without resolving all the addresses or symbols at link time. In other words, a call can be made to a common utility routine without actually having that routine linked into the same module as the calling routine. In this way, groups of routines can be made into modules, and the routines in the different groups can call each other, with the bind time being delayed until load time. In order to use this feature, certain conventions must be followed when calling a routine that is in another module.

To call a routine in another module, an interface routine (or global linkage routine) is called that switches context from the current module to the new module. This context switch is easily performed by saving the TOC pointer to the current module, loading the TOC pointer of the new module, and then branching to the new routine in the other module. The other routine then returns to the original routine in the original module, and the original TOC address is loaded into the TOC register.

To make global linkage as transparent as possible, a call can be made to external routines without specifying the destination module. During bind time, the binder (linkage editor) determines whether to call global linkage code, and inserts the proper global linkage routine to perform the intermodule call. Global linkage is controlled by an import list. An import list contains external symbols that are resolved during run time, either from the system or from the dynamic load of another object file. See the ld command for information about import lists.

The following example calls a routine that may go through global linkage:

.csect  prog1[PR]
...
.extern prog2[PR]        #prog2 is an external symbol.
bl      .prog2[PR]       #call prog2[PR], binder may insert
                         #global linkage code.
cror    31,31,31         #place holder for instruction to
                         #restore TOC address.
The following example shows a call through a global linkage routine:

#AIX® linkage register conventions:
#        R2      TOC
#        R1      stack pointer
#        R0, R12 work registers, not preserved
#        LR      Link Register, return address.
         .csect  .prog1[PR]
         bl      .prog2[GL]             #Branch to global
                                        #linkage code.
         l        2,stktoc(1)           #Restore TOC address
         .toc
prog2:  .tc       prog2[TC],prog2[DS]   #TOC entry:
                                        # address of descriptor
                                        # for out-of-module
                                        # routine
        .extern   prog2[DS]
##
## The following is an example of global linkage code.
        .set      stktoc,20
        .csect   .prog2[GL]
        .globl   .prog2
.prog2:  l        12,prog2(2)           #Get address of
                                        #out-of-module
                                        #descriptor.
         st       2,stktoc(1)           #save callers' toc.
         l        0,0(12)               #Get its entry address
                                        #from descriptor.
         l        2,4(12)               #Get its toc from
                                        #descriptor.
         mtctr    0                     #Put into Count Register.
         bctr                           #Return to entry address
                                        #in Count Register.
                                        #Return is directly to
                                        #original caller.