summaryrefslogtreecommitdiffstats
path: root/util/mkdef.pl
diff options
context:
space:
mode:
authorViktor Dukhovni <openssl-users@dukhovni.org>2017-11-20 21:30:04 -0500
committerViktor Dukhovni <openssl-users@dukhovni.org>2017-11-30 18:33:58 -0500
commit822b5e2645a99bea15329bd66c9723c7e7119cdb (patch)
tree96c1adc3e422f84458e71bebb51887179f87dce6 /util/mkdef.pl
parenta4cefc86c820d3894ca960857ba4e7cf8e2014b0 (diff)
Make possible variant SONAMEs and symbol versions
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>
Diffstat (limited to 'util/mkdef.pl')
-rwxr-xr-xutil/mkdef.pl58
1 files changed, 55 insertions, 3 deletions
diff --git a/util/mkdef.pl b/util/mkdef.pl
index 20338f5770..1e0da1c87b 100755
--- a/util/mkdef.pl
+++ b/util/mkdef.pl
@@ -53,6 +53,58 @@ use FindBin;
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");
@@ -1231,13 +1283,13 @@ EOF
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;
}
@@ -1286,7 +1338,7 @@ EOF
} 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";
}