Skip to content

Commit dc9a2ab

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 <morbo@google.com> Signed-off-by: Pete Swain <swine@google.com>
1 parent f1b8037 commit dc9a2ab

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
@@ -4149,7 +4149,7 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
41494149
unsigned char *insn;
41504150

41514151
list_for_each_entry(sym, &kelf->symbols, list) {
4152-
if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela)
4152+
if (sym->type != STT_FUNC || !sym->sec)
41534153
continue;
41544154

41554155
switch(kelf->arch) {
@@ -4174,6 +4174,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
41744174
break;
41754175
}
41764176
case PPC64:
4177+
if (!sym->sec->rela)
4178+
continue;
41774179
list_for_each_entry(rela, &sym->sec->rela->relas, list) {
41784180
if (!strcmp(rela->sym->name, "_mcount")) {
41794181
sym->has_func_profiling = 1;
@@ -4182,6 +4184,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
41824184
}
41834185
break;
41844186
case X86_64:
4187+
if (!sym->sec->rela)
4188+
continue;
41854189
rela = list_first_entry(&sym->sec->rela->relas, struct rela,
41864190
list);
41874191
if ((rela->type != R_X86_64_NONE &&
@@ -4193,6 +4197,8 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
41934197
sym->has_func_profiling = 1;
41944198
break;
41954199
case S390:
4200+
if (!sym->sec->rela)
4201+
continue;
41964202
/* Check for compiler generated fentry nop - jgnop 0 */
41974203
insn = sym->sec->data->d_buf;
41984204
if (insn[0] == 0xc0 && insn[1] == 0x04 &&

0 commit comments

Comments
 (0)