[PATCH 21/21] sandbox: add support for coverage info generation

Ahmad Fatoum a.fatoum at pengutronix.de
Thu Jun 5 04:35:30 PDT 2025


To be able to check how well along the fuzzer can descend into the
parsers, add first coverage support and a target to generate HTML
coverage information.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 .gitignore                      |  6 ++++++
 Documentation/devel/fuzzing.rst | 30 ++++++++++++++++++++++++++++++
 Makefile                        | 23 ++++++++++++++++++++++-
 arch/sandbox/Kconfig.debug      |  7 +++++++
 arch/sandbox/Makefile           |  7 +++++++
 5 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 0bee67af4881..c37188a9f315 100644
--- a/.gitignore
+++ b/.gitignore
@@ -98,3 +98,9 @@ GTAGS
 /allrandom.config
 /allyes.config
 /compile_commands.json
+
+# coverage data
+default.profdata
+default.profraw
+coverage.info
+coverage_html/
diff --git a/Documentation/devel/fuzzing.rst b/Documentation/devel/fuzzing.rst
index 3151246aef1a..4b6d565a470a 100644
--- a/Documentation/devel/fuzzing.rst
+++ b/Documentation/devel/fuzzing.rst
@@ -62,6 +62,36 @@ We maintain a corpus for every fuzz test on
 
 This helps bootstrap the fuzzer, so it can exercise new paths more quickly.
 
+Determining Source Code Coverage
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+	Coverage instrumentation is currently only supported with LLVM
+        and sandbox.
+
+To collect coverage information, barebox must be built with ``CONFIG_GCOV=y``.
+The linking process will take much longer than usual, but once done, running
+barebox will produce coverage information.
+
+.. code-block:: bash
+
+	images/fuzz-filetype -max_total_time=60 -max_len=2048
+
+After the process exists regularly (i.e., not aborted with ctrl+C!),
+it will produce a ``default.profraw`` file, which needs to be further
+processed:
+
+.. code-block:: bash
+
+	make coverage-html
+
+This will produce a ``${KBUILD_OUTPUT}/coverage_html/`` directory, which can be
+inspected by a web browser:
+
+.. code-block:: bash
+
+	firefox coverage_html/index.html
+
 Adding a fuzzer
 ^^^^^^^^^^^^^^^
 
diff --git a/Makefile b/Makefile
index df0770e832e1..80a403f61dda 100644
--- a/Makefile
+++ b/Makefile
@@ -429,6 +429,8 @@ OBJCOPY		= $(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX)
 OBJDUMP		= $(LLVM_PREFIX)llvm-objdump$(LLVM_SUFFIX)
 READELF		= $(LLVM_PREFIX)llvm-readelf$(LLVM_SUFFIX)
 STRIP		= $(LLVM_PREFIX)llvm-strip$(LLVM_SUFFIX)
+PROFDATA	= $(LLVM_PREFIX)llvm-profdata$(LLVM_SUFFIX)
+COV		= $(LLVM_PREFIX)llvm-cov$(LLVM_SUFFIX)
 else
 CC		= $(CROSS_COMPILE)gcc
 CXX		= $(CROSS_COMPILE)g++
@@ -450,6 +452,7 @@ PERL		= perl
 PYTHON3		= python3
 CHECK		= sparse
 MKIMAGE		= mkimage
+GENHTML		= genhtml
 BASH		= bash
 KGZIP		= gzip
 KBZIP2		= bzip2
@@ -518,7 +521,7 @@ LDFLAGS_elf += $(LDFLAGS_common) --nmagic -s
 
 export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC CXX
 export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL PYTHON3 UTS_MACHINE
-export LEX YACC
+export LEX YACC PROFDATA COV GENHTML
 export HOSTCXX CHECK CHECKFLAGS MKIMAGE
 export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ
 export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
@@ -1418,6 +1421,24 @@ endif
 	@echo  'Execute "make" or "make all" to build all targets marked with [*] '
 	@echo  'For further info see the documentation'
 
+# Code Coverage
+# ---------------------------------------------------------------------------
+
+barebox.coverage_html: barebox.coverage-info
+	genhtml -o $@ $<
+
+barebox.coverage-info: default.profdata
+	$(COV) export --format=lcov -instr-profile $< $(objtree)/barebox >$@
+
+default.profdata: $(srctree)/default.profraw
+	$(PROFDATA) merge -sparse $< -o $@
+
+# We intentionally don't depend on barebox being built as that can take >10
+# minutes when coverage is enabled
+PHONY += coverage-html
+coverage-html: barebox.coverage_html
+	@echo "HTML coverage generated to $(objtree)/$<"
+
 # Generate tags for editors
 # ---------------------------------------------------------------------------
 quiet_cmd_tags = GEN     $@
diff --git a/arch/sandbox/Kconfig.debug b/arch/sandbox/Kconfig.debug
index 4a754e389964..82ee355815c3 100644
--- a/arch/sandbox/Kconfig.debug
+++ b/arch/sandbox/Kconfig.debug
@@ -8,3 +8,10 @@ config ASAN
 
 	  This is the hosted implementation for sandbox as opposed to
 	  KASAN, which is the bare-metal implementation.
+
+config GCOV
+	bool "Enable gcov support"
+	depends on CC_IS_CLANG
+	help
+	  This option allows developers to retrieve coverage data from a sandbox
+	  session. Note that this will greatly increases link times.
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
index f33d7fa961da..f9d79e9a7d15 100644
--- a/arch/sandbox/Makefile
+++ b/arch/sandbox/Makefile
@@ -79,6 +79,13 @@ SANDBOX_LIBS += -Wl,-Bstatic -L"$(CONFIG_CLANG_RUNTIME_DIR)" \
 		-lclang_rt.fuzzer_no_main-$(LIBARCH-y) -Wl,-Bdynamic
 endif
 
+ifeq ($(CONFIG_GCOV),y)
+GCOV_OPT-$(CONFIG_CC_IS_CLANG) = -fprofile-instr-generate -fcoverage-mapping
+GCOV_OPT-$(CONFIG_CC_IS_GCC) = -fprofile-arcs -ftest-coverage
+KBUILD_CFLAGS += $(GCOV_OPT-y)
+BAREBOX_LDFLAGS += $(GCOV_OPT-y)
+endif
+
 ifeq ($(CONFIG_SANDBOX_LINUX_I386),y)
 KBUILD_CFLAGS += -m32
 KBUILD_LDFLAGS += -m elf_i386
-- 
2.39.5




More information about the barebox mailing list