Skip to content

Commit

Permalink
Make possible variant SONAMEs and symbol versions
Browse files Browse the repository at this point in the history
This small change in the Unix template and shared library build
scripts enables building "variant" shared libraries.  A "variant"
shared library has a non-default SONAME, and non default symbol
versions.  This makes it possible to build (say) an OpenSSL 1.1.0
library that can coexist without conflict in the same process address
space as the system's default OpenSSL library which may be OpenSSL
1.0.2.

Such "variant" shared libraries make it possible to link applications
against a custom OpenSSL library installed in /opt/openssl/1.1 or
similar location, and not risk conflict with an indirectly loaded
OpenSSL runtime that is required by some other dependency.

Variant shared libraries have been fully tested under Linux, and
build successfully on MacOS/X producing variant DYLD names.  MacOS/X
Darwin has no symbol versioning, but has a non-flat library namespace.
Variant libraries may therefore support multiple OpenSSL libraries
in the same address space also with MacOS/X, despite lack of symbol
versions, but this has not been verified.

Variant shared libraries are optional and off by default.

Reviewed-by: Richard Levitte <levitte@openssl.org>
  • Loading branch information
Viktor Dukhovni committed Nov 30, 2017
1 parent a4cefc8 commit 822b5e2
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 4 deletions.
21 changes: 21 additions & 0 deletions Configurations/README
Expand Up @@ -101,6 +101,27 @@ In each table entry, the following keys are significant:
files. On unix, this defaults to "" (NOTE:
this is here for future use, it's not
implemented yet)
shlib_variant => A "variant" identifier inserted between the base
shared library name and the extension. On "unixy"
platforms (BSD, Linux, Solaris, MacOS/X, ...) this
supports installation of custom OpenSSL libraries
that don't conflict with other builds of OpenSSL
installed on the system. The variant identifier
becomes part of the SONAME of the library and also
any symbol versions (symbol versions are not used or
needed with MacOS/X). For example, on a system
where a default build would normally create the SSL
shared library as 'libssl.so -> libssl.so.1.1' with
the value of the symlink as the SONAME, a target
definition that sets 'shlib_variant => "-abc"' will
create 'libssl.so -> libssl-abc.so.1.1', again with
an SONAME equal to the value of the symlink. The
symbol versions associated with the variant library
would then be 'OPENSSL_ABC_<version>' rather than
the default 'OPENSSL_<version>'. The string inserted
into symbol versions is obtained by mapping all
letters in the "variant" identifier to upper case
and all non-alphanumeric characters to '_'.

thread_scheme => The type of threads is used on the
configured platform. Currently known
Expand Down
3 changes: 2 additions & 1 deletion Configurations/unix-Makefile.tmpl
Expand Up @@ -8,6 +8,7 @@
our $exeext = $target{exe_extension} || "";
our $libext = $target{lib_extension} || ".a";
our $shlibext = $target{shared_extension} || ".so";
our $shlibvariant = $target{shlib_variant} || "";
our $shlibextsimple = $target{shared_extension_simple} || ".so";
our $shlibextimport = $target{shared_import_extension} || "";
our $dsoext = $target{dso_extension} || ".so";
Expand Down Expand Up @@ -40,7 +41,7 @@
sub shlib {
my $lib = shift;
return () if $disabled{shared} || $lib =~ /\.a$/;
return $unified_info{sharednames}->{$lib} . '$(SHLIB_EXT)';
return $unified_info{sharednames}->{$lib}. $shlibvariant. '$(SHLIB_EXT)';
}
sub shlib_simple {
my $lib = shift;
Expand Down
58 changes: 55 additions & 3 deletions util/mkdef.pl
Expand Up @@ -53,6 +53,58 @@
use lib "$FindBin::Bin/perl";
use OpenSSL::Glob;

# When building a "variant" shared library, with a custom SONAME, also customize
# all the symbol versions. This produces a shared object that can coexist
# without conflict in the same address space as a default build, or an object
# with a different variant tag.
#
# For example, with a target definition that includes:
#
# shlib_variant => "-opt",
#
# we build the following objects:
#
# $ perl -le '
# for (@ARGV) {
# if ($l = readlink) {
# printf "%s -> %s\n", $_, $l
# } else {
# print
# }
# }' *.so*
# libcrypto-opt.so.1.1
# libcrypto.so -> libcrypto-opt.so.1.1
# libssl-opt.so.1.1
# libssl.so -> libssl-opt.so.1.1
#
# whose SONAMEs and dependencies are:
#
# $ for l in *.so; do
# echo $l
# readelf -d $l | egrep 'SONAME|NEEDED.*(ssl|crypto)'
# done
# libcrypto.so
# 0x000000000000000e (SONAME) Library soname: [libcrypto-opt.so.1.1]
# libssl.so
# 0x0000000000000001 (NEEDED) Shared library: [libcrypto-opt.so.1.1]
# 0x000000000000000e (SONAME) Library soname: [libssl-opt.so.1.1]
#
# We case-fold the variant tag to upper case and replace all non-alnum
# characters with "_". This yields the following symbol versions:
#
# $ nm libcrypto.so | grep -w A
# 0000000000000000 A OPENSSL_OPT_1_1_0
# 0000000000000000 A OPENSSL_OPT_1_1_0a
# 0000000000000000 A OPENSSL_OPT_1_1_0c
# 0000000000000000 A OPENSSL_OPT_1_1_0d
# 0000000000000000 A OPENSSL_OPT_1_1_0f
# 0000000000000000 A OPENSSL_OPT_1_1_0g
# $ nm libssl.so | grep -w A
# 0000000000000000 A OPENSSL_OPT_1_1_0
# 0000000000000000 A OPENSSL_OPT_1_1_0d
#
(my $SO_VARIANT = qq{\U$target{"shlib_variant"}}) =~ s/\W/_/g;

my $debug=0;

my $crypto_num= catfile($config{sourcedir},"util","libcrypto.num");
Expand Down Expand Up @@ -1231,13 +1283,13 @@ sub print_def_file
if ($symversion ne $prevsymversion) {
if ($prevsymversion ne "") {
if ($prevprevsymversion ne "") {
print OUT "} OPENSSL_"
print OUT "} OPENSSL${SO_VARIANT}_"
."$prevprevsymversion;\n\n";
} else {
print OUT "};\n\n";
}
}
print OUT "OPENSSL_$symversion {\n global:\n";
print OUT "OPENSSL${SO_VARIANT}_$symversion {\n global:\n";
$prevprevsymversion = $prevsymversion;
$prevsymversion = $symversion;
}
Expand Down Expand Up @@ -1286,7 +1338,7 @@ sub print_def_file
} while ($linux && $thisversion ne $currversion);
if ($linux) {
if ($prevprevsymversion ne "") {
print OUT " local: *;\n} OPENSSL_$prevprevsymversion;\n\n";
print OUT " local: *;\n} OPENSSL${SO_VARIANT}_$prevprevsymversion;\n\n";
} else {
print OUT " local: *;\n};\n\n";
}
Expand Down

0 comments on commit 822b5e2

Please sign in to comment.