[libvirt] [libvirt-glib 4/4] Add scripts for validating the libvirt-glib symbol files

Christophe Fergeau cfergeau at redhat.com
Fri Dec 6 11:38:01 UTC 2013


Import two test scripts from libvirt code which validate that
all symbols in libvirt-glib symbol files exist in the ELF binary, and also
validate the alphabetical sorting. These are hooked up to run with 'make
check'.

This commit is based on a libosinfo patch from Daniel P. Berrange
---
 Makefile.am                   |   2 +
 build-aux/check-symfile.pl    |  70 +++++++++++++++++++++++++++++
 build-aux/check-symsorting.pl | 100 ++++++++++++++++++++++++++++++++++++++++++
 configure.ac                  |   8 ++++
 libvirt-gconfig/Makefile.am   |  15 +++++++
 libvirt-glib/Makefile.am      |  15 +++++++
 libvirt-gobject/Makefile.am   |  15 +++++++
 7 files changed, 225 insertions(+)
 create mode 100755 build-aux/check-symfile.pl
 create mode 100755 build-aux/check-symsorting.pl

diff --git a/Makefile.am b/Makefile.am
index 9101fdb..9b03676 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,8 @@ EXTRA_DIST = $(PACKAGE).spec \
 	     maint.mk \
 	     cfg.mk \
 	     AUTHORS.in \
+	     build-aux/check-symfile.pl \
+	     build-aux/check-symsorting.pl \
 	     $(NULL)
 
 DISTCLEAN_FILES = $(PACKAGE).spec $(pkgconfig_DATA)
diff --git a/build-aux/check-symfile.pl b/build-aux/check-symfile.pl
new file mode 100755
index 0000000..d59a213
--- /dev/null
+++ b/build-aux/check-symfile.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2012-2013 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+die "syntax: $0 SYMFILE ELFLIB(S)" unless int(@ARGV) >= 2;
+
+my $symfile = shift @ARGV;
+my @elflibs = @ARGV;
+
+my %wantsyms;
+my %gotsyms;
+
+my $ret = 0;
+
+open SYMFILE, $symfile or die "cannot read $symfile: $!";
+
+while (<SYMFILE>) {
+    next if /{/;
+    next if /}/;
+    next if /global:/;
+    next if /local:/;
+    next if /^\s*$/;
+    next if /^\s*#/;
+    next if /\*/;
+
+    die "malformed line $_" unless /^\s*(\S+);$/;
+
+    if (exists $wantsyms{$1}) {
+        print STDERR "Symbol $1 is listed twice\n";
+        $ret = 1;
+    } else {
+        $wantsyms{$1} = 1;
+    }
+}
+close SYMFILE;
+
+foreach my $elflib (@elflibs) {
+    open NM, "-|", "nm", $elflib or die "cannot run 'nm $elflib': $!";
+
+    while (<NM>) {
+        next unless /^\S+\s(?:[TBD])\s(\S+)\s*$/;
+
+        $gotsyms{$1} = 1;
+    }
+
+    close NM;
+}
+
+foreach my $sym (keys(%wantsyms)) {
+    next if exists $gotsyms{$sym};
+
+    print STDERR "Expected symbol $sym is not in ELF library\n";
+    $ret = 1;
+}
+
+exit($ret);
diff --git a/build-aux/check-symsorting.pl b/build-aux/check-symsorting.pl
new file mode 100755
index 0000000..470247c
--- /dev/null
+++ b/build-aux/check-symsorting.pl
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2012-2013 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+use strict;
+use warnings;
+
+die "syntax: $0 SRCDIR SYMFILE..." unless int(@ARGV) >= 2;
+
+my $ret = 0;
+my $srcdir = shift;
+my $incomment = 0;
+my $name;
+foreach my $symfile (@ARGV) {
+    open SYMFILE, $symfile or die "cannot read $symfile: $!";
+
+    my $line = 0;
+    my @group;
+
+    while (<SYMFILE>) {
+        chomp;
+
+	if ($incomment) {
+	    if (m,\*/,) {
+		$incomment = 0;
+	    } else {
+		# skip
+	    }
+	} else {
+	    if (m,/\*,) {
+		$incomment = 1;
+	    } elsif (/^(.*)\s*{\s*$/) {
+		@group = ();
+		$line = $.;
+		$name = $1;
+	    } elsif (/^\s*}(.*);$/) {
+		&check_sorting(\@group, $symfile, $line, $name);
+	    } elsif (/^\s*(global|local):/) {
+		# skip
+	    } elsif (/^\s*\*;\s*$/) {
+		# skip
+	    } elsif (/^\s*$/) {
+		# skip
+	    } else {
+		$_ =~ s/;//;
+		push @group, $_;
+	    }
+	}
+    }
+
+    close SYMFILE;
+}
+
+sub check_sorting {
+    my $group = shift;
+    my $symfile = shift;
+    my $line = shift;
+    my $name = shift;
+
+    my @group = @{$group};
+    my @sorted = sort { lc $a cmp lc $b } @group;
+    my $sorted = 1;
+    my $first;
+    my $last;
+
+    # Check that symbols within a group are in order
+    for (my $i = 0 ; $i <= $#sorted ; $i++) {
+        if ($sorted[$i] ne $group[$i]) {
+            $first = $i unless defined $first;
+            $last = $i;
+            $sorted = 0;
+        }
+    }
+    if (!$sorted) {
+        @group = splice @group, $first, ($last-$first+1);
+        @sorted = splice @sorted, $first, ($last-$first+1);
+        print "Symbol block $name at $symfile:$line: symbols not sorted\n";
+        print map { "  " . $_ . "\n" } @group;
+        print "Correct ordering\n";
+        print map { "  " . $_ . "\n" } @sorted;
+        print "\n";
+        $ret = 1;
+    }
+}
+
+exit $ret;
diff --git a/configure.ac b/configure.ac
index 9b5d09c..81e0d4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -232,6 +232,14 @@ AC_SUBST([PYTHON_VERSION])
 AC_SUBST([PYTHON_INCLUDES])
 AC_SUBST([PYTHON_SITE_PACKAGES])
 
