mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
xen: Enable MC/DC coverage for Clang
Clang >= 18 supports Modified Condition/Decision Coverage (MC/DC). This patch enables the detection and usage of this feature when compiling Xen with Clang. - Update detection logic in Kconfig to check for the required set of Clang flags for MC/DC: '-fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc'. This bundle is necessary because '-fcoverage-mcdc' requires '-fcoverage-mapping', which in turn requires '-fprofile-instr-generate'. - Update llvm.c to handle the profile format changes (bitmap section) required for MC/DC. - Guard -Wno-error=coverage-too-many-conditions with CONFIG_CC_IS_GCC to avoid passing a GCC-only warning option to Clang Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com> Acked-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
e6600dc1ba
commit
08c787f66c
4 files changed
+22
-4
No files matched your search
+3
-2
@@ -51,9 +51,10 @@ config CC_HAS_ASM_GOTO_OUTPUT
|
||||
depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
|
||||
depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
|
||||
|
||||
# Compiler supports -fcondition-coverage aka MC/DC
|
||||
# Compiler supports Modified Condition/Decision Coverage (MC/DC).
|
||||
config CC_HAS_MCDC
|
||||
def_bool $(cc-option,-fcondition-coverage)
|
||||
# GCC >= 14, or Clang >= 18
|
||||
def_bool $(cc-option,-fcondition-coverage) || $(cc-option,-fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc)
|
||||
|
||||
# Set code alignment.
|
||||
#
|
||||
|
||||
@@ -136,6 +136,7 @@ non-init-objects = $(filter-out %.init.o, $(obj-y) $(obj-bin-y) $(extra-y))
|
||||
|
||||
ifeq ($(CONFIG_CC_IS_CLANG),y)
|
||||
cov-cflags-$(CONFIG_COVERAGE) := -fprofile-instr-generate -fcoverage-mapping
|
||||
cov-cflags-$(CONFIG_CONDITION_COVERAGE) += -fcoverage-mcdc
|
||||
else
|
||||
cov-cflags-$(CONFIG_COVERAGE) := -fprofile-arcs -ftest-coverage
|
||||
cov-cflags-$(CONFIG_CONDITION_COVERAGE) += -fcondition-coverage
|
||||
|
||||
@@ -98,7 +98,7 @@ $(obj)/usercopy.o: CFLAGS-y += -iquote .
|
||||
ifneq ($(CONFIG_HVM),y)
|
||||
$(obj)/x86_emulate.o: CFLAGS-y += -Wno-unused-label
|
||||
endif
|
||||
ifeq ($(CONFIG_CONDITION_COVERAGE),y)
|
||||
ifeq ($(CONFIG_CONDITION_COVERAGE)$(CONFIG_CC_IS_GCC),yy)
|
||||
$(obj)/x86_emulate.o: CFLAGS-y += -Wno-error=coverage-too-many-conditions
|
||||
endif
|
||||
|
||||
|
||||
@@ -120,6 +120,8 @@ extern const char __start___llvm_prf_names[];
|
||||
extern const char __stop___llvm_prf_names[];
|
||||
extern uint64_t __start___llvm_prf_cnts[];
|
||||
extern uint64_t __stop___llvm_prf_cnts[];
|
||||
extern const char __start___llvm_prf_bits[];
|
||||
extern const char __stop___llvm_prf_bits[];
|
||||
|
||||
#define START_DATA ((const void *)__start___llvm_prf_data)
|
||||
#define END_DATA ((const void *)__stop___llvm_prf_data)
|
||||
@@ -127,16 +129,23 @@ extern uint64_t __stop___llvm_prf_cnts[];
|
||||
#define END_NAMES ((const void *)__stop___llvm_prf_names)
|
||||
#define START_COUNTERS ((void *)__start___llvm_prf_cnts)
|
||||
#define END_COUNTERS ((void *)__stop___llvm_prf_cnts)
|
||||
#define START_BITMAP ((void *)__start___llvm_prf_bits)
|
||||
#define END_BITMAP ((void *)__stop___llvm_prf_bits)
|
||||
|
||||
static void cf_check reset_counters(void)
|
||||
{
|
||||
memset(START_COUNTERS, 0, END_COUNTERS - START_COUNTERS);
|
||||
if ( IS_ENABLED(CONFIG_CONDITION_COVERAGE) )
|
||||
memset(START_BITMAP, 0, END_BITMAP - START_BITMAP);
|
||||
}
|
||||
|
||||
static uint32_t cf_check get_size(void)
|
||||
{
|
||||
return ROUNDUP(sizeof(struct llvm_profile_header) + END_DATA - START_DATA +
|
||||
uint32_t size = ROUNDUP(sizeof(struct llvm_profile_header) + END_DATA - START_DATA +
|
||||
END_COUNTERS - START_COUNTERS + END_NAMES - START_NAMES, 8);
|
||||
if ( IS_ENABLED(CONFIG_CONDITION_COVERAGE) )
|
||||
size += ROUNDUP(END_BITMAP - START_BITMAP, 8);
|
||||
return size;
|
||||
}
|
||||
|
||||
static int cf_check dump(
|
||||
@@ -155,6 +164,10 @@ static int cf_check dump(
|
||||
#endif
|
||||
.names_delta = (uintptr_t)START_NAMES,
|
||||
.value_kind_last = LLVM_PROFILE_NUM_KINDS - 1,
|
||||
#if defined(CONFIG_CONDITION_COVERAGE) && LLVM_PROFILE_VERSION >= 9
|
||||
.num_bitmap_bytes = END_BITMAP - START_BITMAP,
|
||||
.bitmap_delta = START_BITMAP - START_DATA,
|
||||
#endif
|
||||
};
|
||||
unsigned int off = 0;
|
||||
|
||||
@@ -168,6 +181,9 @@ static int cf_check dump(
|
||||
APPEND_TO_BUFFER(&header, sizeof(header));
|
||||
APPEND_TO_BUFFER(START_DATA, END_DATA - START_DATA);
|
||||
APPEND_TO_BUFFER(START_COUNTERS, END_COUNTERS - START_COUNTERS);
|
||||
#if defined(CONFIG_CONDITION_COVERAGE)
|
||||
APPEND_TO_BUFFER(START_BITMAP, END_BITMAP - START_BITMAP);
|
||||
#endif
|
||||
APPEND_TO_BUFFER(START_NAMES, END_NAMES - START_NAMES);
|
||||
#undef APPEND_TO_BUFFER
|
||||
|
||||
|
||||