[RFC 2/4] objtool/klp: allow special section entry size overrides

Joe Lawrence <[email protected]>
Newsgroups org.kernel.vger.live-patching
Message-ID <[email protected]>
Special section entry sizes (ALT_ENTRY_SIZE, JUMP_ENTRY_SIZE,
EX_ENTRY_SIZE) are built into objtool from arch-specific headers.
When processing cached unit test objects that were built from a
different kernel version, these compiled-in sizes may not match the
objects' actual entry sizes, causing create_fake_symbols() to
incorrectly parse special sections.

Allow the user to override the compiled-in defaults via environment
variables of the same name.  When unset, behavior is unchanged.  This
will enable a klp-diff unit test runner to pass the correct entry sizes
from test metadata.

Assisted-by: Cursor:claude-4.6-opus
Signed-off-by: Joe Lawrence <[email protected]>
---
 tools/objtool/klp-diff.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index bd8d64f2f3f6..ebe4a2a087ca 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1749,6 +1749,22 @@ static int clone_sym_relocs(struct elfs *e, struct symbol *patched_sym)
 
 }
 
+static unsigned int entry_size_from_env(const char *name, unsigned int def)
+{
+	const char *str = getenv(name);
+	char *end;
+	unsigned long val;
+
+	if (!str)
+		return def;
+
+	val = strtoul(str, &end, 10);
+	if (*end || !val)
+		return def;
+
+	return val;
+}
+
 static int create_fake_symbol(struct elf *elf, struct section *sec,
 			      unsigned long offset, size_t size)
 {
@@ -1871,6 +1887,21 @@ static int create_fake_symbols(struct elf *elf)
 		}
 
 		entry_size = sec->sh.sh_entsize;
+
+		/*
+		 * Some special sections have multiple relocs per entry,
+		 * so the reloc-based heuristic below doesn't work.  Use
+		 * the arch-defined entry sizes for known special sections.
+		 */
+		if (!entry_size) {
+			if (!strcmp(sec->name, ".altinstructions"))
+				entry_size = entry_size_from_env("ALT_ENTRY_SIZE", ALT_ENTRY_SIZE);
+			else if (!strcmp(sec->name, "__jump_table"))
+				entry_size = entry_size_from_env("JUMP_ENTRY_SIZE", JUMP_ENTRY_SIZE);
+			else if (!strcmp(sec->name, "__ex_table"))
+				entry_size = entry_size_from_env("EX_ENTRY_SIZE", EX_ENTRY_SIZE);
+		}
+
 		if (!entry_size) {
 			entry_size = arch_reloc_size(sec->rsec->relocs);
 			if (sec_size(sec) != entry_size * sec_num_entries(sec->rsec)) {
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.