Explorar o código

Dpkg::Shlibs::SymbolFile: Add support for Ignore-Blacklist-Groups field

The currently available groups are aeabi and gomp.

Closes: #694524
Guillem Jover %!s(int64=12) %!d(string=hai) anos
pai
achega
fdc9a1b07c

+ 2 - 0
debian/changelog

@@ -26,6 +26,8 @@ dpkg (1.17.6) UNRELEASED; urgency=low
     to keep up with the GNU toolchain, or other toolchains emitting different
     symbols.
   * Blacklist GOMP critical section symbols. Closes: #708033
+  * Add support for Ignore-Blacklist-Groups field in symbols files, with the
+    two available group values aeabi and gomp. Closes: #694524
 
   [ Updated dpkg translations ]
   * Swedish (Peter Krefting).

+ 14 - 4
man/deb-symbols.5

@@ -52,10 +52,20 @@ etc.
 .P
 Each entry for a library can also have some fields of meta-information.
 Those fields are stored on lines starting with an asterisk. Currently,
-the only valid field is \fIBuild\-Depends\-Package\fR, it indicates the name
-of the "\-dev" package associated to the library and is used by
-\fBdpkg\-shlibdeps\fP to make sure that the dependency generated is at least as
-strict as the corresponding build dependency.
+the only valid fields are:
+.TP
+.B Build\-Depends\-Package
+It indicates the name of the "\-dev" package associated to the library
+and is used by \fBdpkg\-shlibdeps\fP to make sure that the dependency
+generated is at least as strict as the corresponding build dependency.
+.TP
+.B Ignore\-Blacklist\-Groups
+It indicates what blacklist groups should be ignored, as a whitespace
+separated list, so that the symbols contained in those groups get
+included in the output file. This should only be necessary for toolchain
+packages providing those blacklisted symbols. The available groups are
+system dependent, for ELF and GNU-based systems these are \fBaeabi\fP
+and \fBgomp\fP.
 .SH EXAMPLES
 .SS Simple symbols file
 .PP

+ 11 - 4
scripts/Dpkg/Shlibs/SymbolFile.pm

@@ -71,17 +71,18 @@ for my $i (14 .. 31) {
 }
 
 sub symbol_is_blacklisted {
-    my ($symbol) = @_;
+    my ($symbol, $include_groups) = @_;
 
     return 1 if exists $blacklist{$symbol};
 
     # The ARM Embedded ABI spec states symbols under this namespace as
     # possibly appearing in output objects.
-    return 1 if $symbol =~ /^__aeabi_/;
+    return 1 if not ${$include_groups}{aeabi} and $symbol =~ /^__aeabi_/;
 
     # The GNU implementation of the OpenMP spec, specifies symbols under
     # this namespace as possibly appearing in output objects.
-    return 1 if $symbol =~ /^\.gomp_critical_user_/;
+    return 1 if not ${$include_groups}{gomp}
+                and $symbol =~ /^\.gomp_critical_user_/;
 
     return 0;
 }
