This section explains how to use the following commands, which are necessary to manipulate objects and libraries on AIX by providing the following subsections:
Section 2.7.1, “dump” on page 86
Section 2.7.2, “genkld” on page 88
Section 2.7.3, “ldd” on page 90
Section 2.7.4, “nm” on page 90
Section 2.7.5, “rtl_enable” on page 91
Section 2.7.6, “slibclean” on page 91
The dump command is used to examine the header information of executable files and shared objects. The main options that are useful when working with shared libraries are the -H option and the -Tv options.
Use the dump -H command to determine which shared objects an executable or shared object depends on for symbol resolution at run time. The interesting information is in the last section of output, as shown under the ***Import File Strings*** header in Example 2-18.
$ dump -H func1.so func1.so: ***Loader Section*** Loader Header Information VERSION# #SYMtableENT #RELOCent LENidSTR 0x00000001 0x00000003 0x00000006 0x00000023 #IMPfilID OFFidSTR LENstrTBL OFFstrTBL 0x00000003 0x000000b0 0x00000000 0x00000000 ***Import File Strings*** INDEX PATH BASE MEMBER 0 /usr/lib:/lib 1 libc.a shr.o 2 .. |
The number of INDEX entries will depend on how many shared objects the target depends on for symbol resolution.
The INDEX 0 entry is a colon separated list of directories shown as /usr/lib:/lib in Example 2-18. If the LIBPATH environment variable is not set when the executable is started, the directories listed in the first (index 0) entry will be used in order to look for the shared objects listed in subsequent entries. If LIBPATH is defined, the directories listed in it will be used before the directories in the first (index 0) entry.
The format of the interesting columns is as follows:
PATH | Optional path name component of the shared object or library. A pathname will be present if a path name was specified on the linker command line. It is recommended to avoid having this optional path name. See 2.3.1, “The -L linker option” on page 55 and 2.3.3, “LIBPATH environment variable” on page 58 for further detailed information how this optional path name component will be selected depending on the linker command line file name selections. |
BASE | The name of the archive library containing the shared archive member, or the name of the shared object itself. |
MEMBER | The archive member name of the shared library. In the case of non-archived shared objects, this column will be blank. |
Note
If there is a .. entry in the BASE column, the shared object is enabled for the run-time linking (see 2.5, “Run-time linking” on page 68).
Use the dump -Tv command to examine the symbol information of a shared object or executable. It displays information on the symbols the object is exporting. It also lists the symbols the object or executable will try and import at load time and, if known, the name of the shared object that contains those symbols. The interesting columns are IMEX, IMPid, and Name, as highlighted in Example 2-19.
$ dump -Tv func1.so func1.so: ***Loader Section*** ***Loader Symbol Table Information*** [Index] Value Scn IMEX Sclass Type IMPid Name [0] 0x00000000 undef IMP DS EXTref libc.a(shr.o) printf [1] 0x00000050 .data EXP DS SECdef [noIMid] func1 [2] 0x00000000 undef IMP DS EXTref .. func3 |
The values in these columns have the following meaning:
Name | The symbol name. |
IMEX | Determines whether a symbol is exported from the object file or archive member (EXP) or imported from the other object files or archive members (IMP). |
IMPid | For exported symbols, the value is not used and is always [noIMid]. For imported symbols, there are three patterns for the value, as shown in Table 2-6. |
Value | Description |
---|---|
File name | If the file name is in the form of libabc.a(def.o), then the symbol is imported from the def.o member of the libabc.a library. If the file name is without parentheses, then the symbol is imported from that shared object file. In both cases, the dependent shared object or archive member will be loaded by the system loader upon the program execution time. |
.. | The symbol will be resolved by the run-time linker. After resolving the symbol, the run-time linker tells the system loader to load an appropriate shared object or archive member. |
[noIMid] | The symbol is a deferred symbol and will not be resolved by the run-time linker. It is the application’s responsibility to resolve deferred symbols in order to avoid the application abend due to the unresolved symbols. In order for the programatic symbol resolution, use the dynamic loading (see 2.6, “Dynamic loading” on page 82). |
The genkld command is used to list the shared objects that are loaded in the system shared library segment. The output is quite lengthy and has three columns, the virtual address of the object within the system segment, the size of the object, and the name of the file that was loaded, as shown in Example 2-20.
$ genkld | pg Virtual Address Size File d1febce0 19907 /usr/lib/libcurses.a/shr.o ... rest of the output is omitted on purpose ... |
If the file name does not have a slash character at its end, then it is a shared archive member of a library archive. In Example 2-20, shr.o is a shared archive member of /usr/lib/libcurses.a.
If the file name has a slash character at its end, it is a shared object file, as shown in Example 2-21.
$ genkld | head -1; genkld | grep NIS Virtual Address Size File d00e7000 2237 /usr/lib/security/NIS/ $ ls -l /usr/lib/security/NIS -r-xr-xr-x 1 root system 8760 Sep 15 2002 /usr/lib/security/NIS $ file /usr/lib/security/NIS /usr/lib/security/NIS: executable (RISC System/6000) or object module |
The virtual address of a 32-bit shared object starts from 0xD, whereas the address of a 64-bit shared object typically starts from 0x90000000, as shown in Example 2-22.
$ genkld | head -1; genkld | grep 'libc.a' Virtual Address Size File d01bb3b8 1df /usr/lib/libc.a/dl.o d014d0c2 1da /usr/lib/libc.a/pse.o d01d0be0 1e5907 /usr/lib/libc.a/shr.o 90000000022aca0 20d75e /usr/lib/libc.a/shr_64.o |
The 0xD segment is the system-wide 32-bit shared text segment, which is shared by all the 32-bit processes on the system. As for 64-bit processes, shared objects can be loaded into the system-wide 64-bit shared text segments, which can be located from 0x9000_0000_0000_0000 to 0x9FFF_FFFF_FFFF_FFFF (576 - 640 PB); however, they are most likely loaded into the first segment in this address range.
For further information about the system-wide shared text segments, see 3.2, “The 32-bit user process model” on page 109 and 3.3, “The 64-bit user process model” on page 130.
The ldd[17] command lists the shared objects and archive members that will be loaded to start the executable. The following example shows what shared object modules and shared libraries (dependencies) are required to run the executable file helloworld:
[17] The ldd command is supported on AIX 5L Version 5.2 and later.
# ldd helloworld helloworld needs: ./libone.so ./libtwo.so /usr/lib/libc.a(shr.o) /usr/lib/librtl.a(shr.o)
The command reports dependencies by traversing valid XCOFF header information of the specified executable file.
The nm command displays information about symbols in the specified file, which can be an object file, an executable file, or shared object. For example:
$ nm libone.so .myfunc1 T 144 .myfunc1 t 144 40 .myfunc2 T 0 .myfunc2 T 184 .myfunc2 t 184 40 .printf T 104 .printf t 104 40 TOC d 52 _$STATIC d 0 40 _$STATIC d 52 4 glink.s f - glink.s f - glink.s f - myfunc1 U - myfunc1 d 60 4 myfunc2 D 40 12 myfunc2 d 64 4 printf U - printf d 56 4 source1.c f -
If the file contains no symbol information, the nm command reports the fact, but does not interpret it as an error condition. The nm command reports numerical values in decimal notation by default. Unlike the dump command, nm does not display the shared object or archive member name that is expected to supply the symbol.
The rtl_enable command is used to convert a shared library that is not enabled for run-time linking into a run-time linking enabled one.
The slibclean command can be used by the root user to unload all shared objects with a use count value of zero from the system shared library segment. This command is useful in an environment when shared libraries are under development. You can run the slibclean command followed by the genkld command to ensure that the shared objects under development are not loaded in the system shared library segment. This means that any application started after this will automatically use the latest version of the shared objects since the system loader will search for and load them. It also prevents multiple versions of the same objects existing in the system segment.
During the development of shared objects, you may sometimes see an error message similar to the following when creating a new version of an existing shared object:
# make libone.so cc -O -c source1.c cc -berok -G -o libone.so source1.o ld: 0711-851 SEVERE ERROR: Output file: libone.so The file is in use and cannot be overwritten. make: 1254-004 The error code from the last command is 12.
The error message means that the target shared object file is in use and it has been loaded into the system shared library segment. Once loaded, the file is marked as in use, even if the use count is already zero. Running the slibclean command will unload all of the unused shared objects from the system. An alternative (and simpler) method of avoiding this problem is to use the rm -f command to remove the shared object before creating it.
However, frequent slibclean invocation on production systems should be avoided, because it may affect the system performance by unloading frequently used, but unused when the command is issued, shared objects and libraries on the system. It is recommended to issue slibclean on production systems that are in a software maintenance phase, especially before the deinstallation of no longer required applications or the updating of installed applications.
Note
The root authority is required to use the slibclean command.