+
+with_linux=no
+case $host in
+  *-*-linux*) with_linux=yes ;;
+esac
+AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
+
+
 AC_ARG_ENABLE([introspection],
         AS_HELP_STRING([--enable-introspection], [enable GObject introspection]),
         [], [enable_introspection=check])
diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index 7550afe..d11493b 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -215,6 +215,21 @@ libvirt-gconfig-enum-types.c: $(GCONFIG_HEADER_FILES) libvirt-gconfig-enum-types
 	$(AM_V_GEN) ( $(GLIB_MKENUMS) --template $(srcdir)/libvirt-gconfig-enum-types.c.template $(GCONFIG_HEADER_FILES:%=$(srcdir)/%) ) | \
 	    sed -e "s/G_TYPE_VIR_CONFIG/GVIR_CONFIG_TYPE/" -e "s/g_vir/gvir/" > libvirt-gconfig-enum-types.c
 
+# .libs/libvirt-gconfig.so is built by libtool as a side-effect of the Makefile
+# rule for libosvirt-gconfig.la.  However, checking symbols relies on Linux ELF layout
+if WITH_LINUX
+check-symfile: libvirt-gconfig.sym libvirt-gconfig-1.0.la
+	$(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symfile.pl libvirt-gconfig.sym \
+		.libs/libvirt-gconfig-1.0.so
+else ! WITH_LINUX
+check-symfile:
+endif ! WITH_LINUX
+check-symsorting:
+	$(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symsorting.pl \
+		$(srcdir) libvirt-gconfig.sym
+check-local: check-symfile check-symsorting
+
+
 if WITH_GOBJECT_INTROSPECTION
 
 LibvirtGConfig-1.0.gir: libvirt-gconfig-1.0.la $(G_IR_SCANNER) Makefile.am
diff --git a/libvirt-glib/Makefile.am b/libvirt-glib/Makefile.am
index 1370ebc..c7b8123 100644
--- a/libvirt-glib/Makefile.am
+++ b/libvirt-glib/Makefile.am
@@ -37,6 +37,21 @@ libvirt_glib_1_0_la_LDFLAGS = \
 			-Wl,--version-script=$(srcdir)/libvirt-glib.sym \
 			-version-info $(LIBVIRT_GLIB_VERSION_INFO)
 
+# .libs/libvirt-glib.so is built by libtool as a side-effect of the Makefile
+# rule for libosvirt-glib.la.  However, checking symbols relies on Linux ELF layout
+if WITH_LINUX
+check-symfile: libvirt-glib.sym libvirt-glib-1.0.la
+	$(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symfile.pl libvirt-glib.sym \
+		.libs/libvirt-glib-1.0.so
+else ! WITH_LINUX
+check-symfile:
+endif ! WITH_LINUX
+check-symsorting:
+	$(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symsorting.pl \
+		$(srcdir) libvirt-glib.sym
+check-local: check-symfile check-symsorting
+
+
 if WITH_GOBJECT_INTROSPECTION
 
 LibvirtGLib-1.0.gir: libvirt-glib-1.0.la $(G_IR_SCANNER) Makefile.am
diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am
index 3284b2c..0cc11e7 100644
--- a/libvirt-gobject/Makefile.am
+++ b/libvirt-gobject/Makefile.am
@@ -119,6 +119,21 @@ BUILT_SOURCES = $(GOBJECT_GENERATED_FILES)
 
 CLEANFILES = $(BUILT_SOURCES)
 
+# .libs/libvirt-gobject.so is built by libtool as a side-effect of the Makefile
+# rule for libosvirt-gobject.la.  However, checking symbols relies on Linux ELF layout
+if WITH_LINUX
+check-symfile: libvirt-gobject.sym libvirt-gobject-1.0.la
+	$(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symfile.pl libvirt-gobject.sym \
+		.libs/libvirt-gobject-1.0.so
+else ! WITH_LINUX
+check-symfile:
+endif ! WITH_LINUX
+check-symsorting:
+	$(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symsorting.pl \
+		$(srcdir) libvirt-gobject.sym
+check-local: check-symfile check-symsorting
+
+
 if WITH_GOBJECT_INTROSPECTION
 
 LibvirtGObject-1.0.gir: libvirt-gobject-1.0.la $(G_IR_SCANNER) Makefile.am
-- 
1.8.4.2




More information about the libvir-list mailing list