[llvm-dev] [PATCH for-next 7/9] coverage: introduce support for llvm profiling

Jan Beulich via llvm-dev llvm-dev at lists.llvm.org
Wed Nov 8 00:38:59 PST 2017


>>> On 26.10.17 at 11:19, <roger.pau at citrix.com> wrote:
> --- /dev/null
> +++ b/xen/common/coverage/llvm.c
> @@ -0,0 +1,148 @@
> +/*
> + * Copyright (C) 2017 Citrix Systems R&D
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#include <xen/errno.h>
> +#include <xen/guest_access.h>
> +#include <xen/types.h>
> +#include <xen/coverage.h>
> +
> +#ifndef __clang__
> +#error "LLVM coverage selected without clang compiler"
> +#endif
> +
> +#define LLVM_PROFILE_MAGIC_64 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \
> +       (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 |  \
> +        (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129
> +#define LLVM_PROFILE_MAGIC_32 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \
> +       (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 |  \
> +        (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129

Judging by the file having Xen style, I imply this isn't intended to
very closely match some other original. With that, parentheses
should be added around all the shift operations above.

> +#if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ == 9)

Is it certain that there's never going to be a 3.10? Otherwise
>= might be more suitable for the minor version check.

> +int __llvm_profile_runtime;

This isn't used anywhere - please add a brief comment explaining
the need for it (the more that its type being plain int is also
suspicious).

> +extern struct llvm_profile_data __start___llvm_prf_data;
> +extern struct llvm_profile_data __stop___llvm_prf_data;
> +extern uint64_t __start___llvm_prf_cnts;
> +extern uint64_t __stop___llvm_prf_cnts;
> +extern char __start___llvm_prf_names;
> +extern char __stop___llvm_prf_names;

I guess all of these really want to have [] added, making ...

> +static void *start_data = &__start___llvm_prf_data;
> +static void *end_data = &__stop___llvm_prf_data;
> +static void *start_counters = &__start___llvm_prf_cnts;
> +static void *end_counters = &__stop___llvm_prf_cnts;
> +static void *start_names = &__start___llvm_prf_names;
> +static void *end_names = &__stop___llvm_prf_names;

... the &s here unnecessary. But then - do these really need to
be statics (rather than #define-s)?

I would also guess that at least the names ones could be const.

> +static int dump(XEN_GUEST_HANDLE_PARAM(char) buffer, uint32_t *buf_size)
> +{
> +    struct llvm_profile_header header = {
> +#if BITS_PER_LONG == 64
> +        .magic = LLVM_PROFILE_MAGIC_64,
> +#else
> +        .magic = LLVM_PROFILE_MAGIC_32,
> +#endif

I think this should just be LLVM_PROFILE_MAGIC, with the #ifdef
moved to the #define-s.

> +        .version = LLVM_PROFILE_VERSION,
> +        .data_size = (end_data - start_data) / sizeof(struct llvm_profile_data),
> +        .counters_size = (end_counters - start_counters) / sizeof(uint64_t),
> +        .names_size = end_names - start_names,
> +        .counters_delta = (uintptr_t)start_counters,
> +        .names_delta = (uintptr_t)start_names,
> +        .value_kind_last = LLVM_PROFILE_NUM_KINDS - 1,
> +    };
> +    unsigned int off = 0;
> +
> +#define APPEND_TO_BUFFER(src, size)                     \
> +({                                                      \
> +    if ( off + size > *buf_size )                       \

(size)

> +        return -ENOMEM;                                 \
> +    copy_to_guest_offset(buffer, off, src, size);       \
> +    off += size;                                        \

Ideally here too, albeit only the comma operator has lower
precedence, and that would require parenthesizing in the macro
invocation already (which is also why the arguments to
copy_to_guest_offset() explicitly do not need extra parentheses
added).

> +})
> +    APPEND_TO_BUFFER((char *)&header, sizeof(struct llvm_profile_header));

sizeof(header)

> +    APPEND_TO_BUFFER((char *)start_data, end_data - start_data);
> +    APPEND_TO_BUFFER((char *)start_counters, end_counters - start_counters);
> +    APPEND_TO_BUFFER((char *)start_names, end_names - start_names);

The casts should all be to const char*, and perhaps that would
better be done inside the macro anyway.

> +#undef APPEND_TO_BUFFER
> +
> +    clear_guest_offset(buffer, off, *buf_size - off);
> +
> +    return 0;
> +}
> +
> +struct cov_sysctl_ops cov_ops = {

const

> --- a/xen/include/public/sysctl.h
> +++ b/xen/include/public/sysctl.h
> @@ -646,6 +646,12 @@ struct xen_sysctl_scheduler_op {
>  
>  #define XEN_GCOV_FORMAT_MAGIC    0x58434f56 /* XCOV */

Hmm, shouldn't the private magic #define-s actually be put here
(in which case you'd indeed need to retain both 32- and 64-bit
variants)?

Jan


More information about the llvm-dev mailing list