From ace5550f59e465101808a46d8f46f436850fb72c Mon Sep 17 00:00:00 2001 From: George Guo Date: Thu, 5 Dec 2024 15:17:43 +0800 Subject: [PATCH] kpatch/LoongArch: change local labels with sections symbols Here fix error like: "tcp.o: symbol changed sections: .LBB7266. create-diff-object: unreconcilable difference". Due to LoongArch GCC generating local labels such as .LBB7266, it is difficult to compare the modified sections in the corresponding object files of the two files before and after the patch, so change them with sections symbols in rela section, and delete them in other sections. Co-developed-by: zhanghongchen Signed-off-by: George Guo --- kpatch-build/kpatch-elf.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c index b12c6107..e4f2927c 100755 --- a/kpatch-build/kpatch-elf.c +++ b/kpatch-build/kpatch-elf.c @@ -336,6 +336,22 @@ static void kpatch_create_rela_list(struct kpatch_elf *kelf, rela->sym->name, rela->addend); } + if (kelf->arch == LOONGARCH64) { + /* + * LoongArch GCC creates local labels such as .LBB7266, + * replace them with section symbols. + */ + if (rela->sym->sec && (rela->sym->type == STT_NOTYPE) && + (rela->sym->bind == STB_LOCAL)) { + log_debug("local label: %s -> ", rela->sym->name); + + rela->addend += rela->sym->sym.st_value; + rela->sym = rela->sym->sec->secsym; + log_debug("section symbol: %s\n", rela->sym->name); + } + } + + if (skip) continue; log_debug("offset %d, type %d, %s %s %ld", rela->offset, @@ -625,6 +641,18 @@ struct kpatch_elf *kpatch_elf_open(const char *name) if (find_section_by_name(&kelf->sections, "__patchable_function_entries")) kelf->has_pfe = true; + if (kelf->arch == LOONGARCH64) { + struct symbol *sym, *tmp; + + /* Delete local labels created by LoongArch GCC */ + list_for_each_entry_safe(sym, tmp, &kelf->symbols, list) { + if (sym->sec && !is_rela_section(sym->sec) && + (sym->type == STT_NOTYPE) && + (sym->bind == STB_LOCAL)) + list_del(&sym->list); + } + } + return kelf; }