From af672577b32fa96d50eb33b1be6a040852faba86 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 1 Apr 2022 15:38:53 -0700 Subject: [PATCH] create-diff-object: use toc_rela() in kpatch_line_macro_change_only() For ppc64le, if a rela goes through the .toc, it requires an extra level of indirection. Use toc_rela() here to ensure it gets the rela we care about. This will be needed for the upcoming patch which checks for `__func__`. For non-ppc64le arches, and for ppc64le relas which don't go through the .toc, toc_rela() is a no-op which just returns the rela. So this is harmless for non-.toc cases. Signed-off-by: Josh Poimboeuf --- kpatch-build/create-diff-object.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 3bdbd54..57daa5a 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -672,7 +672,7 @@ static bool kpatch_line_macro_change_only(struct kpatch_elf *kelf, { unsigned long offset, insn1_len, insn2_len; void *data1, *data2, *insn1, *insn2; - struct rela *rela; + struct rela *r, *rela; bool found, found_any = false; if (sec->status != CHANGED || @@ -720,12 +720,16 @@ static bool kpatch_line_macro_change_only(struct kpatch_elf *kelf, return false; found = false; - list_for_each_entry(rela, &sec->rela->relas, list) { + list_for_each_entry(r, &sec->rela->relas, list) { - if (rela->offset < offset + insn1_len) + if (r->offset < offset + insn1_len) continue; - if (toc_rela(rela) && toc_rela(rela)->string) + rela = toc_rela(r); + if (!rela) + continue; + + if (rela->string) continue; if (!strncmp(rela->sym->name, "__warned.", 9) ||