Skip to content

Commit 2a21437

Browse files
author
Suraj Jitindar Singh
committed
kpatch-build: Add sym->has_func_profiling support for aarch64
The "has_function_profiling" support field in the symbol struct is used to show that a function symbol is able to be patched. This is necessary to check that functions which need to be patched are able to be. On arm64 this means the presence of 2 NOP instructions at function entry which are patched by ftrace to call the ftrace handling code. These 2 NOPs are inserted by the compiler and the location of them is recorded in a section called "__patchable_function_entries". Check whether a symbol has a corresponding entry in the "__patchable_function_entries" section and if so mark it as "has_func_profiling". Additionally updated the error message in kpatch_check_func_profiling_calls() to accurately reflect the cause of the failure. Signed-off-by: Suraj Jitindar Singh <surajjs@amazon.com>
1 parent 61fc3f1 commit 2a21437

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

kpatch-build/create-diff-object.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,8 +1632,13 @@ static void kpatch_check_func_profiling_calls(struct kpatch_elf *kelf)
16321632
(sym->parent && sym->parent->status == CHANGED))
16331633
continue;
16341634
if (!sym->twin->has_func_profiling) {
1635+
#ifdef __aarch64__
1636+
log_normal("function %s doesn't have patchable_function_entry,"
1637+
" unable to patch\n", sym->name);
1638+
#else
16351639
log_normal("function %s has no fentry/mcount call, unable to patch\n",
16361640
sym->name);
1641+
#endif
16371642
errs++;
16381643
}
16391644
}

kpatch-build/kpatch-elf.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,9 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
322322
{
323323
struct symbol *sym;
324324
struct rela *rela;
325+
#ifdef __aarch64__
326+
struct section *patchable_sec = NULL;
327+
#endif
325328
list_for_each_entry(sym, &kelf->symbols, list) {
326329
if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela)
327330
continue;
@@ -332,7 +335,27 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
332335
break;
333336
}
334337
}
335-
#else
338+
#elif defined(__aarch64__)
339+
if (!patchable_sec) {
340+
struct section *sec = find_section_by_name(&kelf->sections,
341+
"__patchable_function_entries");
342+
/*
343+
* If we can't find the __patchable_function_entries
344+
* section or there are no relocations in it then not
345+
* patchable.
346+
*/
347+
if (!sec || !sec->rela)
348+
return;
349+
patchable_sec = sec->rela;
350+
}
351+
list_for_each_entry(rela, &patchable_sec->relas,
352+
list) {
353+
if (rela->sym->sec && sym->sec == rela->sym->sec) {
354+
sym->has_func_profiling = 1;
355+
break;
356+
}
357+
}
358+
#else /* x86_64 */
336359
rela = list_first_entry(&sym->sec->rela->relas, struct rela,
337360
list);
338361
if ((rela->type != R_X86_64_NONE &&

0 commit comments

Comments
 (0)