Specifying a Version Binding
When creating a dynamic object that is linked against a shared object containing version definitions, you can instruct the link-editor to limit the binding to specific version definitions. Effectively, the link-editor enables you to control an object's binding to specific interfaces.
An object's binding requirements can be controlled using a
DEPEND_VERSIONS
mapfile
directive. This directive is supplied using
the link-editor's -M
option and an associated
mapfile
. The
DEPEND_VERSIONS
directive uses the
following syntax.
$mapfile_version 2 DEPEND_VERSIONS objname { ALLOW = version_name; REQUIRE = version_name; .... };
-
objname represents the name of the shared object dependency. This name should match the shared object's compilation environment name as used by the link-editor. See Library Naming Conventions.
-
The
ALLOW
attribute is used to specify version definition names within the shared object that should be made available for binding. MultipleALLOW
attributes can be specified. -
The
REQUIRE
attribute allows additional version definitions to be recorded. MultipleREQUIRE
attributes can be specified.
The control of version binding can be useful in the following scenarios.
-
When a shared object defines independent, unique versions. This versioning is possible when defining different standards interfaces. An object can be built with binding controls to ensure the object only binds to a specific interface.
-
When a shared object has been versioned over several software releases. An object can be built with binding controls to restrict its binding to the interfaces that were available in a previous software release. Thus, an object can run with an old release of the shared object dependency, after being built using the latest release of the shared object.
The following example illustrates the use of the version control
mechanism. This example uses the shared object
libfoo.so.1
containing the following
version interface definitions.
$ pvs -dsv libfoo.so.1
libfoo.so.1:
_end;
_GLOBAL_OFFSET_TABLE_;
_DYNAMIC;
_edata;
_PROCEDURE_LINKAGE_TABLE_;
_etext;
SUNW_1.1:
foo1;
foo2;
SUNW_1.1;
SUNW_1.2: {SUNW_1.1}:
bar;
The version definitions SUNW_1.1
and
SUNW_1.2
represent interfaces within
libfoo.so.1
that were made available in
software Release X
and
Release X+1
respectively.
An application can be built to bind only to the interfaces available
in Release X
by using the following
version control mapfile
directive.
$ cat mapfile
$mapfile_version 2
DEPEND_VERSIONS libfoo.so {
ALLOW = SUNW_1.1;
}
For example, suppose you develop an application,
prog
, and want to ensure that the
application can run on Release X
. The
application must only use the interfaces available in
Release X
. If the application
mistakenly references the symbol bar
, then the
application is not compliant with the required interface. This
condition is signalled by the link-editor as an undefined symbol
error.
$ cat prog.c extern void foo1(); extern void bar(); main() { foo1(); bar(); } $ cc -o prog prog.c -M mapfile -L. -R. -lfoo Undefined first referenced symbol in file bar prog.o (symbol belongs to unavailable \ version ./libfoo.so (SUNW_1.2)) ld: fatal: symbol referencing errors
To be compliant with the SUNW_1.1
interface, you
must remove the reference to bar
. You can either
rework the application to remove the requirement on
bar
, or add an implementation of
bar
to the creation of the
application.
Note:
By default, shared object dependencies encountered as part of a link-edit, are also verified against any file control directives. Use the environment variableLD_NOVERSION
to suppress the version
verification of any shared object dependencies.