From ac6c3ef7c88486db9224ad23fa9f720e9fa8d2cc Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Thu, 3 Nov 2022 12:00:37 +0800 Subject: [PATCH 1/4] write e_flags to the output elf file e_flags should be written to the output elf file,because it contain processor-specific flags. For example: LoongArch use e_flags to distinguish LP64/XLP32/LP32. Signed-off-by: Hongchen Zhang --- kpatch-build/kpatch-elf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c index c7d12ec93..b81d1f40e 100644 --- a/kpatch-build/kpatch-elf.c +++ b/kpatch-build/kpatch-elf.c @@ -946,6 +946,7 @@ void kpatch_write_output_elf(struct kpatch_elf *kelf, Elf *elf, char *outfile, memset(&ehout, 0, sizeof(ehout)); ehout.e_ident[EI_DATA] = eh.e_ident[EI_DATA]; ehout.e_machine = eh.e_machine; + ehout.e_flags = eh.e_flags; ehout.e_type = eh.e_type; ehout.e_version = EV_CURRENT; From a9da48eda79b49576704be2cea06f56c28368f37 Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Mon, 7 Nov 2022 19:00:41 +0800 Subject: [PATCH 2/4] fix up wrong rela of debug sections if one debug section's rela reference to __verbose section's symbol (for example, pr_debug) and some of __verbose section's symbols are included,then the __verbose section will be included. But other symbols of __verbose may be not included,then the debug section's relas reference to the not included symbols would result into bad rela in the end output elf file. So if the rela's symbol is not included,just delete that rela. Signed-off-by: Hongchen Zhang --- kpatch-build/create-diff-object.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 1967bd804..8ea091e41 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -2705,8 +2705,9 @@ static void kpatch_include_debug_sections(struct kpatch_elf *kelf) if (!is_rela_section(sec) || !is_debug_section(sec)) continue; list_for_each_entry_safe(rela, saferela, &sec->relas, list) - if (!rela->sym->sec->include) + if (!rela->sym->include || !rela->sym->sec->include) { list_del(&rela->list); + } } } From 5074275b5db0b13c652ef3fd543a3b43bfe8026f Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Thu, 17 Nov 2022 09:56:23 +0800 Subject: [PATCH 3/4] optimize section symbol replace algorithm Let's do R_X86_64_32S judgment firstly, so other architectures would run a little faster. Signed-off-by: Hongchen Zhang --- kpatch-build/create-diff-object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 8ea091e41..0da70bb88 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -1558,9 +1558,9 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) start = sym->sym.st_value; end = sym->sym.st_value + sym->sym.st_size; - if (is_text_section(relasec->base) && + if (rela->type == R_X86_64_32S && + is_text_section(relasec->base) && !is_text_section(sym->sec) && - rela->type == R_X86_64_32S && rela->addend == (long)sym->sec->sh.sh_size && end == (long)sym->sec->sh.sh_size) { From e4732c75b75d0b5bafe286155fa33c891973a496 Mon Sep 17 00:00:00 2001 From: Hongchen Zhang Date: Thu, 17 Nov 2022 10:03:24 +0800 Subject: [PATCH 4/4] reset found flag every replace loop found flag is set to false outside the whole loop of section symbol replacement. So if one replacement occur, later found check would always be ok which is not what we expected. So reset found to false before every section symbol replace. Signed-off-by: Hongchen Zhang --- kpatch-build/create-diff-object.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 0da70bb88..f2eb69258 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -1544,6 +1544,10 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) target_off = rela_target_offset(kelf, relasec, rela); + if (target_off >= (long)rela->sym->sec->sh.sh_size) + continue; + + found = false; /* * Attempt to replace references to unbundled sections * with their symbols.