From dc9a2ab1625b6859bccdc12190b19ee8f751d95a Mon Sep 17 00:00:00 2001 From: Pete Swain Date: Wed, 5 Oct 2022 00:22:20 -0700 Subject: [PATCH] arm64 leaf-function fix On arm64, kpatch_find_func_profiling_calls() was skipping leaf functions, with no relocations, so they weren't patchable. Here other archs need to walk a function's reloc entries to check for __fentry__ or __mcount, so it's valid to skip over functions without sym->sec->rela, because they cannot be patchable, else they would have at least an __fentry__ call relocation. But arm64 marks functions patchable in a different way, with per-func __patchable_function_entries sections referring _to_ the func, not relocations _within_ the func, so a function w/o relocations for text or data can still be patchable. Move the sym->sec->rela check to the per-arch paths. This allows gcc-static-local-var-5.patch to generate livepatch, on arm64 & x86 Suggested-By: Bill Wendling Signed-off-by: Pete Swain --- kpatch-build/create-diff-object.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 212e8f226..2eaa8f578 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -4149,7 +4149,7 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) unsigned char *insn; list_for_each_entry(sym, &kelf->symbols, list) { - if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela) + if (sym->type != STT_FUNC || !sym->sec) continue; switch(kelf->arch) { @@ -4174,6 +4174,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) break; } case PPC64: + if (!sym->sec->rela) + continue; list_for_each_entry(rela, &sym->sec->rela->relas, list) { if (!strcmp(rela->sym->name, "_mcount")) { sym->has_func_profiling = 1; @@ -4182,6 +4184,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) } break; case X86_64: + if (!sym->sec->rela) + continue; rela = list_first_entry(&sym->sec->rela->relas, struct rela, list); if ((rela->type != R_X86_64_NONE && @@ -4193,6 +4197,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) sym->has_func_profiling = 1; break; case S390: + if (!sym->sec->rela) + continue; /* Check for compiler generated fentry nop - jgnop 0 */ insn = sym->sec->data->d_buf; if (insn[0] == 0xc0 && insn[1] == 0x04 &&