From 538208594a1af8b5539d83976e8161b46ea0e40c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Hertzog?= <hertzog@debian.org>
Date: Mon, 14 Nov 2016 11:51:50 +0100
Subject: [PATCH 2/2] dpkg-shlibdeps: improve logic to identify package owning
 a library

With the introduction of merged-/usr, we have libraries in that are
stored in /usr/lib but that dpkg knows under /lib. This breaks some
of the initial assumptions made in dpkg-shlibdeps.

We now scan all possible paths for a given library (instead of trying to
guessing which one is the canonical one) and whenever we find a match in
the dpkg database, we also associate the package for the associated
realpath(). That way when a library is not properly identified, we can fallback on
looking if its realpath is known and be confident that if the library
was packaged, we did identify it correctly.

Closes: #843073
---
 scripts/dpkg-shlibdeps.pl | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/scripts/dpkg-shlibdeps.pl b/scripts/dpkg-shlibdeps.pl
index 3204026..f279f58 100755
--- a/scripts/dpkg-shlibdeps.pl
+++ b/scripts/dpkg-shlibdeps.pl
@@ -6,7 +6,7 @@
 # Copyright © 2000 Wichert Akkerman
 # Copyright © 2006 Frank Lichtenheld
 # Copyright © 2006-2010,2012-2015 Guillem Jover <guillem@debian.org>
-# Copyright © 2007 Raphaël Hertzog
+# Copyright © 2007,2016 Raphaël Hertzog
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -35,7 +35,7 @@ use Dpkg::Util qw(:list);
 use Dpkg::Path qw(relative_to_pkg_root guess_pkg_root_dir
 		  check_files_are_the_same get_control_path);
 use Dpkg::Version;
-use Dpkg::Shlibs qw(find_library get_library_paths);
+use Dpkg::Shlibs qw(find_library_locations get_library_paths);
 use Dpkg::Shlibs::Objdump;
 use Dpkg::Shlibs::SymbolFile;
 use Dpkg::Substvars;
@@ -192,8 +192,8 @@ foreach my $file (keys %exec) {
     my %soname_notfound;
     my %alt_soname;
     foreach my $soname (@sonames) {
-	my $lib = my_find_library($soname, $obj->{RPATH}, $obj->{format}, $file);
-	unless (defined $lib) {
+	my @locations = my_find_library($soname, $obj->{RPATH}, $obj->{format}, $file);
+	unless (scalar(@locations)) {
 	    $soname_notfound{$soname} = 1;
 	    $global_soname_notfound{$soname} = 1;
 	    my $msg = g_("couldn't find library %s needed by %s (ELF " .
@@ -206,12 +206,14 @@ foreach my $file (keys %exec) {
 	    }
 	    next;
 	}
-	$libfiles{$lib} = $soname;
-	my $reallib = realpath($lib);
-	if ($reallib ne $lib) {
-	    $altlibfiles{$reallib} = $soname;
-	}
-	print "Library $soname found in $lib\n" if $debug;
+	foreach my $lib (@locations) {
+	    $libfiles{$lib} = $soname;
+	    my $reallib = realpath($lib);
+	    if ($reallib ne $lib) {
+		$altlibfiles{$reallib} = $soname;
+	    }
+	    print "Library $soname found in $lib\n" if $debug;
+        }
     }
     my $file2pkg = find_packages(keys %libfiles, keys %altlibfiles);
     my $symfile = Dpkg::Shlibs::SymbolFile->new();
@@ -830,17 +832,14 @@ sub my_find_library {
     foreach my $builddir (@builddirs) {
 	next if defined($dir_checked{$builddir});
 	next if ignore_pkgdir($builddir);
-	$file = find_library($lib, \@RPATH, $format, $builddir);
-	return $file if defined($file);
+	my @locations = find_library_locations($lib, \@RPATH, $format, $builddir);
+	return @locations if scalar(@locations);
 	$dir_checked{$builddir} = 1;
     }
 
     # Fallback in the root directory if we have not found what we were
     # looking for in the packages
-    $file = find_library($lib, \@RPATH, $format, '');
-    return $file if defined($file);
-
-    return;
+    return find_library_locations($lib, \@RPATH, $format, '');
 }
 
 my %cached_pkgmatch = ();
@@ -879,7 +878,9 @@ sub find_packages {
 		or syserr(g_('write diversion info to stderr'));
 	} elsif (m/^([-a-z0-9+.:, ]+): (\/.*)$/) {
 	    my ($pkgs, $path) = ($1, $2);
+	    my $realpath = realpath($path);
 	    $cached_pkgmatch{$path} = $pkgmatch->{$path} = [ split /, /, $pkgs ];
+	    $cached_pkgmatch{$realpath} = $pkgmatch->{$realpath} = [ split /, /, $pkgs ];
 	} else {
 	    warning(g_("unknown output from dpkg --search: '%s'"), $_);
 	}
-- 
2.10.2

