Package: dpkg-dev Version: 1.15.0 Severity: wishlist Tags: patch Hello,
when writing a tool which deals with C++ symbols, I found that feature like this would be very useful. You will find the full description in the attached patch header (also copy&pasted below). Just to give you an idea of the real world usage for this: MISSING - current use of deprecated symbols. DEPRECATED - could be used for a few multiarch specific symbols which symbol file preprocessor could turn into normal symbols under certain conditions. (this is just an example, I know about that #include is different but limited way to do it). PRIVATE - C++ template instantiations and other exported private symbols (i.e. those which cannot be found in the headers). The patch is against current master branch. Patch description follows: -- Up until now, all deprecated symbols were treated equally as MISSING. DEPRECATED was a synomym of MISSING. This patch changes sematics of DEPRECATED a bit and adds a new type - PRIVATE. Also types are preserved between symbol file load() and dump(). Descriptions of the deprecation types follow: MISSING - the symbol is typically declared as MISSING if it can no longer be found in the object file itself. If that symbol reappears suddently, it gets undeprecated and its minimal version is bumped to the current version of the object. MISSING symbols are never removed from the symbols file automatically. MISSING used to be a default deprecation type in the earlier versions of dpkg, hence it is kept fully compatible. DEPRECATED - it is similar to MISSING with the exception that if the symbol reappears, its minimal version is kept as it is instead of being bumped. DEPRECATED could be used to mark symbols as optional for whatever the reason. dpkg-gensymbols will still display reappearing DEPRECATED symbols in the diff as it does with MISSING. PRIVATE - useful for marking private symbols which have been falsely exported to the dynamic symbol table by the compiler (e.g. C++). Private symbols are optional, they stay deprecated even if the object file actually have them and they get automatically removed from the symbol file when they disappear from the object file. DEPRECATED and PRIVATE are for manual or for 3rd party tool use. Dpkg::Shlibs::SymbolFile never changes symbol type to DEPRECATED or PRIVATE. It only marks symbols as MISSING as needed. The patch also adds 'export_private' option to dump() which allows to dump private symbols as normal ones (defaults to OFF). dpkg-gensymbols enables this option when exporting symbols files to DEBIAN/symbols but disables it when diff'ing. --- Also current master needs the fix below for man/po/de.po to build: diff --git a/man/po/de.po b/man/po/de.po index c8637d9..63aa7e0 100644 --- a/man/po/de.po +++ b/man/po/de.po @@ -9138,7 +9138,7 @@ msgstr "" #, no-wrap msgid "I<binary>B< contains an unresolvable reference to symbol >I<sym>B<: it's probably a plugin>" msgstr "" -"I<Programm>B< enthält eine nicht-auflösbare Referenz auf Symbol I<Sym>B<: wahrscheinlich eine Erweiterung>." +"I<Programm>B< enthält eine nicht-auflösbare Referenz auf Symbol >I<Sym>B<: wahrscheinlich eine Erweiterung>." # type: Plain text #: ../../man/dpkg-shlibdeps.1:251 -- System Information: Debian Release: squeeze/sid APT prefers unstable APT policy: (500, 'unstable'), (101, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 2.6.29-1-amd64 (SMP w/1 CPU core) Locale: LANG=lt_LT.UTF-8, LC_CTYPE=lt_LT.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages dpkg-dev depends on: ii binutils 2.19.1-1 The GNU assembler, linker and bina ii bzip2 1.0.5-1 high-quality block-sorting file co ii cpio 2.9.90-3 GNU cpio -- a program to manage ar ii dpkg 1.14.25 Debian package management system ii libtimedate-perl 1.1600-9 Time and date functions for Perl ii lzma 4.43-14 Compression method of 7z format in ii make 3.81-5 The GNU version of the "make" util ii patch 2.5.9-5 Apply a diff file to an original ii perl [perl5] 5.10.0-19 Larry Wall's Practical Extraction ii perl-modules 5.10.0-19 Core Perl modules Versions of packages dpkg-dev recommends: ii build-essential 11.4 Informational list of build-essent ii gcc [c-compiler] 4:4.3.3-2 The GNU C compiler ii gcc-4.1 [c-compiler] 4.1.2-25 The GNU C compiler ii gcc-4.3 [c-compiler] 4.3.3-5 The GNU C compiler Versions of packages dpkg-dev suggests: pn debian-keyring <none> (no description available) ii gnupg 1.4.9-4 GNU privacy guard - a free PGP rep -- no debconf information
>From 2593032aef16f5813584d9fe10e7b0636ed6ae93 Mon Sep 17 00:00:00 2001 From: Modestas Vainius <modes...@vainius.eu> Date: Sat, 28 Mar 2009 13:59:56 +0200 Subject: [PATCH] Introduce different types of deprecation. Up until now, all deprecated symbols were treated equally as MISSING. DEPRECATED was a synomym of MISSING. This patch changes sematics of DEPRECATED a bit and adds a new type - PRIVATE. Also types are preserved between symbol file load() and dump(). Descriptions of the deprecation types follow: MISSING - the symbol is typically declared as MISSING if it can no longer be found in the object file itself. If that symbol reappears suddently, it gets undeprecated and its minimal version is bumped to the current version of the object. MISSING symbols are never removed from the symbols file automatically. MISSING used to be a default deprecation type in the earlier versions of dpkg, hence it is kept fully compatible. DEPRECATED - it is similar to MISSING with the exception that if the symbol reappears, its minimal version is kept as it is instead of being bumped. DEPRECATED could be used to mark symbols as optional for whatever the reason. dpkg-gensymbols will still display reappearing DEPRECATED symbols in the diff as it does with MISSING. PRIVATE - useful for marking private symbols which have been falsely exported to the dynamic symbol table by the compiler (e.g. C++). Private symbols are optional, they stay deprecated even if the object file actually have them and they get automatically removed from the symbol file when they disappear from the object file. DEPRECATED and PRIVATE are for manual or for 3rd party tool use. Dpkg::Shlibs::SymbolFile never changes symbol type to DEPRECATED or PRIVATE. It only marks symbols as MISSING as needed. The patch also adds 'export_private' option to dump() which allows to dump private symbols as normal ones (defaults to OFF). dpkg-gensymbols enables this option when exporting symbols files to DEBIAN/symbols but disables it when diff'ing. Signed-off-by: Modestas Vainius <modes...@vainius.eu> --- scripts/Dpkg/Shlibs/SymbolFile.pm | 50 +++++++++++++++++++++++----------- scripts/dpkg-gensymbols.pl | 8 +++--- scripts/t/200_Dpkg_Shlibs.t | 54 +++++++++++++++++++++++++++++++----- 3 files changed, 84 insertions(+), 28 deletions(-) diff --git a/scripts/Dpkg/Shlibs/SymbolFile.pm b/scripts/Dpkg/Shlibs/SymbolFile.pm index 4bd5bc8..0d5f895 100644 --- a/scripts/Dpkg/Shlibs/SymbolFile.pm +++ b/scripts/Dpkg/Shlibs/SymbolFile.pm @@ -129,7 +129,8 @@ sub load { my $sym = { minver => $2, dep_id => defined($3) ? $3 : 0, - deprecated => 0 + type => '', + deprecated => 0, }; if ($name =~ /^\*@(.*)$/) { error(_g("you can't use wildcards on unversioned symbols: %s"), $_) if $1 eq "Base"; @@ -142,13 +143,14 @@ sub load { my $dir = $file; $dir =~ s{[^/]+$}{}; # Strip filename $self->load("$dir$filename", $seen, $current_object_ref); - } elsif (/^#(?:DEPRECATED|MISSING): ([^#]+)#\s*(\S+)\s(\S+)(?:\s(\d+))?/) { + } elsif (/^#(DEPRECATED|MISSING|PRIVATE): ([^#]+)#\s*(\S+)\s(\S+)(?:\s(\d+))?/) { my $sym = { - minver => $3, - dep_id => defined($4) ? $4 : 0, - deprecated => $1 + minver => $4, + dep_id => defined($5) ? $5 : 0, + type => $1, + deprecated => $2, }; - $self->{objects}{$object}{syms}{$2} = $sym; + $self->{objects}{$object}{syms}{$3} = $sym; } elsif (/^#/) { # Skip possible comments } elsif (/^\|\s*(.*)$/) { @@ -203,6 +205,7 @@ sub save { sub dump { my ($self, $fh, %opts) = @_; + $opts{export_private} = 0 unless exists $opts{export_private}; $opts{with_deprecated} = 1 unless exists $opts{with_deprecated}; foreach my $soname (sort keys %{$self->{objects}}) { my @deps = @{$self->{objects}{$soname}{deps}}; @@ -221,8 +224,11 @@ sub dump { } foreach my $sym (sort keys %{$self->{objects}{$soname}{syms}}) { my $info = $self->{objects}{$soname}{syms}{$sym}; - next if $info->{deprecated} and not $opts{with_deprecated}; - print $fh "#MISSING: $info->{deprecated}#" if $info->{deprecated}; + if (!($opts{export_private} && $info->{type} eq 'PRIVATE')) { + next if $info->{deprecated} and not $opts{with_deprecated}; + print $fh "#", ($info->{type}) ? $info->{type} : 'MISSING', + ": $info->{deprecated}#" if ($info->{deprecated}); + } print $fh " $sym $info->{minver}"; print $fh " $info->{dep_id}" if $info->{dep_id}; print $fh "\n"; @@ -256,11 +262,17 @@ sub merge_symbols { if (exists $obj->{syms}{$sym}) { # If the symbol is already listed in the file my $info = $obj->{syms}{$sym}; - if ($info->{deprecated}) { - # Symbol reappeared somehow + # Don't touch the symbol if it is private + if ($info->{deprecated} && $info->{type} ne 'PRIVATE') { + my $dtype = $info->{type}; + # Undeprecate it $info->{deprecated} = 0; - $info->{minver} = $minver; - next; + $info->{type} = ''; + if ($dtype eq 'MISSING') { + # Missing symbol reappeared somehow. Bump minver. + $info->{minver} = $minver; + next; + } # Version of DEPRECATED symbols is not bumped } # We assume that the right dependency information is already # there. @@ -280,6 +292,7 @@ sub merge_symbols { $info = { minver => $minver, deprecated => 0, + type => '', dep_id => 0 }; } @@ -292,12 +305,17 @@ sub merge_symbols { # the symbol was introduced) foreach my $sym (keys %{$self->{objects}{$soname}{syms}}) { if (! exists $dynsyms{$sym}) { - # Do nothing if already deprecated - next if $self->{objects}{$soname}{syms}{$sym}{deprecated}; - my $info = $self->{objects}{$soname}{syms}{$sym}; + if ($info->{deprecated}) { + # Just remove no longer existing private symbols + if ($info->{type} eq 'PRIVATE') { + delete $self->{objects}{$soname}{syms}{$sym}; + } + next; + } if (vercmp($minver, $info->{minver}) > 0) { - $self->{objects}{$soname}{syms}{$sym}{deprecated} = $minver; + $info->{deprecated} = $minver; + $info->{type} = 'MISSING'; } } } diff --git a/scripts/dpkg-gensymbols.pl b/scripts/dpkg-gensymbols.pl index bebe0f7..3beccab 100755 --- a/scripts/dpkg-gensymbols.pl +++ b/scripts/dpkg-gensymbols.pl @@ -189,7 +189,7 @@ $symfile->clear_except(keys %{$od->{objects}}); # Write out symbols files if ($stdout) { $output = "standard output"; - $symfile->save("-", package => $oppackage); + $symfile->save("-", package => $oppackage, export_private => 1); } else { unless (defined($output)) { unless($symfile->is_empty()) { @@ -199,7 +199,7 @@ if ($stdout) { } if (defined($output)) { print "Storing symbols in $output.\n" if $debug; - $symfile->save($output, package => $oppackage); + $symfile->save($output, package => $oppackage, export_private => 1); } else { print "No symbol information to store.\n" if $debug; } @@ -253,8 +253,8 @@ if ($compare) { # and after my $before = File::Temp->new(TEMPLATE=>'dpkg-gensymbolsXXXXXX'); my $after = File::Temp->new(TEMPLATE=>'dpkg-gensymbolsXXXXXX'); - $ref_symfile->dump($before, package => $oppackage); - $symfile->dump($after, package => $oppackage); + $ref_symfile->dump($before, package => $oppackage, export_private => 0); + $symfile->dump($after, package => $oppackage, export_private => 0); seek($before, 0, 0); seek($after, 0, 0); my ($md5_before, $md5_after) = (Digest::MD5->new(), Digest::MD5->new()); $md5_before->addfile($before); diff --git a/scripts/t/200_Dpkg_Shlibs.t b/scripts/t/200_Dpkg_Shlibs.t index 8da5d6a..453b579 100644 --- a/scripts/t/200_Dpkg_Shlibs.t +++ b/scripts/t/200_Dpkg_Shlibs.t @@ -1,6 +1,6 @@ # -*- mode: cperl;-*- -use Test::More tests => 39; +use Test::More tests => 43; use IO::String; use strict; @@ -105,6 +105,23 @@ $sym_file_old->merge_symbols($obj_old, "2.3.6.ds1-13"); ok( $sym_file->has_object('libc.so.6'), 'SONAME in sym file' ); +# Initialize testing for deprecation types +my $deprecated_sym = 'p...@glibc_2.0'; +my $private_sym = 'g...@glibc_2.0'; +my $private_gone_sym = '__libc_cr...@glibc_private'; + +sub set_deprecation_types { + my $syms = shift()->{objects}{'libc.so.6'}{syms}; + $syms->{$deprecated_sym}{deprecated} = 'optional'; + $syms->{$deprecated_sym}{type} = 'DEPRECATED'; + $syms->{$private_sym}{deprecated} = 'internal'; + $syms->{$private_sym}{type} = 'PRIVATE'; + $syms->{$private_gone_sym}{deprecated} = 'disappearing PRIVATE'; + $syms->{$private_gone_sym}{type} = 'PRIVATE'; +} +set_deprecation_types($sym_file); +set_deprecation_types($sym_file_old); + $sym_file->merge_symbols($obj, "2.6-1"); ok( $sym_file->get_new_symbols($sym_file_old), 'has new symbols' ); @@ -115,8 +132,21 @@ is( $sym_file_old->lookup_symbol('__bss_st...@base', ['libc.so.6']), $sym = $sym_file->lookup_symbol('_er...@glibc_2.0', ['libc.so.6'], 1); is_deeply($sym, { 'minver' => '2.3.6.ds1-13', 'dep_id' => 0, - 'deprecated' => '2.6-1', 'depends' => '', - 'soname' => 'libc.so.6' }, 'deprecated symbol'); + 'type' => 'MISSING', 'deprecated' => '2.6-1', 'depends' => '', + 'soname' => 'libc.so.6' }, 'deprecated MISSING symbol'); + +$sym = $sym_file->lookup_symbol($deprecated_sym, ['libc.so.6'], 1); +is_deeply($sym, { 'minver' => '2.3.6.ds1-13', 'dep_id' => 0, + 'type' => '', 'deprecated' => 0, 'depends' => '', + 'soname' => 'libc.so.6' }, 'deprecated DEPRECATED symbol'); + +$sym = $sym_file->lookup_symbol($private_sym, ['libc.so.6'], 1); +is_deeply($sym, { 'minver' => '2.3.6.ds1-13', 'dep_id' => 0, + 'type' => 'PRIVATE', 'deprecated' => 'internal', 'depends' => '', + 'soname' => 'libc.so.6' }, 'deprecated PRIVATE symbol'); + +is( $sym_file->lookup_symbol($private_gone_sym, ['libc.so.6'], 1), + undef, 'missing PRIVATE is gone after merge'); use File::Temp; @@ -129,26 +159,34 @@ $sym_file_dup->{file} = "$srcdir/symbol_file.tmp"; is_deeply($sym_file_dup, $sym_file, 'save -> load' ); +# Test dump( export_private=>1 ). $private_sym should be normal now +$sym_file->save($save_file->filename, export_private => 1); +$sym_file_dup = Dpkg::Shlibs::SymbolFile->new($save_file->filename); +$sym = $sym_file_dup->lookup_symbol($private_sym, ['libc.so.6'], 0); +is_deeply($sym, { 'minver' => '2.3.6.ds1-13', 'dep_id' => 0, + 'type' => '', 'deprecated' => 0, 'depends' => '', + 'soname' => 'libc.so.6' }, 'dump(export_private=>1)'); + # Test include mechanism of SymbolFile $sym_file = Dpkg::Shlibs::SymbolFile->new("$srcdir/symbols.include-1"); $sym = $sym_file->lookup_symbol('symbol_bef...@base', ['libfake.so.1']); -is_deeply($sym, { 'minver' => '0.9', 'dep_id' => 0, 'deprecated' => 0, +is_deeply($sym, { 'minver' => '0.9', 'dep_id' => 0, 'deprecated' => 0, type => '', 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 'symbol before include not lost'); $sym = $sym_file->lookup_symbol('symbol_af...@base', ['libfake.so.1']); -is_deeply($sym, {'minver' => '1.1', 'dep_id' => 0, 'deprecated' => 0, +is_deeply($sym, {'minver' => '1.1', 'dep_id' => 0, 'deprecated' => 0, type => '', 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 'symbol after include not lost'); $sym = $sym_file->lookup_symbol('symbol1_fa...@base', ['libfake.so.1']); -is_deeply($sym, {'minver' => '1.0', 'dep_id' => 0, 'deprecated' => 0, +is_deeply($sym, {'minver' => '1.0', 'dep_id' => 0, 'deprecated' => 0, type => '', 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 'overrides order with #include'); $sym = $sym_file->lookup_symbol('symbol3_fa...@base', ['libfake.so.1']); -is_deeply($sym, { 'minver' => '0', 'dep_id' => 0, 'deprecated' => 0, +is_deeply($sym, { 'minver' => '0', 'dep_id' => 0, 'deprecated' => 0, type => '', 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 'overrides order with #include'); @@ -158,7 +196,7 @@ is($sym_file->get_smallest_version('libfake.so.1'), "0", $sym_file = Dpkg::Shlibs::SymbolFile->new("$srcdir/symbols.include-2"); $sym = $sym_file->lookup_symbol('symbol1_fa...@base', ['libfake.so.1']); -is_deeply($sym, { 'minver' => '1.0', 'dep_id' => 1, 'deprecated' => 0, +is_deeply($sym, { 'minver' => '1.0', 'dep_id' => 1, 'deprecated' => 0, type => '', 'depends' => 'libvirtualfake', 'soname' => 'libfake.so.1' }, 'overrides order with circular #include'); -- 1.6.2.1