|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2] 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@xxxxxxxxx>
---
xen/Kconfig | 2 +-
xen/Rules.mk | 1 +
xen/arch/x86/Makefile | 2 +-
xen/common/coverage/llvm.c | 24 +++++++++++++++++++++++-
4 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/xen/Kconfig b/xen/Kconfig
index a5e5af3b76..5508993f02 100644
--- a/xen/Kconfig
+++ b/xen/Kconfig
@@ -53,7 +53,7 @@ config CC_HAS_ASM_GOTO_OUTPUT
# Compiler supports -fcondition-coverage aka MC/DC
config CC_HAS_MCDC
- def_bool $(cc-option,-fcondition-coverage)
+ def_bool $(cc-option,-fcondition-coverage) ||
$(cc-option,-fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc)
# Set code alignment.
#
diff --git a/xen/Rules.mk b/xen/Rules.mk
index 24f447b957..57ea664f02 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -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
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 407571c510..6c0ff67fa8 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -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
diff --git a/xen/common/coverage/llvm.c b/xen/common/coverage/llvm.c
index 532889c857..a8c7e7e8d2 100644
--- a/xen/common/coverage/llvm.c
+++ b/xen/common/coverage/llvm.c
@@ -120,6 +120,10 @@ 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[];
+#ifdef CONFIG_CONDITION_COVERAGE
+extern const char __start___llvm_prf_bits[];
+extern const char __stop___llvm_prf_bits[];
+#endif
#define START_DATA ((const void *)__start___llvm_prf_data)
#define END_DATA ((const void *)__stop___llvm_prf_data)
@@ -127,16 +131,25 @@ 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);
+#ifdef CONFIG_CONDITION_COVERAGE
+ memset(START_BITMAP, 0, END_BITMAP - START_BITMAP);
+#endif
}
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);
+#ifdef CONFIG_CONDITION_COVERAGE
+ size += ROUNDUP(END_BITMAP - START_BITMAP, 8);
+#endif
+ return size;
}
static int cf_check dump(
@@ -147,11 +160,17 @@ static int cf_check dump(
.version = LLVM_PROFILE_VERSION,
.num_data = DIV_ROUND_UP(END_DATA - START_DATA, sizeof(struct
llvm_profile_data)),
.num_counters = DIV_ROUND_UP(END_COUNTERS - START_COUNTERS,
sizeof(uint64_t)),
+#if defined(CONFIG_CONDITION_COVERAGE) && LLVM_PROFILE_VERSION >= 9
+ .num_bitmap_bytes = END_BITMAP - START_BITMAP,
+#endif
.names_size = END_NAMES - START_NAMES,
#if LLVM_PROFILE_VERSION >= 8
.counters_delta = START_COUNTERS - START_DATA,
#else
.counters_delta = (uintptr_t)START_COUNTERS,
+#endif
+#if defined(CONFIG_CONDITION_COVERAGE) && LLVM_PROFILE_VERSION >= 9
+ .bitmap_delta = START_BITMAP - START_DATA,
#endif
.names_delta = (uintptr_t)START_NAMES,
.value_kind_last = LLVM_PROFILE_NUM_KINDS - 1,
@@ -168,6 +187,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
--
2.49.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |