[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1/2] gcov: Add script to split coverage informations.



From: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>

Split coverage informations extracted from xencov utility.
This script accept coverage blob either as file or from input and extract
into files compatible with gcc format (gcda).

Signed-off-by: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>
---
 tools/misc/Makefile     |    2 +-
 tools/misc/xencov_split |  191 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 192 insertions(+), 1 deletion(-)
 create mode 100755 tools/misc/xencov_split

diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index eef9411..520ef80 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -18,7 +18,7 @@ SUBDIRS-$(CONFIG_LOMOUNT) += lomount
 SUBDIRS-$(CONFIG_MINITERM) += miniterm
 SUBDIRS := $(SUBDIRS-y)
 
-INSTALL_BIN-y := xencons
+INSTALL_BIN-y := xencons xencov_split
 INSTALL_BIN-$(CONFIG_X86) += xen-detect
 INSTALL_BIN := $(INSTALL_BIN-y)
 
diff --git a/tools/misc/xencov_split b/tools/misc/xencov_split
new file mode 100755
index 0000000..cf0521f
--- /dev/null
+++ b/tools/misc/xencov_split
@@ -0,0 +1,191 @@
+#!/usr/bin/perl
+
+# xencov_split - split coverage information from Xen
+#
+# Copyright (C) 2013  - Citrix Systems
+# -----
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+use strict;
+use File::Path qw(mkpath);
+
+# some magic constants
+my $magic = 0x67636461;
+my $ctrBase = 0x01a10000;
+
+my $xenMagic = 0x58544346;     # file header
+my $xenTagFunc = 0x58544366;   # functions tag
+my $xenTagCount0 = 0x58544330; # counter 0 tag
+my $xenTagEnd = 0x5854432e;    # end file
+
+# open input file
+if ($ARGV[0]) {
+       my $fn = $ARGV[0];
+       open(IN, '<', $fn) or die "opening file \"$fn\"";
+} else {
+       open(IN, '<&STDIN') or die "redirecting input";
+}
+
+my $pos = 0;
+
+sub getRaw($)
+{
+    my $l = shift;
+    die 'got no data to read' if $l < 0;
+    my $res = '';
+    do {
+        my $data;
+        my $r = read(IN, $data, $l);
+        die "error $! reading data from input at position $pos" if 
!defined($r);
+        die "unexpected end of file at position $pos" if !$r;
+        $l -= $r;
+        $pos += $r;
+        $res .= $data;
+    } while ($l > 0);
+    return $res;
+}
+
+sub get32()
+{
+    return unpack('V', getRaw(4));
+}
+
+sub get64()
+{
+    # This is returned as raw data as some Perl version could not
+    # support 64 bit integer
+    # This is ok for little endian machines
+    return getRaw(8);
+}
+
+sub align()
+{
+    my $l = $pos & 7;
+    getRaw(8-$l) if $l;
+}
+
+# read a string prefixed by length
+sub getS()
+{
+    my $l = get32();
+    my $res = getRaw($l);
+    align();
+    return $res;
+}
+
+sub parseFunctions($)
+{
+    my $numCounters = shift;
+    my $num = get32();
+
+    my @funcs;
+    for my $n (1..$num) {
+        my @data;
+        my $ident = get32();
+        my $checksum = get32();
+        for my $n (1..$numCounters) {
+            push @data, get32(); # number of counters for a type
+        }
+        push @funcs, [$ident, $checksum, \@data];
+    }
+    align();
+    return @funcs;
+}
+
+sub parseCounters($)
+{
+    my $tag = shift;
+    die sprintf("wrong tag 0x%08x pos $pos (0x%08x)", $tag, $pos) if $tag < 
$xenTagCount0;
+    $tag -= $xenTagCount0;
+    die sprintf('wrong tag 0x%08x', $tag) if $tag > 5;
+    my $data = '';
+
+    my $num = get32();
+    for my $n (1..$num) {
+        $data .= get64();
+    }
+    align();
+    return [$tag, $data];
+}
+
+
+sub parseFile()
+{
+    my $ver = get32();
+    my $stamp = get32();
+    my $fn = getS();
+    align();
+
+    my $numCounters;
+
+    print "got file $fn\n";
+    die if $fn !~ m,^(/.*?)[^/]+\.gcda$,;
+    mkpath(".$1");
+    open(OUT, '>', ".$fn") or die;
+
+    print OUT pack('VVV', $magic, $ver, $stamp);
+
+    # read counters of file
+    my @ctrs;
+    my @funcs;
+    my $tag;
+    for (;;) {
+        $tag = get32();
+        last if ($tag == $xenMagic || $tag == $xenTagEnd);
+        if ($tag == $xenTagFunc) {
+            die if scalar(@funcs);
+            @funcs = parseFunctions(scalar(@ctrs));
+            next;
+        }
+
+        # must be a counter
+        push @ctrs, parseCounters($tag);
+        ++$numCounters;
+    }
+
+    # print all functions
+    for my $f (@funcs) {
+        # tag tag_len ident checksum
+        print OUT pack('VVVV', 0x01000000, 2, $f->[0], $f->[1]);
+        # all counts
+        my $n = 0;
+        for my $c (@{$f->[2]}) {
+            my ($type, $data) = @{$ctrs[$n]};
+            print OUT pack('VV', $ctrBase + 0x20000 * $type, $c*2);
+            die "--$c--$type--$data--" if length($data) < $c * 8;
+            print OUT substr($data, 0, $c * 8);
+            $ctrs[$n] = [$type, substr($data, $c * 8)];
+            ++$n;
+        }
+    }
+    close(OUT);
+
+    return $tag;
+}
+
+my $tag = get32();
+die 'no coverage or wrong file format' if $tag != $xenMagic;
+for (;;) {
+    if ($tag == $xenMagic) {
+        $tag = parseFile();
+    } elsif ($tag == $xenTagEnd) {
+        last;
+    } else {
+        die "wrong tag $tag";
+    }
+}
+
+
-- 
1.7.9.5

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.