Hiding and Exporting Symbols When Building a Shared Library

When building a shared library, you may want to hide a symbol in the library for the following reasons:

When building a shared library, you may want to hide a symbol in the library for the following reasons:

Hiding a symbol ensures that the definition can only be accessed by other routines in the same library. When linking with other object modules or libraries, the definition is hidden from them.

When linking with other libraries (to create an executable), hiding a symbol ensures that the library uses the local definition of a routine rather than a definition that occurs earlier in the link order.

Exporting a symbol is necessary if the symbol must be accessible outside the shared library. But remember that, by default, most symbols are global definitions anyway, so it is not necessary to explicitly export symbols. In C, all functions and global variables that are not explicitly declared as static have global definitions, while static functions and variables have local definitions. In FORTRAN, global definitions are generated for all subroutines, functions, and initialized common blocks.

When using +e, be sure to export any data symbols defined in the shared library that is used by another shared library or the program, even if these other files have definitions of the data symbols. Otherwise, your shared library uses its own private copy of the global data, and another library or the program file cannot see any change.

One example of a data symbol that must be exported from a shared library is errno. The errno data symbol is defined in every shared library and program; if this definition is hidden, the value of errno is not be shared outside of the library.

Hiding Symbols when Combining .o Files with the -r Option

The -roption combines multiple .o files, creating a single .o file. The reasons for hiding symbols in an .o file are the same as the reasons listed above for shared libraries. However, a performance improvement occurs only if the resulting .o file is later linked into a shared library.

Hiding and Exporting Symbols when Creating an a.out File

In PA-32 mode, the linker exports all of a program's global definitions that are imported by shared libraries specified on the linker command line. For example, given the following linker command, all global symbols in crt0.o and prog.o that are referenced by libm or libc are automatically exported:

$ ld /usr/ccs/lib/crt0.o prog.o -lm -lc

With libraries that are explicitly loaded with shl_load, this behavior may not always be sufficient because the linker does not search explicitly loaded libraries (they aren't even present on the command line). You can work around this using the -Eor +e linker option.

As mentioned previously in the section “Exporting Symbols from main with -E” (page 38) , the -Eoption forces the export of all symbols from the program, regardless of whether they are referenced by shared libraries on the linker command line. The +e option allows you to be more selective in what symbols are exported. You can use +e to limit the exported symbols to only those symbols you want to be visible.

For example, the following ld command exports the symbols main and foo. The symbol main is referenced by libc. The symbol foo is referenced at run time by an explicitly loaded library not specified at link time:

$ ld /usr/ccs/lib/crt0.o prog.o +e main +e foo -lm -lc -ldld

When using +e, be sure to export any data symbols defined in the program that may also be defined in explicitly loaded libraries. If a data symbol that a shared library imports is not exported from the program file, the program uses its own copy while the shared library uses a different copy

40 Determining How to Link Programs or Libraries (Linker Tasks)