[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