JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Linker and Libraries Guide     Oracle Solaris 11 Information Library
search filter icon
search icon

Document Information

Preface

Part I Using the Link-Editor and Runtime Linker

1.  Introduction to the Oracle Solaris Link Editors

2.  Link-Editor

3.  Runtime Linker

4.  Shared Objects

5.  Interfaces and Versioning

6.  Establishing Dependencies with Dynamic String Tokens

Part II Quick Reference

7.  Link-Editor Quick Reference

8.  Versioning Quick Reference

Naming Conventions

Defining a Shared Object's Interface

Versioning a Shared Object

Versioning an Existing (Non-versioned) Shared Object

Updating a Versioned Shared Object

Adding New Symbols

Internal Implementation Changes

New Symbols and Internal Implementation Changes

Migrating Symbols to a Standard Interface

Part III Advanced Topics

9.  Direct Bindings

10.  Mapfiles

11.  Extensibility Mechanisms

Part IV ELF Application Binary Interface

12.  Object File Format

13.  Program Loading and Dynamic Linking

14.  Thread-Local Storage

Part V Appendices

A.  Linker and Libraries Updates and New Features

B.  System V Release 4 (Version 1) Mapfiles

Index

Updating a Versioned Shared Object

The only changes that can be made to a shared object that can be absorbed by internal versioning are compatible changes. See Interface Compatibility. Any incompatible changes require producing a new shared object with a new external versioned name. See Coordination of Versioned Filenames.

Compatible updates that can be accommodated by internal versioning fall into three basic categories.

The first two categories are achieved by associating an interface version definition with the appropriate symbols. The latter is achieved by creating a weak version definition that has no associated symbols.

Adding New Symbols

Any compatible new release of a shared object that contains new global symbols should assign these symbols to a new version definition. This new version definition should inherit the previous version definition.

The following mapfile example assigns the new symbol foo3 to the new interface version definition SUNW_1.2. This new interface inherits the original interface SUNW_1.1.

$ cat mapfile
$mapfile_version 2
SYMBOL_VERSION SUNW_1.2 {                   # Release X+1.
        global:
                foo3;
} SUNW_1.1;

SYMBOL_VERSION SUNW_1.1 {                   # Release X.
        global:
                foo2;
                foo1;
        local:
                *;
};

The inheritance of version definitions reduces the amount of version information that must be recorded in any user of the shared object.

Internal Implementation Changes

Any compatible new release of the shared object that consists of an update to the implementation of the object, for example, a bug fix or performance improvement, should be accompanied by a weak version definition. This new version definition should inherit the latest version definition present at the time the update occurred.

The following mapfile example generates a weak version definition SUNW_1.1.1. This new interface indicates that the internal changes were made to the implementation offered by the previous interface SUNW_1.1.

$ cat mapfile
$mapfile_version 2
SYMBOL_VERSION SUNW_1.1.1 { } SUNW_1.1;     # Release X+1.
 
SYMBOL_VERSION SUNW_1.1 {                   # Release X.
        global:
                foo2;
                foo1;
        local:
                *;
};

New Symbols and Internal Implementation Changes

If both internal changes and the addition of a new interface have occurred during the same release, both a weak version and an interface version definition should be created. The following example shows the addition of a version definition SUNW_1.2 and an interface change SUNW_1.1.1, which are added during the same release cycle. Both interfaces inherit the original interface SUNW_1.1.

$ cat mapfile
$mapfile_version 2
SYMBOL_VERSION SUNW_1.2 {                   # Release X+1.
        global:
                foo3;
} SUNW_1.1;
 
SYMBOL_VERSION SUNW_1.1.1 { } SUNW_1.1;     # Release X+1.
 
SYMBOL_VERSION SUNW_1.1 {                   # Release X.
        global:
                foo2;
                foo1;
        local:
                *;
};

Note - The comments for the SUNW_1.1 and SUNW_1.1.1 version definitions indicate that they have both been applied to the same release.


Migrating Symbols to a Standard Interface

Occasionally, symbols offered by a vendor's interface become absorbed into a new industry standard. When creating a new standard interface, make sure to maintain the original interface definitions provided by the shared object. Create intermediate version definitions on which the new standard, and original interface definitions, can be built.

The following mapfile example shows the addition of a new industry standard interface STAND.1. This interface contains the new symbol foo4 and the existing symbols foo3 and foo1, which were originally offered through the interfaces SUNW_1.2 and SUNW_1.1 respectively.

$ cat mapfile
$mapfile_version 2
SYMBOL_VERSION STAND.1 {                    # Release X+2.
        global:
                foo4;
} STAND.0.1 STAND.0.2;
 
SYMBOL_VERSION SUNW_1.2 {                   # Release X+1.
        global:
                SUNW_1.2;
} STAND.0.1 SUNW_1.1;
 
SYMBOL_VERSION SUNW_1.1.1 { } SUNW_1.1;     # Release X+1.
 
SYMBOL_VERSION SUNW_1.1 {                   # Release X.
        global:
                foo2;
        local:
                *;
} STAND.0.2;
                                            # Subversion - providing for
SYMBOL_VERSION STAND.0.1 {                  # SUNW_1.2 and STAND.1 interfaces.
        global:
                foo3;
};
                                            # Subversion - providing for
SYMBOL_VERSION STAND.0.2 {                  # SUNW_1.1 and STAND.1 interfaces.
        global:
                foo1;
};

The symbols foo3 and foo1 are pulled into their own intermediate interface definitions, which are used to create the original and new interface definitions.

The new definition of the SUNW_1.2 interface has referenced its own version definition symbol. Without this reference, the SUNW_1.2 interface would have contained no immediate symbol references and hence would be categorized as a weak version definition.

When migrating symbol definitions to a standards interface, any original interface definitions must continue to represent the same symbol list. This requirement can be validated using pvs(1). The following example shows the symbol list of the SUNW_1.2 interface as it existed in the software release X+1.

$ pvs -ds -N SUNW_1.2 libfoo.so.1
        SUNW_1.2:
                foo3;
        SUNW_1.1:
                foo2;
                foo1;

Although the introduction of the new standards interface in software release X+2 has changed the interface version definitions available, the list of symbols provided by each of the original interfaces remains constant. The following example shows that interface SUNW_1.2 still provides symbols foo1, foo2 and foo3.

$ pvs -ds -N SUNW_1.2 libfoo.so.1
        SUNW_1.2:
        STAND.0.1:
                foo3;
        SUNW_1.1:
                foo2;
        STAND.0.2:
                foo1;

An application might only reference one of the new subversions. In this case, any attempt to run the application on a previous release results in a runtime versioning error. See Binding to a Version Definition.

An application's version binding can be promoted by directly referencing an existing version name. See Binding to Additional Version Definitions. For example, if an application only references the symbol foo1 from the shared object libfoo.so.1, then its version reference is to STAND.0.2. To enable this application to be run on previous releases, the version binding can be promoted to SUNW_1.1 using a version control mapfile directive.

$ cat prog.c
extern void foo1();

main()
{
        foo1();
}
$ cc -o prog prog.c -L. -R. -lfoo
$ pvs -r prog
        libfoo.so.1 (STAND.0.2);

$ cat mapfile
$mapfile_version 2
DEPEND_VERSIONS libfoo.so {
        ALLOW = SUNW_1.1;
        REQUIRE = SUNW_1.1;
};
$ cc -M mapfile -o prog prog.c -L. -R. -lfoo
$ pvs -r prog
        libfoo.so.1 (SUNW_1.1);

In practice, you rarely have to promote a version binding in this manner. The introduction of new standards binary interfaces is rare, and most applications reference many symbols from an interface family.