All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.