Localizing Symbol Instances

Multiply defined symbols of the same name that provide different implementations, should be isolated to avoid accidental interposition. The simplest way to remove a symbol from the interfaces that are exported by an object, is to reduce the symbol to local. Demoting a symbol to local can be achieved by defining the symbol "static", or possibly through the use of symbol attributes provided by the compilers.

A symbol can also be reduced to local by using the link-editor and a mapfile. The following example shows a mapfile that reduces the global function error() to a local symbol by using the local scoping directive.

$ cc -o A.so.1 -G -Kpic error.c a.c b.c ....
$ elfdump -sN.symtab A.so.1 | fgrep error
    [36]     0x2d0   0x14  FUNC GLOB  D    0 .text      error
$ cat mapfile
$mapfile_version 2
SYMBOL_SCOPE {
        local:
                error;
};
$ cc -o A.so.2 -G -Kpic -M mapfile error.c a.c b.c ....
$ elfdump -sN.symtab A.so.2 | fgrep error
    [24]     0x2c8   0x14  FUNC LOCL  H    0 .text      error

Although individual symbols can be reduced to locals using explicit mapfile definitions, defining the entire interface family through symbol versioning is recommended. See Interfaces and Versioning.

Versioning is a useful technique typically employed to identify the interfaces that are exported from shared objects. Similarly, executables can be versioned to define their exported interfaces. An executable need only export the interfaces that must be made available for the dependencies of the object to bind to. Frequently, the code that you add to an executable need export no interfaces.

Global symbols can be demoted to local symbols using the link-editor's -B local option, or the auto-reduction mapfile directive "*". Both techniques reduce any global symbols that have not explicitly been defined to remain global. In addition, both techniques ensure that any global symbols that can be bound to from any dependencies, remain global.

By removing any exported interfaces from an executable, the executable is protected from future interposition issues than might occur as the objects dependencies evolve.