diff --git a/Makefile.am b/Makefile.am
index c06a931815ad4471c9079598ec51a1cc3d720d9d..b098aa3306f557d96fa6bebaa3cd8337f6b4125c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -152,10 +152,11 @@ include $(top_srcdir)/data/disabled.mk
 # GNOME-style installed-tests
 
 insttestsdir                         = $(libexecdir)/installed-tests/$(PACKAGE_TARNAME)
+nobase_insttests_LTLIBRARIES         =
 
 if ENABLE_LIBRARY
 # /!\ Order is important here: the helper library must come first
-nobase_insttests_LTLIBRARIES         = tests/red/libhelper.la                  \
+nobase_insttests_LTLIBRARIES        += tests/red/libhelper.la                  \
                                        tests/green/libhelper.la                \
                                        tests/helper/libhelper.la               \
                                        tests/red/libnotgl.la                   \
@@ -333,6 +334,57 @@ tests/shim/%.c: tests/shim/%.excluded tests/shim/%.shared tests/shim/%.symbols d
 		$@
 endif
 
+if ENABLE_SHARED
+nobase_insttests_LTLIBRARIES        += tests/version1/libunversionedabibreak.la \
+                                       tests/version2/libunversionedabibreak.la \
+                                       tests/version1/libunversionednumber.la \
+                                       tests/version2/libunversionednumber.la \
+                                       tests/version1/libunversionedsymbols.la \
+                                       tests/version2/libunversionedsymbols.la \
+                                       tests/version1/libversionedabibreak.la \
+                                       tests/version2/libversionedabibreak.la \
+                                       tests/version1/libversionedlikedbus.la \
+                                       tests/version2/libversionedlikedbus.la \
+                                       tests/version1/libversionedlikeglibc.la \
+                                       tests/version2/libversionedlikeglibc.la \
+                                       tests/version1/libversionednumber.la \
+                                       tests/version2/libversionednumber.la \
+                                       tests/version1/libversionedsymbols.la \
+                                       tests/version2/libversionedsymbols.la \
+                                       tests/version1/libversionedupgrade.la \
+                                       tests/version2/libversionedupgrade.la
+tests_version1_libunversionedabibreak_la_LDFLAGS = -shared -version-number 1:0:0
+tests_version2_libunversionedabibreak_la_LDFLAGS = -shared -version-number 1:0:0
+tests_version1_libunversionednumber_la_LDFLAGS = -shared -version-number 1:0:0
+tests_version2_libunversionednumber_la_LDFLAGS = -shared -version-number 1:2:3
+tests_version1_libunversionedsymbols_la_LDFLAGS = -shared -version-number 1:0:0
+tests_version2_libunversionedsymbols_la_LDFLAGS = -shared -version-number 1:0:0
+tests_version1_libversionedabibreak_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                 -Wl,--version-script=$(srcdir)/tests/version1/libversionedabibreak.map
+tests_version2_libversionedabibreak_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                 -Wl,--version-script=$(srcdir)/tests/version2/libversionedabibreak.map
+tests_version1_libversionedlikedbus_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                 -Wl,--version-script=$(srcdir)/tests/version1/libversionedlikedbus.map
+tests_version2_libversionedlikedbus_la_LDFLAGS = -shared -version-number 1:2:0 \
+                                                 -Wl,--version-script=$(srcdir)/tests/version2/libversionedlikedbus.map
+tests_version1_libversionedlikeglibc_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                  -Wl,--version-script=$(srcdir)/tests/version1/libversionedlikeglibc.map
+tests_version2_libversionedlikeglibc_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                  -Wl,--version-script=$(srcdir)/tests/version2/libversionedlikeglibc.map
+tests_version1_libversionednumber_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                               -Wl,--version-script=$(srcdir)/tests/libversioned.map
+tests_version2_libversionednumber_la_LDFLAGS = -shared -version-number 1:2:3 \
+                                               -Wl,--version-script=$(srcdir)/tests/libversioned.map
+tests_version1_libversionedsymbols_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                -Wl,--version-script=$(srcdir)/tests/libversioned.map
+tests_version2_libversionedsymbols_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                -Wl,--version-script=$(srcdir)/tests/libversioned.map
+tests_version1_libversionedupgrade_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                -Wl,--version-script=$(srcdir)/tests/version1/libversionedupgrade.map
+tests_version2_libversionedupgrade_la_LDFLAGS = -shared -version-number 1:0:0 \
+                                                -Wl,--version-script=$(srcdir)/tests/version2/libversionedupgrade.map
+endif
+
 LOG_DRIVER                           = env AM_TAP_AWK='$(AWK)'                 \
                                        $(SHELL) $(top_srcdir)/build-aux/tap-driver.sh
 LOG_COMPILER                         =
