From 717db96e56118b4a457f7bf6988cb7c3d1af6b12 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Fri, 8 Nov 2024 11:52:51 +0800 Subject: [PATCH] adapt kpatch_bundle_symbols to kernel change and fix function ptr relocation --- kpatch-build/create-diff-object.c | 10 ++++++++-- kpatch-build/kpatch-build | 1 + kpatch-build/lookup.c | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 6f3937f..fc756f3 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -229,7 +229,8 @@ static void kpatch_bundle_symbols(struct kpatch_elf *kelf) list_for_each_entry(sym, &kelf->symbols, list) { if (is_bundleable(sym)) { if (sym->sym.st_value != 0 && - !is_gcc6_localentry_bundled_sym(sym)) { + !is_gcc6_localentry_bundled_sym(sym) && + !(getenv("CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS") && sym->sym.st_value == 20)) { ERROR("symbol %s at offset %lu within section %s, expected 0", sym->name, sym->sym.st_value, sym->sec->name); @@ -3228,10 +3229,15 @@ static int kpatch_is_core_module_symbol(char *name) static int function_ptr_rela(const struct rela *rela) { const struct rela *rela_toc = toc_rela(rela); + int entry_offset = 0; + + if (getenv("CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS")) + entry_offset = 20; return (rela_toc && rela_toc->sym->type == STT_FUNC && !rela_toc->sym->parent && - rela_toc->addend == (int)rela_toc->sym->sym.st_value && + (rela_toc->addend == (int)rela_toc->sym->sym.st_value || + rela_toc->addend == (int)rela_toc->sym->sym.st_value - entry_offset) && (rela->type == R_X86_64_32S || rela->type == R_PPC64_TOC16_HA || rela->type == R_PPC64_TOC16_LO_DS || diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build index 6a0645a..782007e 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build @@ -930,6 +930,7 @@ grep -q "CONFIG_JUMP_LABEL=y" "" && CONFIG_JUMP_LABEL=1 grep -q "CONFIG_MODVERSIONS=y" "$CONFIGFILE" && CONFIG_MODVERSIONS=1 grep -q "CONFIG_CC_IS_CLANG=y" "$CONFIGFILE" && CONFIG_CC_IS_CLANG=1 grep -q "CONFIG_LD_IS_LLD=y" "$CONFIGFILE" && CONFIG_LD_IS_LLD=1 +grep -q "CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y" "$CONFIGFILE" && export CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=1 # unsupported kernel option checking grep -q "CONFIG_DEBUG_INFO_SPLIT=y" "$CONFIGFILE" && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported" diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c index 458b447..2fe1fd0 100644 --- a/kpatch-build/lookup.c +++ b/kpatch-build/lookup.c @@ -107,6 +107,11 @@ static bool locals_match(struct lookup_table *table, int idx, continue; if (table_sym->type != STT_FUNC && table_sym->type != STT_OBJECT) continue; + /* + * BTF info may not be enabled when compiling kernel, but exists in vmlinux symtab + */ + if (!strncmp(table_sym->name, "__BTF_ID__", 10)) + continue; found = 0; sym = file_sym; -- 2.33.0