Skip to content

Commit 9d916b8

Browse files
committed
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 <[email protected]> Signed-off-by: Pete Swain <[email protected]>
1 parent 890c0c2 commit 9d916b8

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

kpatch-build/create-diff-object.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4048,7 +4048,7 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
40484048
unsigned char *insn;
40494049

40504050
list_for_each_entry(sym, &kelf->symbols, list) {
4051-
if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela)
4051+
if (sym->type != STT_FUNC || !sym->sec)
40524052
continue;
40534053

40544054
switch(kelf->arch) {
@@ -4077,6 +4077,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
40774077
break;
40784078
}
40794079
case PPC64:
4080+
if (!sym->sec->rela)
4081+
continue;
40804082
list_for_each_entry(rela, &sym->sec->rela->relas, list) {
40814083
if (!strcmp(rela->sym->name, "_mcount")) {
40824084
sym->has_func_profiling = 1;
@@ -4085,6 +4087,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
40854087
}
40864088
break;
40874089
case X86_64:
4090+
if (!sym->sec->rela)
4091+
continue;
40884092
rela = list_first_entry(&sym->sec->rela->relas, struct rela,
40894093
list);
40904094
if ((rela->type != R_X86_64_NONE &&
@@ -4096,6 +4100,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
40964100
sym->has_func_profiling = 1;
40974101
break;
40984102
case S390:
4103+
if (!sym->sec->rela)
4104+
continue;
40994105
/* Check for compiler generated fentry nop - jgnop 0 */
41004106
insn = sym->sec->data->d_buf;
41014107
if (insn[0] == 0xc0 && insn[1] == 0x04 &&

0 commit comments

Comments
 (0)