[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |