Skip to content

Commit

Permalink
arm64 leaf-function fix
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Pete Swain <[email protected]>
  • Loading branch information
swine committed Jan 9, 2023
1 parent f1b8037 commit dc9a2ab
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion kpatch-build/create-diff-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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 &&
Expand All @@ -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 &&
Expand Down

0 comments on commit dc9a2ab

Please sign in to comment.