@@ -397,12 +398,18 @@ sub merge_symbols {
     error(_g('cannot merge symbols from objects without SONAME'))
         unless $soname;
 
+    my %include_groups = ();
+    my $groups = $self->get_field($soname, 'Ignore-Blacklist-Groups');
+    if (defined $groups) {
+        $include_groups{$_} = 1 foreach (split /\s+/, $groups);
+    }
+
     my %dynsyms;
     foreach my $sym ($object->get_exported_dynamic_symbols()) {
         my $name = $sym->{name} . '@' .
                    ($sym->{version} ? $sym->{version} : 'Base');
         my $symobj = $self->lookup_symbol($name, $soname);
-        if (symbol_is_blacklisted($sym->{name})) {
+        if (symbol_is_blacklisted($sym->{name}, \%include_groups)) {
             next unless (defined $symobj and $symobj->has_tag('ignore-blacklist'));
         }
         $dynsyms{$name} = $sym;

+ 5 - 0
scripts/Makefile.am

@@ -203,6 +203,10 @@ test_cases = \
 	t/910_merge_changelogs.t
 
 test_data = \
+	t/200_Dpkg_Shlibs/symbols.blacklisted \
+	t/200_Dpkg_Shlibs/symbols.blacklist-groups \
+	t/200_Dpkg_Shlibs/symbols.blacklist-filter \
+	t/200_Dpkg_Shlibs/symbols.blacklist-ignore \
 	t/200_Dpkg_Shlibs/symbols.fake-1 \
 	t/200_Dpkg_Shlibs/symbols.fake-2 \
 	t/200_Dpkg_Shlibs/symbols.fake-3 \
@@ -222,6 +226,7 @@ test_data = \
 	t/200_Dpkg_Shlibs/objdump.space \
 	t/200_Dpkg_Shlibs/objdump.basictags-amd64 \
 	t/200_Dpkg_Shlibs/objdump.basictags-i386 \
+	t/200_Dpkg_Shlibs/objdump.blacklisted \
 	t/200_Dpkg_Shlibs/objdump.patterns \
 	t/200_Dpkg_Shlibs/objdump.glib-ia64 \
 	t/200_Dpkg_Shlibs/objdump.libc6-2.3 \

+ 82 - 1
scripts/t/200_Dpkg_Shlibs.t

@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 106;
+use Test::More tests => 118;
 use Cwd;
 use IO::String;
 
@@ -187,6 +187,87 @@ sub save_load_test {
 
 save_load_test( $sym_file, 'save -> load' );
 
+
+# Test ignoring blacklisted symbols
+open $objdump, '<', "$datadir/objdump.blacklisted"
+    or die "objdump.blacklisted: $!";
+$obj->reset();
+$obj->parse_objdump_output($objdump);
+close $objdump;
+
+# Do not ignore any blacklist
+$sym_file = Dpkg::Shlibs::SymbolFile->new(file => "$datadir/symbols.blacklist-filter");
+$sym_file->merge_symbols($obj, '100.MISSING');
+
+$sym = $sym_file->lookup_symbol('symbol@Base', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => 'symbol@Base',
+                minver => '1.0', dep_id => 0, deprecated => 0),
+          'symbol unaffected w/o ignoring blacklists');
+
+$sym = $sym_file->lookup_symbol('.gomp_critical_user_foo@Base', ['libblacklisted.so.0']);
+is($sym, undef, 'gomp symbol omitted while filtering on blacklists');
+
+$sym = $sym_file->lookup_symbol('__aeabi_lcmp@GCC_3.0', ['libblacklisted.so.0']);
+is($sym, undef, 'known aeabi symbol omitted while filtering on blacklists');
+
+$sym = $sym_file->lookup_symbol('__aeabi_unknown@GCC_4.0', ['libblacklisted.so.0']);
+is($sym, undef, 'unknown aeabi symbol omitted while filtering on blacklists');
+
+# Ignore blacklists using the ignore-blacklists symbol tag
+$sym_file = Dpkg::Shlibs::SymbolFile->new(file => "$datadir/symbols.blacklist-ignore");
+$sym_file->merge_symbols($obj, '100.MISSING');
+
+$sym = $sym_file->lookup_symbol('symbol@Base', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => 'symbol@Base',
+                minver => '1.0', dep_id => 0, deprecated => 0),
+          'symbol unaffected while ignoring blacklists via symbol tag');
+
+$sym = $sym_file->lookup_symbol('.gomp_critical_user_foo@Base', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => '.gomp_critical_user_foo@Base',
+                minver => '2.0', dep_id => 0, deprecated => 0,
+                tags => { 'ignore-blacklist' => undef },
+                tagorder => [ 'ignore-blacklist' ]),
+          'blacklisted gomp symbol included via symbol tag');
+
+$sym = $sym_file->lookup_symbol('__aeabi_lcmp@GCC_3.0', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => '__aeabi_lcmp@GCC_3.0',
+                minver => '3.0', dep_id => 0, deprecated => 0,
+                tags => { 'ignore-blacklist' => undef },
+                tagorder => [ 'ignore-blacklist' ]),
+          'blacklisted known aeabi symbol included via symbol tag');
+
+$sym = $sym_file->lookup_symbol('__aeabi_unknown@GCC_4.0', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => '__aeabi_unknown@GCC_4.0',
+                minver => '4.0', dep_id => 0, deprecated => 0,
+                tags => { 'ignore-blacklist' => undef },
+                tagorder => [ 'ignore-blacklist' ]),
+          'blacklisted unknown aeabi symbol omitted via symbol tag');
+
+# Ignore blacklists using the Ignore-Blacklist-Groups field
+$sym_file = Dpkg::Shlibs::SymbolFile->new(file => "$datadir/symbols.blacklist-groups");
+$sym_file->merge_symbols($obj, '100.MISSING');
+
+$sym = $sym_file->lookup_symbol('symbol@Base', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => 'symbol@Base',
+                minver => '1.0', dep_id => 0, deprecated => 0),
+          'symbol unaffected w/o ignoring blacklists');
+
+$sym = $sym_file->lookup_symbol('.gomp_critical_user_foo@Base', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => '.gomp_critical_user_foo@Base',
+                minver => '2.0', dep_id => 0, deprecated => 0),
+          'blacklisted gomp symbol included via library field');
+
+$sym = $sym_file->lookup_symbol('__aeabi_lcmp@GCC_3.0', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => '__aeabi_lcmp@GCC_3.0',
+                minver => '3.0', dep_id => 0, deprecated => 0),
+          'blacklisted known aeabi symbol included via library field');
+
+$sym = $sym_file->lookup_symbol('__aeabi_unknown@GCC_4.0', ['libblacklisted.so.0']);
+is_deeply($sym, Dpkg::Shlibs::Symbol->new(symbol => '__aeabi_unknown@GCC_4.0',
+                minver => '4.0', dep_id => 0, deprecated => 0),
+          'blacklisted unknown aeabi symbol included via library field');
+
+
 # Test include mechanism of SymbolFile
 $sym_file = Dpkg::Shlibs::SymbolFile->new(file => "$datadir/symbols.include-1");
 

