From nobody Sat Jun 13 22:16:20 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 43671423A63; Tue, 5 May 2026 10:56:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777978568; cv=none; b=COH69sJjEXkca1OZOpCuIdtEMjKl+8Ia235eXRb/AINOqQbLbN03n2WXq3c9+u7aXv6qCV5ZT+EJ2gS3YnPsgmbIAQtS5SmgiyhTo/W5zMFfZeiL4IIbWr2bdPWCF2PkF0sbULBDbF6N1/2Va3uUCgy48Wchl8ev2rbeTsjycqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777978568; c=relaxed/simple; bh=qVn7/rSEa32PL0rW94bxbyyY9ClTm/FACcA5LdbAXgs=; h=Date:From:To:Subject:Cc:MIME-Version:Message-ID:Content-Type; b=rbV4pZU5aN+G6b4cRPr5m+sFTRkKI0h577aTCWw4LZwib+sz1ztWw6fgIKaCcMgFZvAnxbAAP4Mt3hC6CS/dCjfxiwfnXtKRRxXpg9r57oqmESnl54YopXap+XNAFYe/mUTpsbfidKLp2244ML4u4WOID2+yuvKDOJCkfre2x5A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=iSd68bGS; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=kjJT/CXP; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="iSd68bGS"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="kjJT/CXP" Date: Tue, 05 May 2026 10:56:00 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1777978562; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=jAdfwl0Q9MouXZ1sywYdAob95/ZZxYa4J04haxY+s18=; b=iSd68bGSK9V2tMGuk+Hlc+sA+eUPxyA9EffwoEKHqj51D+5bGC5DpcEHr8NXvP0Ru4fq2Y d5SYL+fCLjw7jwVEQ7wymQlTgG3sbhY4Po04bzcgO9EvHwrvL4eFXVL2p292S2zRwNi1pr WhBHqAashUOHPEbpBOshsJhQV6QHqcwuyAruJuW/Zkc6gbd9TwaTFbbWdtXFdHk8YjPoZ9 UzT6EfDZoVEkcuU/A6P49tmfTB3DYOastcBhkFzAzMsAzSSv4/g5lQyXFI1hVMwsSDUgRL DVoDpxvtML/MMQwmcCmQLjbOSHzjRNsQHBzZ1J8TMybmqQaMpSDfW4U00X6MQg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1777978562; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=jAdfwl0Q9MouXZ1sywYdAob95/ZZxYa4J04haxY+s18=; b=kjJT/CXP8wrmAyDm7zsacYnGlQB62mPbdqdXtXib1KKxZHxRt8Csrqs1v8qdjj0xRUqv5g gMP4Ab7oadXj4CBQ== From: "tip-bot2 for Josh Poimboeuf" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: objtool/core] objtool/klp: Calculate object checksums Cc: Song Liu , Josh Poimboeuf , x86@kernel.org, linux-kernel@vger.kernel.org Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <177797856055.424702.8858444934254038125.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the objtool/core branch of tip: Commit-ID: 873a2208ea31e822e0a5eea86b8a3fd07208db45 Gitweb: https://git.kernel.org/tip/873a2208ea31e822e0a5eea86b8a3fd07= 208db45 Author: Josh Poimboeuf AuthorDate: Wed, 15 Apr 2026 22:49:53 -07:00 Committer: Josh Poimboeuf CommitterDate: Mon, 04 May 2026 21:16:06 -07:00 objtool/klp: Calculate object checksums Start checksumming data objects in preparation for revamping the correlation algorithm. Acked-by: Song Liu Signed-off-by: Josh Poimboeuf --- tools/objtool/include/objtool/checksum.h | 44 +++++++---- tools/objtool/include/objtool/warn.h | 29 +++---- tools/objtool/klp-checksum.c | 89 ++++++++++++++++++----- tools/objtool/klp-diff.c | 2 +- 4 files changed, 117 insertions(+), 47 deletions(-) diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/inclu= de/objtool/checksum.h index be4eb7d..d46293f 100644 --- a/tools/objtool/include/objtool/checksum.h +++ b/tools/objtool/include/objtool/checksum.h @@ -6,28 +6,44 @@ =20 #ifdef BUILD_KLP =20 -static inline void checksum_init(struct symbol *func) +static inline void checksum_init(struct symbol *sym) { - if (func && !func->csum.state) { - func->csum.state =3D XXH3_createState(); - XXH3_64bits_reset(func->csum.state); + if (sym && !sym->csum.state) { + sym->csum.state =3D XXH3_createState(); + XXH3_64bits_reset(sym->csum.state); } } =20 -static inline void checksum_update(struct symbol *func, - struct instruction *insn, - const void *data, size_t size) +static inline void __checksum_update(struct symbol *sym, const void *data, + size_t size) { - XXH3_64bits_update(func->csum.state, data, size); - dbg_checksum(func, insn, XXH3_64bits_digest(func->csum.state)); + XXH3_64bits_update(sym->csum.state, data, size); } =20 -static inline void checksum_finish(struct symbol *func) +static inline void __checksum_update_insn(struct symbol *sym, + struct instruction *insn, + const void *data, size_t size) { - if (func && func->csum.state) { - func->csum.checksum =3D XXH3_64bits_digest(func->csum.state); - XXH3_freeState(func->csum.state); - func->csum.state =3D NULL; + __checksum_update(sym, data, size); + dbg_checksum_insn(sym, insn, XXH3_64bits_digest(sym->csum.state)); +} + +static inline void __checksum_update_object(struct symbol *sym, + unsigned long offset, + const char *what, const void *data, + size_t size) +{ + __checksum_update(sym, &offset, sizeof(offset)); + __checksum_update(sym, data, size); + dbg_checksum_object(sym, offset, what, XXH3_64bits_digest(sym->csum.state= )); +} + +static inline void checksum_finish(struct symbol *sym) +{ + if (sym && sym->csum.state) { + sym->csum.checksum =3D XXH3_64bits_digest(sym->csum.state); + XXH3_freeState(sym->csum.state); + sym->csum.state =3D NULL; } } =20 diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index fa8b7d2..595ee80 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -130,10 +130,22 @@ static inline void unindent(int *unused) { indent--; } objname ? ": " : "", \ ##__VA_ARGS__) =20 -#define dbg(args...) \ +#define dbg_checksum_insn(func, insn, checksum) \ ({ \ - if (unlikely(debug)) \ - __dbg(args); \ + if (unlikely(func->debug_checksum)) { \ + char *insn_off =3D offstr(insn->sec, insn->offset); \ + __dbg("checksum: %s(): %s %016llx", \ + func->name, insn_off, (unsigned long long)checksum);\ + free(insn_off); \ + } \ +}) + +#define dbg_checksum_object(sym, offset, what, checksum) \ +({ \ + if (unlikely(sym->debug_checksum)) \ + __dbg("checksum: %s+0x%lx: %s %016llx", \ + sym->name, offset, what, \ + (unsigned long long)checksum); \ }) =20 #define __dbg_indent(format, ...) \ @@ -147,15 +159,4 @@ static inline void unindent(int *unused) { indent--; } __dbg_indent(args); \ indent++ =20 -#define dbg_checksum(func, insn, checksum) \ -({ \ - if (unlikely(insn->sym && insn->sym->pfunc && \ - insn->sym->pfunc->debug_checksum)) { \ - char *insn_off =3D offstr(insn->sec, insn->offset); \ - __dbg("checksum: %s %s %016llx", \ - func->name, insn_off, (unsigned long long)checksum);\ - free(insn_off); \ - } \ -}) - #endif /* _WARN_H */ diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c index e4a910f..19653db 100644 --- a/tools/objtool/klp-checksum.c +++ b/tools/objtool/klp-checksum.c @@ -35,7 +35,7 @@ static int checksum_debug_init(struct objtool_file *file) *comma =3D '\0'; =20 for_each_sym_by_name(file->elf, s, sym) { - if (!is_func_sym(sym)) + if (!is_func_sym(sym) && !is_object_sym(sym)) continue; sym->debug_checksum =3D 1; found =3D true; @@ -66,14 +66,14 @@ static void checksum_update_insn(struct objtool_file *f= ile, struct symbol *func, if (insn->fake) return; =20 - checksum_update(func, insn, insn->sec->data->d_buf + insn->offset, insn->= len); + __checksum_update_insn(func, insn, insn->sec->data->d_buf + insn->offset,= insn->len); =20 if (!reloc) { struct symbol *call_dest =3D insn_call_dest(insn); =20 if (call_dest) - checksum_update(func, insn, call_dest->demangled_name, - strlen(call_dest->demangled_name)); + __checksum_update_insn(func, insn, call_dest->demangled_name, + strlen(call_dest->demangled_name)); goto alts; } =20 @@ -84,7 +84,7 @@ static void checksum_update_insn(struct objtool_file *fil= e, struct symbol *func, char *str; =20 str =3D sym->sec->data->d_buf + sym->offset + offset; - checksum_update(func, insn, str, strlen(str)); + __checksum_update_insn(func, insn, str, strlen(str)); goto alts; } =20 @@ -96,8 +96,9 @@ static void checksum_update_insn(struct objtool_file *fil= e, struct symbol *func, offset -=3D sym->offset; } =20 - checksum_update(func, insn, sym->demangled_name, strlen(sym->demangled_na= me)); - checksum_update(func, insn, &offset, sizeof(offset)); + __checksum_update_insn(func, insn, sym->demangled_name, + strlen(sym->demangled_name)); + __checksum_update_insn(func, insn, &offset, sizeof(offset)); =20 alts: for (alt =3D insn->alts; alt; alt =3D alt->next) { @@ -108,12 +109,13 @@ alts: break; in_alt =3D true; =20 - checksum_update(func, insn, &alt->type, sizeof(alt->type)); + __checksum_update_insn(func, insn, &alt->type, + sizeof(alt->type)); =20 if (alt_group && alt_group->orig_group) { struct instruction *alt_insn; =20 - checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feat= ure)); + __checksum_update_insn(func, insn, &alt_group->feature,sizeof(alt_group= ->feature)); =20 for (alt_insn =3D alt->insn; alt_insn; alt_insn =3D next_insn_same_sec(= file, alt_insn)) { checksum_update_insn(file, func, alt_insn); @@ -128,31 +130,82 @@ alts: } } =20 +static void checksum_update_object(struct objtool_file *file, struct symbo= l *sym) +{ + struct reloc *reloc; + + __checksum_update_object(sym, 0, "len", &sym->len, sizeof(sym->len)); + + if (sym->sec->data->d_buf) + __checksum_update_object(sym, 0, "data", + sym->sec->data->d_buf + sym->offset, + sym->len); + + sym_for_each_reloc(file->elf, sym, reloc) { + unsigned long sym_offset =3D reloc_offset(reloc) - sym->offset; + struct symbol *target =3D reloc->sym; + s64 offset; + + offset =3D reloc_addend(reloc); + + if (is_string_sec(target->sec)) { + char *str; + + str =3D target->sec->data->d_buf + target->offset + offset; + __checksum_update_object(sym, sym_offset, + "reloc string", str, strlen(str)); + continue; + } + + if (is_sec_sym(target)) { + target =3D find_symbol_containing(reloc->sym->sec, offset); + if (!target) + continue; + + offset -=3D target->offset; + } + + __checksum_update_object(sym, sym_offset, "reloc name", + target->demangled_name, + strlen(target->demangled_name)); + __checksum_update_object(sym, sym_offset, "reloc addend", + &offset, sizeof(offset)); + } +} + int calculate_checksums(struct objtool_file *file) { struct instruction *insn; - struct symbol *func; + struct symbol *sym; =20 if (checksum_debug_init(file)) return -1; =20 - for_each_sym(file->elf, func) { + for_each_sym(file->elf, sym) { + /* * Skip cold subfunctions and aliases: they share the * parent's checksum via func_for_each_insn() which * follows func->cfunc into the cold subfunction. */ - if (!is_func_sym(func) || is_cold_func(func) || - is_alias_sym(func) || !func->len) + if (is_cold_func(sym) || is_alias_sym(sym) || !sym->len || + !sym->sec || !sym->sec->data) continue; =20 - checksum_init(func); + if (is_func_sym(sym)) { + checksum_init(sym); + func_for_each_insn(file, sym, insn) + checksum_update_insn(file, sym, insn); + checksum_finish(sym); =20 - func_for_each_insn(file, func, insn) - checksum_update_insn(file, func, insn); + } else if (is_object_sym(sym)) { + checksum_init(sym); + checksum_update_object(file, sym); + checksum_finish(sym); + } =20 - checksum_finish(func); } + return 0; } =20 @@ -213,7 +266,7 @@ int cmd_klp_checksum(int argc, const char **argv) int ret; =20 const struct option options[] =3D { - OPT_STRING(0, "debug-checksum", &opts.debug_checksum, "funcs", "enable c= hecksum debug output"), + OPT_STRING(0, "debug-checksum", &opts.debug_checksum, "syms", "enable ch= ecksum debug output"), OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), OPT_END(), }; diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 95359ad..5f13d75 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -201,7 +201,7 @@ static int read_sym_checksums(struct elf *elf) return -1; } =20 - if (is_func_sym(sym)) + if (is_func_sym(sym) || is_object_sym(sym)) sym->csum.checksum =3D sym_checksum->checksum; } =20