xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: George Dunlap <george.dunlap@eu.citrix.com>
To: Frediano Ziglio <frediano.ziglio@citrix.com>
Cc: Matthew Daley <mattjd@gmail.com>,
	Christoph Egger <chegger@amazon.de>,
	Ian Campbell <Ian.Campbell@citrix.com>,
	Miguel Clara <miguelmclara@gmail.com>,
	xen-devel@lists.xen.org
Subject: Re: [PATCH] gcov: Support gcc 4.7
Date: Mon, 17 Jun 2013 10:50:08 +0100	[thread overview]
Message-ID: <51BEDBD0.9010409@eu.citrix.com> (raw)
In-Reply-To: <1371457748.9654.3.camel@hamster.uk.xensource.com>

On 17/06/13 09:29, Frediano Ziglio wrote:
> gcc 4.7 changed format used internally for coverage data.
> This patch address these changes.
> The information that gcc generate are mostly the same but to support common
> sections.
> The only difference in the blob exported by Xen is that functions have 2
> different checksums instead of one.
>
> Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com>

At this point we'd like to completely freeze the tree except for 
critical bugfixes.  I think this will have to wait for 4.4.

  -George

> ---
>   tools/misc/xencov_split   |   26 ++++++--
>   xen/arch/x86/xen.lds.S    |    1 +
>   xen/common/gcov/gcov.c    |  161 +++++++++++++++++++++++++++++++++++++--------
>   xen/include/public/gcov.h |   16 ++++-
>   xen/include/xen/gcov.h    |   68 ++++++++++++++++++-
>   5 files changed, 235 insertions(+), 37 deletions(-)
>
> Patch tested with gcc 4.7, x64 with x86 dom0 and lcov 1.10.
>
> diff --git a/tools/misc/xencov_split b/tools/misc/xencov_split
> index 2e5aa80..af0f580 100755
> --- a/tools/misc/xencov_split
> +++ b/tools/misc/xencov_split
> @@ -27,7 +27,8 @@ my $magic = 0x67636461;
>   my $ctrBase = 0x01a10000;
>   
>   my $xenMagic = 0x58544346;	# file header
> -my $xenTagFunc = 0x58544366;	# functions tag
> +my $xenTagFunc  = 0x58544366;	# functions tag
> +my $xenTagFunc2 = 0x58544367;	# functions tag2
>   my $xenTagCount0 = 0x58544330;	# counter 0 tag
>   my $xenTagEnd = 0x5854432e;	# end file
>   
> @@ -86,9 +87,9 @@ sub getS()
>       return $res;
>   }
>   
> -sub parseFunctions($)
> +sub parseFunctions($$)
>   {
> -    my $numCounters = shift;
> +    my ($numCounters, $ver) = @_;
>       my $num = get32();
>   
>       my @funcs;
> @@ -96,10 +97,12 @@ sub parseFunctions($)
>           my @data;
>           my $ident = get32();
>           my $checksum = get32();
> +        my $checksum2 = 0;
> +        $checksum2 = get32() if $ver > 1;
>           for my $n (1..$numCounters) {
>               push @data, get32(); # number of counters for a type
>           }
> -        push @funcs, [$ident, $checksum, \@data];
> +        push @funcs, [$ver, $ident, $checksum, $checksum2, \@data];
>       }
>       align();
>       return @funcs;
> @@ -147,7 +150,12 @@ sub parseFile()
>           last if ($tag == $xenMagic || $tag == $xenTagEnd);
>           if ($tag == $xenTagFunc) {
>               die if scalar(@funcs);
> -            @funcs = parseFunctions(scalar(@ctrs));
> +            @funcs = parseFunctions(scalar(@ctrs), 1);
> +            next;
> +        }
> +        if ($tag == $xenTagFunc2) {
> +            die if scalar(@funcs);
> +            @funcs = parseFunctions(scalar(@ctrs), 2);
>               next;
>           }
>   
> @@ -159,10 +167,14 @@ sub parseFile()
>       # print all functions
>       for my $f (@funcs) {
>           # tag tag_len ident checksum
> -        print OUT pack('VVVV', 0x01000000, 2, $f->[0], $f->[1]);
> +        if ($f->[0] == 1) {
> +            print OUT pack('VVVV',  0x01000000, 2, $f->[1], $f->[2]);
> +        } else {
> +            print OUT pack('VVVVV', 0x01000000, 3, $f->[1], $f->[2], $f->[3]);
> +        }
>           # all counts
>           my $n = 0;
> -        for my $c (@{$f->[2]}) {
> +        for my $c (@{$f->[4]}) {
>               my ($type, $data) = @{$ctrs[$n]};
>               print OUT pack('VV', $ctrBase + 0x20000 * $type, $c*2);
>               die "--$c--$type--$data--" if length($data) < $c * 8;
> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
> index d959941..bdc4c91 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -112,6 +112,7 @@ SECTIONS
>          . = ALIGN(8);
>          __ctors_start = .;
>          *(.ctors)
> +       *(.init_array)
>          __ctors_end = .;
>     } :text
>     . = ALIGN(32);
> diff --git a/xen/common/gcov/gcov.c b/xen/common/gcov/gcov.c
> index b5717b9..1d32d8f 100644
> --- a/xen/common/gcov/gcov.c
> +++ b/xen/common/gcov/gcov.c
> @@ -106,17 +106,120 @@ static int write_string(write_iter_t *iter, const char *s)
>   
>   static inline int next_type(const struct gcov_info *info, int *type)
>   {
> -    while ( ++*type < XENCOV_COUNTERS && !counter_active(info, *type) )
> +    while ( ++*type < XENCOV_COUNTERS_MASK && !counter_active(info, *type) )
>           continue;
>       return *type;
>   }
>   
> +static inline const struct gcov_fn_info_407 *
> +next_func(const struct gcov_info_407 *info, int *n_func)
> +{
> +    while ( ++*n_func < info->n_functions ) {
> +        const struct gcov_fn_info_407 *fn = info->functions[*n_func];
> +
> +        /* the test for info member handle common data redefinitions
> +           in object files */
> +        if ( fn && fn->info == info)
> +             return fn;
> +    }
> +
> +    return NULL;
> +}
> +
> +static inline const struct gcov_ctr_info_407 *
> +next_ctr(const struct gcov_fn_info_407 *fn, int *n_ctr)
> +{
> +    while ( ++*n_ctr < XENCOV_COUNTERS_407 )
> +        if ( fn->info->merge[*n_ctr] )
> +            return &fn->ctrs[*n_ctr];
> +
> +    return NULL;
> +}
> +
>   static inline void align_iter(write_iter_t *iter)
>   {
>       iter->write_offset =
>           (iter->write_offset + sizeof(uint64_t) - 1) & -sizeof(uint64_t);
>   }
>   
> +static int write_info(write_iter_t *iter, const struct gcov_info* info)
> +{
> +    const struct gcov_ctr_info *ctr;
> +    int type, ret;
> +    size_t size_fn = sizeof(struct gcov_fn_info);
> +
> +    /* dump counters */
> +    ctr = info->counts;
> +    for ( type = -1; next_type(info, &type) < XENCOV_COUNTERS_MASK; ++ctr )
> +    {
> +        align_iter(iter);
> +        chk(write32(iter, XENCOV_TAG_COUNTER(type)));
> +        chk(write32(iter, ctr->num));
> +        chk(write_raw(iter, ctr->values,
> +                          ctr->num * sizeof(ctr->values[0])));
> +
> +        size_fn += sizeof(unsigned);
> +    }
> +
> +    /* dump all functions together */
> +    align_iter(iter);
> +    chk(write32(iter, XENCOV_TAG_FUNC));
> +    chk(write32(iter, info->n_functions));
> +    chk(write_raw(iter, info->functions, info->n_functions * size_fn));
> +
> +    return 0;
> +}
> +
> +static int write_info_407(write_iter_t *iter, const struct gcov_info_407* info)
> +{
> +    int ret;
> +    const struct gcov_fn_info_407 *fn;
> +    const struct gcov_ctr_info_407 *ctr;
> +    int n_func, n_ctr;
> +    unsigned int num_func = 0;
> +    unsigned int ctrs[XENCOV_COUNTERS_407];
> +
> +    for ( n_ctr = 0; n_ctr < XENCOV_COUNTERS_407; ++n_ctr )
> +        ctrs[n_ctr] = 0;
> +
> +    /* scan to total counters */
> +    for ( n_func = -1; (fn = next_func(info, &n_func)) != NULL; )
> +    {
> +        ++num_func;
> +        for ( n_ctr = -1; (ctr = next_ctr(fn, &n_ctr)) != NULL; )
> +            ctrs[n_ctr] += ctr->num;
> +    }
> +
> +    /* output counters */
> +    for ( n_ctr = 0; n_ctr < XENCOV_COUNTERS_407; ++n_ctr )
> +    {
> +        if ( !ctrs[n_ctr] ) continue;
> +        align_iter(iter);
> +        chk(write32(iter, XENCOV_TAG_COUNTER(n_ctr)));
> +        chk(write32(iter, ctrs[n_ctr]));
> +        for ( n_func = -1; (fn = next_func(info, &n_func)) != NULL; )
> +        {
> +            ctr = &fn->ctrs[n_ctr];
> +            chk(write_raw(iter, ctr->values,
> +                          ctr->num * sizeof(ctr->values[0])));
> +        }
> +    }
> +
> +    /* dump all functions together */
> +    align_iter(iter);
> +    chk(write32(iter, XENCOV_TAG_FUNC2));
> +    chk(write32(iter, num_func));
> +    for ( n_func = -1; (fn = next_func(info, &n_func)) != NULL; )
> +    {
> +        chk(write32(iter, fn->ident));
> +        chk(write32(iter, fn->lineno_checksum));
> +        chk(write32(iter, fn->cfg_checksum));
> +        for ( n_ctr = -1; (ctr = next_ctr(fn, &n_ctr)) != NULL; )
> +            chk(write32(iter, ctr->num));
> +    }
> +    return 0;
> +}
> +
>   static int write_gcov(write_iter_t *iter)
>   {
>       struct gcov_info *info;
> @@ -128,10 +231,6 @@ static int write_gcov(write_iter_t *iter)
>       /* dump all files */
>       for ( info = info_list ; info; info = info->next )
>       {
> -        const struct gcov_ctr_info *ctr;
> -        int type;
> -        size_t size_fn = sizeof(struct gcov_fn_info);
> -
>           align_iter(iter);
>           chk(write32(iter, XENCOV_TAG_FILE));
>           chk(write32(iter, info->version));
> @@ -139,23 +238,10 @@ static int write_gcov(write_iter_t *iter)
>           chk(write_string(iter, info->filename));
>   
>           /* dump counters */
> -        ctr = info->counts;
> -        for ( type = -1; next_type(info, &type) < XENCOV_COUNTERS; ++ctr )
> -        {
> -            align_iter(iter);
> -            chk(write32(iter, XENCOV_TAG_COUNTER(type)));
> -            chk(write32(iter, ctr->num));
> -            chk(write_raw(iter, ctr->values,
> -                          ctr->num * sizeof(ctr->values[0])));
> -
> -            size_fn += sizeof(unsigned);
> -        }
> -
> -        /* dump all functions together */
> -        align_iter(iter);
> -        chk(write32(iter, XENCOV_TAG_FUNC));
> -        chk(write32(iter, info->n_functions));
> -        chk(write_raw(iter, info->functions, info->n_functions * size_fn));
> +        if (info->version < XENCOV_VERSION_407)
> +            chk(write_info(iter, info));
> +        else
> +            chk(write_info_407(iter, (struct gcov_info_407 *) info));
>       }
>   
>       /* stop tag */
> @@ -164,19 +250,38 @@ static int write_gcov(write_iter_t *iter)
>       return 0;
>   }
>   
> +static void reset_info(struct gcov_info *info)
> +{
> +    const struct gcov_ctr_info *ctr;
> +    int type;
> +
> +    ctr = info->counts;
> +    for ( type = -1; next_type(info, &type) < XENCOV_COUNTERS_MASK; ++ctr )
> +        memset(ctr->values, 0, ctr->num * sizeof(ctr->values[0]));
> +}
> +
> +static void reset_info_407(struct gcov_info_407 *info)
> +{
> +    const struct gcov_fn_info_407 *fn;
> +    const struct gcov_ctr_info_407 *ctr;
> +    int n_func, n_ctr;
> +
> +    for ( n_func = -1; (fn = next_func(info, &n_func)) != NULL; )
> +        for ( n_ctr = -1; (ctr = next_ctr(fn, &n_ctr)) != NULL; )
> +            memset(ctr->values, 0, ctr->num * sizeof(ctr->values[0]));
> +}
> +
>   static int reset_counters(void)
>   {
>       struct gcov_info *info;
>   
>       for ( info = info_list ; info; info = info->next )
>       {
> -        const struct gcov_ctr_info *ctr;
> -        int type;
> -
>           /* reset counters */
> -        ctr = info->counts;
> -        for ( type = -1; next_type(info, &type) < XENCOV_COUNTERS; ++ctr )
> -            memset(ctr->values, 0, ctr->num * sizeof(ctr->values[0]));
> +        if ( info->version < XENCOV_VERSION_407 )
> +            reset_info(info);
> +        else
> +            reset_info_407((struct gcov_info_407 *) info);
>       }
>   
>       return 0;
> diff --git a/xen/include/public/gcov.h b/xen/include/public/gcov.h
> index 1b29b48..e7573fb 100644
> --- a/xen/include/public/gcov.h
> +++ b/xen/include/public/gcov.h
> @@ -28,10 +28,12 @@
>   #ifndef __XEN_PUBLIC_GCOV_H__
>   #define __XEN_PUBLIC_GCOV_H__ __XEN_PUBLIC_GCOV_H__
>   
> -#define XENCOV_COUNTERS         5
> +#define XENCOV_COUNTERS_MASK    5
> +#define XENCOV_COUNTERS         8
>   #define XENCOV_TAG_BASE         0x58544300u
>   #define XENCOV_TAG_FILE         (XENCOV_TAG_BASE+0x46u)
>   #define XENCOV_TAG_FUNC         (XENCOV_TAG_BASE+0x66u)
> +#define XENCOV_TAG_FUNC2        (XENCOV_TAG_BASE+0x67u)
>   #define XENCOV_TAG_COUNTER(n)   (XENCOV_TAG_BASE+0x30u+((n)&0xfu))
>   #define XENCOV_TAG_END          (XENCOV_TAG_BASE+0x2eu)
>   #define XENCOV_IS_TAG_COUNTER(n) \
> @@ -93,6 +95,18 @@ struct xencov_function
>   };
>   
>   /**
> + * Information for each function
> + * Number of counter is equal to the number of counter structures got before
> + */
> +struct xencov_function2
> +{
> +    uint32_t ident;
> +    uint32_t lineno_checksum;
> +    uint32_t cfg_checksum;
> +    uint32_t num_counters[1];
> +};
> +
> +/**
>    * Information for all functions
>    * Aligned to 8 bytes
>    */
> diff --git a/xen/include/xen/gcov.h b/xen/include/xen/gcov.h
> index 27c5c37..f36388a 100644
> --- a/xen/include/xen/gcov.h
> +++ b/xen/include/xen/gcov.h
> @@ -40,6 +40,8 @@ struct gcov_fn_info
>       unsigned int n_ctrs[0];
>   };
>   
> +typedef void (*gcov_merge_func)(gcov_type *, unsigned int);
> +
>   /**
>    * struct gcov_ctr_info - profiling data per counter type
>    * @num: number of counter values for this type
> @@ -53,7 +55,7 @@ struct gcov_ctr_info
>   {
>       unsigned int num;
>       gcov_type *values;
> -    void (*merge)(gcov_type *, unsigned int);
> +    gcov_merge_func merge;
>   };
>   
>   /**
> @@ -82,6 +84,70 @@ struct gcov_info
>       struct gcov_ctr_info      counts[0];
>   };
>   
> +struct gcov_info_407;
> +
> +/**
> + * struct gcov_ctr_info_407 - profiling data per counter type
> + * @num: number of counter values for this type
> + * @values: array of counter values for this type
> + * @merge: merge function for counter values of this type (unused)
> + *
> + * This data is generated by gcc during compilation and doesn't change
> + * at run-time with the exception of the values array.
> + */
> +struct gcov_ctr_info_407
> +{
> +    unsigned int num;
> +    gcov_type *values;
> +};
> +
> +
> +/**
> + * struct gcov_fn_info_407 - profiling meta data per function
> + * @ident: object file-unique function identifier
> + * @lineno_checksum: function lineno checksum
> + * @cfg_checksum: function cfg checksum
> + * @ctrs: counters for this function
> + *
> + * This data is generated by gcc during compilation and doesn't change
> + * at run-time.
> + */
> +struct gcov_fn_info_407
> +{
> +    const struct gcov_info_407 *info;
> +    unsigned int ident;
> +    unsigned int lineno_checksum;
> +    unsigned int cfg_checksum;
> +    struct gcov_ctr_info_407 ctrs[0];
> +};
> +
> +#define XENCOV_COUNTERS_407 8
> +#define XENCOV_VERSION_407 0x34303700
> +
> +/**
> + * struct gcov_info_407 - profiling data per object file
> + * @version: gcov version magic indicating the gcc version used for compilation
> + * @next: list head for a singly-linked list
> + * @stamp: time stamp
> + * @filename: name of the associated gcov data file
> + * @merge: merge functions
> + * @n_functions: number of instrumented functions
> + * @functions: function data
> + *
> + * This data is generated by gcc during compilation and doesn't change
> + * at run-time with the exception of the next pointer.
> + */
> +struct gcov_info_407
> +{
> +    unsigned int              version;
> +    struct gcov_info          *next;
> +    unsigned int              stamp;
> +    const char                *filename;
> +    gcov_merge_func           merge[XENCOV_COUNTERS_407];
> +    unsigned int              n_functions;
> +    const struct gcov_fn_info_407 * const *functions;
> +};
> +
>   
>   /**
>    * Sysctl operations for coverage

  parent reply	other threads:[~2013-06-17  9:50 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-17  8:29 [PATCH] gcov: Support gcc 4.7 Frediano Ziglio
2013-06-17  8:58 ` Jan Beulich
2013-06-28 10:18   ` Frediano Ziglio
2013-06-28 10:26     ` Jan Beulich
2013-06-17  9:50 ` George Dunlap [this message]
2013-06-17 10:42 ` Ian Campbell
2013-06-17 10:46   ` Frediano Ziglio
2013-06-17 10:49     ` Ian Campbell
2013-06-17 12:25       ` Frediano Ziglio
2013-06-18 14:32       ` Frediano Ziglio
2013-06-18 14:53         ` George Dunlap
2013-06-18 15:04           ` Frediano Ziglio
2013-06-17 10:49   ` Egger, Christoph

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51BEDBD0.9010409@eu.citrix.com \
    --to=george.dunlap@eu.citrix.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=chegger@amazon.de \
    --cc=frediano.ziglio@citrix.com \
    --cc=mattjd@gmail.com \
    --cc=miguelmclara@gmail.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).