+ 15 - 0
scripts/t/200_Dpkg_Shlibs/objdump.blacklisted

@@ -0,0 +1,15 @@
+
+libblacklisted.so.0:     file format elf32-littlearm
+architecture: arm, flags 0x00000150:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x0000f668
+
+Dynamic Section:
+  SONAME               libblacklisted.so.0
+
+DYNAMIC SYMBOL TABLE:
+00018ef4 g    DF .text	00000008  Base        .gomp_critical_user_foo
+0001c7f0 g    DF .text	00000018  Base        .gomp_critical_user_bar
+00011614 g    DF .text	00000014  GCC_3.0     __aeabi_lcmp
+000115d8  w   DF .text	00000000  GCC_4.0     __aeabi_unknown
+00015378 g    DF .text	0000000c  Base        symbol

+ 3 - 0
scripts/t/200_Dpkg_Shlibs/symbols.blacklist-filter

@@ -0,0 +1,3 @@
+libblacklisted.so.0 libblacklisted0 #MINVER#
+#include "symbols.blacklisted"
+ symbol@Base 1.0

+ 4 - 0
scripts/t/200_Dpkg_Shlibs/symbols.blacklist-groups

@@ -0,0 +1,4 @@
+libblacklisted.so.0 libblacklisted0 #MINVER#
+* Ignore-Blacklist-Groups: aeabi gomp
+#include "symbols.blacklisted"
+ symbol@Base 1.0

+ 3 - 0
scripts/t/200_Dpkg_Shlibs/symbols.blacklist-ignore

@@ -0,0 +1,3 @@
+libblacklisted.so.0 libblacklisted0 #MINVER#
+(ignore-blacklist)#include "symbols.blacklisted"
+ symbol@Base 1.0

+ 4 - 0
scripts/t/200_Dpkg_Shlibs/symbols.blacklisted

@@ -0,0 +1,4 @@
+ .gomp_critical_user_foo@Base 2.0
+ .gomp_critical_user_bar@Base 2.0
+ __aeabi_lcmp@GCC_3.0 3.0
+ __aeabi_unknown@GCC_4.0 4.0