2.4. Supported link methods on AIX

In order to link application program code with objects and libraries, AIX supports several link methods shown in Table 2-3 on page 64 (for the definition of terms used in this table, see Table B-1 on page 443). These methods are not mutually exclusive, except for the combination of lazy loading and run-time link methods. Therefore, an executable can be generated using more than one link methods.

Table 2-3. Supported link methods
Link methodSymbol resolutionSymbol reboundModule loadingLinker optionExplained section
Defaultlink-timeN/Aprogram load-timeN/ASection 2.4.1, “AIX default linking” on page 64
Staticlink-timeN/Aprogram load-time[a]-bstaticSection 2.4.2, “Static linking” on page 66
Lazy loading[b]link-timeN/Arun time-blazySection 2.4.3, “Lazy loading” on page 67
Run timelink-timeprogram load-timeprogram load-time-brtlSection 2.5, “Run-time linking” on page 68
Dynamic loading[c]run timeN/ASection 2.6, “Dynamic loading” on page 82

[a] Program text of statically linked objects and archive members are contained in the executable file.

[b] The lazy loading is actually a variation of the default link method. Except for the timing when referenced shared modules are loaded, the behavior is quite similar to the default link method.

[c] Dynamic loading is a programming scheme provided by a set of sub-routines rather than by linker options or special object file types.

2.4.1. AIX default linking

The linker can handle two types of files as input: object file or library. On AIX, object files and archive members in a library can be static or shared, as explained in 2.2.4, “Difference between shared and static objects on AIX” on page 51. Regardless of static or shared, the input file names are specified in the same way in the linker command line in the default link method, as explained in 2.3.2, “Searching objects and libraries at link-time” on page 56.

It is imperative to understand that the default link method is used when generating an executable file, unless the following linker options are explicitly specified:

-bstaticStatic linking
-blazyLazy loading
-brtlRun-time linking

Shared and static objects

Static objects are always statically linked and contained in the generated executable file. Shared objects are usually dynamically linked, thus the shared library code is not contained in the generated executable file. However, shared objects can be linked statically (see 2.4.2, “Static linking” on page 66).

Figure 2-4 depicts the difference between static and shared objects or archive members in the generated executable file. In this figure, the following commands are used in order to build the executable file a.out:

Figure 2-4. Static and shared text code in the executable file


  • Compile

    cc -c main.c foo1.c foo2.c
    
  • Link

    cc main1.o foo1.o foo2.o -labc -L/project/lib
    

If a shared object is linked, its shared program text is loaded into the system shared library segment and shared by all processes that reference it, as depicted in Figure 2-3 on page 63.

LDR_CNTRL=PREREAD_SHLIB

If not already loaded, a shared object is loaded into memory when the program that depends on the shared object is executed. The loading process is done by the kernel virtual memory manager (VMM) on a demand-page basis, and the actual loading page size depends on the current VMM setting defined by several options, which are set by either the vmo command on AIX 5L Version 5.2 or the vmtune command on other versions of AIX.

For detailed information about VMM, please refer to the AIX 5L Version 5.2 Performance Management Guide.

In some cases, especially if shared libraries are written by C++ and there are many references between these libraries, it may be faster to read the library into memory rather at the program load-time than the default demand-page basis.

In this case, set the following environment variable:

LDR_CNTRL=PREREAD_SHLIB

2.4.2. Static linking

AIX supports the -bdynamic and -bstatic linker options to determine how shared objects and libraries should be treated by the linker.[14] These options are toggles and can be used repeatedly in the same linker command line.

[14] The -bdynamic and -bstatic linker options has been supported by AIX, starting from Version 4.3.

When -bdynamic is in effect, which is the default, shared objects are used in the usual way, whereas when -bstatic is in effect, all referenced objects are linked statically, even if those objects are shared objects.

For example, if a program is built using the command line shown in Figure 2-5, the three command line arguments, func1.o, -ldef, and -ljkl, are treated as static, whereas the other arguments, -labc and -lghi, are treated as shared. Therefore, the object module func1.o and referenced archive members in libraries, libdef.a and libjkl.a, are statically linked with main.o.

Figure 2-5. The -bdynamic and -bstatic linker options


Note

We are assuming all objects and libraries except for main.o are shared in Figure 2-5. Non-shared objects or archive members are statically linked regardless of the effectiveness of -bdynamic.


If you use the -bstatic option, the -bdynamic option should be specified as the last option on the link line to ensure that the system libraries are treated as shared objects by the linker. Otherwise, all the object members in the system libraries are treated as static, and the executable produced will be larger than normal and may not work on future versions of AIX since it is statically linked with a specific version of system libraries. The -bdynamic added at the end of the command line ensures that the system libraries, such as libc.a, are processed as shared objects.

Note

Statically linking shared objects or shared archive members in the 64-bit development environment is not supported.


2.4.3. Lazy loading

Lazy loading, [15] which is a variation of the default linking method, is a mechanism for deferring the loading of modules until one of its functions is required to be executed. By default, the system loader automatically loads all of the module’s dependants at the same time.

[15] The lazy loading function has been supported by AIX, starting from Version 4.3.

By linking a module with the -blazy linker option, the module is loaded only when a function within it is called for the first time; however, symbol resolution is performed at link-time.

Note

Lazy loading only works if the run-time linker (-brtl option) is not specified when building executables. A module is lazy loaded when all references to the module are function calls. If variables in the module are referenced, the module is loaded in the normal way.


Let us assume, for example, that main() calls myfunc1() while myfunc1() is in the libone.so shared module. If myfunc1() calls myfunc2() conditionally in shared module libtwo.so, then libtwo.so is a candidate for lazy loading. If myfunc2() is never called, then libtwo.so is not loaded at all. If myfunc2() is called, the lazy loading code executes the load() function to load libtwo.so, patches a function descriptor to make sure subsequent calls simply go directly to the function itself, and then invokes the called function. If for some reason the module cannot be loaded, the lazy loader’s error-handler is invoked.

Using lazy loading does not usually change the behavior of a program, but there are the following exceptions:

  • Any program that relies on the order that modules are loaded in is going to be affected, because modules can be loaded in a different order, and some modules might not be loaded at all.

  • Be careful while comparing function pointers if you are using lazy loading. Usually a function has a unique address in order to compare two function pointers to determine whether they refer to the same function. When using lazy loading to link a module, the address of a function in a lazy loaded module is not the same address computed by other modules. Programs that depend upon the comparison of function pointers should not use lazy loading.

  • If any modules are loaded with relative path names and if the program changes working directories, the dependent module might not be found when it needs to be loaded. When you use lazy loading, you should use only absolute path names when referring to dependent modules at link-time.

The decision to enable lazy loading is made at link-time on a module-by-module basis. In a single program, you can mix modules that use lazy loading with modules that do not. When linking a single module, a reference to a variable in a dependent module prevents that module from being loaded lazily. If all references to a module are to function symbols, the dependent module can be loaded lazily.

Tracing the lazy loading execution

The environment variable LDLAZYDEBUG can be used to trace the lazy loading activity as it takes place. The value of this variable is the sum of one or more of the values shown in Table 2-4.

Table 2-4. LDLAZYDEBUG environment variable values
ValueDescription
1Show load or look-up errors. If a requested symbol is not available in the loaded referenced module, a message is displayed before the error handler is called.
2Write tracing messages to stderr instead of stdout.
4Display the name of the module that is getting loaded.
8Display the name of the called function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset