diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 6a4848a27..27f3c8f26 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -1632,8 +1632,13 @@ static void kpatch_check_func_profiling_calls(struct kpatch_elf *kelf) (sym->parent && sym->parent->status == CHANGED)) continue; if (!sym->twin->has_func_profiling) { +#ifdef __aarch64__ + log_normal("function %s doesn't have patchable_function_entry," + " unable to patch\n", sym->name); +#else log_normal("function %s has no fentry/mcount call, unable to patch\n", sym->name); +#endif errs++; } } diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c index 7e272e2c8..4ac830a97 100644 --- a/kpatch-build/kpatch-elf.c +++ b/kpatch-build/kpatch-elf.c @@ -322,6 +322,9 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) { struct symbol *sym; struct rela *rela; +#ifdef __aarch64__ + struct section *patchable_sec = NULL; +#endif list_for_each_entry(sym, &kelf->symbols, list) { if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela) continue; @@ -332,7 +335,27 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) break; } } -#else +#elif defined(__aarch64__) + if (!patchable_sec) { + struct section *sec = find_section_by_name(&kelf->sections, + "__patchable_function_entries"); + /* + * If we can't find the __patchable_function_entries + * section or there are no relocations in it then not + * patchable. + */ + if (!sec || !sec->rela) + return; + patchable_sec = sec->rela; + } + list_for_each_entry(rela, &patchable_sec->relas, + list) { + if (rela->sym->sec && sym->sec == rela->sym->sec) { + sym->has_func_profiling = 1; + break; + } + } +#else /* x86_64 */ rela = list_first_entry(&sym->sec->rela->relas, struct rela, list); if ((rela->type != R_X86_64_NONE &&