All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: Bill Wendling <morbo@google.com>, Chuck Wolber <chuck@wolber.net>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	Justin Stitt <justinstitt@google.com>,
	llvm@lists.linux.dev, Marco Elver <elver@google.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Nathan Chancellor <nathan@kernel.org>,
	Nick Desaulniers <ndesaulniers@google.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@kernel.org>
Subject: [RFC PATCH 11/20] objtool: Detect code coverage instrumentation in noinstr code
Date: Wed, 28 Oct 2026 07:59:35 -0400	[thread overview]
Message-ID: <20261028120034.871983-12-sashal@kernel.org> (raw)
In-Reply-To: <20261028120034.871983-1-sashal@kernel.org>

gcov and Clang's source-based code coverage update their counters
inline, rather than by calling into a runtime like KCOV does, so
coverage instrumentation in noinstr code goes unnoticed by the noinstr
validation of call destinations.

Flag instructions in noinstr code, outside of instrumentation_begin()
and instrumentation_end() sections, that reference coverage counters:
GCC's __gcov<N>.* counters (including the MC/DC counters), Clang's gcov
__llvm_gcov_ctr* counters, and the __llvm_prf_cnts and __llvm_prf_bits
sections of Clang's source-based code coverage.

Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/objtool/check.c | 53 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 464f6c9d9ff0b..6382d2a44ef2b 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4,6 +4,7 @@
  */
 
 #define _GNU_SOURCE /* memmem() */
+#include <ctype.h>
 #include <fnmatch.h>
 #include <string.h>
 #include <stdlib.h>
@@ -3507,6 +3508,52 @@ static inline bool noinstr_call_dest(struct objtool_file *file,
 	return false;
 }
 
+/*
+ * Code coverage instrumentation (gcov, Clang's source-based coverage) updates
+ * its counters inline rather than through calls, so it can't be caught by
+ * checking the call destinations of noinstr code.
+ */
+static bool is_coverage_counter(struct symbol *sym)
+{
+	if (!strcmp(sym->sec->name, "__llvm_prf_cnts") ||
+	    !strcmp(sym->sec->name, "__llvm_prf_bits"))
+		return true;
+
+	return (strstarts(sym->name, "__gcov") && isdigit((unsigned char)sym->name[6])) ||
+	       strstarts(sym->name, "__llvm_gcov_ctr");
+}
+
+static bool insn_updates_coverage(struct objtool_file *file,
+				  struct instruction *insn)
+{
+	struct symbol *sym;
+	struct reloc *reloc;
+
+	for (reloc = insn_reloc(file, insn);
+	     reloc;
+	     reloc = find_reloc_by_dest_range(file->elf, insn->sec,
+					      reloc_offset(reloc) + 1,
+					      insn->offset + insn->len -
+					      (reloc_offset(reloc) + 1))) {
+
+		sym = reloc->sym;
+		if (!sym->sec)
+			continue;
+
+		if (is_sec_sym(sym)) {
+			sym = find_symbol_containing(sym->sec,
+						     arch_insn_adjusted_addend(insn, reloc));
+			if (!sym)
+				sym = reloc->sym;
+		}
+
+		if (is_coverage_counter(sym))
+			return true;
+	}
+
+	return false;
+}
+
 static int validate_call(struct objtool_file *file,
 			 struct instruction *insn,
 			 struct insn_state *state)
@@ -3680,6 +3727,12 @@ static int validate_insn(struct objtool_file *file, struct symbol *func,
 	if (statep->noinstr)
 		statep->instr += insn->instr;
 
+	if (statep->noinstr && statep->instr <= 0 &&
+	    insn_updates_coverage(file, insn)) {
+		WARN_INSN(insn, "coverage counter update in .noinstr.text section");
+		return 1;
+	}
+
 	if (insn->hint) {
 		if (insn->restore) {
 			struct instruction *save_insn, *i;
-- 
2.53.0


  parent reply	other threads:[~2026-10-28 12:01 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 11:59 [RFC PATCH 00/20] Unify code coverage and add Clang source-based coverage with MC/DC Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 01/20] coverage: move gcov and kcov under kernel/coverage/ Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 02/20] kbuild: unify static coverage instrumentation as COVERAGE_PROFILE Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 04/20] compiler_types.h: Don't instrument __always_inline functions for coverage Sasha Levin
2026-10-28 13:51   ` Peter Zijlstra
2026-10-28 14:01     ` Peter Zijlstra
2026-10-28 16:45       ` Sasha Levin
2026-10-29  5:49         ` Chuck Wolber
2026-10-28 11:59 ` [RFC PATCH 07/20] perf: Always inline the empty perf_lopwr_cb() stub Sasha Levin
2026-10-29 12:01   ` sashiko-bot
2026-10-28 11:59 ` [RFC PATCH 10/20] x86/sev: Use non-instrumented bitops in the GHCB accessors Sasha Levin
2026-10-28 11:59 ` Sasha Levin [this message]
2026-10-28 14:11   ` [RFC PATCH 11/20] objtool: Detect code coverage instrumentation in noinstr code Peter Zijlstra
2026-10-28 16:45     ` Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 12/20] x86/sev: Stop excluding noinstr.o from code coverage Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 14/20] coverage: add Clang's source-based " Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 15/20] x86: Enable " Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 16/20] coverage: add MC/DC measurement Sasha Levin
2026-10-28 19:14   ` Nathan Chancellor
2026-10-28 20:39     ` Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 18/20] kconfig: add CC_HAS_CONDITION_COVERAGE for MC/DC support detection Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 19/20] gcov: add MC/DC condition coverage support Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 20/20] Documentation: dev-tools: document the common code coverage interface Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261028120034.871983-12-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=chuck@wolber.net \
    --cc=elver@google.com \
    --cc=jpoimboe@kernel.org \
    --cc=justinstitt@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=mhiramat@kernel.org \
    --cc=morbo@google.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=peterz@infradead.org \
    --cc=tglx@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.