Hi!

On Mon, 2021-11-22 at 22:49:43 +0100, Joachim Reichel wrote:
> Package: dpkg-dev
> Version: 1.20.9
> Severity: serious
> Control: affects -1 cppcheck

> dpkg-shlibdeps calculates too low minimum version requirements for cppcheck 
> on libc6 (see bug 1000146).
> 
> To reproduce, build cppcheck 2.6-1 in unstable chroot without cleaning up, 
> e.g., "dpkg-buildpackage -rfakeroot -us -uc".
> 
> $ grep Depends debian/cppcheck/DEBIAN/control
> Depends: libc6 (>= 2.29), [...]
> 
> But running the binary with libc6 2.31 fails with
> 
> cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by cppcheck)
> cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by 
> /usr/lib/x86_64-linux-gnu/libstdc++.so.6)
> cppcheck: ./libc.so.6: version `GLIBC_2.32' not found (required by 
> /lib/x86_64-linux-gnu/libpthread.so.0)
> 
> I believe that is the case because a certain symbol in the .bss section is 
> ignored (this is the only symbol with 2.32 suffix):
> 
> $ objdump -w -T ./debian/cppcheck/usr/bin/cppcheck | grep 
> __libc_single_threaded
> 00000000004670e0 g    DO .bss   0000000000000001  GLIBC_2.32  
> __libc_single_threaded
> 
> $ nm -D ./debian/cppcheck/usr/bin/cppcheck | grep __libc_single_threaded
> 00000000004670e0 B __libc_single_threaded@@GLIBC_2.32
> 
> $ dpkg-shlibdeps ./debian/cppcheck/usr/bin/cppcheck; cat debian/substvars
> shlibs:Depends=libc6 (>= 2.29), [...]
> 
> After hacking /usr/share/perl5/Dpkg/Shlibs/Objdump.pm:462 to read
> "defined => ($sect ne '*UND*') && ($sect ne '.bss')"
> (maybe not the right solution, just for demonstration):

Thanks for the investigation! But, I'm afraid that would mean
dpkg-gensymbols missing symbols on the generated .symbols file. Also
marking all such symbols from «.bss» would start emitting tons of
warnings for non-imported symbols, more so in cppcheck case as it is
built with -rdynamic (which exports those).

After some further checking, it seems newer binutils have started
qualifying symbols in copy relocation with the version string, which
the code was not matching (but i386 was not affected f.ex. as it does
not use copy relocations for those). The attached patch seems to work
on amd64, but I'll check tomorrow whether the same applies to other
arches and if they use the same symbol format. But at least it should
improve things and not cause regressions as it will try both formats.

Thanks,
Guillem
From a9c4f1806f1927a2da42712658f4cfdd37f73e50 Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Tue, 23 Nov 2021 02:26:50 +0100
Subject: [PATCH] Dpkg::Shlibs::Objdump: Fix apply_relocations to work with
 versioned symbols
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since at least binutils 2.28 copy relocations for versioned symbols have
the version appended after «@@». We were not taking this into account
which meant these did not match and did not get marked as undefined.

Try both the version qualified symbol and the bare symbol name to cope
with old and new formats.

Closes: #1000421
---
 scripts/Dpkg/Shlibs/Objdump.pm | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/scripts/Dpkg/Shlibs/Objdump.pm b/scripts/Dpkg/Shlibs/Objdump.pm
index 93319d1eb..43d786edd 100644
--- a/scripts/Dpkg/Shlibs/Objdump.pm
+++ b/scripts/Dpkg/Shlibs/Objdump.pm
@@ -488,9 +488,20 @@ sub apply_relocations {
 	# We want to mark as undefined symbols those which are currently
 	# defined but that depend on a copy relocation
 	next if not $sym->{defined};
-	next if not exists $self->{dynrelocs}{$sym->{name}};
-	if ($self->{dynrelocs}{$sym->{name}} =~ /^R_.*_COPY$/) {
+
+        my @relocs;
+        push @relocs, $sym->{name} . '@@' . $sym->{version} if $sym->{version};
+
+        # Symbols that are not versioned, or versioned but linked with old
+        # binutils do not have a version appended.
+        push @relocs, $sym->{name};
+
+        foreach my $reloc (@relocs) {
+            next if not exists $self->{dynrelocs}{$reloc};
+            next if not $self->{dynrelocs}{$reloc} =~ /^R_.*_COPY$/;
+
 	    $sym->{defined} = 0;
+            last;
 	}
     }
 }
-- 
2.34.0

Reply via email to