From 3dc1fe6ee55d973a25a0441d0f6b41e00a58227b Mon Sep 17 00:00:00 2001 From: Saman Dehghan Date: Wed, 1 Oct 2025 16:52:32 -0500 Subject: [PATCH 1/5] Support LLVM raw profile versions 8, 9, and 10 This change enables compatibility for measuring code coverage with Clang versions 14 through 20 by supporting their respective raw profile formats. Signed-off-by: Saman Dehghan --- xen/common/coverage/llvm.c | 78 +++++++++++++++++++++++++++----------- xen/include/xen/types.h | 1 + 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/xen/common/coverage/llvm.c b/xen/common/coverage/llvm.c index 517b2aa8c202..f92f10654cf9 100644 --- a/xen/common/coverage/llvm.c +++ b/xen/common/coverage/llvm.c @@ -44,27 +44,55 @@ ((uint64_t)'f' << 16) | ((uint64_t)'R' << 8) | ((uint64_t)129) #endif -#define LLVM_PROFILE_VERSION 4 +#if __clang_major__ >= 19 +#define LLVM_PROFILE_VERSION 10 +#define LLVM_PROFILE_NUM_KINDS 3 +#elif __clang_major__ == 18 +#define LLVM_PROFILE_VERSION 9 #define LLVM_PROFILE_NUM_KINDS 2 +#elif __clang_major__ >= 14 +#define LLVM_PROFILE_VERSION 8 +#define LLVM_PROFILE_NUM_KINDS 2 +#else +#error "Unsupported Clang version" +#endif struct llvm_profile_data { uint64_t name_ref; uint64_t function_hash; - void *counter; - void *function; - void *values; + intptr_t *relative_counter; +#if __clang_major__ >= 18 + intptr_t *relative_bitmap; +#endif + intptr_t *function; + intptr_t *values; uint32_t nr_counters; uint16_t nr_value_sites[LLVM_PROFILE_NUM_KINDS]; +#if __clang_major__ >= 18 + uint32_t numbitmap_bytes; +#endif }; struct llvm_profile_header { uint64_t magic; uint64_t version; - uint64_t data_size; - uint64_t counters_size; + uint64_t binary_ids_size; + uint64_t num_data; + uint64_t padding_bytes_before_counters; + uint64_t num_counters; + uint64_t padding_bytes_after_counters; + uint64_t num_bitmap_bytes; + uint64_t padding_bytes_after_bitmap_bytes; uint64_t names_size; +#if __clang_major__ >= 18 uint64_t counters_delta; + uint64_t bitmap_delta; +#endif uint64_t names_delta; +#if __clang_major__ >= 19 + uint64_t num_vtables; + uint64_t vnames_size; +#endif uint64_t value_kind_last; }; @@ -76,19 +104,20 @@ struct llvm_profile_header { */ int __llvm_profile_runtime; -extern const struct llvm_profile_data __start___llvm_prf_data[]; -extern const struct llvm_profile_data __stop___llvm_prf_data[]; -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 char __start___llvm_prf_data[]; +extern char __stop___llvm_prf_data[]; +extern char __start___llvm_prf_names[]; +extern char __stop___llvm_prf_names[]; +extern char __start___llvm_prf_cnts[]; +extern char __stop___llvm_prf_cnts[]; + +#define START_DATA ((const char *)__start___llvm_prf_data) +#define END_DATA ((const char *)__stop___llvm_prf_data) +#define START_NAMES ((const char *)__start___llvm_prf_names) +#define END_NAMES ((const char *)__stop___llvm_prf_names) +#define START_COUNTERS ((char *)__start___llvm_prf_cnts) +#define END_COUNTERS ((char *)__stop___llvm_prf_cnts) -#define START_DATA ((const void *)__start___llvm_prf_data) -#define END_DATA ((const void *)__stop___llvm_prf_data) -#define START_NAMES ((const void *)__start___llvm_prf_names) -#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) static void cf_check reset_counters(void) { @@ -107,10 +136,15 @@ static int cf_check dump( struct llvm_profile_header header = { .magic = LLVM_PROFILE_MAGIC, .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, + .binary_ids_size = 0, + .num_data = (((intptr_t)END_DATA + sizeof(struct llvm_profile_data) - 1) + - (intptr_t)START_DATA) / sizeof(struct llvm_profile_data), + .padding_bytes_before_counters = 0, + .num_counters = (((intptr_t)END_COUNTERS + sizeof(uint64_t) - 1) + - (intptr_t)START_COUNTERS) / sizeof(uint64_t), + .padding_bytes_after_counters = 0, + .names_size = (END_NAMES - START_NAMES) * sizeof(char), + .counters_delta = (uintptr_t)START_COUNTERS - (uintptr_t)START_DATA, .names_delta = (uintptr_t)START_NAMES, .value_kind_last = LLVM_PROFILE_NUM_KINDS - 1, }; diff --git a/xen/include/xen/types.h b/xen/include/xen/types.h index 73ddccbbd5dc..799bfe0b95f2 100644 --- a/xen/include/xen/types.h +++ b/xen/include/xen/types.h @@ -18,6 +18,7 @@ typedef signed long ssize_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __UINTPTR_TYPE__ uintptr_t; +typedef __INTPTR_TYPE__ intptr_t; /* * Users of this macro are expected to pass a positive value. From 58af111d1d131168276a8de27616829c7ad19239 Mon Sep 17 00:00:00 2001 From: Saman Dehghan Date: Mon, 6 Oct 2025 15:31:02 -0500 Subject: [PATCH 2/5] revert some unnecessary changes --- xen/common/coverage/llvm.c | 47 +++++++++++++++++++------------------- xen/include/xen/types.h | 1 - 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/xen/common/coverage/llvm.c b/xen/common/coverage/llvm.c index f92f10654cf9..949276c72cd6 100644 --- a/xen/common/coverage/llvm.c +++ b/xen/common/coverage/llvm.c @@ -60,12 +60,12 @@ struct llvm_profile_data { uint64_t name_ref; uint64_t function_hash; - intptr_t *relative_counter; + void *relative_counter; #if __clang_major__ >= 18 - intptr_t *relative_bitmap; + void *relative_bitmap; #endif - intptr_t *function; - intptr_t *values; + void *function; + void *values; uint32_t nr_counters; uint16_t nr_value_sites[LLVM_PROFILE_NUM_KINDS]; #if __clang_major__ >= 18 @@ -104,20 +104,19 @@ struct llvm_profile_header { */ int __llvm_profile_runtime; -extern char __start___llvm_prf_data[]; -extern char __stop___llvm_prf_data[]; -extern char __start___llvm_prf_names[]; -extern char __stop___llvm_prf_names[]; -extern char __start___llvm_prf_cnts[]; -extern char __stop___llvm_prf_cnts[]; - -#define START_DATA ((const char *)__start___llvm_prf_data) -#define END_DATA ((const char *)__stop___llvm_prf_data) -#define START_NAMES ((const char *)__start___llvm_prf_names) -#define END_NAMES ((const char *)__stop___llvm_prf_names) -#define START_COUNTERS ((char *)__start___llvm_prf_cnts) -#define END_COUNTERS ((char *)__stop___llvm_prf_cnts) +extern const struct llvm_profile_data __start___llvm_prf_data[]; +extern const struct llvm_profile_data __stop___llvm_prf_data[]; +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[]; +#define START_DATA ((const void *)__start___llvm_prf_data) +#define END_DATA ((const void *)__stop___llvm_prf_data) +#define START_NAMES ((const void *)__start___llvm_prf_names) +#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) static void cf_check reset_counters(void) { @@ -137,15 +136,15 @@ static int cf_check dump( .magic = LLVM_PROFILE_MAGIC, .version = LLVM_PROFILE_VERSION, .binary_ids_size = 0, - .num_data = (((intptr_t)END_DATA + sizeof(struct llvm_profile_data) - 1) - - (intptr_t)START_DATA) / sizeof(struct llvm_profile_data), + .num_data = ((END_DATA + sizeof(struct llvm_profile_data) - 1) + - START_DATA) / sizeof(struct llvm_profile_data), .padding_bytes_before_counters = 0, - .num_counters = (((intptr_t)END_COUNTERS + sizeof(uint64_t) - 1) - - (intptr_t)START_COUNTERS) / sizeof(uint64_t), + .num_counters = ((END_COUNTERS + sizeof(uint64_t) - 1) + - START_COUNTERS) / sizeof(uint64_t), .padding_bytes_after_counters = 0, - .names_size = (END_NAMES - START_NAMES) * sizeof(char), - .counters_delta = (uintptr_t)START_COUNTERS - (uintptr_t)START_DATA, - .names_delta = (uintptr_t)START_NAMES, + .names_size = END_NAMES - START_NAMES, + .counters_delta = START_COUNTERS - START_DATA, + .names_delta = START_NAMES, .value_kind_last = LLVM_PROFILE_NUM_KINDS - 1, }; unsigned int off = 0; diff --git a/xen/include/xen/types.h b/xen/include/xen/types.h index 799bfe0b95f2..73ddccbbd5dc 100644 --- a/xen/include/xen/types.h +++ b/xen/include/xen/types.h @@ -18,7 +18,6 @@ typedef signed long ssize_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __UINTPTR_TYPE__ uintptr_t; -typedef __INTPTR_TYPE__ intptr_t; /* * Users of this macro are expected to pass a positive value. From 450945988741b0fcfe4a289e30dadcdc87cdc340 Mon Sep 17 00:00:00 2001 From: Saman Dehghan Date: Mon, 6 Oct 2025 20:55:40 -0500 Subject: [PATCH 3/5] names --- xen/common/coverage/llvm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/xen/common/coverage/llvm.c b/xen/common/coverage/llvm.c index 949276c72cd6..53ab005c64a3 100644 --- a/xen/common/coverage/llvm.c +++ b/xen/common/coverage/llvm.c @@ -84,8 +84,8 @@ struct llvm_profile_header { uint64_t num_bitmap_bytes; uint64_t padding_bytes_after_bitmap_bytes; uint64_t names_size; -#if __clang_major__ >= 18 uint64_t counters_delta; +#if __clang_major__ >= 18 uint64_t bitmap_delta; #endif uint64_t names_delta; @@ -144,7 +144,14 @@ static int cf_check dump( .padding_bytes_after_counters = 0, .names_size = END_NAMES - START_NAMES, .counters_delta = START_COUNTERS - START_DATA, - .names_delta = START_NAMES, +#if __clang_major__ >= 18 + .bitmap_delta = 0, +#endif + .names_delta = (uintptr_t)START_NAMES, +#if __clang_major__ >= 19 + .num_vtables = 0, + .vnames_size = 0, +#endif .value_kind_last = LLVM_PROFILE_NUM_KINDS - 1, }; unsigned int off = 0; From e81fc63a7833884c82e050c78abbcac5fc83b973 Mon Sep 17 00:00:00 2001 From: Saman Dehghan Date: Thu, 9 Oct 2025 20:25:51 -0500 Subject: [PATCH 4/5] support llvm raw version 5 and 7 (6 version is only for 13.0.0.rc1). clang-{11,12,13} --- xen/common/coverage/llvm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/xen/common/coverage/llvm.c b/xen/common/coverage/llvm.c index 53ab005c64a3..219def74a730 100644 --- a/xen/common/coverage/llvm.c +++ b/xen/common/coverage/llvm.c @@ -53,6 +53,12 @@ #elif __clang_major__ >= 14 #define LLVM_PROFILE_VERSION 8 #define LLVM_PROFILE_NUM_KINDS 2 +#elif __clang_major__ == 13 +#define LLVM_PROFILE_VERSION 7 +#define LLVM_PROFILE_NUM_KINDS 2 +#elif __clang_major__ >= 11 +#define LLVM_PROFILE_VERSION 5 +#define LLVM_PROFILE_NUM_KINDS 2 #else #error "Unsupported Clang version" #endif @@ -76,13 +82,17 @@ struct llvm_profile_data { struct llvm_profile_header { uint64_t magic; uint64_t version; +#if __clang_major__ >= 13 uint64_t binary_ids_size; +#endif uint64_t num_data; uint64_t padding_bytes_before_counters; uint64_t num_counters; uint64_t padding_bytes_after_counters; +#if __clang_major__ >= 18 uint64_t num_bitmap_bytes; uint64_t padding_bytes_after_bitmap_bytes; +#endif uint64_t names_size; uint64_t counters_delta; #if __clang_major__ >= 18 @@ -135,15 +145,26 @@ static int cf_check dump( struct llvm_profile_header header = { .magic = LLVM_PROFILE_MAGIC, .version = LLVM_PROFILE_VERSION, +#if __clang_major__ >= 13 .binary_ids_size = 0, +#endif .num_data = ((END_DATA + sizeof(struct llvm_profile_data) - 1) - START_DATA) / sizeof(struct llvm_profile_data), .padding_bytes_before_counters = 0, .num_counters = ((END_COUNTERS + sizeof(uint64_t) - 1) - START_COUNTERS) / sizeof(uint64_t), .padding_bytes_after_counters = 0, +#if __clang_major__ >= 18 + .num_bitmap_bytes = 0, + .padding_bytes_after_bitmap_bytes = 0, +#endif .names_size = END_NAMES - START_NAMES, +#if __clang_major__ >= 14 .counters_delta = START_COUNTERS - START_DATA, +#elif + .counters_delta = (uintptr_t)START_COUNTERS +#endif + #if __clang_major__ >= 18 .bitmap_delta = 0, #endif From 067a88b62e15903ab5c0b8251aaaf9fd87eb24e9 Mon Sep 17 00:00:00 2001 From: Saman Dehghan Date: Thu, 9 Oct 2025 20:26:51 -0500 Subject: [PATCH 5/5] update error messgae --- xen/common/coverage/llvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/common/coverage/llvm.c b/xen/common/coverage/llvm.c index 219def74a730..20ccf164698e 100644 --- a/xen/common/coverage/llvm.c +++ b/xen/common/coverage/llvm.c @@ -60,7 +60,7 @@ #define LLVM_PROFILE_VERSION 5 #define LLVM_PROFILE_NUM_KINDS 2 #else -#error "Unsupported Clang version" +#error "LLVM coverage selected but an unsupported clang version is used" #endif struct llvm_profile_data {