@@ -476,3 +528,12 @@ EXTRA_DIST             += doc/capsule-init-project.xml
 EXTRA_DIST             += doc/capsule-mkstublib.xml
 EXTRA_DIST             += doc/devhelp2man.xslt
 EXTRA_DIST             += tests/glib-tap.sh
+EXTRA_DIST             += tests/libversioned.map
+EXTRA_DIST             += tests/version1/libversionedabibreak.map
+EXTRA_DIST             += tests/version1/libversionedlikedbus.map
+EXTRA_DIST             += tests/version1/libversionedlikeglibc.map
+EXTRA_DIST             += tests/version1/libversionedupgrade.map
+EXTRA_DIST             += tests/version2/libversionedabibreak.map
+EXTRA_DIST             += tests/version2/libversionedlikedbus.map
+EXTRA_DIST             += tests/version2/libversionedlikeglibc.map
+EXTRA_DIST             += tests/version2/libversionedupgrade.map
diff --git a/tests/CapsuleTest.pm b/tests/CapsuleTest.pm
index 4d2893136b423f75c46e37d937c311764024f17e..106bee223579ec983e92620e8c5b2ebafbf6bbfa 100644
--- a/tests/CapsuleTest.pm
+++ b/tests/CapsuleTest.pm
@@ -30,9 +30,11 @@ use Test::More;
 
 our @EXPORT = qw(
     assert_run_verbose
+    bind_usr
     diag_multiline
     explain_wait_status
     get_symbols_with_nm
+    libcapsule_uninstalled
     run_ok
     run_verbose
     skip_all_unless_bwrap
@@ -336,6 +338,71 @@ sub get_symbols_with_nm {
     return sort @symbols_produced;
 }
 
+=item bind_usr(I<TREE>[, I<DEST>])
+
+Return B<bwrap>(1) arguments that would bind-mount I<TREE> on I<DEST>.
+If I<TREE> has a F<usr> directory, it is assumed to be a complete
+sysroot with F<bin>, F<sbin>, F<lib*> and F<usr> directories, which
+will be mounted on I<DEST>. If not, it is assumed to be a merged
+F</usr>, and will be mounted on I<DEST>F</usr>, with compatibility
+symbolic links in I<DEST> for the F<bin>, F<sbin> and F<lib*>
+subdirectories.
+
+=cut
+
+sub bind_usr {
+    my $tree = shift;
+    my $dest = shift;
+    $dest = '' unless defined $dest;
+    my @bwrap;
+
+    my $has_usr = (-d "$tree/usr");
+
+    if ($has_usr) {
+        push @bwrap, '--ro-bind', "$tree/usr", "$dest/usr";
+    }
+    else {
+        push @bwrap, '--ro-bind', "$tree", "$dest/usr";
+    }
+
+    opendir(my $dir, $tree);
+    while (defined(my $subdir = readdir $dir)) {
+        if ($subdir =~ /^lib/ || $subdir =~ /^s?bin$/) {
+            if ($has_usr) {
+                push @bwrap, '--ro-bind', "$tree/$subdir", "$dest/$subdir";
+            }
+            else {
+                push @bwrap, '--symlink', "usr/$subdir", "$dest/$subdir";
+            }
+        }
+    }
+    closedir $dir;
+
+    if (-e "$tree/etc/ld.so.cache") {
+        push @bwrap, "--ro-bind", "$tree/etc/ld.so.cache",
+            "$dest/etc/ld.so.cache";
+    }
+
+    # TODO: This wouldn't be necessary in a purely glvnd system
+    if (-d "$tree/etc/alternatives") {
+        push @bwrap, "--ro-bind", "$tree/etc/alternatives",
+            "$dest/etc/alternatives";
+    }
+
+    return @bwrap;
+}
+
+=item libcapsule_uninstalled()
+
+Return true if libcapsule is uninstalled (build-time tests) and false
+if we are carrying out installed-tests.
+
+=cut
+
+sub libcapsule_uninstalled {
+    return exists $ENV{CAPSULE_TESTS_UNINSTALLED};
+}
+
 =back
 
 =head1 ENVIRONMENT
diff --git a/tests/capture-libs.pl b/tests/capture-libs.pl
index a268a7f3bb8c219b4aa023a3f287686fbcb99ffa..6840e8e16b5981b206fdf25f8a2b923b75781702 100755
--- a/tests/capture-libs.pl
+++ b/tests/capture-libs.pl
@@ -31,6 +31,12 @@ use lib $FindBin::Bin;
 
 use CapsuleTest;
 
+sub tolerant_readlink ($)
+{
+    no autodie;
+    return readlink shift;
+}
+
 skip_all_unless_bwrap;
 
 my $LIBDIR = qr{/(?:usr/)?lib(?:32|64|x32)?(?:/\w+-linux-gnu\w*)?(?:/i686)?(?:/cmov)?};
@@ -39,6 +45,8 @@ my $test_tempdir = File::Temp->newdir();
 diag "Working directory: $test_tempdir";
 my $host = "${test_tempdir}/host";
 mkdir($host);
+my $container = "${test_tempdir}/container";
+mkdir($container);
 my $libdir = "${test_tempdir}/libdir";
 
 run_ok(['rm', '-fr', $libdir]);
@@ -404,6 +412,115 @@ SKIP: {
     ok(! -e "$libdir/libjpeg.so.62");
 };
 
+SKIP: {
+    my $version1 = "$builddir/tests/version1";
+    $version1 .= '/.libs' if libcapsule_uninstalled;
+    my $version2 = "$builddir/tests/version2";
+    $version2 .= '/.libs' if libcapsule_uninstalled;
+
+    skip "shared libraries disabled", 1 unless -e "$version1/libunversionedsymbols.so.1";
+
+    run_ok(['rm', '-fr', $libdir]);
+    mkdir($libdir);
+    $result = run_verbose([qw(bwrap --ro-bind / /),
+                           '--tmpfs', $host,
+                           bind_usr('/', $host),
+                           '--tmpfs', $container,
+                           bind_usr('/', $container),
+                           '--ro-bind', $version1, "$host/opt",
+                           '--ro-bind', $version2, "$container/opt",
+                           '--bind', $libdir, $libdir,
+                           qw(--dev-bind /dev /dev),
+                           'env', 'CAPSULE_DEBUG=all',
+                           $CAPSULE_CAPTURE_LIBS_TOOL, '--link-target=/run/host',
+                           "--dest=$libdir", "--provider=$host",
+                           "--container=$container",
+                           'path-match:/opt/lib*.so.1'],
+                           '2>', \$stderr, '>&2');
+    diag $stderr;
+    ok($result);
+    is(tolerant_readlink("$libdir/libunversionedabibreak.so.1"),
+       '/run/host/opt/libunversionedabibreak.so.1.0.0',
+       "should take provider's version when neither's symbols are a superset of the other");
+    ok(! -l "$libdir/libunversionednumber.so.1",
+       "should not take provider's version when container's numeric tail is strictly newer");
+    TODO: {
+    local $TODO = 'counting symbols not yet implemented';
+    ok(! -l "$libdir/libunversionedsymbols.so.1",
+       "should not take provider's version when container has strictly more symbols");
+    }
+    is(tolerant_readlink("$libdir/libversionedabibreak.so.1"),
+       '/run/host/opt/libversionedabibreak.so.1.0.0',
+       "should take provider's version when neither's symbol-versions are a superset of the other");
+    ok(! -l "$libdir/libversionedlikedbus.so.1",
+       "should not take provider's older fake libdbus");
+    TODO: {
+    local $TODO = 'comparing versioned symbols not yet implemented';
+    ok(! -l "$libdir/libversionedlikeglibc.so.1",
+       "should not take provider's older fake glibc");
+    }
+    ok(! -l "$libdir/libversionednumber.so.1",
+       "should not take provider's version when container's numeric tail is strictly newer and symbols are equal");
+    TODO: {
+    local $TODO = 'comparing versioned symbols not yet implemented';
+    ok(! -l "$libdir/libversionedsymbols.so.1",
+       "should not take provider's version when container has strictly more symbols");
+    }
+    TODO: {
+    local $TODO = 'comparing versioned symbols not yet implemented';
+    ok(! -l "$libdir/libversionedupgrade.so.1",
+       "should not take provider's version when container has strictly more symbols");
+    }
+
+    # The opposite.
+    run_ok(['rm', '-fr', $libdir]);
+    mkdir($libdir);
+    $result = run_verbose([qw(bwrap --ro-bind / /),
+                           '--tmpfs', $host,
+                           bind_usr('/', $host),
+                           '--tmpfs', $container,
+                           bind_usr('/', $container),
+                           '--ro-bind', $version1, "$container/opt",
+                           '--ro-bind', $version2, "$host/opt",
+                           '--bind', $libdir, $libdir,
+                           qw(--dev-bind /dev /dev),
+                           'env', 'CAPSULE_DEBUG=all',
+                           $CAPSULE_CAPTURE_LIBS_TOOL, '--link-target=/run/host',
+                           "--dest=$libdir", "--provider=$host",
+                           "--container=$container",
+                           'path-match:/opt/lib*.so.1'],
+                           '2>', \$stderr, '>&2');
+    diag $stderr;
+    ok($result);
+    is(tolerant_readlink("$libdir/libunversionedabibreak.so.1"),
+       '/run/host/opt/libunversionedabibreak.so.1.0.0',
+       "should take provider's version when neither's symbols are a superset of the other");
+    is(tolerant_readlink("$libdir/libunversionednumber.so.1"),
+       '/run/host/opt/libunversionednumber.so.1.2.3',
+       "should take provider's version when container's numeric tail is strictly older");
+    is(tolerant_readlink("$libdir/libunversionedsymbols.so.1"),
+       '/run/host/opt/libunversionedsymbols.so.1.0.0',
+       "should take provider's version when it has strictly more symbols than container");
+    is(tolerant_readlink("$libdir/libversionedabibreak.so.1"),
+       '/run/host/opt/libversionedabibreak.so.1.0.0',
+       "should take provider's version when neither's symbol-versions are a superset of the other");
+    is(tolerant_readlink("$libdir/libversionedlikedbus.so.1"),
+       '/run/host/opt/libversionedlikedbus.so.1.2.0',
+       "should take provider's newer fake libdbus");
+    is(tolerant_readlink("$libdir/libversionedlikeglibc.so.1"),
+       '/run/host/opt/libversionedlikeglibc.so.1.0.0',
+       "should take provider's newer fake glibc");
+    is(tolerant_readlink("$libdir/libversionednumber.so.1"),
+       '/run/host/opt/libversionednumber.so.1.2.3',
+       "should take provider's version when its numeric tail is strictly newer and symbols are equal");
+    is(tolerant_readlink("$libdir/libversionedsymbols.so.1"),
+       '/run/host/opt/libversionedsymbols.so.1.0.0',
+       "should take provider's version when it has strictly more symbols");
+    is(tolerant_readlink("$libdir/libversionedupgrade.so.1"),
+       '/run/host/opt/libversionedupgrade.so.1.0.0',
+       "should take provider's version when it has strictly more symbols");
+}
+
 done_testing;
 
 # vim:set sw=4 sts=4 et:
diff --git a/tests/libversioned.map b/tests/libversioned.map
new file mode 100644
index 0000000000000000000000000000000000000000..72eb3014514adb75ee9bab73e98f34ddbb231c5d
--- /dev/null
+++ b/tests/libversioned.map
@@ -0,0 +1,4 @@
+LIBVERSIONED1 {
+  global:
+    *;
+};
diff --git a/tests/manual/gl.pl b/tests/manual/gl.pl
index d8a076ff4104dfc0fad32ff22131c6211eabeb80..2310d6e626b77b4bedf65f11849bf2746008bcef 100755
--- a/tests/manual/gl.pl
+++ b/tests/manual/gl.pl
@@ -297,60 +297,6 @@ my %CAPSULE_CAPTURE_LIBS_TOOLS;
 
 =over
 
-=item bind_usr(I<TREE>[, I<DEST>])
-
-Return B<bwrap>(1) arguments that would bind-mount I<TREE> on I<DEST>.
-If I<TREE> has a F<usr> directory, it is assumed to be a complete
-sysroot with F<bin>, F<sbin>, F<lib*> and F<usr> directories, which
-will be mounted on I<DEST>. If not, it is assumed to be a merged
-F</usr>, and will be mounted on I<DEST>F</usr>, with compatibility
-symbolic links in I<DEST> for the F<bin>, F<sbin> and F<lib*>
-subdirectories.
-
-=cut
-
-sub bind_usr {
-    my $tree = shift;
-    my $dest = shift;
-    $dest = '' unless defined $dest;
-    my @bwrap;
-
-    my $has_usr = (-d "$tree/usr");
-
-    if ($has_usr) {
-        push @bwrap, '--ro-bind', "$tree/usr", "$dest/usr";
-    }
-    else {
-        push @bwrap, '--ro-bind', "$tree", "$dest/usr";
-    }
-
-    opendir(my $dir, $tree);
-    while (defined(my $subdir = readdir $dir)) {
-        if ($subdir =~ /^lib/ || $subdir =~ /^s?bin$/) {
-            if ($has_usr) {
-                push @bwrap, '--ro-bind', "$tree/$subdir", "$dest/$subdir";
-            }
-            else {
-                push @bwrap, '--symlink', "usr/$subdir", "$dest/$subdir";
-            }
-        }
-    }
-    closedir $dir;
-
-    if (-e "$tree/etc/ld.so.cache") {
-        push @bwrap, "--ro-bind", "$tree/etc/ld.so.cache",
-            "$dest/etc/ld.so.cache";
-    }
-
-    # TODO: This wouldn't be necessary in a purely glvnd system
-    if (-d "$tree/etc/alternatives") {
-        push @bwrap, "--ro-bind", "$tree/etc/alternatives",
-            "$dest/etc/alternatives";
-    }
-
-    return @bwrap;
-}
-
 =item run_in_container(I<TREE>, I<ARGV>, ...)
 
 Use B<bwrap>(1) to run the command I<ARGV> (an array reference) in I<TREE>,
diff --git a/tests/version1/libunversionedabibreak.c b/tests/version1/libunversionedabibreak.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libunversionedabibreak.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libunversionednumber.c b/tests/version1/libunversionednumber.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libunversionednumber.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libunversionedsymbols.c b/tests/version1/libunversionedsymbols.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libunversionedsymbols.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libversionedabibreak.c b/tests/version1/libversionedabibreak.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libversionedabibreak.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libversionedabibreak.map b/tests/version1/libversionedabibreak.map
new file mode 100644
index 0000000000000000000000000000000000000000..72eb3014514adb75ee9bab73e98f34ddbb231c5d
--- /dev/null
+++ b/tests/version1/libversionedabibreak.map
@@ -0,0 +1,4 @@
+LIBVERSIONED1 {
+  global:
+    *;
+};
diff --git a/tests/version1/libversionedlikedbus.c b/tests/version1/libversionedlikedbus.c
new file mode 100644
index 0000000000000000000000000000000000000000..96302ccbf2ec8e2cadb6311b019808ab6b86ae31
--- /dev/null
+++ b/tests/version1/libversionedlikedbus.c
@@ -0,0 +1,6 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
+__attribute__((__visibility__("default"))) int _private1(int);
+int _private1(int x) { return x; }
diff --git a/tests/version1/libversionedlikedbus.map b/tests/version1/libversionedlikedbus.map
new file mode 100644
index 0000000000000000000000000000000000000000..f96c71c41988f3d8dfcc71dd3c4b85a1a36a4daf
--- /dev/null
+++ b/tests/version1/libversionedlikedbus.map
@@ -0,0 +1,8 @@
+LIBVERSIONED1 {
+  global:
+    symbol*;
+};
+LIBVERSIONEDPRIVATE_1_0_0 {
+  global:
+    _private*;
+};
diff --git a/tests/version1/libversionedlikeglibc.c b/tests/version1/libversionedlikeglibc.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libversionedlikeglibc.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libversionedlikeglibc.map b/tests/version1/libversionedlikeglibc.map
new file mode 100644
index 0000000000000000000000000000000000000000..d38767289b0510130a989280532068d35ec4f187
--- /dev/null
+++ b/tests/version1/libversionedlikeglibc.map
@@ -0,0 +1,4 @@
+LIBVERSIONED1 {
+  global:
+    symbol*;
+};
diff --git a/tests/version1/libversionednumber.c b/tests/version1/libversionednumber.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libversionednumber.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libversionedsymbols.c b/tests/version1/libversionedsymbols.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libversionedsymbols.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libversionedupgrade.c b/tests/version1/libversionedupgrade.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version1/libversionedupgrade.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version1/libversionedupgrade.map b/tests/version1/libversionedupgrade.map
new file mode 100644
index 0000000000000000000000000000000000000000..72eb3014514adb75ee9bab73e98f34ddbb231c5d
--- /dev/null
+++ b/tests/version1/libversionedupgrade.map
@@ -0,0 +1,4 @@
+LIBVERSIONED1 {
+  global:
+    *;
+};
diff --git a/tests/version2/libunversionedabibreak.c b/tests/version2/libunversionedabibreak.c
new file mode 100644
index 0000000000000000000000000000000000000000..72d6338c811c80669c64f87c6fdea0ccd004c6f6
--- /dev/null
+++ b/tests/version2/libunversionedabibreak.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol3(int);
+int symbol3(int x) { return x; }
diff --git a/tests/version2/libunversionednumber.c b/tests/version2/libunversionednumber.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version2/libunversionednumber.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version2/libunversionedsymbols.c b/tests/version2/libunversionedsymbols.c
new file mode 100644
index 0000000000000000000000000000000000000000..903b505e9097c255b121368dd85e20f7c28de760
--- /dev/null
+++ b/tests/version2/libunversionedsymbols.c
@@ -0,0 +1,6 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol3(int);
+int symbol3(int x) { return x; }
diff --git a/tests/version2/libversionedabibreak.c b/tests/version2/libversionedabibreak.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version2/libversionedabibreak.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version2/libversionedabibreak.map b/tests/version2/libversionedabibreak.map
new file mode 100644
index 0000000000000000000000000000000000000000..5d4b411c3c4c176681befc453cae1e6547cd4963
--- /dev/null
+++ b/tests/version2/libversionedabibreak.map
@@ -0,0 +1,4 @@
+LIBVERSIONED2 {
+  global:
+    *;
+};
diff --git a/tests/version2/libversionedlikedbus.c b/tests/version2/libversionedlikedbus.c
new file mode 100644
index 0000000000000000000000000000000000000000..c47e5ee3a5e21cc9740f7f82c2dca2fa6782c374
--- /dev/null
+++ b/tests/version2/libversionedlikedbus.c
@@ -0,0 +1,8 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol3(int);
+int symbol3(int x) { return x; }
+__attribute__((__visibility__("default"))) int _private1(int);
+int _private1(int x) { return x; }
diff --git a/tests/version2/libversionedlikedbus.map b/tests/version2/libversionedlikedbus.map
new file mode 100644
index 0000000000000000000000000000000000000000..c8fd609ca7dda89f2eaf4d0ba6ea7e9d58d1047b
--- /dev/null
+++ b/tests/version2/libversionedlikedbus.map
@@ -0,0 +1,8 @@
+LIBVERSIONED1 {
+  global:
+    symbol*;
+};
+LIBVERSIONEDPRIVATE_1_2_0 {
+  global:
+    _private*;
+};
diff --git a/tests/version2/libversionedlikeglibc.c b/tests/version2/libversionedlikeglibc.c
new file mode 100644
index 0000000000000000000000000000000000000000..881190b8a79af2caec6170ff1144679e8f49af17
--- /dev/null
+++ b/tests/version2/libversionedlikeglibc.c
@@ -0,0 +1,8 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__asm__(".symver _original_symbol2,symbol2@LIBVERSIONED1");
+__attribute__((__visibility__("default"))) int _original_symbol2(int);
+int _original_symbol2(int x) { return x; }
+__asm__(".symver symbol2,symbol2@@LIBVERSIONED2");
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x + 1; }
diff --git a/tests/version2/libversionedlikeglibc.map b/tests/version2/libversionedlikeglibc.map
new file mode 100644
index 0000000000000000000000000000000000000000..a80ed396df8211c191680bc8c170abb48c84b75e
--- /dev/null
+++ b/tests/version2/libversionedlikeglibc.map
@@ -0,0 +1,6 @@
+LIBVERSIONED1 {
+  global:
+    symbol*;
+};
+LIBVERSIONED2 {
+} LIBVERSIONED1;
diff --git a/tests/version2/libversionednumber.c b/tests/version2/libversionednumber.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ab82e7e9129e60447a3678f618fb7ab40ea0931
--- /dev/null
+++ b/tests/version2/libversionednumber.c
@@ -0,0 +1,4 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
diff --git a/tests/version2/libversionedsymbols.c b/tests/version2/libversionedsymbols.c
new file mode 100644
index 0000000000000000000000000000000000000000..903b505e9097c255b121368dd85e20f7c28de760
--- /dev/null
+++ b/tests/version2/libversionedsymbols.c
@@ -0,0 +1,6 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol3(int);
+int symbol3(int x) { return x; }
diff --git a/tests/version2/libversionedupgrade.c b/tests/version2/libversionedupgrade.c
new file mode 100644
index 0000000000000000000000000000000000000000..903b505e9097c255b121368dd85e20f7c28de760
--- /dev/null
+++ b/tests/version2/libversionedupgrade.c
@@ -0,0 +1,6 @@
+__attribute__((__visibility__("default"))) int symbol1(int);
+int symbol1(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol2(int);
+int symbol2(int x) { return x; }
+__attribute__((__visibility__("default"))) int symbol3(int);
+int symbol3(int x) { return x; }
diff --git a/tests/version2/libversionedupgrade.map b/tests/version2/libversionedupgrade.map
new file mode 100644
index 0000000000000000000000000000000000000000..787c3302548ea0f6cd340a35e2f6de79cfed529f
--- /dev/null
+++ b/tests/version2/libversionedupgrade.map
@@ -0,0 +1,9 @@
+LIBVERSIONED1 {
+  global:
+    symbol1;
+    symbol2;
+};
+LIBVERSIONED2 {
+  global:
+    symbol3;
+} LIBVERSIONED1;