[XEN][PATCH] coverage: add extended coverage capabilities

Grygorii Strashko posted 1 patch 1 week ago
xen/Kconfig.debug          | 10 ++++++++++
xen/Rules.mk               | 13 +++++++++++++
xen/arch/arm/setup.c       |  2 ++
xen/arch/x86/setup.c       |  4 ++++
xen/common/libelf/Makefile |  4 +++-
xen/common/libfdt/Makefile |  4 +++-
6 files changed, 35 insertions(+), 2 deletions(-)
[XEN][PATCH] coverage: add extended coverage capabilities
Posted by Grygorii Strashko 1 week ago
From: Grygorii Strashko <grygorii_strashko@epam.com>

Added CONFIG_COVERAGE_EXTENDED to enable coverage for .init and lib code.
When enabled - Xen .init data will not be freed.

Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
---
 xen/Kconfig.debug          | 10 ++++++++++
 xen/Rules.mk               | 13 +++++++++++++
 xen/arch/arm/setup.c       |  2 ++
 xen/arch/x86/setup.c       |  4 ++++
 xen/common/libelf/Makefile |  4 +++-
 xen/common/libfdt/Makefile |  4 +++-
 6 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
index d900d926c555..3e04e1a3992b 100644
--- a/xen/Kconfig.debug
+++ b/xen/Kconfig.debug
@@ -44,6 +44,16 @@ config COVERAGE
 
 	  If unsure, say N here.
 
+config COVERAGE_EXTENDED
+    bool "Extended Code coverage support"
+    depends on COVERAGE
+    default y
+    help
+      Enable Extended code coverage support which include .init and libs code.
+      The .init sections are not freed in this case.
+
+      If unsure, say N here.
+
 config CONDITION_COVERAGE
 	bool "Condition coverage support"
 	depends on COVERAGE && CC_HAS_MCDC
diff --git a/xen/Rules.mk b/xen/Rules.mk
index 2b28d1ac3c18..6d66a2332fb0 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -145,11 +145,18 @@ endif
 # Ensure that profile/coverage data is updated atomically
 $(call cc-option-add,cov-cflags-$(CONFIG_COVERAGE),CC,-fprofile-update=atomic)
 
+ifeq ($(CONFIG_COVERAGE_EXTENDED),y)
+$(nocov-y) $(extra-y): \
+    cov-cflags-y :=
+
+$(obj-y) $(obj-bin-y) $(extra-y) $(lib-y): _c_flags += $(cov-cflags-y)
+else
 # Reset cov-cflags-y in cases where an objects has another one as prerequisite
 $(nocov-y) $(filter %.init.o, $(obj-y) $(obj-bin-y) $(extra-y)): \
     cov-cflags-y :=
 
 $(non-init-objects): _c_flags += $(cov-cflags-y)
+endif
 
 ifeq ($(CONFIG_UBSAN),y)
 # Any -fno-sanitize= options need to come after any -fsanitize= options
@@ -260,6 +267,7 @@ $(obj)/%.o: $(src)/%.S FORCE
 
 
 quiet_cmd_obj_init_o = INIT_O  $@
+ifneq ($(CONFIG_COVERAGE_EXTENDED),y)
 define cmd_obj_init_o
     $(OBJDUMP) -h $< | while read idx name sz rest; do \
         case "$$name" in \
@@ -272,6 +280,11 @@ define cmd_obj_init_o
     done || exit $$?; \
     $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
 endef
