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
