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