xen/arch/x86/xen.lds.S | 6 +++++ xen/common/coverage/llvm.c | 54 +++++++++++++++++++++++++++++++++----- xen/include/xen/xen.lds.h | 13 +++++++++ 3 files changed, 67 insertions(+), 6 deletions(-)
This change enables compatibility for measuring code coverage
with Clang versions 11 through 20 by supporting their respective raw
profile formats.
1- Added support for LLVM raw profile versions 5, 6, 7, 8, 9, and 10.
2- Initialized llvm_profile_header for all versions based on llvm source
code in compiler-rt/include/profile/InstrProfData.inc for each version.
3- We tested this patch for all Clang versions from 11 through 20
on x86 platform.
4- Fixed linking warnings related to LLVM profile sections in x86.
Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com>
Release-Acked-By: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Tested-by: Wentao Zhang <wentaoz5@illinois.edu>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes from v3 to v4:
1- Use LLVM_PROFILE_VERSION in preprocessor conditionals
instead of __clang_major__.
2- Use DIV_ROUND_UP helper.
3- Remove unnecessary zero initialization inside struct.
4- Remove fallback macro definitions in linker script.
Changes from v2 to v3:
1- Additionally support raw profile version 5, 6, 7 in clang 11, 12, 13.
2- Fix coverage related linking warnings in x86.
3- Revert unnecessary type changes, casting, etc.
---
xen/arch/x86/xen.lds.S | 6 +++++
xen/common/coverage/llvm.c | 54 +++++++++++++++++++++++++++++++++-----
xen/include/xen/xen.lds.h | 13 +++++++++
3 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 966e514f20..5d02f83a40 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -186,6 +186,8 @@ SECTIONS
} PHDR(note) PHDR(text)
#endif
+ LLVM_COV_RO_DATA
+
_erodata = .;
. = ALIGN(SECTION_ALIGN);
@@ -323,6 +325,8 @@ SECTIONS
*(.data .data.*)
} PHDR(text)
+ LLVM_COV_RW_DATA
+
DECL_SECTION(.bss) {
__bss_start = .;
*(.bss.page_aligned*)
@@ -357,6 +361,8 @@ SECTIONS
DWARF2_DEBUG_SECTIONS
+ LLVM_COV_DEBUG
+
#ifdef CONFIG_HYPERV_GUEST
hv_hcall_page = ABSOLUTE(HV_HCALL_PAGE - XEN_VIRT_START + __XEN_VIRT_START);
#endif
diff --git a/xen/common/coverage/llvm.c b/xen/common/coverage/llvm.c
index 517b2aa8c2..532889c857 100644
--- a/xen/common/coverage/llvm.c
+++ b/xen/common/coverage/llvm.c
@@ -44,27 +44,65 @@
((uint64_t)'f' << 16) | ((uint64_t)'R' << 8) | ((uint64_t)129)
#endif
-#define LLVM_PROFILE_VERSION 4
+#if __clang_major__ >= 19 && __clang_major__ <= 20
+#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
+#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 "LLVM coverage selected but an unsupported clang version is used"
+#endif
struct llvm_profile_data {
uint64_t name_ref;
uint64_t function_hash;
- void *counter;
+ void *relative_counter;
+#if LLVM_PROFILE_VERSION >= 9
+ void *relative_bitmap;
+#endif
void *function;
void *values;
uint32_t nr_counters;
uint16_t nr_value_sites[LLVM_PROFILE_NUM_KINDS];
+#if LLVM_PROFILE_VERSION >= 9
+ uint32_t numbitmap_bytes;
+#endif
};
struct llvm_profile_header {
uint64_t magic;
uint64_t version;
- uint64_t data_size;
- uint64_t counters_size;
+#if LLVM_PROFILE_VERSION >= 7
+ 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 LLVM_PROFILE_VERSION >= 9
+ uint64_t num_bitmap_bytes;
+ uint64_t padding_bytes_after_bitmap_bytes;
+#endif
uint64_t names_size;
uint64_t counters_delta;
+#if LLVM_PROFILE_VERSION >= 9
+ uint64_t bitmap_delta;
+#endif
uint64_t names_delta;
+#if LLVM_PROFILE_VERSION == 10
+ uint64_t num_vtables;
+ uint64_t vnames_size;
+#endif
uint64_t value_kind_last;
};
@@ -107,10 +145,14 @@ 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),
+ .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)),
.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
.names_delta = (uintptr_t)START_NAMES,
.value_kind_last = LLVM_PROFILE_NUM_KINDS - 1,
};
diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h
index b126dfe887..d80c895959 100644
--- a/xen/include/xen/xen.lds.h
+++ b/xen/include/xen/xen.lds.h
@@ -81,6 +81,19 @@
.stab.index 0 : { *(.stab.index) } \
.stab.indexstr 0 : { *(.stab.indexstr) }
+/* Clang coverage sections. */
+#define LLVM_COV_RW_DATA \
+ DECL_SECTION(__llvm_prf_cnts) { *(__llvm_prf_cnts) } \
+ DECL_SECTION(__llvm_prf_data) { *(__llvm_prf_data) } \
+ DECL_SECTION(__llvm_prf_bits) { *(__llvm_prf_bits) }
+
+#define LLVM_COV_RO_DATA \
+ DECL_SECTION(__llvm_prf_names) { *(__llvm_prf_names) }
+
+#define LLVM_COV_DEBUG \
+ DECL_DEBUG(__llvm_covfun, 8) \
+ DECL_DEBUG(__llvm_covmap, 8)
+
/*
* ELF sections.
*
--
2.49.0
On 27/10/2025 9:30 pm, Saman Dehghan wrote: > This change enables compatibility for measuring code coverage > with Clang versions 11 through 20 by supporting their respective raw > profile formats. > > 1- Added support for LLVM raw profile versions 5, 6, 7, 8, 9, and 10. > 2- Initialized llvm_profile_header for all versions based on llvm source > code in compiler-rt/include/profile/InstrProfData.inc for each version. > 3- We tested this patch for all Clang versions from 11 through 20 > on x86 platform. > 4- Fixed linking warnings related to LLVM profile sections in x86. > > > Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com> > Release-Acked-By: Oleksii Kurochko <oleksii.kurochko@gmail.com> > Tested-by: Wentao Zhang <wentaoz5@illinois.edu> > Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> > --- > Changes from v3 to v4: > 1- Use LLVM_PROFILE_VERSION in preprocessor conditionals > instead of __clang_major__. > 2- Use DIV_ROUND_UP helper. > 3- Remove unnecessary zero initialization inside struct. > 4- Remove fallback macro definitions in linker script. > Changes from v2 to v3: > 1- Additionally support raw profile version 5, 6, 7 in clang 11, 12, 13. > 2- Fix coverage related linking warnings in x86. > 3- Revert unnecessary type changes, casting, etc. > --- Excellent. Thankyou. This all looks in order. I've committed it. ~Andrew
On 27.10.2025 23:36, Andrew Cooper wrote: > On 27/10/2025 9:30 pm, Saman Dehghan wrote: >> This change enables compatibility for measuring code coverage >> with Clang versions 11 through 20 by supporting their respective raw >> profile formats. >> >> 1- Added support for LLVM raw profile versions 5, 6, 7, 8, 9, and 10. >> 2- Initialized llvm_profile_header for all versions based on llvm source >> code in compiler-rt/include/profile/InstrProfData.inc for each version. >> 3- We tested this patch for all Clang versions from 11 through 20 >> on x86 platform. >> 4- Fixed linking warnings related to LLVM profile sections in x86. >> >> >> Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com> >> Release-Acked-By: Oleksii Kurochko <oleksii.kurochko@gmail.com> >> Tested-by: Wentao Zhang <wentaoz5@illinois.edu> >> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> >> --- >> Changes from v3 to v4: >> 1- Use LLVM_PROFILE_VERSION in preprocessor conditionals >> instead of __clang_major__. >> 2- Use DIV_ROUND_UP helper. >> 3- Remove unnecessary zero initialization inside struct. >> 4- Remove fallback macro definitions in linker script. >> Changes from v2 to v3: >> 1- Additionally support raw profile version 5, 6, 7 in clang 11, 12, 13. >> 2- Fix coverage related linking warnings in x86. >> 3- Revert unnecessary type changes, casting, etc. >> --- > > Excellent. Thankyou. This all looks in order. I've committed it. I thought I would backport this, but I would need a variant that wouldn't regress profile version 4 on the older branches. Jan
On Mon, Nov 10, 2025 at 8:03 AM Jan Beulich <jbeulich@suse.com> wrote: > > On 27.10.2025 23:36, Andrew Cooper wrote: > > On 27/10/2025 9:30 pm, Saman Dehghan wrote: > >> This change enables compatibility for measuring code coverage > >> with Clang versions 11 through 20 by supporting their respective raw > >> profile formats. > >> > >> 1- Added support for LLVM raw profile versions 5, 6, 7, 8, 9, and 10. > >> 2- Initialized llvm_profile_header for all versions based on llvm source > >> code in compiler-rt/include/profile/InstrProfData.inc for each version. > >> 3- We tested this patch for all Clang versions from 11 through 20 > >> on x86 platform. > >> 4- Fixed linking warnings related to LLVM profile sections in x86. > >> > >> > >> Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com> > >> Release-Acked-By: Oleksii Kurochko <oleksii.kurochko@gmail.com> > >> Tested-by: Wentao Zhang <wentaoz5@illinois.edu> > >> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> > >> --- > >> Changes from v3 to v4: > >> 1- Use LLVM_PROFILE_VERSION in preprocessor conditionals > >> instead of __clang_major__. > >> 2- Use DIV_ROUND_UP helper. > >> 3- Remove unnecessary zero initialization inside struct. > >> 4- Remove fallback macro definitions in linker script. > >> Changes from v2 to v3: > >> 1- Additionally support raw profile version 5, 6, 7 in clang 11, 12, 13. > >> 2- Fix coverage related linking warnings in x86. > >> 3- Revert unnecessary type changes, casting, etc. > >> --- > > > > Excellent. Thankyou. This all looks in order. I've committed it. > > I thought I would backport this, but I would need a variant that wouldn't > regress profile version 4 on the older branches Thanks Jan for offering to backport this. Which target branches do you have in your mind? > regress profile version 4 on the older branches Do you mean some of these branches are still using clang < 11 so that we need to adapt our patch accordingly? Let me know how we can help. Thanks Saman > > Jan
On 10.11.2025 22:26, Saman Dehghan wrote: > On Mon, Nov 10, 2025 at 8:03 AM Jan Beulich <jbeulich@suse.com> wrote: >> >> On 27.10.2025 23:36, Andrew Cooper wrote: >>> On 27/10/2025 9:30 pm, Saman Dehghan wrote: >>>> This change enables compatibility for measuring code coverage >>>> with Clang versions 11 through 20 by supporting their respective raw >>>> profile formats. >>>> >>>> 1- Added support for LLVM raw profile versions 5, 6, 7, 8, 9, and 10. >>>> 2- Initialized llvm_profile_header for all versions based on llvm source >>>> code in compiler-rt/include/profile/InstrProfData.inc for each version. >>>> 3- We tested this patch for all Clang versions from 11 through 20 >>>> on x86 platform. >>>> 4- Fixed linking warnings related to LLVM profile sections in x86. >>>> >>>> >>>> Signed-off-by: Saman Dehghan <samaan.dehghan@gmail.com> >>>> Release-Acked-By: Oleksii Kurochko <oleksii.kurochko@gmail.com> >>>> Tested-by: Wentao Zhang <wentaoz5@illinois.edu> >>>> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> >>>> --- >>>> Changes from v3 to v4: >>>> 1- Use LLVM_PROFILE_VERSION in preprocessor conditionals >>>> instead of __clang_major__. >>>> 2- Use DIV_ROUND_UP helper. >>>> 3- Remove unnecessary zero initialization inside struct. >>>> 4- Remove fallback macro definitions in linker script. >>>> Changes from v2 to v3: >>>> 1- Additionally support raw profile version 5, 6, 7 in clang 11, 12, 13. >>>> 2- Fix coverage related linking warnings in x86. >>>> 3- Revert unnecessary type changes, casting, etc. >>>> --- >>> >>> Excellent. Thankyou. This all looks in order. I've committed it. >> >> I thought I would backport this, but I would need a variant that wouldn't >> regress profile version 4 on the older branches > > Thanks Jan for offering to backport this. Which target branches do you > have in your mind? The two ones in general maintenance, 4.20 and 4.19. I expect a single patch will do, i.e. will apply to both equally. >> regress profile version 4 on the older branches > > Do you mean some of these branches are still using clang < 11 so that > we need to adapt our patch accordingly? Let me know how we can help. Well, the introduction of 11 as the baseline requirement did happen in the 4.21 dev cycle. Prior to that, 3.5 was the baseline. As we only had support for profile version 4 (Clang 3.9 onwards as it looks), only that version would need covering. Of course, if other versions could be easily supported, that might be fine as well. Yet this isn't a requirement at all. Jan
© 2016 - 2026 Red Hat, Inc.