+else
+define cmd_obj_init_o
+    $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
+endef
+endif
 
 $(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y)): $(obj)/%.init.o: $(obj)/%.o FORCE
 	$(call if_changed,obj_init_o)
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 7ad870e382c2..900585eb7099 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -68,10 +68,12 @@ static __used void noreturn init_done(void)
 {
     int rc;
 
+#if !defined(CONFIG_COVERAGE_EXTENDED)
     /* Must be done past setting system_state. */
     unregister_init_virtual_region();
 
     free_init_memory();
+#endif
 
     /*
      * We have finished booting. Mark the section .data.ro_after_init
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 872a8c63f94a..05810fa67787 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -845,6 +845,7 @@ static void noreturn init_done(void)
 
     domain_unpause_by_systemcontroller(dom0);
 
+#if !defined(CONFIG_COVERAGE_EXTENDED)
     /* MUST be done prior to removing .init data. */
     unregister_init_virtual_region();
 
@@ -867,6 +868,9 @@ static void noreturn init_done(void)
     destroy_xen_mappings(start, end);
     init_xenheap_pages(__pa(start), __pa(end));
     printk("Freed %lukB init memory\n", (end - start) >> 10);
+#else
+    (void) end, (void) start, (void)va;
+#endif
 
     /* Mark .rodata/ro_after_init as RO.  Maybe reform the superpage. */
     modify_xen_mappings((unsigned long)&__2M_rodata_start,
diff --git a/xen/common/libelf/Makefile b/xen/common/libelf/Makefile
index 917d12b006f7..337a3a8e1b35 100644
--- a/xen/common/libelf/Makefile
+++ b/xen/common/libelf/Makefile
@@ -1,5 +1,7 @@
 obj-bin-y := libelf.o
-nocov-y += libelf.o
+ifneq ($(CONFIG_COVERAGE_EXTENDED),y)
+	nocov-y += libelf.o
+endif
 libelf-objs := libelf-tools.o libelf-loader.o libelf-dominfo.o
 
 SECTIONS := text data $(SPECIAL_DATA_SECTIONS)
diff --git a/xen/common/libfdt/Makefile b/xen/common/libfdt/Makefile
index 6ce679f98f47..8c62563ccdbc 100644
--- a/xen/common/libfdt/Makefile
+++ b/xen/common/libfdt/Makefile
@@ -5,7 +5,9 @@ SECTIONS := text data $(SPECIAL_DATA_SECTIONS)
 # For CONFIG_OVERLAY_DTB, libfdt functionalities will be needed during runtime.
 ifneq ($(CONFIG_OVERLAY_DTB),y)
 OBJCOPYFLAGS := $(foreach s,$(SECTIONS),--rename-section .$(s)=.init.$(s))
-nocov-y += libfdt.o
+ifneq ($(CONFIG_COVERAGE_EXTENDED),y)
+	nocov-y += libfdt.o
+endif
 endif
 
 obj-y += libfdt.o
-- 
2.34.1
Re: [XEN][PATCH] coverage: add extended coverage capabilities
Posted by Andrew Cooper 6 days, 19 hours ago
On 03/12/2025 10:24 pm, Grygorii Strashko wrote:
> From: Grygorii Strashko <grygorii_strashko@epam.com>
>
> Added CONFIG_COVERAGE_EXTENDED to enable coverage for .init and lib code.
> When enabled - Xen .init data will not be freed.
>
> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
> ---
>  xen/Kconfig.debug          | 10 ++++++++++
>  xen/Rules.mk               | 13 +++++++++++++
>  xen/arch/arm/setup.c       |  2 ++
>  xen/arch/x86/setup.c       |  4 ++++
>  xen/common/libelf/Makefile |  4 +++-
>  xen/common/libfdt/Makefile |  4 +++-
>  6 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
> index d900d926c555..3e04e1a3992b 100644
> --- a/xen/Kconfig.debug
> +++ b/xen/Kconfig.debug
> @@ -44,6 +44,16 @@ config COVERAGE
>  
>  	  If unsure, say N here.
>  
> +config COVERAGE_EXTENDED
> +    bool "Extended Code coverage support"
> +    depends on COVERAGE
> +    default y
> +    help
> +      Enable Extended code coverage support which include .init and libs code.
> +      The .init sections are not freed in this case.
> +
> +      If unsure, say N here.

IMO this is unhelpful.  Noone wants to opt for the model we've got right
now.

Instead, I think we want:

config RELAX_INIT_CHECK
    bool

and have CONFIG_COVERAGE select it.  There's no need for any user
visible option here.


> +
>  config CONDITION_COVERAGE
>  	bool "Condition coverage support"
>  	depends on COVERAGE && CC_HAS_MCDC
> diff --git a/xen/Rules.mk b/xen/Rules.mk
> index 2b28d1ac3c18..6d66a2332fb0 100644
> --- a/xen/Rules.mk
> +++ b/xen/Rules.mk
> @@ -260,6 +267,7 @@ $(obj)/%.o: $(src)/%.S FORCE
>  
>  
>  quiet_cmd_obj_init_o = INIT_O  $@
> +ifneq ($(CONFIG_COVERAGE_EXTENDED),y)
>  define cmd_obj_init_o
>      $(OBJDUMP) -h $< | while read idx name sz rest; do \
>          case "$$name" in \
> @@ -272,6 +280,11 @@ define cmd_obj_init_o
>      done || exit $$?; \
>      $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
>  endef
> +else
> +define cmd_obj_init_o
> +    $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
> +endef
> +endif

This wants to be something more like:

@@ -261,6 +268,7 @@ $(obj)/%.o: $(src)/%.S FORCE
 
 quiet_cmd_obj_init_o = INIT_O  $@
 define cmd_obj_init_o
+ifneq ($(CONFIG_RELAX_INIT_CHECK),y)
     $(OBJDUMP) -h $< | while read idx name sz rest; do \
         case "$$name" in \
         .*.local) ;; \
@@ -269,7 +277,8 @@ define cmd_obj_init_o
             echo "Error: size of $<:$$name is 0x$$sz" >&2; \
             exit $$(expr $$idx + 1);; \
         esac; \
-    done || exit $$?; \
+    done || exit $$?
+endif
     $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
 endef

 
to avoid duplicating the OBJCOPY invocation.

> diff --git a/xen/common/libelf/Makefile b/xen/common/libelf/Makefile
> index 917d12b006f7..337a3a8e1b35 100644
> --- a/xen/common/libelf/Makefile
> +++ b/xen/common/libelf/Makefile
> @@ -1,5 +1,7 @@
>  obj-bin-y := libelf.o
> -nocov-y += libelf.o
> +ifneq ($(CONFIG_COVERAGE_EXTENDED),y)
> +	nocov-y += libelf.o
> +endif
>  libelf-objs := libelf-tools.o libelf-loader.o libelf-dominfo.o
>  
>  SECTIONS := text data $(SPECIAL_DATA_SECTIONS)
> diff --git a/xen/common/libfdt/Makefile b/xen/common/libfdt/Makefile
> index 6ce679f98f47..8c62563ccdbc 100644
> --- a/xen/common/libfdt/Makefile
> +++ b/xen/common/libfdt/Makefile
> @@ -5,7 +5,9 @@ SECTIONS := text data $(SPECIAL_DATA_SECTIONS)
>  # For CONFIG_OVERLAY_DTB, libfdt functionalities will be needed during runtime.
>  ifneq ($(CONFIG_OVERLAY_DTB),y)
>  OBJCOPYFLAGS := $(foreach s,$(SECTIONS),--rename-section .$(s)=.init.$(s))
> -nocov-y += libfdt.o
> +ifneq ($(CONFIG_COVERAGE_EXTENDED),y)
> +	nocov-y += libfdt.o
> +endif

both of these simply want to drop their nocov-ness now that coverage
does work for them.

~Andrew

Re: [XEN][PATCH] coverage: add extended coverage capabilities
Posted by Grygorii Strashko 6 days, 7 hours ago

On 04.12.25 12:02, Andrew Cooper wrote:
> On 03/12/2025 10:24 pm, Grygorii Strashko wrote:
>> From: Grygorii Strashko <grygorii_strashko@epam.com>
>>
>> Added CONFIG_COVERAGE_EXTENDED to enable coverage for .init and lib code.
>> When enabled - Xen .init data will not be freed.
>>
>> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
>> ---
>>   xen/Kconfig.debug          | 10 ++++++++++
>>   xen/Rules.mk               | 13 +++++++++++++
>>   xen/arch/arm/setup.c       |  2 ++
>>   xen/arch/x86/setup.c       |  4 ++++
>>   xen/common/libelf/Makefile |  4 +++-
>>   xen/common/libfdt/Makefile |  4 +++-
>>   6 files changed, 35 insertions(+), 2 deletions(-)
>>
>> diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
>> index d900d926c555..3e04e1a3992b 100644
>> --- a/xen/Kconfig.debug
>> +++ b/xen/Kconfig.debug
>> @@ -44,6 +44,16 @@ config COVERAGE
>>   
>>   	  If unsure, say N here.
>>   
>> +config COVERAGE_EXTENDED
>> +    bool "Extended Code coverage support"
>> +    depends on COVERAGE
>> +    default y
>> +    help
>> +      Enable Extended code coverage support which include .init and libs code.
>> +      The .init sections are not freed in this case.
>> +
>> +      If unsure, say N here.
> 
> IMO this is unhelpful.  Noone wants to opt for the model we've got right
> now.
> 
> Instead, I think we want:
> 
> config RELAX_INIT_CHECK
>      bool
> 
> and have CONFIG_COVERAGE select it.  There's no need for any user
> visible option here.
> 
> 
>> +
>>   config CONDITION_COVERAGE
>>   	bool "Condition coverage support"
>>   	depends on COVERAGE && CC_HAS_MCDC
>> diff --git a/xen/Rules.mk b/xen/Rules.mk
>> index 2b28d1ac3c18..6d66a2332fb0 100644
>> --- a/xen/Rules.mk
>> +++ b/xen/Rules.mk
>> @@ -260,6 +267,7 @@ $(obj)/%.o: $(src)/%.S FORCE
>>   
>>   
>>   quiet_cmd_obj_init_o = INIT_O  $@
>> +ifneq ($(CONFIG_COVERAGE_EXTENDED),y)
>>   define cmd_obj_init_o
>>       $(OBJDUMP) -h $< | while read idx name sz rest; do \
>>           case "$$name" in \
>> @@ -272,6 +280,11 @@ define cmd_obj_init_o
>>       done || exit $$?; \
>>       $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
>>   endef
>> +else
>> +define cmd_obj_init_o
>> +    $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
>> +endef
>> +endif
> 
> This wants to be something more like:
> 
> @@ -261,6 +268,7 @@ $(obj)/%.o: $(src)/%.S FORCE
>   
>   quiet_cmd_obj_init_o = INIT_O  $@
>   define cmd_obj_init_o
> +ifneq ($(CONFIG_RELAX_INIT_CHECK),y)
>       $(OBJDUMP) -h $< | while read idx name sz rest; do \
>           case "$$name" in \
>           .*.local) ;; \
> @@ -269,7 +277,8 @@ define cmd_obj_init_o
>               echo "Error: size of $<:$$name is 0x$$sz" >&2; \
>               exit $$(expr $$idx + 1);; \
>           esac; \
> -    done || exit $$?; \
> +    done || exit $$?
> +endif
>       $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@
>   endef
> 

above diff is not working and generates build failure :(

-- 
Best regards,
-grygorii


Re: [XEN][PATCH] coverage: add extended coverage capabilities
Posted by Grygorii Strashko 6 days, 18 hours ago
Hi Andrew,

On 04.12.25 12:02, Andrew Cooper wrote:
> On 03/12/2025 10:24 pm, Grygorii Strashko wrote:
>> From: Grygorii Strashko <grygorii_strashko@epam.com>
>>
>> Added CONFIG_COVERAGE_EXTENDED to enable coverage for .init and lib code.
>> When enabled - Xen .init data will not be freed.
>>
>> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
>> ---
>>   xen/Kconfig.debug          | 10 ++++++++++
>>   xen/Rules.mk               | 13 +++++++++++++
>>   xen/arch/arm/setup.c       |  2 ++
>>   xen/arch/x86/setup.c       |  4 ++++
>>   xen/common/libelf/Makefile |  4 +++-
>>   xen/common/libfdt/Makefile |  4 +++-
>>   6 files changed, 35 insertions(+), 2 deletions(-)
>>
>> diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
>> index d900d926c555..3e04e1a3992b 100644
>> --- a/xen/Kconfig.debug
>> +++ b/xen/Kconfig.debug
>> @@ -44,6 +44,16 @@ config COVERAGE
>>   
>>   	  If unsure, say N here.
>>   
>> +config COVERAGE_EXTENDED
>> +    bool "Extended Code coverage support"
>> +    depends on COVERAGE
>> +    default y
>> +    help
>> +      Enable Extended code coverage support which include .init and libs code.
>> +      The .init sections are not freed in this case.
>> +
>> +      If unsure, say N here.
> 
> IMO this is unhelpful.  Noone wants to opt for the model we've got right
> now.
> 
> Instead, I think we want:
> 
> config RELAX_INIT_CHECK
>      bool
> 
> and have CONFIG_COVERAGE select it.  There's no need for any user
> visible option here.
> 

So It will be always enabled if CONFIG_COVERAGE=y, Right?



-- 
Best regards,
-grygorii


Re: [XEN][PATCH] coverage: add extended coverage capabilities
Posted by Andrew Cooper 6 days, 17 hours ago
On 04/12/2025 11:00 am, Grygorii Strashko wrote:
> Hi Andrew,
>
> On 04.12.25 12:02, Andrew Cooper wrote:
>> On 03/12/2025 10:24 pm, Grygorii Strashko wrote:
>>> From: Grygorii Strashko <grygorii_strashko@epam.com>
>>>
>>> Added CONFIG_COVERAGE_EXTENDED to enable coverage for .init and lib
>>> code.
>>> When enabled - Xen .init data will not be freed.
>>>
>>> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
>>> ---
>>>   xen/Kconfig.debug          | 10 ++++++++++
>>>   xen/Rules.mk               | 13 +++++++++++++
>>>   xen/arch/arm/setup.c       |  2 ++
>>>   xen/arch/x86/setup.c       |  4 ++++
>>>   xen/common/libelf/Makefile |  4 +++-
>>>   xen/common/libfdt/Makefile |  4 +++-
>>>   6 files changed, 35 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
>>> index d900d926c555..3e04e1a3992b 100644
>>> --- a/xen/Kconfig.debug
>>> +++ b/xen/Kconfig.debug
>>> @@ -44,6 +44,16 @@ config COVERAGE
>>>           If unsure, say N here.
>>>   +config COVERAGE_EXTENDED
>>> +    bool "Extended Code coverage support"
>>> +    depends on COVERAGE
>>> +    default y
>>> +    help
>>> +      Enable Extended code coverage support which include .init and
>>> libs code.
>>> +      The .init sections are not freed in this case.
>>> +
>>> +      If unsure, say N here.
>>
>> IMO this is unhelpful.  Noone wants to opt for the model we've got right
>> now.
>>
>> Instead, I think we want:
>>
>> config RELAX_INIT_CHECK
>>      bool
>>
>> and have CONFIG_COVERAGE select it.  There's no need for any user
>> visible option here.
>>
>
> So It will be always enabled if CONFIG_COVERAGE=y, Right?

Correct.

Now I come to think of it, IIRC UBSAN is also excluded on init objects
for related reasons.  (At a later point), we can see about giving it a
similar treatment.

~Andrew